changeset 18976:dcb260e7a648

maint: Periodic merge of gui-release to default.
author John W. Eaton <jwe@octave.org>
date Fri, 01 Aug 2014 12:10:05 -0400
parents 19cb2530c16b (diff) c59745865c7f (current diff)
children fe505ff21d5b
files build-aux/common.mk configure.ac doc/interpreter/external.txi libgui/qterminal/libqterminal/unix/TerminalView.cpp libgui/src/m-editor/file-editor-interface.h libgui/src/m-editor/octave-qscintilla.cc libgui/src/main-window.cc libgui/src/settings-dialog.cc libgui/src/shortcut-manager.cc libinterp/parse-tree/lex.ll libinterp/parse-tree/module.mk libinterp/parse-tree/oct-parse.in.yy m4/acinclude.m4
diffstat 570 files changed, 21929 insertions(+), 9262 deletions(-) [+]
line wrap: on
line diff
--- a/Makefile.am	Fri Aug 01 09:06:21 2014 -0400
+++ b/Makefile.am	Fri Aug 01 12:10:05 2014 -0400
@@ -129,6 +129,11 @@
 check: all
 	$(MAKE) -C test check
 
+if AMCOND_HAVE_LLVM
+check-jit: all
+	$(MAKE) -C test check-jit
+endif
+
 run-octave: run-octave.in Makefile
 	@$(do_subst_script_vals)
 	chmod a+rx "$@"
--- a/NEWS	Fri Aug 01 09:06:21 2014 -0400
+++ b/NEWS	Fri Aug 01 12:10:05 2014 -0400
@@ -1,3 +1,102 @@
+Summary of important user-visible changes for version 4.2:
+---------------------------------------------------------
+
+ ** A new syntax for object oriented programming termed classdef has been
+    introduced.  See the manual for more extensive documentation of the
+    classdef interface.
+    
+    New keywords:
+
+      classdef      endclassdef
+      enumeration   endenumeration
+      events        endevents
+      methods       endmethods
+      properties    endproperties
+
+ ** Interpolation function changes for Matlab compatibility
+
+    The interpolation method 'cubic' is now equivalent to 'pchip'
+    for interp1, interp2, and interp3.  Previously, 'cubic' was equivalent
+    to 'spline' for interp2.  This may produce different results as 'spline'
+    has continuous 1st and 2nd derivatives while 'pchip' only has a continuous
+    1st derivative.
+
+ ** Integer formats used in the printf family of functions now work for
+    64-bit integers and are more compatible with Matlab when printing
+    non-integer values.  Now instead of truncating, Octave will switch
+    the effective format to '%g' in the following circumstances:
+
+      * the value of an integer type (int8, uint32, etc.) value exceeds
+        the maximum for the format specifier.  For '%d', the limit is
+        intmax ('int64') and for '%u' it is intmax ('uint64').
+
+      * round(x) != x or the value is outside the range allowed by the
+        integer format specifier.
+
+    There is still one difference:  Matlab switches to '%e' and Octave
+    is currently switching to '%g'.
+
+ ** Z-order stacking issues with patches, grid lines, and line object
+    plot markers for on screen display and printing have all been resolved.
+    For 2-D plots the axis grid lines can be placed on top of the plot
+    with set (gca, "layer", "top").
+
+ ** The patch graphic object has been overhauled.  It now produces visual
+    results equivalent to Matlab even for esoteric combinations of
+    faces/vertices/cdata.
+
+ ** The polar() plot function now draws a circular theta axis and 
+    radial rho axis rather than using a rectangular x/y axis.
+
+ ** linkprop has been completely re-coded for performance and Matlab
+    compatibility.  It now returns a linkprop object which must be stored
+    in a variable for as long as the graphic objects should remain linked.
+    To unlink properties use 'clear hlink' where hlink is the variable
+    containing the linkprop object.
+
+ ** Other new functions added in 4.2:
+
+      bandwidth            isbanded        javachk
+      dir_in_loadpath      isdiag          linkaxes
+      hgload               istril          numfields
+      hgsave               istriu
+
+ ** Deprecated functions.
+
+    The following functions have been deprecated in Octave 4.2 and will
+    be removed from Octave 4.6 (or whatever version is the second major
+    release after 4.2):
+
+      bicubic
+      find_dir_in_path
+      nfields
+
+    The following functions were deprecated in Octave 3.8 and have been
+    removed from Octave 4.2.
+
+      default_save_options    java_new            
+      gen_doc_cache           java_unsigned_conversion  
+      interp1q                javafields                
+      isequalwithequalnans    javamethods               
+      java_convert_matrix     re_read_readline_init_file
+      java_debug              read_readline_init_file   
+      java_invoke             saving_history            
+                              
+    The following keywords were deprecated in Octave 3.8 and have been
+    removed from Octave 4.2
+
+      static
+
+    The following configuration variables were deprecated in Octave 3.8
+    and have been removed from Octave 4.2
+
+      CC_VERSION  (now GCC_VERSION)
+      CXX_VERSION (now GXX_VERSION)
+
+    The internal class <Octave_map> was deprecated in Octave 3.8 and has
+    been removed from Octave 4.2.  Replacement classes are
+    <octave_map> (struct array) or <octave_scalar_map> for a single structure.
+
 Summary of important user-visible changes for version 4.0:
 ---------------------------------------------------------
 
@@ -27,7 +126,7 @@
 
  ** Other new functions added in 4.0.0:
 
-    validateattributes
+      validateattributes
 
  ** Deprecated functions.
 
--- a/bootstrap.conf	Fri Aug 01 09:06:21 2014 -0400
+++ b/bootstrap.conf	Fri Aug 01 12:10:05 2014 -0400
@@ -50,10 +50,12 @@
   isatty
   largefile
   link
+  log
   log2
   log2-ieee
   log2f
   log2f-ieee
+  logf
   lstat
   malloc-gnu
   mbrtowc
@@ -66,8 +68,8 @@
   open
   opendir
   pathmax
+  progname
   putenv
-  progname
   readdir
   readlink
   realloc-gnu
--- a/build-aux/common.mk	Fri Aug 01 09:06:21 2014 -0400
+++ b/build-aux/common.mk	Fri Aug 01 12:10:05 2014 -0400
@@ -108,8 +108,6 @@
 # C compiler flags.
 
 CC = @CC@
-## FIXME: CC_VERSION is deprecated and should be removed in version 3.12
-CC_VERSION = @CC_VERSION@
 GCC_VERSION = @GCC_VERSION@
 CPICFLAG = @CPICFLAG@
 XTRA_CFLAGS = @XTRA_CFLAGS@
@@ -132,8 +130,6 @@
 # C++ compiler flags.
 
 CXX = @CXX@
-## FIXME: CXX_VERSION is deprecated and should be removed in version 3.12
-CXX_VERSION = @CXX_VERSION@
 GXX_VERSION = @GXX_VERSION@
 CXXCPP = @CXXCPP@
 CXXPICFLAG = @CXXPICFLAG@
@@ -519,7 +515,6 @@
   -e "s|%OCTAVE_CONF_CANONICAL_HOST_TYPE%|\"${canonical_host_type}\"|" \
   -e "s|%OCTAVE_CONF_CARBON_LIBS%|\"${CARBON_LIBS}\"|" \
   -e "s|%OCTAVE_CONF_CC%|\"${CC}\"|" \
-  -e "s|%OCTAVE_CONF_CC_VERSION%|\"${CC_VERSION}\"|" \
   -e "s|%OCTAVE_CONF_CCOLAMD_CPPFLAGS%|\"${CCOLAMD_CPPFLAGS}\"|" \
   -e "s|%OCTAVE_CONF_CCOLAMD_LDFLAGS%|\"${CCOLAMD_LDFLAGS}\"|" \
   -e "s|%OCTAVE_CONF_CCOLAMD_LIBS%|\"${CCOLAMD_LIBS}\"|" \
--- a/configure.ac	Fri Aug 01 09:06:21 2014 -0400
+++ b/configure.ac	Fri Aug 01 12:10:05 2014 -0400
@@ -19,13 +19,13 @@
 ### <http://www.gnu.org/licenses/>.
 
 AC_PREREQ([2.62])
-AC_INIT([GNU Octave], [3.9.0+], [http://octave.org/bugs.html], [octave])
+AC_INIT([GNU Octave], [4.1.0+], [http://octave.org/bugs.html], [octave])
 
 dnl Note that the version number is duplicated here and in AC_INIT
 dnl because AC_INIT requires it to be static, not computed from
 dnl shell variables.
-OCTAVE_MAJOR_VERSION=3
-OCTAVE_MINOR_VERSION=9
+OCTAVE_MAJOR_VERSION=4
+OCTAVE_MINOR_VERSION=1
 OCTAVE_PATCH_VERSION=0+
 
 dnl PACKAGE_VERSION is set by the AC_INIT VERSION arg
@@ -329,10 +329,6 @@
 fi
 AC_SUBST(GXX_VERSION)
 
-## FIXME: CXX_VERSION is deprecated and should be removed in Octave version 3.12
-CXX_VERSION=$gxx_version
-AC_SUBST(CXX_VERSION)
-
 ### Determine which C compiler to use (we expect to find gcc).
 
 AC_PROG_CC
@@ -379,10 +375,6 @@
 fi
 AC_SUBST(GCC_VERSION)
 
-## FIXME: CC_VERSION is deprecated and should be removed in Octave version 3.12
-CC_VERSION=$GCC_VERSION
-AC_SUBST(CC_VERSION)
-
 ### Also check g++ version number, it might be different from the
 ## gcc version number.
 
@@ -865,9 +857,13 @@
       warn_llvm="Missing LLVM file TargetData.h.  JIT compiler is disabled."
     fi
 
+    AC_CHECK_HEADERS([llvm/IR/Verifier.h])
+
     OCTAVE_LLVM_FUNCTION_ADDATTRIBUTE_API
     OCTAVE_LLVM_FUNCTION_ADDFNATTR_API
     OCTAVE_LLVM_CALLINST_ADDATTRIBUTE_API
+    OCTAVE_LLVM_RAW_FD_OSTREAM_API
+    OCTAVE_LLVM_LEGACY_PASSMANAGER_API
     AC_LANG_POP(C++)
     CPPFLAGS="$save_CPPFLAGS"
     CXXFLAGS="$save_CXXFLAGS"
@@ -895,6 +891,7 @@
 AC_SUBST(LLVM_CXXFLAGS)
 AC_SUBST(LLVM_LDFLAGS)
 AC_SUBST(LLVM_LIBS)
+AM_CONDITIONAL([AMCOND_HAVE_LLVM], [test -z "$warn_llvm"])
 
 ### Check for HDF5 library.
 
@@ -2186,7 +2183,7 @@
 AC_CHECK_FUNCS([log1p log1pf pipe])
 AC_CHECK_FUNCS([realpath resolvepath roundl])
 AC_CHECK_FUNCS([select setgrent setpwent siglongjmp strsignal])
-AC_CHECK_FUNCS([tcgetattr tcsetattr tempnam tgammaf toascii])
+AC_CHECK_FUNCS([tcgetattr tcsetattr tgammaf toascii])
 AC_CHECK_FUNCS([umask waitpid])
 AC_CHECK_FUNCS([_kbhit])
 
@@ -2847,7 +2844,8 @@
 fi
 
 AM_CONDITIONAL([AMCOND_BUILD_GUI], [test $build_gui = yes])
-AM_CONDITIONAL([AMCOND_HAVE_QSCINTILLA], [test "$octave_cv_lib_qscintilla" = yes])
+AM_CONDITIONAL([AMCOND_HAVE_QSCINTILLA],
+               [test "$octave_cv_lib_qscintilla" = yes])
 AM_CONDITIONAL([WIN32_TERMINAL], [test $win32_terminal = yes])
 AC_SUBST(QT_CPPFLAGS)
 AC_SUBST(QT_LDFLAGS)
--- a/doc/interpreter/container.txi	Fri Aug 01 09:06:21 2014 -0400
+++ b/doc/interpreter/container.txi	Fri Aug 01 12:10:05 2014 -0400
@@ -507,7 +507,7 @@
 
 Other functions that can manipulate the fields of a structure are given below.
 
-@DOCSTRING(nfields)
+@DOCSTRING(numfields)
 
 @DOCSTRING(fieldnames)
 
--- a/doc/interpreter/contrib.txi	Fri Aug 01 09:06:21 2014 -0400
+++ b/doc/interpreter/contrib.txi	Fri Aug 01 12:10:05 2014 -0400
@@ -284,8 +284,10 @@
 An exception are matrix or cell constructors:
 
 @example
+@group
   [sin(x), cos(x)]
   @{sin(x), cos(x)@}
+@end group
 @end example
 
 @noindent
--- a/doc/interpreter/contributors.in	Fri Aug 01 09:06:21 2014 -0400
+++ b/doc/interpreter/contributors.in	Fri Aug 01 12:10:05 2014 -0400
@@ -3,6 +3,7 @@
 Adam H. Aitkenhead
 Giles Anderson
 Joel Andersson
+Pedro Angelo
 Muthiah Annamalai
 Markus Appel
 Branden Archer
@@ -15,6 +16,7 @@
 Heinz Bauschke
 Julien Bect
 Roman Belov
+Markus Bergholz
 Karl Berry
 David Billinghurst
 Don Bindner
@@ -69,6 +71,7 @@
 Peter Ekberg
 Rolf Fabian
 Gunnar Farnebäck
+Massimiliano Fasi
 Stephen Fegan
 Ramon Garcia Fernandez
 Torsten Finke
@@ -80,6 +83,7 @@
 Walter Gautschi
 Klaus Gebhardt
 Driss Ghaddab
+Eugenio Gianniti 
 Nicolo Giorgetti
 Arun Giridhar
 Michael D. Godfrey
@@ -88,6 +92,7 @@
 Tomislav Goles
 Keith Goodman
 Brian Gough
+Michael C. Grant
 Steffen Groot
 Etienne Grossmann
 David Grundberg
@@ -119,6 +124,7 @@
 John Hunt
 Teemu Ikonen
 Alan W. Irwin
+Allan Jacobs
 Geoff Jacobsen
 Mats Jansson
 Cai Jianming
@@ -188,6 +194,7 @@
 Júlio Hoffimann Mendes
 Ed Meyer
 Thorsten Meyer
+Stefan Miereis
 Petr Mikulik
 Mike Miller
 Stefan Monnier
@@ -210,12 +217,14 @@
 Michael O'Brien
 Peter O'Gorman
 Thorsten Ohl
+Kai T. Ohlhus
 Arno Onken
 Valentin Ortega-Clavero
 Luis F. Ortiz
 Carl Osterwisch
 Janne Olavi Paanajärvi
 Scott Pakin
+Jason Alan Palmer
 Gabriele Pannocchia
 Sylvain Pelissier
 Per Persson
@@ -234,6 +243,7 @@
 Francesco Potortì
 Konstantinos Poulios
 Jarno Rajahalme
+Eduardo Ramos
 James B. Rawlings
 Eric S. Raymond
 Balint Reczey
@@ -266,6 +276,7 @@
 Julian Schnidder
 Nicol N. Schraudolph
 Sebastian Schubert
+Lasse Schuirmann
 Ludwig Schwardt
 Thomas L. Scofield
 Daniel J. Sebald
@@ -282,6 +293,7 @@
 Joerg Specht
 Quentin H. Spencer
 Christoph Spiel
+David Spies
 Richard Stallman
 Russell Standish
 Brett Stewart
@@ -325,6 +337,7 @@
 Martin Weiser
 Michael Weitzel
 David Wells
+Joachim Wiesemann
 Fook Fah Yap
 Sean Young
 Michael Zeising
--- a/doc/interpreter/diagperm.txi	Fri Aug 01 09:06:21 2014 -0400
+++ b/doc/interpreter/diagperm.txi	Fri Aug 01 12:10:05 2014 -0400
@@ -489,21 +489,18 @@
 right and the consequent usage of smarter algorithms for certain operations
 implies, as a side effect, small differences in treating zeros.
 The contents of this section apply also to sparse matrices, discussed in
-the following chapter. (@pxref{Sparse Matrices})
+the following chapter.  (@pxref{Sparse Matrices})
 
-The IEEE floating point standard defines the result of the expressions @code{0*Inf} and 
-@code{0*NaN} as @code{NaN}. This is widely agreed to be a good
-compromise.
-Numerical software dealing with structured and sparse matrices (including
-Octave) however, almost always makes a distinction between a "numerical zero"
-and an "assumed zero". 
-A "numerical zero" is a zero value occurring in a place where any floating-point
-value could occur.  It is normally stored somewhere in memory as an explicit
-value. 
-An "assumed zero", on the contrary, is a zero matrix element implied by the
-matrix structure (diagonal, triangular) or a sparsity pattern; its value is
-usually not stored explicitly anywhere, but is implied by the underlying
-data structure.
+The IEEE floating point standard defines the result of the expressions
+@code{0*Inf} and @code{0*NaN} as @code{NaN}.  This is widely agreed to be a
+good compromise.  Numerical software dealing with structured and sparse matrices
+(including Octave) however, almost always makes a distinction between a
+"numerical zero" and an "assumed zero".  A "numerical zero" is a zero value
+occurring in a place where any floating-point value could occur.  It is
+normally stored somewhere in memory as an explicit value.  An "assumed zero", on
+the contrary, is a zero matrix element implied by the matrix structure
+(diagonal, triangular) or a sparsity pattern; its value is usually not stored
+explicitly anywhere, but is implied by the underlying data structure.
 
 The primary distinction is that an assumed zero, when multiplied 
 by any number, or divided by any nonzero number,
--- a/doc/interpreter/doccheck/aspell-octave.en.pws	Fri Aug 01 09:06:21 2014 -0400
+++ b/doc/interpreter/doccheck/aspell-octave.en.pws	Fri Aug 01 12:10:05 2014 -0400
@@ -52,6 +52,7 @@
 backend
 Backends
 backends
+backtrace
 bartlett
 BaseValue
 basevalue
@@ -235,6 +236,7 @@
 dMatrix
 dmperm
 Dobkin
+docstring
 docstrings
 dOmega
 doNotSpecify
@@ -387,6 +389,7 @@
 goto
 Goto
 gotos
+gperf
 GPL
 GPLK
 gplot
@@ -499,6 +502,7 @@
 javaaddpath
 javamem
 jbig
+JDK
 JIT
 jpeg
 JPEG
@@ -678,8 +682,10 @@
 nbininv
 nbinpdf
 nbinrnd
+ncols
 nd
 ndgrid
+ndims
 ne
 Nelder
 neq
@@ -700,7 +706,11 @@
 nolabel
 noncommercially
 nonconformant
+nondecreasing
+nonincreasing
+nonnan
 nonsmooth
+nonsparse
 nonzeros
 NOP
 noperm
@@ -713,9 +723,11 @@
 noscal
 noshare
 notin
+nrows
 nthargout
 NTSC
 ntsc
+numel
 Numpy
 nzmax
 oct
@@ -726,6 +738,7 @@
 onCleanup
 online
 OpenGL
+OpenJDK
 oplus
 Oppenheim
 Ord
@@ -1166,6 +1179,7 @@
 wp
 wspace
 xb
+xboxes
 xc
 xcorr
 xdata
@@ -1188,9 +1202,11 @@
 xu
 xwd
 xy
+xyboxes
 xyerrorbar
 xyerrorbars
 xyz
+yboxes
 yc
 ydata
 yerrorbar
--- a/doc/interpreter/errors.txi	Fri Aug 01 09:06:21 2014 -0400
+++ b/doc/interpreter/errors.txi	Fri Aug 01 12:10:05 2014 -0400
@@ -285,7 +285,7 @@
 @group
 function rand42
   old_state = rand ("state");
-  restore_state = onCleanup (@@() rand ("state", old_state);
+  restore_state = onCleanup (@@() rand ("state", old_state));
   rand ("state", 42);
   @dots{}
 endfunction  # rand generator state restored by onCleanup
--- a/doc/interpreter/external.txi	Fri Aug 01 09:06:21 2014 -0400
+++ b/doc/interpreter/external.txi	Fri Aug 01 12:10:05 2014 -0400
@@ -589,7 +589,7 @@
 @subsubsection Array and Sparse Class Differences
 
 The number of elements in a sparse matrix is considered to be the number
-of non-zero elements rather than the product of the dimensions.  Therefore
+of nonzero elements rather than the product of the dimensions.  Therefore
 
 @example
 @group
@@ -600,13 +600,13 @@
 @end example
 
 @noindent
-returns the number of non-zero elements.  If the user really requires the
-number of elements in the matrix, including the non-zero elements, they
+returns the number of nonzero elements.  If the user really requires the
+number of elements in the matrix, including the nonzero elements, they
 should use @code{numel} rather than @code{nelem}.  Note that for very
 large matrices, where the product of the two dimensions is larger than
 the representation of an unsigned int, then @code{numel} can overflow.
 An example is @code{speye (1e6)} which will create a matrix with a million
-rows and columns, but only a million non-zero elements.  Therefore the
+rows and columns, but only a million nonzero elements.  Therefore the
 number of rows by the number of columns in this case is more than two
 hundred times the maximum value that can be represented by an unsigned int.
 The use of @code{numel} should therefore be avoided useless it is known
@@ -707,7 +707,7 @@
 technique for creating a sparse matrix.
 
 The alternative is to first create a sparse matrix with the desired
-number of non-zero elements and then later fill those elements in.
+number of nonzero elements and then later fill those elements in.
 Sample code:
 
 @example
@@ -748,7 +748,7 @@
 @var{nz} greater than 4 is also valid.  The disadvantage is that the matrix
 occupies more memory than strictly needed.
 
-It is not always possible to know the number of non-zero elements prior
+It is not always possible to know the number of nonzero elements prior
 to filling a matrix.  For this reason the additional unused storage of 
 a sparse matrix can be removed after its creation with the
 @code{maybe_compress} function.  In addition, @code{maybe_compress} can
@@ -850,7 +850,7 @@
 sm.maybe_mutate ();  // If don't know a priori the final # of nz.
 @end example
 
-Note that both increasing and decreasing the number of non-zero elements in
+Note that both increasing and decreasing the number of nonzero elements in
 a sparse matrix is expensive as it involves memory reallocation.  Also as
 parts of the matrix, though not its entirety, exist as old and new copies
 at the same time, additional memory is needed.  Therefore, if possible this
@@ -1607,6 +1607,7 @@
 An example of the behavior of this function within Octave is then
 
 @example
+@group
 a(1).f1 = "f11"; a(1).f2 = "f12"; 
 a(2).f1 = "f21"; a(2).f2 = "f22";
 b = mystruct (a);
@@ -1625,6 +1626,7 @@
 
      this = this3
      that = that3
+@end group
 @end example
 
 @node Sparse Matrices with Mex-Files
@@ -1653,11 +1655,11 @@
 
 @noindent
 @code{mxGetNzmax} gets the maximum number of elements that can be stored
-in the sparse matrix.  This is not necessarily the number of non-zero
+in the sparse matrix.  This is not necessarily the number of nonzero
 elements in the sparse matrix.  @code{mxGetJc} returns an array with one
 additional value than the number of columns in the sparse matrix.  The
 difference between consecutive values of the array returned by
-@code{mxGetJc} define the number of non-zero elements in each column of
+@code{mxGetJc} define the number of nonzero elements in each column of
 the sparse matrix.  Therefore,
 
 @example
@@ -1673,10 +1675,10 @@
 @end example
 
 @noindent
-returns the actual number of non-zero elements stored in the matrix in
+returns the actual number of nonzero elements stored in the matrix in
 @code{nz}.  As the arrays returned by @code{mxGetPr} and @code{mxGetPi}
-only contain the non-zero values of the matrix, we also need a pointer
-to the rows of the non-zero elements, and this is given by
+only contain the nonzero values of the matrix, we also need a pointer
+to the rows of the nonzero elements, and this is given by
 @code{mxGetIr}.  A complete example of the use of sparse matrices in
 mex-files is given by the file @file{mysparse.c} shown below.
 
@@ -1692,7 +1694,7 @@
 mysparse (sm)
 @result{}
 Matrix is 2-by-2 real sparse matrix with 2 elements
-last non-zero element (2, 2) = 3.14159
+last nonzero element (2, 2) = 3.14159
 @end group
 @end example
 
@@ -1790,8 +1792,8 @@
 This feature should be used with care as the list of built-in functions can
 change.  No guarantees can be made that a function that is currently built in
 won't be implemented as a .m file or as a dynamically linked function in the
-future.  An example of how to call built-in functions from C++ can be seen in the
-code
+future.  An example of how to call built-in functions from C++ can be seen in
+the code
 
 @example
 @EXAMPLEFILE(standalonebuiltin.cc)
--- a/doc/interpreter/func.txi	Fri Aug 01 09:06:21 2014 -0400
+++ b/doc/interpreter/func.txi	Fri Aug 01 12:10:05 2014 -0400
@@ -802,7 +802,7 @@
 
 @DOCSTRING(command_line_path)
 
-@DOCSTRING(find_dir_in_path)
+@DOCSTRING(dir_in_loadpath)
 
 @node Subfunctions
 @subsection Subfunctions
--- a/doc/interpreter/grammar.txi	Fri Aug 01 09:06:21 2014 -0400
+++ b/doc/interpreter/grammar.txi	Fri Aug 01 12:10:05 2014 -0400
@@ -49,9 +49,8 @@
 @item @code{function} @tab @code{global} @tab @code{if}
 @item @code{methods} @tab @code{otherwise} @tab @code{parfor}
 @item @code{persistent} @tab @code{properties} @tab @code{return}
-@item @code{static} @tab @code{switch} @tab @code{try}
-@item @code{until} @tab @code{unwind_protect} @tab @code{unwind_protect_cleanup}
-@item @code{while}
+@item @code{switch} @tab @code{try} @tab @code{until}
+@item @code{unwind_protect} @tab @code{unwind_protect_cleanup} @tab @code{while}
 @end multitable
 
 The function @code{iskeyword} can be used to quickly check whether an
--- a/doc/interpreter/install.txi	Fri Aug 01 09:06:21 2014 -0400
+++ b/doc/interpreter/install.txi	Fri Aug 01 12:10:05 2014 -0400
@@ -734,6 +734,7 @@
 Suggestions on how to compile ATLAS would be most welcome.
 
 @item @sc{glpk}
+
 @item Qhull (@url{http://www.qhull.org})
 
 Both @sc{glpk} and Qhull use @code{int} internally so maximum problem
@@ -846,7 +847,7 @@
 
 @noindent
 in the kernel configuration files (typically found in the directory
-@file{/sys/i386/conf}.  After making this change, you'll need to rebuild
+@file{/sys/i386/conf}).  After making this change, you'll need to rebuild
 the kernel, install it, and reboot.
 
 @item
@@ -1026,3 +1027,4 @@
 @env{FFLAGS} is set to @qcode{"-O"}.
 
 @end itemize
+
--- a/doc/interpreter/java.txi	Fri Aug 01 09:06:21 2014 -0400
+++ b/doc/interpreter/java.txi	Fri Aug 01 12:10:05 2014 -0400
@@ -163,9 +163,11 @@
 @cindex path, removing from classpath
 @DOCSTRING(javarmpath)
 
-The following four functions provide information and control over the interface
+The following functions provide information and control over the interface
 between Octave and the Java Virtual Machine.
 
+@DOCSTRING(javachk)
+
 @DOCSTRING(usejava)
 
 @cindex memory, displaying Java memory status
--- a/doc/interpreter/linalg.txi	Fri Aug 01 09:06:21 2014 -0400
+++ b/doc/interpreter/linalg.txi	Fri Aug 01 12:10:05 2014 -0400
@@ -27,12 +27,12 @@
 @cite{@sc{lapack} Users' Guide} is available at:
 @cite{http://www.netlib.org/lapack/lug/}
 
-A common text for engineering courses is G. Strang, @cite{Linear Algebra
-and Its Applications, 4th Edition}. It has become a widespread reference
-for linear algebra. An alternative is P. Lax @cite{Linear Algebra and
-Its Applications}, and also is a good choice. It claims to be suitable
-for high school students with substantial mathematical interests as well
-as first-year undergraduates.
+A common text for engineering courses is @nospell{G. Strang},
+@cite{Linear Algebra and Its Applications, 4th Edition}. It has become a
+widespread reference for linear algebra. An alternative is P. Lax
+@cite{Linear Algebra and Its Applications}, and also is a good choice.  It
+claims to be suitable for high school students with substantial mathematical
+interests as well as first-year undergraduates.
 
 @menu
 * Techniques Used for Linear Algebra::
@@ -49,7 +49,7 @@
 Octave includes a polymorphic solver that selects an appropriate matrix
 factorization depending on the properties of the matrix itself.
 Generally, the cost of determining the matrix type is small relative to
-the cost of factorizing the matrix itself. In any case the matrix type
+the cost of factorizing the matrix itself.  In any case the matrix type
 is cached once it is calculated so that it is not re-determined each
 time it is used in a linear equation.
 
@@ -96,6 +96,8 @@
 
 @DOCSTRING(balance)
 
+@DOCSTRING(bandwidth)
+
 @DOCSTRING(cond)
 
 @DOCSTRING(det)
@@ -212,3 +214,4 @@
 @DOCSTRING(cgs)
 
 @DOCSTRING(gmres)
+
--- a/doc/interpreter/macros.texi	Fri Aug 01 09:06:21 2014 -0400
+++ b/doc/interpreter/macros.texi	Fri Aug 01 12:10:05 2014 -0400
@@ -28,14 +28,14 @@
 @c which is `XXX'.  This looks particularly bad when the macro body is 
 @c single or double-quoted text, such as a property value `"position"'
 @ifinfo
-@rmacro qcode{arg}
+@macro qcode{arg}
 \arg\
-@end rmacro
+@end macro
 @end ifinfo
 @ifnotinfo
-@rmacro qcode{arg}
+@macro qcode{arg}
 @code{\arg\}
-@end rmacro
+@end macro
 @end ifnotinfo
 
 @c The following macro is used for the on-line help system, but we don't
--- a/doc/interpreter/numbers.txi	Fri Aug 01 09:06:21 2014 -0400
+++ b/doc/interpreter/numbers.txi	Fri Aug 01 12:10:05 2014 -0400
@@ -811,6 +811,8 @@
 
 @DOCSTRING(isnumeric)
 
+@DOCSTRING(islogical)
+
 @DOCSTRING(isfloat)
 
 @DOCSTRING(isreal)
@@ -835,7 +837,13 @@
 
 @DOCSTRING(isdefinite)
 
-@DOCSTRING(islogical)
+@DOCSTRING(isbanded)
+
+@DOCSTRING(isdiag)
+
+@DOCSTRING(istril)
+
+@DOCSTRING(istriu)
 
 @DOCSTRING(isprime)
 
--- a/doc/interpreter/plot.txi	Fri Aug 01 09:06:21 2014 -0400
+++ b/doc/interpreter/plot.txi	Fri Aug 01 12:10:05 2014 -0400
@@ -937,6 +937,17 @@
 
 @DOCSTRING(orient)
 
+@code{print} and @code{saveas} are used when work on a plot has finished
+and the output must be in a publication-ready format.  During intermediate
+stages it is often better to save the graphics object and all of its
+associated information so that changes---to colors, axis limits, marker styles,
+etc.---can be made easily from within Octave.  The @code{hgsave}/@code{hgload}
+commands can be used to save and re-create a graphics object.
+
+@DOCSTRING(hgsave)
+
+@DOCSTRING(hgload)
+
 @node Interacting with Plots
 @subsection Interacting with Plots
 
@@ -1233,18 +1244,21 @@
 
 @noindent
 sets the range of the x-axis for the current axes object in the current
-figure to @samp{[-10, 10]}.  Additionally, calling set with a graphics
-object index as the only argument returns a structure containing the
-default values for all the properties for the given object type.  For
-example,
+figure to @samp{[-10, 10]}.
+
+Default property values can also be queried if the @code{set} function is
+called without a value argument.  When only one argument is given (a graphic
+handle) then a structure with defaults for all properties of the given object
+type is returned.  For example,
 
 @example
 set (gca ())
 @end example
 
 @noindent
-returns a structure containing the default property values for axes
-objects.
+returns a structure containing the default property values for axes objects.
+If @code{set} is called with two arguments (a graphic handle and a property
+name) then only the defaults for the requested property are returned.
 
 @DOCSTRING(get)
 
@@ -2868,6 +2882,8 @@
 
 @DOCSTRING(linkprop)
 
+@DOCSTRING(linkaxes)
+
 These capabilities are used in a number of basic graphics objects.
 The @code{hggroup} objects created by the functions of Octave contain
 one or more graphics object and are used to:
--- a/doc/interpreter/sparse.txi	Fri Aug 01 09:06:21 2014 -0400
+++ b/doc/interpreter/sparse.txi	Fri Aug 01 12:10:05 2014 -0400
@@ -44,13 +44,13 @@
 There are many classes of mathematical problems which give rise to
 matrices, where a large number of the elements are zero.  In this case
 it makes sense to have a special matrix type to handle this class of
-problems where only the non-zero elements of the matrix are
+problems where only the nonzero elements of the matrix are
 stored.  Not only does this reduce the amount of memory to store the
 matrix, but it also means that operations on this type of matrix can
 take advantage of the a priori knowledge of the positions of the
-non-zero elements to accelerate their calculations.
+nonzero elements to accelerate their calculations.
 
-A matrix type that stores only the non-zero elements is generally called
+A matrix type that stores only the nonzero elements is generally called
 sparse.  It is the purpose of this document to discuss the basics of the
 storage and creation of sparse matrices and the fundamental operations
 on them.
@@ -81,7 +81,7 @@
 With full matrices, knowledge of the point of an element of the matrix
 within the matrix is implied by its position in the computers memory. 
 However, this is not the case for sparse matrices, and so the positions
-of the non-zero elements of the matrix must equally be stored. 
+of the nonzero elements of the matrix must equally be stored. 
 
 An obvious way to do this is by storing the elements of the matrix as
 triplets, with two elements being their position in the array 
@@ -94,9 +94,9 @@
 In this format the position of each element in a row and the data are
 stored as previously.  However, if we assume that all elements in the
 same column are stored adjacent in the computers memory, then we only
-need to store information on the number of non-zero elements in each
+need to store information on the number of nonzero elements in each
 column, rather than their positions.  Thus assuming that the matrix has
-more non-zero elements than there are columns in the matrix, we win in
+more nonzero elements than there are columns in the matrix, we win in
 terms of the amount of memory used.
 
 In fact, the column index contains one more element than the number of
@@ -109,7 +109,7 @@
 @group
   for (j = 0; j < nc; j++)
     for (i = cidx(j); i < cidx(j+1); i++)
-       printf ("non-zero element (%i,%i) is %d\n", 
+       printf ("nonzero element (%i,%i) is %d\n", 
            ridx(i), j, data(i));
 @end group
 @end example
@@ -125,7 +125,7 @@
 @end group
 @end example
 
-The non-zero elements of this matrix are
+The nonzero elements of this matrix are
 
 @example
 @group
@@ -319,7 +319,7 @@
 in fact a sparse matrix.
 
 Another very basic function is @dfn{nnz} that returns the number of
-non-zero entries there are in a sparse matrix, while the function
+nonzero entries there are in a sparse matrix, while the function
 @dfn{nzmax} returns the amount of storage allocated to the sparse
 matrix.  Note that Octave tends to crop unused memory at the first
 opportunity for sparse objects.  There are some cases of user created
@@ -376,7 +376,7 @@
 
 There are several graphical means of finding out information about
 sparse matrices.  The first is the @dfn{spy} command, which displays
-the structure of the non-zero elements of the
+the structure of the nonzero elements of the
 matrix.  @xref{fig:spmatrix}, for an example of the use of
 @dfn{spy}.  More advanced graphical information can be obtained with the
 @dfn{treeplot}, @dfn{etreeplot} and @dfn{gplot} commands.
@@ -390,7 +390,7 @@
 interconnections between nodes are represented as an adjacency
 matrix.  That is, if the i-th node in a graph is connected to the j-th
 node.  Then the ij-th node (and in the case of undirected graphs the
-@nospell{ji-th} node) of the sparse adjacency matrix is non-zero.  If each node
+@nospell{ji-th} node) of the sparse adjacency matrix is nonzero.  If each node
 is then associated with a set of coordinates, then the @dfn{gplot}
 command can be used to graphically display the interconnections
 between nodes.
@@ -509,9 +509,9 @@
 The two basic reasons to use sparse matrices are to reduce the memory 
 usage and to not have to do calculations on zero elements.  The two are
 closely related in that the computation time on a sparse matrix operator
-or function is roughly linear with the number of non-zero elements.
+or function is roughly linear with the number of nonzero elements.
 
-Therefore, there is a certain density of non-zero elements of a matrix 
+Therefore, there is a certain density of nonzero elements of a matrix 
 where it no longer makes sense to store it as a sparse matrix, but rather
 as a full matrix.  For this reason operators and functions that have a 
 high probability of returning a full matrix will always return one.  For
@@ -630,7 +630,7 @@
 of zero is important must not be done using sparse matrices.
 
 In general any function or operator used on a sparse matrix will
-result in a sparse matrix with the same or a larger number of non-zero
+result in a sparse matrix with the same or a larger number of nonzero
 elements than the original matrix.  This is particularly true for the
 important case of sparse matrix factorizations.  The usual way to
 address this is to reorder the matrix, such that its factorization is
@@ -667,7 +667,7 @@
 @ifset htmltex
 598
 @end ifset
-non-zero terms, while this Cholesky@tie{}factorization has
+nonzero terms, while this Cholesky@tie{}factorization has
 @ifinfo
 @ifnothtml
 71,
@@ -693,7 +693,7 @@
 @ifset htmltex
 399
 @end ifset
-non-zero terms which is a significant improvement.
+nonzero terms which is a significant improvement.
 
 The Cholesky@tie{}factorization itself can be used to determine the
 appropriate sparsity preserving reordering of the matrix during the
@@ -793,12 +793,12 @@
 
 @item If the matrix is not square, or any of the previous solvers flags
 a singular or near singular matrix, find a minimum norm solution using
-@sc{cxsparse}@footnote{The @sc{cholmod}, @sc{umfpack} and @sc{cxsparse} packages were
-written by Tim Davis and are available at
+@sc{cxsparse}@footnote{The @sc{cholmod}, @sc{umfpack} and @sc{cxsparse}
+packages were written by Tim Davis and are available at
 @url{http://www.cise.ufl.edu/research/sparse/}}.
 @end enumerate
 
-The band density is defined as the number of non-zero values in the band
+The band density is defined as the number of nonzero values in the band
 divided by the total number of values in the full band.  The banded
 matrix solvers can be entirely disabled by using @dfn{spparms} to set
 @code{bandden} to 1 (i.e., @code{spparms ("bandden", 1)}).
@@ -997,7 +997,7 @@
 as constant on each simplex (represented by the vector @code{conductivity}).
 Based on the finite element geometry, we first calculate a system (or
 stiffness) matrix for each simplex (represented as 3-by-3 elements on the
-diagonal of the element-wise system matrix @code{SE}.  Based on @code{SE} 
+diagonal of the element-wise system matrix @code{SE}).  Based on @code{SE} 
 and a N-by-DE connectivity matrix @code{C}, representing the connections 
 between simplices and vertices, the global connectivity matrix @code{S} is
 calculated.
--- a/doc/interpreter/stmt.txi	Fri Aug 01 09:06:21 2014 -0400
+++ b/doc/interpreter/stmt.txi	Fri Aug 01 12:10:05 2014 -0400
@@ -83,10 +83,10 @@
 @var{condition} is true.
 
 The condition in an @code{if} statement is considered true if its value
-is non-zero, and false if its value is zero.  If the value of the
+is nonzero, and false if its value is zero.  If the value of the
 conditional expression in an @code{if} statement is a vector or a
 matrix, it is considered true only if it is non-empty and @emph{all}
-of the elements are non-zero.
+of the elements are nonzero.
 
 The second form of an if statement looks like this:
 
@@ -398,10 +398,10 @@
 The @code{while} statement is the simplest looping statement in Octave.
 It repeatedly executes a statement as long as a condition is true.  As
 with the condition in an @code{if} statement, the condition in a
-@code{while} statement is considered true if its value is non-zero, and
+@code{while} statement is considered true if its value is nonzero, and
 false if its value is zero.  If the value of the conditional expression
 in a @code{while} statement is a vector or a matrix, it is considered
-true only if it is non-empty and @emph{all} of the elements are non-zero.
+true only if it is non-empty and @emph{all} of the elements are nonzero.
 
 Octave's @code{while} statement looks like this:
 
@@ -463,10 +463,10 @@
 true, and the test of the condition is at the end of the loop, so the
 body of the loop is always executed at least once.  As with the
 condition in an @code{if} statement, the condition in a @code{do-until}
-statement is considered true if its value is non-zero, and false if its
+statement is considered true if its value is nonzero, and false if its
 value is zero.  If the value of the conditional expression in a
 @code{do-until} statement is a vector or a matrix, it is considered 
-true only if it is non-empty and @emph{all} of the elements are non-zero.
+true only if it is non-empty and @emph{all} of the elements are nonzero.
 
 Octave's @code{do-until} statement looks like this:
 
--- a/doc/interpreter/testfun.txi	Fri Aug 01 09:06:21 2014 -0400
+++ b/doc/interpreter/testfun.txi	Fri Aug 01 12:10:05 2014 -0400
@@ -297,14 +297,14 @@
 @group
 function output = must_be_zero (@var{input})
   if (@var{input} != 0)
-    error ("Non-zero input!")
+    error ("Nonzero input!")
   endif
   output = input;
 endfunction
 
 %!fail ("must_be_zero (1)");
 %!assert (must_be_zero (0), 0);
-%!error <Non-zero> must_be_zero (1);
+%!error <Nonzero> must_be_zero (1);
 %!xtest error ("This code generates an error");
 @end group
 @end example
@@ -320,7 +320,7 @@
 >>>>> /path/to/must_be_zero.m
   ***** fail ("must_be_zero (1)");
   ***** assert (must_be_zero (0), 0);
-  ***** error <Non-zero> must_be_zero (1);
+  ***** error <Nonzero> must_be_zero (1);
   ***** xtest error ("This code generates an error");
 !!!!! known failure
 This code generates an error
--- a/doc/interpreter/var.txi	Fri Aug 01 09:06:21 2014 -0400
+++ b/doc/interpreter/var.txi	Fri Aug 01 12:10:05 2014 -0400
@@ -221,8 +221,7 @@
 @end example
 
 The behavior of persistent variables is equivalent to the behavior of
-static variables in C@.  The command @code{static} in Octave is also
-recognized and is equivalent to @code{persistent}.
+static variables in C@.
 
 Like global variables, a persistent variable may only be initialized once.
 For example, after executing the following code
--- a/doc/interpreter/vectorize.txi	Fri Aug 01 09:06:21 2014 -0400
+++ b/doc/interpreter/vectorize.txi	Fri Aug 01 12:10:05 2014 -0400
@@ -697,7 +697,7 @@
 for i = 1:length (A)
   ## this will be two columns, the first is the difference and
   ## the second the mean of the two elements used for the diff.
-  B(i,:) = [A(i+1)-A(i), (A(i+1) + A(i))/2)];
+  B(i,:) = [A(i+1)-A(i), (A(i+1) + A(i))/2];
 endfor
 @end group
 @end example
@@ -713,3 +713,4 @@
 a column vector.  This is a common vectorization trick.
 
 @end itemize
+
--- a/doc/refcard/refcard.tex	Fri Aug 01 09:06:21 2014 -0400
+++ b/doc/refcard/refcard.tex	Fri Aug 01 12:10:05 2014 -0400
@@ -536,7 +536,7 @@
 speye ({\it n)}&create sparse identity matrix.\cr
 sprand ({\it n}, {\it m}, {\it d})&sparse rand matrix of density {\it d}.\cr
 spdiags (...)&sparse generalization of {\it diag}.\cr
-nnz ({\it s})&No. non-zero elements in sparse matrix.\cr
+nnz ({\it s})&No. nonzero elements in sparse matrix.\cr
 \endsec
 
 \sec Ranges;
--- a/examples/mysparse.c	Fri Aug 01 09:06:21 2014 -0400
+++ b/examples/mysparse.c	Fri Aug 01 12:10:05 2014 -0400
@@ -32,7 +32,7 @@
       i = n;
       while (jc[i] == jc[i-1] && i != 0) i--;
 
-      mexPrintf ("last non-zero element (%d, %d) = (%g, %g)\n",
+      mexPrintf ("last nonzero element (%d, %d) = (%g, %g)\n",
                  ir[nz-1]+ 1, i, pr[nz-1], pi[nz-1]);
 
       v = mxCreateSparse (m, n, nz, mxCOMPLEX);
@@ -65,7 +65,7 @@
 
       i = n;
       while (jc[i] == jc[i-1] && i != 0) i--;
-      mexPrintf ("last non-zero element (%d, %d) = %d\n",
+      mexPrintf ("last nonzero element (%d, %d) = %d\n",
                  ir[nz-1]+ 1, i, pbr[nz-1]);
 
       v = mxCreateSparseLogicalMatrix (m, n, nz);
@@ -95,7 +95,7 @@
 
       i = n;
       while (jc[i] == jc[i-1] && i != 0) i--;
-      mexPrintf ("last non-zero element (%d, %d) = %g\n",
+      mexPrintf ("last nonzero element (%d, %d) = %g\n",
                  ir[nz-1]+ 1, i, pr[nz-1]);
 
       v = mxCreateSparse (m, n, nz, mxREAL);
--- a/libgui/graphics/Backend.cc	Fri Aug 01 09:06:21 2014 -0400
+++ b/libgui/graphics/Backend.cc	Fri Aug 01 12:10:05 2014 -0400
@@ -53,16 +53,16 @@
   if (go.isa ("figure"))
     return std::string ("__plot_stream__");
   else if (go.isa ("uicontrol")
-	   || go.isa ("uipanel")
-	   || go.isa ("uimenu")
-	   || go.isa ("uicontextmenu")
-	   || go.isa ("uitoolbar")
-	   || go.isa ("uipushtool")
-	   || go.isa ("uitoggletool"))
+           || go.isa ("uipanel")
+           || go.isa ("uimenu")
+           || go.isa ("uicontextmenu")
+           || go.isa ("uitoolbar")
+           || go.isa ("uipushtool")
+           || go.isa ("uitoggletool"))
     return std::string ("__object__");
   else
     qCritical ("QtHandles::Backend: no __object__ property known for object "
-	       "of type %s", go.type ().c_str ());
+               "of type %s", go.type ().c_str ());
 
   return std::string ();
 }
@@ -73,7 +73,7 @@
   ObjectFactory* factory = ObjectFactory::instance ();
 
   connect (this, SIGNAL (createObject (double)),
-	   factory, SLOT (createObject (double)));
+           factory, SLOT (createObject (double)));
 }
 
 Backend::~Backend (void)
@@ -92,13 +92,13 @@
       || go.isa ("uitoggletool"))
     {
       Logger::debug ("Backend::initialize %s from thread %08x",
-		     go.type ().c_str (), QThread::currentThreadId ());
+                     go.type ().c_str (), QThread::currentThreadId ());
 
       ObjectProxy* proxy = new ObjectProxy ();
       graphics_object gObj (go);
 
-      gObj.get_properties ().set(toolkitObjectProperty (go),
-				 OCTAVE_PTR_TYPE ((OCTAVE_INTPTR_TYPE) proxy));
+      OCTAVE_PTR_TYPE tmp (reinterpret_cast <OCTAVE_INTPTR_TYPE> (proxy));
+      gObj.get_properties ().set(toolkitObjectProperty (go), tmp);
 
       emit createObject (go.get_handle ().value ());
 
@@ -123,30 +123,30 @@
     return;
 
   Logger::debug ("Backend::update %s(%d) from thread %08x",
-		 go.type ().c_str (), pId, QThread::currentThreadId ());
+                 go.type ().c_str (), pId, QThread::currentThreadId ());
 
   ObjectProxy* proxy = toolkitObjectProxy (go);
 
   if (proxy)
     {
       if (go.isa ("uicontrol")
-	  && pId == uicontrol::properties::ID_STYLE)
-	{
-	  // Special case: we need to recreate the control widget
-	  // associated with the octave graphics_object
+          && pId == uicontrol::properties::ID_STYLE)
+        {
+          // Special case: we need to recreate the control widget
+          // associated with the octave graphics_object
 
-	  finalize (go);
-	  initialize (go);
-	}
+          finalize (go);
+          initialize (go);
+        }
       else
-	proxy->update (pId);
+        proxy->update (pId);
     }
 }
 
 void Backend::finalize (const graphics_object& go)
 {
   Logger::debug ("Backend::finalize %s from thread %08x",
-		 go.type ().c_str (), QThread::currentThreadId ());
+                 go.type ().c_str (), QThread::currentThreadId ());
 
   ObjectProxy* proxy = toolkitObjectProxy (go);
 
@@ -168,7 +168,7 @@
       ObjectProxy* proxy = toolkitObjectProxy (go);
 
       if (proxy)
-	proxy->redraw ();
+        proxy->redraw ();
     }
 }
 
@@ -189,12 +189,12 @@
       octave_value ov = go.get (toolkitObjectProperty (go));
 
       if (ov.is_defined () && ! ov.is_empty ())
-	{
-	  OCTAVE_INTPTR_TYPE ptr = ov.OCTAVE_PTR_SCALAR ().value ();
+        {
+          OCTAVE_INTPTR_TYPE ptr = ov.OCTAVE_PTR_SCALAR ().value ();
 
-	  if (! error_state)
-	    return reinterpret_cast<ObjectProxy*> (ptr);
-	}
+          if (! error_state)
+            return reinterpret_cast<ObjectProxy*> (ptr);
+        }
     }
 
   return 0;
--- a/libgui/graphics/BaseControl.cc	Fri Aug 01 09:06:21 2014 -0400
+++ b/libgui/graphics/BaseControl.cc	Fri Aug 01 12:10:05 2014 -0400
@@ -45,24 +45,24 @@
       || props.style_is ("popupmenu"))
     {
       p.setColor (QPalette::Base,
-		  Utils::fromRgb (props.get_backgroundcolor_rgb ()));
+                  Utils::fromRgb (props.get_backgroundcolor_rgb ()));
       p.setColor (QPalette::Text,
-		  Utils::fromRgb (props.get_foregroundcolor_rgb ()));
+                  Utils::fromRgb (props.get_foregroundcolor_rgb ()));
     }
   else if (props.style_is ("pushbutton")
-	   || props.style_is ("togglebutton"))
+           || props.style_is ("togglebutton"))
     {
       p.setColor (QPalette::Button,
-		  Utils::fromRgb (props.get_backgroundcolor_rgb ()));
+                  Utils::fromRgb (props.get_backgroundcolor_rgb ()));
       p.setColor (QPalette::ButtonText,
-		  Utils::fromRgb (props.get_foregroundcolor_rgb ()));
+                  Utils::fromRgb (props.get_foregroundcolor_rgb ()));
     }
   else
     {
       p.setColor (QPalette::Window,
-		  Utils::fromRgb (props.get_backgroundcolor_rgb ()));
+                  Utils::fromRgb (props.get_backgroundcolor_rgb ()));
       p.setColor (QPalette::WindowText,
-		  Utils::fromRgb (props.get_foregroundcolor_rgb ()));
+                  Utils::fromRgb (props.get_foregroundcolor_rgb ()));
     }
 
   w->setPalette (p);
@@ -83,7 +83,7 @@
 
   Matrix bb = up.get_boundingbox (false);
   w->setGeometry (xround (bb(0)), xround (bb(1)),
-		  xround (bb(2)), xround (bb(3)));
+                  xround (bb(2)), xround (bb(3)));
   w->setFont (Utils::computeFont<uicontrol> (up, bb(3)));
   updatePalette (up, w);
   w->setEnabled (up.enable_is ("on"));
@@ -108,11 +108,11 @@
    switch (pId)
     {
     case uicontrol::properties::ID_POSITION:
-	{
-	  Matrix bb = up.get_boundingbox (false);
-	  w->setGeometry (xround (bb(0)), xround (bb(1)),
-			  xround (bb(2)), xround (bb(3)));
-	}
+        {
+          Matrix bb = up.get_boundingbox (false);
+          w->setGeometry (xround (bb(0)), xround (bb(1)),
+                          xround (bb(2)), xround (bb(3)));
+        }
       break;
     case uicontrol::properties::ID_FONTNAME:
     case uicontrol::properties::ID_FONTSIZE:
@@ -147,62 +147,62 @@
     }
 }
 
-bool BaseControl::eventFilter (QObject* watched, QEvent* event)
+bool BaseControl::eventFilter (QObject* watched, QEvent* xevent)
 {
-  switch (event->type ())
+  switch (xevent->type ())
     {
     case QEvent::Resize:
       if (m_normalizedFont)
-	{
-	  gh_manager::auto_lock lock;
+        {
+          gh_manager::auto_lock lock;
 
-	  qWidget<QWidget> ()->setFont (Utils::computeFont<uicontrol>
-					(properties<uicontrol> ()));
-	}
+          qWidget<QWidget> ()->setFont (Utils::computeFont<uicontrol>
+                                        (properties<uicontrol> ()));
+        }
       break;
     case QEvent::MouseButtonPress:
-	{
-	  gh_manager::auto_lock lock;
+        {
+          gh_manager::auto_lock lock;
 
-	  QMouseEvent* m = dynamic_cast<QMouseEvent*> (event);
-	  graphics_object go = object ();
-	  uicontrol::properties& up = Utils::properties<uicontrol> (go);
-	  graphics_object fig = go.get_ancestor ("figure");
+          QMouseEvent* m = dynamic_cast<QMouseEvent*> (xevent);
+          graphics_object go = object ();
+          uicontrol::properties& up = Utils::properties<uicontrol> (go);
+          graphics_object fig = go.get_ancestor ("figure");
 
-	  if (m->button () != Qt::LeftButton
-	      || ! up.enable_is ("on"))
-	    {
-	      gh_manager::post_set (fig.get_handle (), "selectiontype",
-				    Utils::figureSelectionType (m), false);
-	      gh_manager::post_set (fig.get_handle (), "currentpoint",
-				    Utils::figureCurrentPoint (fig, m),
-				    false);
-	      gh_manager::post_callback (fig.get_handle (),
-					 "windowbuttondownfcn");
-	      gh_manager::post_callback (m_handle, "buttondownfcn");
+          if (m->button () != Qt::LeftButton
+              || ! up.enable_is ("on"))
+            {
+              gh_manager::post_set (fig.get_handle (), "selectiontype",
+                                    Utils::figureSelectionType (m), false);
+              gh_manager::post_set (fig.get_handle (), "currentpoint",
+                                    Utils::figureCurrentPoint (fig, m),
+                                    false);
+              gh_manager::post_callback (fig.get_handle (),
+                                         "windowbuttondownfcn");
+              gh_manager::post_callback (m_handle, "buttondownfcn");
 
-	      if (m->button () == Qt::RightButton)
-		ContextMenu::executeAt (up, m->globalPos ());
-	    }
-	  else
-	    {
-	      if (up.style_is ("listbox"))
-		gh_manager::post_set (fig.get_handle (), "selectiontype",
-				      Utils::figureSelectionType (m), false);
-	      else
-		gh_manager::post_set (fig.get_handle (), "selectiontype",
-				      octave_value ("normal"), false);
-	    }
-	}
+              if (m->button () == Qt::RightButton)
+                ContextMenu::executeAt (up, m->globalPos ());
+            }
+          else
+            {
+              if (up.style_is ("listbox"))
+                gh_manager::post_set (fig.get_handle (), "selectiontype",
+                                      Utils::figureSelectionType (m), false);
+              else
+                gh_manager::post_set (fig.get_handle (), "selectiontype",
+                                      octave_value ("normal"), false);
+            }
+        }
       break;
     case QEvent::MouseMove:
       if (qWidget<QWidget> ()->hasMouseTracking ())
         {
-	  gh_manager::auto_lock lock;
+          gh_manager::auto_lock lock;
 
-	  QMouseEvent* m = dynamic_cast<QMouseEvent*> (event);
-	  graphics_object go = object ();
-	  graphics_object fig = go.get_ancestor ("figure");
+          QMouseEvent* m = dynamic_cast<QMouseEvent*> (xevent);
+          graphics_object go = object ();
+          graphics_object fig = go.get_ancestor ("figure");
 
           gh_manager::post_set (fig.get_handle (), "currentpoint",
                                 Utils::figureCurrentPoint (fig, m), false);
@@ -215,7 +215,7 @@
           gh_manager::auto_lock lock;
 
           octave_scalar_map keyData =
-            Utils::makeKeyEventStruct (dynamic_cast<QKeyEvent*> (event));
+            Utils::makeKeyEventStruct (dynamic_cast<QKeyEvent*> (xevent));
           graphics_object fig = object ().get_ancestor ("figure");
 
           gh_manager::post_set (fig.get_handle (), "currentcharacter",
@@ -226,7 +226,7 @@
     default: break;
     }
 
-  return Object::eventFilter (watched, event);
+  return Object::eventFilter (watched, xevent);
 }
 
 }; // namespace QtHandles
--- a/libgui/graphics/ButtonControl.cc	Fri Aug 01 09:06:21 2014 -0400
+++ b/libgui/graphics/ButtonControl.cc	Fri Aug 01 12:10:05 2014 -0400
@@ -46,7 +46,7 @@
       Matrix value = up.get_value ().matrix_value ();
 
       if (value.numel () > 0 && value(0) == up.get_max ())
-	btn->setChecked (true);
+        btn->setChecked (true);
     }
 
   connect (btn, SIGNAL (clicked (void)), SLOT (clicked (void)));
@@ -70,19 +70,19 @@
     case uicontrol::properties::ID_VALUE:
       m_blockCallback = true;
       if (btn->isCheckable ())
-	{
-	  Matrix value = up.get_value ().matrix_value ();
+        {
+          Matrix value = up.get_value ().matrix_value ();
 
-	  if (value.numel () > 0)
-	    {
-	      double dValue = value(0);
+          if (value.numel () > 0)
+            {
+              double dValue = value(0);
 
-	      if (dValue == up.get_min () && btn->isChecked ())
-		btn->setChecked (false);
-	      else if (dValue == up.get_max () && ! btn->isChecked ())
-		btn->setChecked (true);
-	    }
-	}
+              if (dValue == up.get_min () && btn->isChecked ())
+                btn->setChecked (false);
+              else if (dValue == up.get_max () && ! btn->isChecked ())
+                btn->setChecked (true);
+            }
+        }
       m_blockCallback = false;
       break;
     default:
@@ -105,8 +105,8 @@
       double newValue = (checked ? up.get_max () : up.get_min ());
 
       if (oldValue.numel() != 1
-	  || (newValue != oldValue(0)))
-	gh_manager::post_set (m_handle, "value", newValue, false);
+          || (newValue != oldValue(0)))
+        gh_manager::post_set (m_handle, "value", newValue, false);
       gh_manager::post_callback (m_handle, "callback");
     }
 }
--- a/libgui/graphics/Canvas.cc	Fri Aug 01 09:06:21 2014 -0400
+++ b/libgui/graphics/Canvas.cc	Fri Aug 01 12:10:05 2014 -0400
@@ -95,7 +95,7 @@
       draw (m_handle);
 
       if (m_mouseMode == ZoomMode && m_mouseAxes.ok ())
-	drawZoomBox (m_mouseAnchor, m_mouseCurrent);
+        drawZoomBox (m_mouseAnchor, m_mouseCurrent);
     }
 }
 
@@ -109,65 +109,65 @@
       axes::properties& ap = Utils::properties<axes> (ax);
 
       switch (m_mouseMode)
-	{
-	case RotateMode:
-	    {
-	      Matrix bb = ap.get_boundingbox (true);
-	      Matrix view = ap.get_view ().matrix_value ();
+        {
+        case RotateMode:
+            {
+              Matrix bb = ap.get_boundingbox (true);
+              Matrix view = ap.get_view ().matrix_value ();
 
-	      // Compute new view angles
-	      view(0) += ((m_mouseCurrent.x () - event->x ())
-			  * (180.0 / bb(2)));
-	      view(1) += ((event->y () - m_mouseCurrent.y ())
-			  * (180.0 / bb(3)));
+              // Compute new view angles
+              view(0) += ((m_mouseCurrent.x () - event->x ())
+                          * (180.0 / bb(2)));
+              view(1) += ((event->y () - m_mouseCurrent.y ())
+                          * (180.0 / bb(3)));
 
-	      // Clipping
-	      view(1) = std::min (view(1), 90.0);
-	      view(1) = std::max (view(1), -90.0);
-	      if (view(0) > 180.0)
-		view(0) -= 360.0;
-	      else if (view(0) < -180.0)
-		view(0) += 360.0;
+              // Clipping
+              view(1) = std::min (view(1), 90.0);
+              view(1) = std::max (view(1), -90.0);
+              if (view(0) > 180.0)
+                view(0) -= 360.0;
+              else if (view(0) < -180.0)
+                view(0) += 360.0;
 
-	      // Snapping
-	      double snapMargin = 1.0;
-	      for (int a = -90; a <= 90; a += 90)
-		if ((a - snapMargin) < view(1)
-		    && view(1) < (a + snapMargin))
-		  {
-		    view(1) = a;
-		    break;
-		  }
-	      for (int a = -180; a <= 180; a += 180)
-		if ((a - snapMargin) < view(0)
-		    && view(0) < (a + snapMargin))
-		  {
-		    if (a == 180)
-		      view(0) = -180;
-		    else
-		      view(0) = a;
-		    break;
-		  }
+              // Snapping
+              double snapMargin = 1.0;
+              for (int a = -90; a <= 90; a += 90)
+                if ((a - snapMargin) < view(1)
+                    && view(1) < (a + snapMargin))
+                  {
+                    view(1) = a;
+                    break;
+                  }
+              for (int a = -180; a <= 180; a += 180)
+                if ((a - snapMargin) < view(0)
+                    && view(0) < (a + snapMargin))
+                  {
+                    if (a == 180)
+                      view(0) = -180;
+                    else
+                      view(0) = a;
+                    break;
+                  }
 
-	      // Update axes properties
-	      ap.set_view (view);
+              // Update axes properties
+              ap.set_view (view);
 
-	      // Update current mouse position
-	      m_mouseCurrent = event->pos ();
+              // Update current mouse position
+              m_mouseCurrent = event->pos ();
 
-	      // Force immediate redraw
-	      redraw (true);
-	    }
-	  break;
-	case ZoomMode:
-	  m_mouseCurrent = event->pos();
-	  redraw (true);
-	  break;
-	case PanMode:
-	  break;
-	default:
-	  break;
-	}
+              // Force immediate redraw
+              redraw (true);
+            }
+          break;
+        case ZoomMode:
+          m_mouseCurrent = event->pos();
+          redraw (true);
+          break;
+        case PanMode:
+          break;
+        default:
+          break;
+        }
     }
   else if (m_mouseMode == NoMode)
     {
@@ -178,8 +178,8 @@
           graphics_object figObj (obj.get_ancestor ("figure"));
 
           updateCurrentPoint (figObj, obj, event);
-	  gh_manager::post_callback (figObj.get_handle (),
-				     "windowbuttonmotionfcn");
+          gh_manager::post_callback (figObj.get_handle (),
+                                     "windowbuttonmotionfcn");
         }
     }
 }
@@ -199,24 +199,24 @@
       octave_idx_type num_children = children.numel ();
 
       for (int i = 0; i < num_children; i++)
-	{
-	  graphics_object childObj (gh_manager::get_object (children(i)));
+        {
+          graphics_object childObj (gh_manager::get_object (children(i)));
 
           if (childObj.isa ("axes"))
             axesList.append (childObj);
-	  else if (childObj.isa ("uicontrol") || childObj.isa ("uipanel"))
-	    {
-	      Matrix bb = childObj.get_properties ().get_boundingbox (false);
-	      QRectF r (bb(0), bb(1), bb(2), bb(3));
+          else if (childObj.isa ("uicontrol") || childObj.isa ("uipanel"))
+            {
+              Matrix bb = childObj.get_properties ().get_boundingbox (false);
+              QRectF r (bb(0), bb(1), bb(2), bb(3));
 
-	      r.adjust (-5, -5, 5, 5);
-	      if (r.contains (event->posF ()))
-		{
-		  currentObj = childObj;
-		  break;
-		}
-	    }
-	}
+              r.adjust (-5, -5, 5, 5);
+              if (r.contains (event->posF ()))
+                {
+                  currentObj = childObj;
+                  break;
+                }
+            }
+        }
 
       if (! currentObj)
         {
@@ -269,61 +269,61 @@
       MouseMode newMouseMode = NoMode;
 
       if (fig)
-	newMouseMode = fig->mouseMode ();
+        newMouseMode = fig->mouseMode ();
 
       switch (newMouseMode)
-	{
-	case NoMode:
-	  gh_manager::post_set (figObj.get_handle (), "selectiontype",
-				Utils::figureSelectionType (event), false);
+        {
+        case NoMode:
+          gh_manager::post_set (figObj.get_handle (), "selectiontype",
+                                Utils::figureSelectionType (event), false);
           updateCurrentPoint (figObj, obj, event);
-	  gh_manager::post_callback (figObj.get_handle (),
-				     "windowbuttondownfcn");
+          gh_manager::post_callback (figObj.get_handle (),
+                                     "windowbuttondownfcn");
           gh_manager::post_callback (currentObj.get_handle (),
                                      "buttondownfcn");
-	  if (event->button () == Qt::RightButton)
-	    ContextMenu::executeAt (currentObj.get_properties (),
-				    event->globalPos ());
-	  break;
-	case RotateMode:
-	case ZoomMode:
-	case PanMode:
-	  if (axesObj)
-	    {
-	      if (event->buttons () == Qt::LeftButton
-		  && event->modifiers () == Qt::NoModifier)
-		{
-		  m_mouseAnchor = m_mouseCurrent = event->pos ();
-		  m_mouseAxes = axesObj.get_handle ();
-		  m_mouseMode = newMouseMode;
-		}
-	      else if (newMouseMode == ZoomMode
-		       && event->modifiers () == Qt::NoModifier)
-		{
-		  switch (event->buttons ())
-		    {
-		    case Qt::RightButton:
-		      Utils::properties<axes> (axesObj).unzoom ();
-		      break;
-		    case Qt::MidButton:
-			{
-			  axes::properties& ap =
-			    Utils::properties<axes> (axesObj);
+          if (event->button () == Qt::RightButton)
+            ContextMenu::executeAt (currentObj.get_properties (),
+                                    event->globalPos ());
+          break;
+        case RotateMode:
+        case ZoomMode:
+        case PanMode:
+          if (axesObj)
+            {
+              if (event->buttons () == Qt::LeftButton
+                  && event->modifiers () == Qt::NoModifier)
+                {
+                  m_mouseAnchor = m_mouseCurrent = event->pos ();
+                  m_mouseAxes = axesObj.get_handle ();
+                  m_mouseMode = newMouseMode;
+                }
+              else if (newMouseMode == ZoomMode
+                       && event->modifiers () == Qt::NoModifier)
+                {
+                  switch (event->buttons ())
+                    {
+                    case Qt::RightButton:
+                      Utils::properties<axes> (axesObj).unzoom ();
+                      break;
+                    case Qt::MidButton:
+                        {
+                          axes::properties& ap =
+                            Utils::properties<axes> (axesObj);
 
-			  ap.clear_zoom_stack ();
-			  ap.set_xlimmode ("auto");
-			  ap.set_ylimmode ("auto");
-			  ap.set_zlimmode ("auto");
-			}
-		      break;
-		    }
-		  redraw (false);
-		}
-	    }
-	  break;
-	default:
-	  break;
-	}
+                          ap.clear_zoom_stack ();
+                          ap.set_xlimmode ("auto");
+                          ap.set_ylimmode ("auto");
+                          ap.set_zlimmode ("auto");
+                        }
+                      break;
+                    }
+                  redraw (false);
+                }
+            }
+          break;
+        default:
+          break;
+        }
     }
 }
 
@@ -337,26 +337,26 @@
       graphics_object ax = gh_manager::get_object (m_mouseAxes);
 
       if (ax.valid_object ())
-	{
-	  axes::properties& ap = Utils::properties<axes> (ax);
+        {
+          axes::properties& ap = Utils::properties<axes> (ax);
 
-	  ColumnVector p0 = ap.pixel2coord (m_mouseAnchor.x (),
-					    m_mouseAnchor.y ());
-	  ColumnVector p1 = ap.pixel2coord (event->x (),
-					    event->y ());
+          ColumnVector p0 = ap.pixel2coord (m_mouseAnchor.x (),
+                                            m_mouseAnchor.y ());
+          ColumnVector p1 = ap.pixel2coord (event->x (),
+                                            event->y ());
 
-	  Matrix xl (1, 2, 0.0);
-	  Matrix yl (1, 2, 0.0);
+          Matrix xl (1, 2, 0.0);
+          Matrix yl (1, 2, 0.0);
 
-	  xl(0) = std::min (p0(0), p1(0));
-	  xl(1) = std::max (p0(0), p1(0));
-	  yl(0) = std::min (p0(1), p1(1));
-	  yl(1) = std::max (p0(1), p1(1));
+          xl(0) = std::min (p0(0), p1(0));
+          xl(1) = std::max (p0(0), p1(0));
+          yl(0) = std::min (p0(1), p1(1));
+          yl(1) = std::max (p0(1), p1(1));
 
-	  ap.zoom (xl, yl);
+          ap.zoom (xl, yl);
 
-	  redraw (false);
-	}
+          redraw (false);
+        }
     }
   else if (m_mouseMode == NoMode)
     {
@@ -407,7 +407,7 @@
 }
 
 Canvas* Canvas::create (const std::string& /* name */, QWidget* parent,
-			const graphics_handle& handle)
+                        const graphics_handle& handle)
 {
   // Only OpenGL
   return new GLCanvas (parent, handle);
--- a/libgui/graphics/Canvas.h	Fri Aug 01 09:06:21 2014 -0400
+++ b/libgui/graphics/Canvas.h	Fri Aug 01 12:10:05 2014 -0400
@@ -58,7 +58,7 @@
   virtual QWidget* qWidget (void) = 0;
 
   static Canvas* create (const std::string& name, QWidget* parent,
-			 const graphics_handle& handle);
+                         const graphics_handle& handle);
 
 protected:
   virtual void draw (const graphics_handle& handle) = 0;
--- a/libgui/graphics/CheckBoxControl.cc	Fri Aug 01 09:06:21 2014 -0400
+++ b/libgui/graphics/CheckBoxControl.cc	Fri Aug 01 12:10:05 2014 -0400
@@ -41,7 +41,7 @@
       Container* container = parent->innerContainer ();
 
       if (container)
-	return new CheckBoxControl (go, new QCheckBox (container));
+        return new CheckBoxControl (go, new QCheckBox (container));
     }
 
   return 0;
--- a/libgui/graphics/Container.cc	Fri Aug 01 09:06:21 2014 -0400
+++ b/libgui/graphics/Container.cc	Fri Aug 01 12:10:05 2014 -0400
@@ -37,8 +37,8 @@
 namespace QtHandles
 {
 
-Container::Container (QWidget* parent)
-  : ContainerBase (parent), m_canvas (0)
+Container::Container (QWidget* xparent)
+  : ContainerBase (xparent), m_canvas (0)
 {
   setFocusPolicy (Qt::ClickFocus);
 }
@@ -47,25 +47,25 @@
 {
 }
 
-Canvas* Container::canvas (const graphics_handle& handle, bool create)
+Canvas* Container::canvas (const graphics_handle& xhandle, bool xcreate)
 {
-  if (! m_canvas && create)
+  if (! m_canvas && xcreate)
     {
-      graphics_object go = gh_manager::get_object (handle);
+      graphics_object go = gh_manager::get_object (xhandle);
 
       if (go)
-	{
-	  graphics_object fig = go.get_ancestor ("figure");
+        {
+          graphics_object fig = go.get_ancestor ("figure");
 
-	  m_canvas = Canvas::create (fig.get("renderer").string_value (),
-				     this, handle);
+          m_canvas = Canvas::create (fig.get("renderer").string_value (),
+                                     this, xhandle);
 
-	  QWidget* canvasWidget = m_canvas->qWidget ();
+          QWidget* canvasWidget = m_canvas->qWidget ();
 
-	  canvasWidget->lower ();
-	  canvasWidget->show ();
-	  canvasWidget->setGeometry (0, 0, width (), height ());
-	}
+          canvasWidget->lower ();
+          canvasWidget->show ();
+          canvasWidget->setGeometry (0, 0, width (), height ());
+        }
     }
 
   return m_canvas;
@@ -81,26 +81,26 @@
   foreach (QObject* qObj, children ())
     {
       if (qObj->isWidgetType ())
-	{
-	  Object* obj = Object::fromQObject (qObj);
+        {
+          Object* obj = Object::fromQObject (qObj);
 
-	  if (obj)
-	    {
-	      Matrix bb = obj->properties ().get_boundingbox (false);
+          if (obj)
+            {
+              Matrix bb = obj->properties ().get_boundingbox (false);
 
-	      obj->qWidget<QWidget> ()
-		->setGeometry (xround (bb(0)), xround (bb(1)),
-			       xround (bb(2)), xround (bb(3)));
-	    }
-	}
+              obj->qWidget<QWidget> ()
+                ->setGeometry (xround (bb(0)), xround (bb(1)),
+                               xround (bb(2)), xround (bb(3)));
+            }
+        }
     }
 }
 
-void Container::childEvent (QChildEvent* event)
+void Container::childEvent (QChildEvent* xevent)
 {
-  if (event->child ()->isWidgetType ())
+  if (xevent->child ()->isWidgetType ())
     {
-      qobject_cast<QWidget*> (event->child ())->setMouseTracking (hasMouseTracking ());
+      qobject_cast<QWidget*> (xevent->child ())->setMouseTracking (hasMouseTracking ());
     }
 }
 
--- a/libgui/graphics/ContextMenu.cc	Fri Aug 01 09:06:21 2014 -0400
+++ b/libgui/graphics/ContextMenu.cc	Fri Aug 01 12:10:05 2014 -0400
@@ -35,11 +35,11 @@
 
 ContextMenu* ContextMenu::create (const graphics_object& go)
 {
-  Object* parent = Object::parentObject (go);
+  Object* xparent = Object::parentObject (go);
 
-  if (parent)
+  if (xparent)
     {
-      QWidget* w = parent->qWidget<QWidget> ();
+      QWidget* w = xparent->qWidget<QWidget> ();
 
       return new ContextMenu (go, new QMenu (w));
     }
@@ -47,13 +47,13 @@
   return 0;
 }
 
-ContextMenu::ContextMenu (const graphics_object& go, QMenu* menu)
-    : Object (go, menu)
+ContextMenu::ContextMenu (const graphics_object& go, QMenu* xmenu)
+    : Object (go, xmenu)
 {
-  menu->setAutoFillBackground (true);
+  xmenu->setAutoFillBackground (true);
 
-  connect (menu, SIGNAL (aboutToShow (void)), SLOT (aboutToShow (void)));
-  connect (menu, SIGNAL (aboutToHide (void)), SLOT (aboutToHide (void)));
+  connect (xmenu, SIGNAL (aboutToShow (void)), SLOT (aboutToShow (void)));
+  connect (xmenu, SIGNAL (aboutToHide (void)), SLOT (aboutToHide (void)));
 }
 
 ContextMenu::~ContextMenu (void)
@@ -63,25 +63,25 @@
 void ContextMenu::update (int pId)
 {
   uicontextmenu::properties& up = properties<uicontextmenu> ();
-  QMenu* menu = qWidget<QMenu> ();
+  QMenu* xmenu = qWidget<QMenu> ();
 
   switch (pId)
     {
     case base_properties::ID_VISIBLE:
       if (up.is_visible ())
-	{
-	  Matrix pos = up.get_position ().matrix_value ();
-	  QWidget* parentW = menu->parentWidget ();
-	  QPoint pt;
+        {
+          Matrix pos = up.get_position ().matrix_value ();
+          QWidget* parentW = xmenu->parentWidget ();
+          QPoint pt;
 
-	  pt.rx () = xround (pos(0));
-	  pt.ry () = parentW->height () - xround (pos(1));
-	  pt = parentW->mapToGlobal (pt);
+          pt.rx () = xround (pos(0));
+          pt.ry () = parentW->height () - xround (pos(1));
+          pt = parentW->mapToGlobal (pt);
 
-	  menu->popup (pt);
-	}
+          xmenu->popup (pt);
+        }
       else
-	menu->hide ();
+        xmenu->hide ();
       break;
     default:
       Object::update (pId);
@@ -114,18 +114,18 @@
       graphics_object go = gh_manager::get_object (h);
 
       if (go.valid_object ())
-	{
-	  ContextMenu* cMenu =
-	    dynamic_cast<ContextMenu*> (Backend::toolkitObject (go));
+        {
+          ContextMenu* cMenu =
+            dynamic_cast<ContextMenu*> (Backend::toolkitObject (go));
 
-	  if (cMenu)
-	    {
-	      QMenu* menu = cMenu->qWidget<QMenu> ();
+          if (cMenu)
+            {
+              QMenu* menu = cMenu->qWidget<QMenu> ();
 
-	      if (menu)
-		menu->popup (pt);
-	    }
-	}
+              if (menu)
+                menu->popup (pt);
+            }
+        }
     }
 }
 
--- a/libgui/graphics/EditControl.cc	Fri Aug 01 09:06:21 2014 -0400
+++ b/libgui/graphics/EditControl.cc	Fri Aug 01 12:10:05 2014 -0400
@@ -43,14 +43,14 @@
       Container* container = parent->innerContainer ();
 
       if (container)
-	{
-	  uicontrol::properties& up = Utils::properties<uicontrol> (go);
+        {
+          uicontrol::properties& up = Utils::properties<uicontrol> (go);
 
-	  if ((up.get_max () - up.get_min ()) > 1)
-	    return new EditControl (go, new TextEdit (container));
-	  else
-	    return new EditControl (go, new QLineEdit (container));
-	}
+          if ((up.get_max () - up.get_min ()) > 1)
+            return new EditControl (go, new TextEdit (container));
+          else
+            return new EditControl (go, new QLineEdit (container));
+        }
     }
 
   return 0;
@@ -74,12 +74,12 @@
 
   edit->setText (Utils::fromStdString (up.get_string_string ()));
   edit->setAlignment (Utils::fromHVAlign (up.get_horizontalalignment (),
-					  up.get_verticalalignment ()));
+                                          up.get_verticalalignment ()));
 
   connect (edit, SIGNAL (textEdited (const QString&)),
-	   SLOT (textChanged (void)));
+           SLOT (textChanged (void)));
   connect (edit, SIGNAL (editingFinished (void)),
-	   SLOT (editingFinished (void)));
+           SLOT (editingFinished (void)));
 }
 
 EditControl::EditControl (const graphics_object& go, TextEdit* edit)
@@ -103,9 +103,9 @@
   edit->setPlainText (Utils::fromStdString (up.get_string_string ()));
   
   connect (edit, SIGNAL (textChanged (void)),
-	   SLOT (textChanged (void)));
+           SLOT (textChanged (void)));
   connect (edit, SIGNAL (editingFinished (void)),
-	   SLOT (editingFinished (void)));
+           SLOT (editingFinished (void)));
 }
 
 EditControl::~EditControl (void)
@@ -129,11 +129,11 @@
   if (! handled)
     {
       switch (pId)
-	{
-	default:
-	  BaseControl::update (pId);
-	  break;
-	}
+        {
+        default:
+          BaseControl::update (pId);
+          break;
+        }
     }
 }
 
@@ -150,17 +150,17 @@
     case uicontrol::properties::ID_HORIZONTALALIGNMENT:
     case uicontrol::properties::ID_VERTICALALIGNMENT:
       edit->setAlignment (Utils::fromHVAlign (up.get_horizontalalignment (),
-					      up.get_verticalalignment ()));
+                                              up.get_verticalalignment ()));
       return true;
     case uicontrol::properties::ID_MIN:
     case uicontrol::properties::ID_MAX:
       if ((up.get_max () - up.get_min ()) > 1)
-	{
-	  QWidget* container = edit->parentWidget ();
+        {
+          QWidget* container = edit->parentWidget ();
 
-	  delete edit;
-	  init (new TextEdit (container), true);
-	}
+          delete edit;
+          init (new TextEdit (container), true);
+        }
       return true;
     default:
       break;
@@ -182,12 +182,12 @@
     case uicontrol::properties::ID_MIN:
     case uicontrol::properties::ID_MAX:
       if ((up.get_max () - up.get_min ()) <= 1)
-	{
-	  QWidget* container = edit->parentWidget ();
+        {
+          QWidget* container = edit->parentWidget ();
 
-	  delete edit;
-	  init (new QLineEdit (container), true);
-	}
+          delete edit;
+          init (new QLineEdit (container), true);
+        }
       return true;
     default:
       break;
@@ -206,8 +206,8 @@
   if (m_textChanged)
     {
       QString txt = (m_multiLine
-		     ? qWidget<TextEdit> ()->toPlainText ()
-		     : qWidget<QLineEdit> ()->text ());
+                     ? qWidget<TextEdit> ()->toPlainText ()
+                     : qWidget<QLineEdit> ()->text ());
 
       gh_manager::post_set (m_handle, "string", Utils::toStdString (txt), false);
       gh_manager::post_callback (m_handle, "callback");
--- a/libgui/graphics/Figure.cc	Fri Aug 01 09:06:21 2014 -0400
+++ b/libgui/graphics/Figure.cc	Fri Aug 01 12:10:05 2014 -0400
@@ -61,8 +61,8 @@
       graphics_object go (gh_manager::get_object (kids(i)));
 
       if (go && (go.isa ("uicontrol") || go.isa ("uipanel")
-		 || go.isa ("uibuttongroup")))
-	return true;
+                 || go.isa ("uibuttongroup")))
+        return true;
     }
 
   return false;
@@ -77,7 +77,7 @@
       graphics_object go (gh_manager::get_object (kids(i)));
 
       if (go && go.isa ("uimenu"))
-	return true;
+        return true;
     }
 
   return false;
@@ -173,7 +173,7 @@
 
   MouseModeActionGroup* mouseModeGroup = new MouseModeActionGroup (win);
   connect (mouseModeGroup, SIGNAL (modeChanged (MouseMode)),
-	   SLOT (setMouseMode (MouseMode)));
+           SLOT (setMouseMode (MouseMode)));
   m_figureToolBar->addActions (mouseModeGroup->actions ());
 
   m_menuBar = new MenuBar (win);
@@ -188,23 +188,23 @@
   fileMenu->addAction (tr ("Save &As"))->setEnabled (false);
   fileMenu->addSeparator ();
   fileMenu->addAction (tr ("&Close Figure"), this,
-		       SLOT (fileCloseFigure (void)), Qt::CTRL|Qt::Key_W);
+                       SLOT (fileCloseFigure (void)), Qt::CTRL|Qt::Key_W);
 
   QMenu* editMenu = m_menuBar->addMenu (tr ("&Edit"));
   editMenu->menuAction ()->setObjectName ("builtinMenu");
   editMenu->addAction (tr ("Cop&y"), this, SLOT (editCopy (void)),
-		       Qt::CTRL|Qt::Key_C)->setEnabled (false);
+                       Qt::CTRL|Qt::Key_C)->setEnabled (false);
   editMenu->addAction (tr ("Cu&t"), this, SLOT (editCut (void)),
-		       Qt::CTRL|Qt::Key_X)->setEnabled (false);
+                       Qt::CTRL|Qt::Key_X)->setEnabled (false);
   editMenu->addAction (tr ("&Paste"), this, SLOT (editPaste(void)),
-		       Qt::CTRL|Qt::Key_V)->setEnabled (false);
+                       Qt::CTRL|Qt::Key_V)->setEnabled (false);
   editMenu->addSeparator ();
   editMenu->addActions (mouseModeGroup->actions ());
 
   QMenu* helpMenu = m_menuBar->addMenu (tr ("&Help"));
   helpMenu->menuAction ()->setObjectName ("builtinMenu");
   helpMenu->addAction (tr ("&About QtHandles"), this,
-		       SLOT (helpAboutQtHandles (void)));
+                       SLOT (helpAboutQtHandles (void)));
   helpMenu->addAction (tr ("About &Qt"), qApp, SLOT (aboutQt (void)));
 
   m_menuBar->addReceiver (this);
@@ -226,12 +226,12 @@
     }
 
   foreach (QFrame* frame,
-	   qWidget<QWidget> ()->findChildren<QFrame*> ("UIPanel"))
+           qWidget<QWidget> ()->findChildren<QFrame*> ("UIPanel"))
     {
       Object* obj = Object::fromQObject (frame);
 
       if (obj)
-	obj->slotRedraw ();
+        obj->slotRedraw ();
     }
 }
 
@@ -260,20 +260,20 @@
   switch (pId)
     {
     case figure::properties::ID_POSITION:
-	{
+        {
           m_innerRect = boundingBoxToRect (fp.get_boundingbox (true));
           //qDebug () << "Figure::update(position):" << m_innerRect;
-	  int offset = 0;
+          int offset = 0;
 
           foreach (QToolBar* tb, win->findChildren<QToolBar*> ())
             if (! tb->isHidden ())
               offset += tb->sizeHint ().height ();
-	  if (! m_menuBar->isHidden ())
-	    offset += m_menuBar->sizeHint ().height () + 1;
+          if (! m_menuBar->isHidden ())
+            offset += m_menuBar->sizeHint ().height () + 1;
           //qDebug () << "Figure::update(position)(adjusted):" << m_innerRect.adjusted (0, -offset, 0, 0);
-	  win->setGeometry (m_innerRect.adjusted (0, -offset, 0, 0));
+          win->setGeometry (m_innerRect.adjusted (0, -offset, 0, 0));
           //qDebug () << "Figure::update(position): done";
-	}
+        }
       break;
     case figure::properties::ID_NAME:
     case figure::properties::ID_NUMBERTITLE:
@@ -281,17 +281,17 @@
       break;
     case figure::properties::ID_VISIBLE:
       if (fp.is_visible ())
-	QTimer::singleShot (0, win, SLOT (show ()));
+        QTimer::singleShot (0, win, SLOT (show ()));
       else
-	win->hide ();
+        win->hide ();
       break;
     case figure::properties::ID_TOOLBAR:
       if (fp.toolbar_is ("none"))
-	showFigureToolBar (false);
+        showFigureToolBar (false);
       else if (fp.toolbar_is ("figure"))
-	showFigureToolBar (true);
+        showFigureToolBar (true);
       else // "auto"
-	showFigureToolBar (! hasUiControlChildren (fp));
+        showFigureToolBar (! hasUiControlChildren (fp));
       break;
     case figure::properties::ID_MENUBAR:
       showMenuBar (fp.menubar_is ("figure"));
@@ -332,9 +332,9 @@
       QRect r = qWidget<QWidget> ()->geometry ();
 
       if (! visible)
-	r.adjust (0, dy, 0, 0);
+        r.adjust (0, dy, 0, 0);
       else
-	r.adjust (0, -dy, 0, 0);
+        r.adjust (0, -dy, 0, 0);
 
       m_blockUpdates = true;
       qWidget<QWidget> ()->setGeometry (r);
@@ -344,12 +344,12 @@
       updateBoundingBox (false);
 
       if (visible)
-	m_mouseMode = m_lastMouseMode;
+        m_mouseMode = m_lastMouseMode;
       else
-	{
-	  m_lastMouseMode = m_mouseMode;
-	  m_mouseMode = NoMode;
-	}
+        {
+          m_lastMouseMode = m_mouseMode;
+          m_mouseMode = NoMode;
+        }
     }
 }
 
@@ -373,9 +373,9 @@
 
       //qDebug () << "Figure::showMenuBar:" << r;
       if (! visible)
-	r.adjust (0, dy, 0, 0);
+        r.adjust (0, dy, 0, 0);
       else
-	r.adjust (0, -dy, 0, 0);
+        r.adjust (0, -dy, 0, 0);
       //qDebug () << "Figure::showMenuBar(adjusted):" << r;
 
       m_blockUpdates = true;
@@ -467,7 +467,7 @@
       if (flags & UpdateBoundingBoxSize)
         r.setSize (win->frameGeometry ().size ());
 
-      if (r.isValid () && r != m_outerRect )
+      if (r.isValid () && r != m_outerRect)
         {
           //qDebug() << "outer rect changed:" << m_outerRect << "->>" << r;
           m_outerRect = r;
@@ -493,103 +493,103 @@
   gh_manager::post_function (Figure::updateBoundingBoxHelper, d);
 }
 
-bool Figure::eventNotifyBefore (QObject* obj, QEvent* event)
+bool Figure::eventNotifyBefore (QObject* obj, QEvent* xevent)
 {
   if (! m_blockUpdates)
     {
       if (obj == m_container)
-	{
+        {
           // Do nothing...
-	}
+        }
       else if (obj == m_menuBar)
-	{
-	  switch (event->type ())
-	    {
-	    case QEvent::ActionRemoved:
-		{
-		  QAction* a = dynamic_cast<QActionEvent*> (event)->action ();
+        {
+          switch (xevent->type ())
+            {
+            case QEvent::ActionRemoved:
+                {
+                  QAction* a = dynamic_cast<QActionEvent*> (xevent)->action ();
 
-		  if (! a->isSeparator ()
-		      && a->objectName () != "builtinMenu")
+                  if (! a->isSeparator ()
+                      && a->objectName () != "builtinMenu")
                     updateMenuBar ();
-		}
-	      break;
-	    default:
-	      break;
-	    }
-	}
+                }
+              break;
+            default:
+              break;
+            }
+        }
       else
-	{
-	  switch (event->type ())
-	    {
-	    case QEvent::Close:
-	      event->ignore ();
-	      gh_manager::post_callback (m_handle, "closerequestfcn");
-	      return true;
-	    default:
-	      break;
-	    }
-	}
+        {
+          switch (xevent->type ())
+            {
+            case QEvent::Close:
+              xevent->ignore ();
+              gh_manager::post_callback (m_handle, "closerequestfcn");
+              return true;
+            default:
+              break;
+            }
+        }
     }
 
   return false;
 }
 
-void Figure::eventNotifyAfter (QObject* watched, QEvent* event)
+void Figure::eventNotifyAfter (QObject* watched, QEvent* xevent)
 {
   if (! m_blockUpdates)
     {
       if (watched == m_container)
         {
-	  switch (event->type ())
-	    {
-	    case QEvent::Resize:
-	      updateBoundingBox (true, UpdateBoundingBoxSize);
-	      break;
-	    case QEvent::ChildAdded:
-	      if (dynamic_cast<QChildEvent*> (event)->child
-		  ()->isWidgetType())
-		{
-		  gh_manager::auto_lock lock;
-		  const figure::properties& fp = properties<figure> ();
+          switch (xevent->type ())
+            {
+            case QEvent::Resize:
+              updateBoundingBox (true, UpdateBoundingBoxSize);
+              break;
+            case QEvent::ChildAdded:
+              if (dynamic_cast<QChildEvent*> (xevent)->child
+                  ()->isWidgetType())
+                {
+                  gh_manager::auto_lock lock;
+                  const figure::properties& fp = properties<figure> ();
 
-		  showFigureToolBar (! hasUiControlChildren (fp));
-		}
-	    default:
-	      break;
-	    }
+                  showFigureToolBar (! hasUiControlChildren (fp));
+                }
+            default:
+              break;
+            }
         }
       else if (watched == m_menuBar)
         {
-	  switch (event->type ())
-	    {
-	    case QEvent::ActionAdded:
-		{
-		  QAction* a = dynamic_cast<QActionEvent*> (event)->action ();
+          switch (xevent->type ())
+            {
+            case QEvent::ActionAdded:
+                {
+                  QAction* a = dynamic_cast<QActionEvent*> (xevent)->action ();
 
-		  if (! a->isSeparator ()
+                  if (! a->isSeparator ()
                       && a->objectName () != "builtinMenu")
                     updateMenuBar ();
-		}
-	      break;
-	    default:
-	      break;
-	    }
+                }
+              break;
+            default:
+              break;
+            }
         }
       else
         {
-	  switch (event->type ())
-	    {
-	    case QEvent::Move:
-	      updateBoundingBox (false, UpdateBoundingBoxPosition);
-	      updateBoundingBox (true, UpdateBoundingBoxPosition);
-	      break;
-	    case QEvent::Resize:
-	      updateBoundingBox (false, UpdateBoundingBoxSize);
-	      break;
-	    default:
-	      break;
-	    }
+          switch (xevent->type ())
+            {
+            case QEvent::Move:
+              updateBoundingBox (false, UpdateBoundingBoxPosition);
+              updateBoundingBox (true, UpdateBoundingBoxPosition);
+              break;
+            case QEvent::Resize:
+              updateBoundingBox (false, UpdateBoundingBoxSize);
+              break;
+            default:
+              break;
+            }
         }
     }
 }
@@ -597,7 +597,7 @@
 void Figure::helpAboutQtHandles (void)
 {
   QMessageBox::about (qWidget<QMainWindow> (), tr ("About QtHandles"),
-		      ABOUT_TEXT);
+                      ABOUT_TEXT);
 }
 
 void Figure::fileNewFigure (void)
@@ -656,9 +656,9 @@
       QRect r = win->geometry ();
 
       if (visible)
-	r.adjust (0, -sz.height (), 0, 0);
+        r.adjust (0, -sz.height (), 0, 0);
       else
-	r.adjust (0, sz.height (), 0, 0);
+        r.adjust (0, sz.height (), 0, 0);
 
       m_blockUpdates = true;
       win->setGeometry (r);
--- a/libgui/graphics/Figure.h	Fri Aug 01 09:06:21 2014 -0400
+++ b/libgui/graphics/Figure.h	Fri Aug 01 12:10:05 2014 -0400
@@ -37,11 +37,11 @@
 
 enum MouseMode
 {
-  NoMode	= 0,
-  RotateMode	= 1,
-  ZoomMode	= 2,
-  PanMode	= 3,
-  SelectMode	= 4
+  NoMode        = 0,
+  RotateMode    = 1,
+  ZoomMode      = 2,
+  PanMode       = 3,
+  SelectMode    = 4
 };
 
 class Container;
--- a/libgui/graphics/FigureWindow.cc	Fri Aug 01 09:06:21 2014 -0400
+++ b/libgui/graphics/FigureWindow.cc	Fri Aug 01 12:10:05 2014 -0400
@@ -31,8 +31,8 @@
 namespace QtHandles
 {
 
-FigureWindow::FigureWindow (QWidget* parent)
-  : FigureWindowBase (parent)
+FigureWindow::FigureWindow (QWidget* xparent)
+  : FigureWindowBase (xparent)
 {
 }
 
--- a/libgui/graphics/GLCanvas.cc	Fri Aug 01 09:06:21 2014 -0400
+++ b/libgui/graphics/GLCanvas.cc	Fri Aug 01 12:10:05 2014 -0400
@@ -37,8 +37,8 @@
 namespace QtHandles
 {
 
-GLCanvas::GLCanvas (QWidget* parent, const graphics_handle& handle)
-  : QGLWidget (parent), Canvas (handle)
+GLCanvas::GLCanvas (QWidget* xparent, const graphics_handle& xhandle)
+  : QGLWidget (xparent), Canvas (xhandle)
 {
   setFocusPolicy (Qt::ClickFocus);
 }
@@ -47,9 +47,9 @@
 {
 }
 
-void GLCanvas::draw (const graphics_handle& handle)
+void GLCanvas::draw (const graphics_handle& xhandle)
 {
-  graphics_object go = gh_manager::get_object (handle);
+  graphics_object go = gh_manager::get_object (xhandle);
 
   if (go)
     {
@@ -119,31 +119,31 @@
   canvasPaintEvent ();
 }
 
-void GLCanvas::mouseMoveEvent (QMouseEvent* event)
+void GLCanvas::mouseMoveEvent (QMouseEvent* xevent)
 {
-  canvasMouseMoveEvent (event);
+  canvasMouseMoveEvent (xevent);
 }
 
-void GLCanvas::mousePressEvent (QMouseEvent* event)
+void GLCanvas::mousePressEvent (QMouseEvent* xevent)
 {
-  canvasMousePressEvent (event);
+  canvasMousePressEvent (xevent);
 }
 
-void GLCanvas::mouseReleaseEvent (QMouseEvent* event)
+void GLCanvas::mouseReleaseEvent (QMouseEvent* xevent)
 {
-  canvasMouseReleaseEvent (event);
+  canvasMouseReleaseEvent (xevent);
 }
 
-void GLCanvas::keyPressEvent (QKeyEvent* event)
+void GLCanvas::keyPressEvent (QKeyEvent* xevent)
 {
-  if (! canvasKeyPressEvent (event))
-    QGLWidget::keyPressEvent (event);
+  if (! canvasKeyPressEvent (xevent))
+    QGLWidget::keyPressEvent (xevent);
 }
 
-void GLCanvas::keyReleaseEvent (QKeyEvent* event)
+void GLCanvas::keyReleaseEvent (QKeyEvent* xevent)
 {
-  if (! canvasKeyReleaseEvent (event))
-    QGLWidget::keyReleaseEvent (event);
+  if (! canvasKeyReleaseEvent (xevent))
+    QGLWidget::keyReleaseEvent (xevent);
 }
 
 }; // namespace QtHandles
--- a/libgui/graphics/GLCanvas.h	Fri Aug 01 09:06:21 2014 -0400
+++ b/libgui/graphics/GLCanvas.h	Fri Aug 01 12:10:05 2014 -0400
@@ -39,7 +39,7 @@
   void draw (const graphics_handle& handle);
   void drawZoomBox (const QPoint& p1, const QPoint& p2);
   void resize (int /* x */, int /* y */,
-	       int /* width */, int /* height */) { }
+               int /* width */, int /* height */) { }
   graphics_object selectFromAxes (const graphics_object& ax,
                                   const QPoint& pt);
   QWidget* qWidget (void) { return this; }
--- a/libgui/graphics/GenericEventNotify.h	Fri Aug 01 09:06:21 2014 -0400
+++ b/libgui/graphics/GenericEventNotify.h	Fri Aug 01 12:10:05 2014 -0400
@@ -86,7 +86,7 @@
 class T : public B, public GenericEventNotifySender \
 { \
 public: \
-  T (QWidget* parent) : B (parent), GenericEventNotifySender () { } \
+  T (QWidget* xparent) : B (xparent), GenericEventNotifySender () { } \
   ~ T (void) { } \
 \
   bool event (QEvent* evt) \
--- a/libgui/graphics/ListBoxControl.cc	Fri Aug 01 09:06:21 2014 -0400
+++ b/libgui/graphics/ListBoxControl.cc	Fri Aug 01 12:10:05 2014 -0400
@@ -69,7 +69,7 @@
       Container* container = parent->innerContainer ();
 
       if (container)
-	return new ListBoxControl (go, new QListWidget (container));
+        return new ListBoxControl (go, new QListWidget (container));
     }
 
   return 0;
@@ -92,25 +92,25 @@
       int lc = list->count ();
 
       for (octave_idx_type i = 0; i < n; i++)
-	{
-	  int idx = xround (value(i));
+        {
+          int idx = xround (value(i));
 
-	  if (1 <= idx && idx <= lc)
-	    {
-	      list->item (idx-1)->setSelected (true);
-	      if (i == 0
-		  && list->selectionMode () ==
-		  	QAbstractItemView::SingleSelection)
-		break;
-	    }
-	}
+          if (1 <= idx && idx <= lc)
+            {
+              list->item (idx-1)->setSelected (true);
+              if (i == 0
+                  && list->selectionMode () ==
+                        QAbstractItemView::SingleSelection)
+                break;
+            }
+        }
     }
 
   list->removeEventFilter (this);
   list->viewport ()->installEventFilter (this);
 
   connect (list, SIGNAL (itemSelectionChanged (void)),
-	   SLOT (itemSelectionChanged (void)));
+           SLOT (itemSelectionChanged (void)));
 }
 
 ListBoxControl::~ListBoxControl (void)
@@ -134,9 +134,9 @@
     case uicontrol::properties::ID_MIN:
     case uicontrol::properties::ID_MAX:
       if ((up.get_max () - up.get_min ()) > 1)
-	list->setSelectionMode (QAbstractItemView::ExtendedSelection);
+        list->setSelectionMode (QAbstractItemView::ExtendedSelection);
       else
-	list->setSelectionMode (QAbstractItemView::SingleSelection);
+        list->setSelectionMode (QAbstractItemView::SingleSelection);
       break;
     case uicontrol::properties::ID_VALUE:
       m_blockCallback = true;
--- a/libgui/graphics/Menu.cc	Fri Aug 01 09:06:21 2014 -0400
+++ b/libgui/graphics/Menu.cc	Fri Aug 01 12:10:05 2014 -0400
@@ -46,11 +46,11 @@
       int keyMod = Qt::CTRL;
 
       if (c >= 'A' && c <= 'Z')
-	keyMod |= Qt::SHIFT;
+        keyMod |= Qt::SHIFT;
       if (c >= 'a' && c <= 'z')
-	c -= ('a' - 'A');
+        c -= ('a' - 'A');
       if (c >= 'A' && c <= 'Z')
-	return QKeySequence (keyMod | static_cast<int> (c));
+        return QKeySequence (keyMod | static_cast<int> (c));
     }
 
   return QKeySequence ();
@@ -65,13 +65,13 @@
       QObject* qObj = parent->qObject ();
 
       if (qObj)
-	return new Menu (go, new QAction (qObj), parent);
+        return new Menu (go, new QAction (qObj), parent);
     }
 
   return 0;
 }
 
-Menu::Menu (const graphics_object& go, QAction* action, Object* parent)
+Menu::Menu (const graphics_object& go, QAction* action, Object* xparent)
     : Object (go, action), m_parent (0), m_separator (0)
 {
   uimenu::properties& up = properties<uimenu> ();
@@ -92,7 +92,7 @@
       m_separator->setVisible (up.is_visible ());
     }
 
-  MenuContainer* menuContainer = dynamic_cast<MenuContainer*> (parent);
+  MenuContainer* menuContainer = dynamic_cast<MenuContainer*> (xparent);
 
   if (menuContainer)
     m_parent = menuContainer->menu ();
@@ -102,46 +102,46 @@
       int pos = static_cast<int> (up.get_position ());
 
       if (pos <= 0)
-	{
-	  if (m_separator)
-	    m_parent->insertAction (0, m_separator);
-	  m_parent->insertAction (0, action);
+        {
+          if (m_separator)
+            m_parent->insertAction (0, m_separator);
+          m_parent->insertAction (0, action);
 
-	  int count = 0;
+          int count = 0;
 
-	  foreach (QAction* a, m_parent->actions ())
-	    if (! a->isSeparator () && a->objectName () != "builtinMenu")
-	      count++;
-	  up.get_property ("position").set
-	    (octave_value (static_cast<double> (count)), true, false);
-	}
+          foreach (QAction* a, m_parent->actions ())
+            if (! a->isSeparator () && a->objectName () != "builtinMenu")
+              count++;
+          up.get_property ("position").set
+            (octave_value (static_cast<double> (count)), true, false);
+        }
       else
-	{
+        {
 
-	  int count = 0;
-	  QAction* before = 0;
+          int count = 0;
+          QAction* before = 0;
 
-	  foreach (QAction* a, m_parent->actions ())
-	    if (! a->isSeparator () && a->objectName () != "builtinMenu")
-	      {
-		count++;
-		if (pos <= count)
-		  {
-		    before = a;
-		    break;
-		  }
-	      }
+          foreach (QAction* a, m_parent->actions ())
+            if (! a->isSeparator () && a->objectName () != "builtinMenu")
+              {
+                count++;
+                if (pos <= count)
+                  {
+                    before = a;
+                    break;
+                  }
+              }
 
-	  if (m_separator)
-	    m_parent->insertAction (before, m_separator);
-	  m_parent->insertAction (before, action);
+          if (m_separator)
+            m_parent->insertAction (before, m_separator);
+          m_parent->insertAction (before, action);
 
-	  if (before)
-	    updateSiblingPositions ();
-	  else
-	    up.get_property ("position").set
-	      (octave_value (static_cast<double> (count+1)), true, false);
-	}
+          if (before)
+            updateSiblingPositions ();
+          else
+            up.get_property ("position").set
+              (octave_value (static_cast<double> (count+1)), true, false);
+        }
     }
 
   connect (action, SIGNAL (triggered (bool)), SLOT (actionTriggered (void)));
@@ -163,76 +163,76 @@
       break;
     case uimenu::properties::ID_CHECKED:
       if (up.is_checked ())
-	{
-	  action->setCheckable (true);
-	  action->setChecked (up.is_checked ());
-	}
+        {
+          action->setCheckable (true);
+          action->setChecked (up.is_checked ());
+        }
       else
-	{
-	  action->setChecked (false);
-	  action->setCheckable (false);
-	}
+        {
+          action->setChecked (false);
+          action->setCheckable (false);
+        }
       break;
     case uimenu::properties::ID_ENABLE:
       action->setEnabled (up.is_enable ());
       break;
     case uimenu::properties::ID_ACCELERATOR:
       if (! action->menu ())
-	action->setShortcut (accelSequence (up));
+        action->setShortcut (accelSequence (up));
       break;
     case uimenu::properties::ID_SEPARATOR:
       if (up.is_separator ())
-	{
-	  if (! m_separator)
-	    {
-	      m_separator = new QAction (action);
-	      m_separator->setSeparator (true);
-	      m_separator->setVisible (up.is_visible ());
-	      if (m_parent)
-		m_parent->insertAction (action, m_separator);
-	    }
-	}
+        {
+          if (! m_separator)
+            {
+              m_separator = new QAction (action);
+              m_separator->setSeparator (true);
+              m_separator->setVisible (up.is_visible ());
+              if (m_parent)
+                m_parent->insertAction (action, m_separator);
+            }
+        }
       else
-	{
-	  if (m_separator)
-	    delete m_separator;
-	  m_separator = 0;
-	}
+        {
+          if (m_separator)
+            delete m_separator;
+          m_separator = 0;
+        }
       break;
     case uimenu::properties::ID_VISIBLE:
       action->setVisible (up.is_visible ());
       if (m_separator)
-	m_separator->setVisible (up.is_visible ());
+        m_separator->setVisible (up.is_visible ());
       break;
     case uimenu::properties::ID_POSITION:
       if (m_separator)
-	m_parent->removeAction (m_separator);
+        m_parent->removeAction (m_separator);
       m_parent->removeAction (action);
-	{
-	  int pos = static_cast<int> (up.get_position ());
-	  QAction* before = 0;
+        {
+          int pos = static_cast<int> (up.get_position ());
+          QAction* before = 0;
 
-	  if (pos > 0)
-	    {
-	      int count = 0;
+          if (pos > 0)
+            {
+              int count = 0;
 
-	      foreach (QAction* a, m_parent->actions ())
-		if (! a->isSeparator () && a->objectName () != "builtinMenu")
-		  {
-		    count++;
-		    if (pos <= count)
-		      {
-			before = a;
-			break;
-		      }
-		  }
-	    }
+              foreach (QAction* a, m_parent->actions ())
+                if (! a->isSeparator () && a->objectName () != "builtinMenu")
+                  {
+                    count++;
+                    if (pos <= count)
+                      {
+                        before = a;
+                        break;
+                      }
+                  }
+            }
 
-	  if (m_separator)
-	    m_parent->insertAction (before, m_separator);
-	  m_parent->insertAction (before, action);
-	  updateSiblingPositions ();
-	}
+          if (m_separator)
+            m_parent->insertAction (before, m_separator);
+          m_parent->insertAction (before, action);
+          updateSiblingPositions ();
+        }
       break;
     default:
       Object::update (pId);
@@ -251,7 +251,7 @@
       action->setMenu (_menu);
       action->setShortcut (QKeySequence ());
       connect (_menu, SIGNAL (aboutToShow (void)),
-	       this, SLOT (actionHovered (void)));
+               this, SLOT (actionHovered (void)));
     }
 
   return _menu;
@@ -278,29 +278,29 @@
       double count = 1.0;
 
       foreach (QAction* a, m_parent->actions ())
-	{
-	  if (! a->isSeparator () && a->objectName () != "builtinMenu")
-	    {
-	      Object* aObj = Object::fromQObject (a);
+        {
+          if (! a->isSeparator () && a->objectName () != "builtinMenu")
+            {
+              Object* aObj = Object::fromQObject (a);
 
-	      if (aObj)
-		{
-		  graphics_object go = aObj->object ();
+              if (aObj)
+                {
+                  graphics_object go = aObj->object ();
 
-		  // Probably overkill as a uimenu child can only be another
-		  // uimenu object.
-		  if (go.isa ("uimenu"))
-		    {
-		      uimenu::properties& up = Utils::properties<uimenu> (go);
+                  // Probably overkill as a uimenu child can only be another
+                  // uimenu object.
+                  if (go.isa ("uimenu"))
+                    {
+                      uimenu::properties& up = Utils::properties<uimenu> (go);
 
-		      up.get_property ("position").set
-			(octave_value (count), true, false);
-		    }
-		}
+                      up.get_property ("position").set
+                        (octave_value (count), true, false);
+                    }
+                }
 
-	      count++;
-	    }
-	}
+              count++;
+            }
+        }
     }
 }
 
--- a/libgui/graphics/MouseModeActionGroup.cc	Fri Aug 01 09:06:21 2014 -0400
+++ b/libgui/graphics/MouseModeActionGroup.cc	Fri Aug 01 12:10:05 2014 -0400
@@ -33,17 +33,17 @@
 namespace QtHandles
 {
 
-MouseModeActionGroup::MouseModeActionGroup (QObject* parent)
-  : QObject (parent), m_current (0)
+MouseModeActionGroup::MouseModeActionGroup (QObject* xparent)
+  : QObject (xparent), m_current (0)
 {
   m_actions.append (new QAction (QIcon (":/images/rotate.png"),
-				 tr ("Rotate"), this));
+                                 tr ("Rotate"), this));
   m_actions.append (new QAction (QIcon (":/images/zoom.png"),
-				 tr ("Zoom"), this));
+                                 tr ("Zoom"), this));
   m_actions.append (new QAction (QIcon (":/images/pan.png"),
-				 tr ("Pan"), this));
+                                 tr ("Pan"), this));
   m_actions.append (new QAction (QIcon (":/images/select.png"),
-				 tr ("Select"), this));
+                                 tr ("Select"), this));
   m_actions[2]->setEnabled (false);
   m_actions[3]->setEnabled (false);
 
@@ -63,23 +63,23 @@
   if (! checked)
     {
       if (sender () == m_current)
-	{
-	  m_current = 0;
-	  emit modeChanged (NoMode);
-	}
+        {
+          m_current = 0;
+          emit modeChanged (NoMode);
+        }
     }
   else
     {
       int i = m_actions.indexOf (qobject_cast<QAction*> (sender ()));
 
       if (i >= 0)
-	{
-	  m_current = m_actions[i];
-	  for (int j = 0; j < m_actions.size (); j++)
-	    if (j != i)
-	      m_actions[j]->setChecked (false);
-	  emit modeChanged (static_cast<MouseMode> (i+1));
-	}
+        {
+          m_current = m_actions[i];
+          for (int j = 0; j < m_actions.size (); j++)
+            if (j != i)
+              m_actions[j]->setChecked (false);
+          emit modeChanged (static_cast<MouseMode> (i+1));
+        }
     }
 }
 
--- a/libgui/graphics/Object.cc	Fri Aug 01 09:06:21 2014 -0400
+++ b/libgui/graphics/Object.cc	Fri Aug 01 12:10:05 2014 -0400
@@ -40,8 +40,8 @@
 
   if (! lock)
     qCritical ("QtHandles::Object::Object: "
-	       "creating Object (h=%g) without a valid lock!!!",
-	       m_handle.value ());
+               "creating Object (h=%g) without a valid lock!!!",
+               m_handle.value ());
 
   init (obj);
 }
@@ -50,16 +50,16 @@
 {
   if (m_qobject)
     qCritical ("QtHandles::Object::init: "
-	       "resetting QObject while in invalid state");
+               "resetting QObject while in invalid state");
 
   m_qobject = obj;
 
   if (m_qobject)
     {
       m_qobject->setProperty ("QtHandles::Object",
-			      qVariantFromValue<void*> (this));
+                              qVariantFromValue<void*> (this));
       connect (m_qobject, SIGNAL (destroyed (QObject*)),
-	       SLOT (objectDestroyed (QObject*)));
+               SLOT (objectDestroyed (QObject*)));
     }
 }
 
@@ -73,8 +73,8 @@
 
   if (! lock)
     qCritical ("QtHandles::Object::object: "
-	       "accessing graphics object (h=%g) without a valid lock!!!",
-	       m_handle.value ());
+               "accessing graphics object (h=%g) without a valid lock!!!",
+               m_handle.value ());
 
   return gh_manager::get_object (m_handle);
 }
@@ -93,7 +93,7 @@
       break;
     default:
       if (object ().valid_object ())
-	update (pId);
+        update (pId);
       break;
     }
 }
--- a/libgui/graphics/Object.h	Fri Aug 01 09:06:21 2014 -0400
+++ b/libgui/graphics/Object.h	Fri Aug 01 12:10:05 2014 -0400
@@ -55,14 +55,14 @@
   typename T::properties& properties (void)
     {
       return dynamic_cast<typename T::properties&>
-	(object ().get_properties ());
+        (object ().get_properties ());
     }
   
   template <class T>
   const typename T::properties& properties (void) const
     {
       return dynamic_cast<const typename T::properties&>
-	(object ().get_properties ());
+        (object ().get_properties ());
     }
 
   graphics_object object (void) const;
--- a/libgui/graphics/ObjectFactory.cc	Fri Aug 01 09:06:21 2014 -0400
+++ b/libgui/graphics/ObjectFactory.cc	Fri Aug 01 12:10:05 2014 -0400
@@ -62,7 +62,7 @@
   if (! s_instanceCreated)
     {
       if (QThread::currentThread () != QApplication::instance ()->thread ())
-	s_instance.moveToThread (QApplication::instance ()->thread ());
+        s_instance.moveToThread (QApplication::instance ()->thread ());
       s_instanceCreated = true;
     }
 
@@ -78,72 +78,72 @@
   if (go.valid_object ())
     {
       if (go.get_properties ().is_beingdeleted ())
-	qWarning ("ObjectFactory::createObject: object is being deleted");
+        qWarning ("ObjectFactory::createObject: object is being deleted");
       else
-	{
-	  ObjectProxy* proxy = Backend::toolkitObjectProxy (go);
+        {
+          ObjectProxy* proxy = Backend::toolkitObjectProxy (go);
 
-	  if (proxy)
-	    {
-	      Logger::debug ("ObjectFactory::createObject: "
-			     "create %s from thread %08x",
-			     go.type ().c_str (), QThread::currentThreadId ());
+          if (proxy)
+            {
+              Logger::debug ("ObjectFactory::createObject: "
+                             "create %s from thread %08x",
+                             go.type ().c_str (), QThread::currentThreadId ());
 
-	      Object* obj = 0;
+              Object* obj = 0;
 
-	      if (go.isa ("figure"))
-		obj = Figure::create (go);
-	      else if (go.isa ("uicontrol"))
-		{
-		  uicontrol::properties& up =
-		   Utils::properties<uicontrol> (go);
+              if (go.isa ("figure"))
+                obj = Figure::create (go);
+              else if (go.isa ("uicontrol"))
+                {
+                  uicontrol::properties& up =
+                   Utils::properties<uicontrol> (go);
 
-		  if (up.style_is ("pushbutton"))
-		    obj = PushButtonControl::create (go);
-		  else if (up.style_is ("edit"))
-		    obj = EditControl::create (go);
-		  else if (up.style_is ("checkbox"))
-		    obj = CheckBoxControl::create (go);
-		  else if (up.style_is ("radiobutton"))
-		    obj = RadioButtonControl::create (go);
-		  else if (up.style_is ("togglebutton"))
-		    obj = ToggleButtonControl::create (go);
-		  else if (up.style_is ("text"))
-		    obj = TextControl::create (go);
-		  else if (up.style_is ("popupmenu"))
-		    obj = PopupMenuControl::create (go);
-		  else if (up.style_is ("slider"))
-		    obj = SliderControl::create (go);
-		  else if (up.style_is ("listbox"))
-		    obj = ListBoxControl::create (go);
-		}
-	      else if (go.isa ("uipanel"))
-		obj = Panel::create (go);
-	      else if (go.isa ("uimenu"))
-		obj = Menu::create (go);
-	      else if (go.isa ("uicontextmenu"))
-		obj = ContextMenu::create (go);
-	      else if (go.isa ("uitoolbar"))
-		obj = ToolBar::create (go);
-	      else if (go.isa ("uipushtool"))
-		obj = PushTool::create (go);
-	      else if (go.isa ("uitoggletool"))
-		obj = ToggleTool::create (go);
-	      else
-		qWarning ("ObjectFactory::createObject: unsupported type `%s'",
-			  go.type ().c_str ());
+                  if (up.style_is ("pushbutton"))
+                    obj = PushButtonControl::create (go);
+                  else if (up.style_is ("edit"))
+                    obj = EditControl::create (go);
+                  else if (up.style_is ("checkbox"))
+                    obj = CheckBoxControl::create (go);
+                  else if (up.style_is ("radiobutton"))
+                    obj = RadioButtonControl::create (go);
+                  else if (up.style_is ("togglebutton"))
+                    obj = ToggleButtonControl::create (go);
+                  else if (up.style_is ("text"))
+                    obj = TextControl::create (go);
+                  else if (up.style_is ("popupmenu"))
+                    obj = PopupMenuControl::create (go);
+                  else if (up.style_is ("slider"))
+                    obj = SliderControl::create (go);
+                  else if (up.style_is ("listbox"))
+                    obj = ListBoxControl::create (go);
+                }
+              else if (go.isa ("uipanel"))
+                obj = Panel::create (go);
+              else if (go.isa ("uimenu"))
+                obj = Menu::create (go);
+              else if (go.isa ("uicontextmenu"))
+                obj = ContextMenu::create (go);
+              else if (go.isa ("uitoolbar"))
+                obj = ToolBar::create (go);
+              else if (go.isa ("uipushtool"))
+                obj = PushTool::create (go);
+              else if (go.isa ("uitoggletool"))
+                obj = ToggleTool::create (go);
+              else
+                qWarning ("ObjectFactory::createObject: unsupported type `%s'",
+                          go.type ().c_str ());
 
-	      if (obj)
-		proxy->setObject (obj);
-	    }
-	  else
-	    qWarning ("ObjectFactory::createObject: no proxy for handle %g",
-		      handle);
-	}
+              if (obj)
+                proxy->setObject (obj);
+            }
+          else
+            qWarning ("ObjectFactory::createObject: no proxy for handle %g",
+                      handle);
+        }
     }
   else
     qWarning ("ObjectFactory::createObject: invalid object for handle %g",
-	      handle);
+              handle);
 }
 
 };
--- a/libgui/graphics/ObjectProxy.cc	Fri Aug 01 09:06:21 2014 -0400
+++ b/libgui/graphics/ObjectProxy.cc	Fri Aug 01 12:10:05 2014 -0400
@@ -43,26 +43,26 @@
   if (obj != m_object)
     {
       if (m_object)
-	{
-	  disconnect (this, SIGNAL (sendUpdate (int)),
-		      m_object, SLOT (slotUpdate (int)));
-	  disconnect (this, SIGNAL (sendFinalize (void)),
-		      m_object, SLOT (slotFinalize (void)));
-	  disconnect (this, SIGNAL (sendRedraw (void)),
-		      m_object, SLOT (slotRedraw (void)));
-	}
+        {
+          disconnect (this, SIGNAL (sendUpdate (int)),
+                      m_object, SLOT (slotUpdate (int)));
+          disconnect (this, SIGNAL (sendFinalize (void)),
+                      m_object, SLOT (slotFinalize (void)));
+          disconnect (this, SIGNAL (sendRedraw (void)),
+                      m_object, SLOT (slotRedraw (void)));
+        }
 
       m_object = obj;
 
       if (m_object)
-	{
-	  connect (this, SIGNAL (sendUpdate (int)),
-		   m_object, SLOT (slotUpdate (int)));
-	  connect (this, SIGNAL (sendFinalize (void)),
-		   m_object, SLOT (slotFinalize (void)));
-	  connect (this, SIGNAL (sendRedraw (void)),
-		   m_object, SLOT (slotRedraw (void)));
-	}
+        {
+          connect (this, SIGNAL (sendUpdate (int)),
+                   m_object, SLOT (slotUpdate (int)));
+          connect (this, SIGNAL (sendFinalize (void)),
+                   m_object, SLOT (slotFinalize (void)));
+          connect (this, SIGNAL (sendRedraw (void)),
+                   m_object, SLOT (slotRedraw (void)));
+        }
     }
 }
 
--- a/libgui/graphics/Panel.cc	Fri Aug 01 09:06:21 2014 -0400
+++ b/libgui/graphics/Panel.cc	Fri Aug 01 12:10:05 2014 -0400
@@ -58,13 +58,13 @@
 static void setupPalette (const uipanel::properties& pp, QPalette& p)
 {
   p.setColor (QPalette::Window,
-	      Utils::fromRgb (pp.get_backgroundcolor_rgb ()));
+              Utils::fromRgb (pp.get_backgroundcolor_rgb ()));
   p.setColor (QPalette::WindowText,
-	      Utils::fromRgb (pp.get_foregroundcolor_rgb ()));
+              Utils::fromRgb (pp.get_foregroundcolor_rgb ()));
   p.setColor (QPalette::Light,
-	      Utils::fromRgb (pp.get_highlightcolor_rgb ()));
+              Utils::fromRgb (pp.get_highlightcolor_rgb ()));
   p.setColor (QPalette::Dark,
-	      Utils::fromRgb (pp.get_shadowcolor_rgb ()));
+              Utils::fromRgb (pp.get_shadowcolor_rgb ()));
 }
 
 static int borderWidthFromProperties (const uipanel::properties& pp)
@@ -75,7 +75,7 @@
     {
       bw = xround (pp.get_borderwidth ());
       if (pp.bordertype_is ("etchedin") || pp.bordertype_is ("etchedout"))
-	bw *= 2;
+        bw *= 2;
     }
 
   return bw;
@@ -90,7 +90,7 @@
       Container* container = parent->innerContainer ();
 
       if (container)
-	return new Panel (go, new QFrame (container));
+        return new Panel (go, new QFrame (container));
     }
 
   return 0;
@@ -105,7 +105,7 @@
   frame->setAutoFillBackground (true);
   Matrix bb = pp.get_boundingbox (false);
   frame->setGeometry (xround (bb(0)), xround (bb(1)),
-		      xround (bb(2)), xround (bb(3)));
+                      xround (bb(2)), xround (bb(3)));
   frame->setFrameStyle (frameStyleFromProperties (pp));
   frame->setLineWidth (xround (pp.get_borderwidth ()));
   QPalette pal = frame->palette ();
@@ -144,71 +144,71 @@
 {
 }
 
-bool Panel::eventFilter (QObject* watched, QEvent* event)
+bool Panel::eventFilter (QObject* watched, QEvent* xevent)
 {
   if (! m_blockUpdates)
     {
       if (watched == qObject ())
-	{
-	  switch (event->type ())
-	    {
-	    case QEvent::Resize:
-		{
-		  gh_manager::auto_lock lock;
-		  graphics_object go = object ();
+        {
+          switch (xevent->type ())
+            {
+            case QEvent::Resize:
+                {
+                  gh_manager::auto_lock lock;
+                  graphics_object go = object ();
 
-		  if (go.valid_object ())
-		    {
-		      if (m_title)
-			{
-			  const uipanel::properties& pp =
-			    Utils::properties<uipanel> (go);
+                  if (go.valid_object ())
+                    {
+                      if (m_title)
+                        {
+                          const uipanel::properties& pp =
+                            Utils::properties<uipanel> (go);
 
-			  if (pp.fontunits_is ("normalized"))
-			    {
-			      QFrame* frame = qWidget<QFrame> ();
+                          if (pp.fontunits_is ("normalized"))
+                            {
+                              QFrame* frame = qWidget<QFrame> ();
 
-			      m_title->setFont (Utils::computeFont<uipanel>
-						(pp, frame->height ()));
-			      m_title->resize (m_title->sizeHint ());
-			    }
-			}
-		      updateLayout ();
-		    }
-		}
-	      break;
-	    case QEvent::MouseButtonPress:
-		{
-		  QMouseEvent* m = dynamic_cast<QMouseEvent*> (event);
+                              m_title->setFont (Utils::computeFont<uipanel>
+                                                (pp, frame->height ()));
+                              m_title->resize (m_title->sizeHint ());
+                            }
+                        }
+                      updateLayout ();
+                    }
+                }
+              break;
+            case QEvent::MouseButtonPress:
+                {
+                  QMouseEvent* m = dynamic_cast<QMouseEvent*> (xevent);
 
-		  if (m->button () == Qt::RightButton)
-		    {
-		      gh_manager::auto_lock lock;
+                  if (m->button () == Qt::RightButton)
+                    {
+                      gh_manager::auto_lock lock;
 
-		      ContextMenu::executeAt (properties (), m->globalPos ());
-		    }
-		}
-	      break;
-	    default:
-	      break;
-	    }
-	}
+                      ContextMenu::executeAt (properties (), m->globalPos ());
+                    }
+                }
+              break;
+            default:
+              break;
+            }
+        }
       else if (watched == m_container)
-	{
-	  switch (event->type ())
-	    {
-	    case QEvent::Resize:
-	      if (qWidget<QWidget> ()->isVisible ())
-		{
-		  gh_manager::auto_lock lock;
+        {
+          switch (xevent->type ())
+            {
+            case QEvent::Resize:
+              if (qWidget<QWidget> ()->isVisible ())
+                {
+                  gh_manager::auto_lock lock;
 
-		  properties ().update_boundingbox ();
-		}
-	      break;
-	    default:
-	      break;
-	    }
-	}
+                  properties ().update_boundingbox ();
+                }
+              break;
+            default:
+              break;
+            }
+        }
     }
 
   return false;
@@ -224,13 +224,13 @@
   switch (pId)
     {
     case uipanel::properties::ID_POSITION:
-	{
-	  Matrix bb = pp.get_boundingbox (false);
+        {
+          Matrix bb = pp.get_boundingbox (false);
 
-	  frame->setGeometry (xround (bb(0)), xround (bb(1)),
-			      xround (bb(2)), xround (bb(3)));
-	  updateLayout ();
-	}
+          frame->setGeometry (xround (bb(0)), xround (bb(1)),
+                              xround (bb(2)), xround (bb(3)));
+          updateLayout ();
+        }
       break;
     case uipanel::properties::ID_BORDERWIDTH:
       frame->setLineWidth (xround (pp.get_borderwidth ()));
@@ -240,46 +240,46 @@
     case uipanel::properties::ID_FOREGROUNDCOLOR:
     case uipanel::properties::ID_HIGHLIGHTCOLOR:
     case uipanel::properties::ID_SHADOWCOLOR:
-	{
-	  QPalette pal = frame->palette ();
+        {
+          QPalette pal = frame->palette ();
 
-	  setupPalette (pp, pal);
-	  frame->setPalette (pal);
-	  if (m_title)
-	    m_title->setPalette (pal);
-	}
+          setupPalette (pp, pal);
+          frame->setPalette (pal);
+          if (m_title)
+            m_title->setPalette (pal);
+        }
       break;
     case uipanel::properties::ID_TITLE:
-	{
-	  QString title = Utils::fromStdString (pp.get_title ());
+        {
+          QString title = Utils::fromStdString (pp.get_title ());
 
-	  if (title.isEmpty ())
-	    {
-	      if (m_title)
-		delete m_title;
-	      m_title = 0;
-	    }
-	  else
-	    {
-	      if (! m_title)
-		{
-		  QPalette pal = frame->palette ();
+          if (title.isEmpty ())
+            {
+              if (m_title)
+                delete m_title;
+              m_title = 0;
+            }
+          else
+            {
+              if (! m_title)
+                {
+                  QPalette pal = frame->palette ();
 
-		  m_title = new QLabel (title, frame);
-		  m_title->setAutoFillBackground (true);
-		  m_title->setContentsMargins (4, 0, 4, 0);
-		  m_title->setPalette (pal);
-		  m_title->setFont (Utils::computeFont<uipanel> (pp));
-		  m_title->show ();
-		}
-	      else
-		{
-		  m_title->setText (title);
-		  m_title->resize (m_title->sizeHint ());
-		}
-	    }
-	  updateLayout ();
-	}
+                  m_title = new QLabel (title, frame);
+                  m_title->setAutoFillBackground (true);
+                  m_title->setContentsMargins (4, 0, 4, 0);
+                  m_title->setPalette (pal);
+                  m_title->setFont (Utils::computeFont<uipanel> (pp));
+                  m_title->show ();
+                }
+              else
+                {
+                  m_title->setText (title);
+                  m_title->resize (m_title->sizeHint ());
+                }
+            }
+          updateLayout ();
+        }
     case uipanel::properties::ID_TITLEPOSITION:
       updateLayout ();
       break;
@@ -292,11 +292,11 @@
     case uipanel::properties::ID_FONTWEIGHT:
     case uipanel::properties::ID_FONTANGLE:
       if (m_title)
-	{
-	  m_title->setFont (Utils::computeFont<uipanel> (pp));
-	  m_title->resize (m_title->sizeHint ());
-	  updateLayout ();
-	}
+        {
+          m_title->setFont (Utils::computeFont<uipanel> (pp));
+          m_title->resize (m_title->sizeHint ());
+          updateLayout ();
+        }
       break;
     case uipanel::properties::ID_VISIBLE:
       frame->setVisible (pp.is_visible ());
@@ -326,9 +326,9 @@
   int bw = borderWidthFromProperties (pp);
 
   frame->setFrameRect (QRect (xround (bb(0)) - bw, xround (bb(1)) - bw,
-			      xround (bb(2)) + 2*bw, xround (bb(3)) + 2*bw));
+                              xround (bb(2)) + 2*bw, xround (bb(3)) + 2*bw));
   m_container->setGeometry (xround (bb(0)), xround (bb(1)),
-			    xround (bb(2)), xround (bb(3)));
+                            xround (bb(2)), xround (bb(3)));
 
   if (m_blockUpdates)
     pp.update_boundingbox ();
@@ -339,19 +339,19 @@
       int offset = 5;
 
       if (pp.titleposition_is ("lefttop"))
-	m_title->move (bw+offset, 0);
+        m_title->move (bw+offset, 0);
       else if (pp.titleposition_is ("righttop"))
-	m_title->move (frame->width () - bw - offset - sz.width (), 0);
+        m_title->move (frame->width () - bw - offset - sz.width (), 0);
       else if (pp.titleposition_is ("leftbottom"))
-	m_title->move (bw+offset, frame->height () - sz.height ());
+        m_title->move (bw+offset, frame->height () - sz.height ());
       else if (pp.titleposition_is ("rightbottom"))
-	m_title->move (frame->width () - bw - offset - sz.width (),
-		       frame->height () - sz.height ());
+        m_title->move (frame->width () - bw - offset - sz.width (),
+                       frame->height () - sz.height ());
       else if (pp.titleposition_is ("centertop"))
-	m_title->move (frame->width () / 2 - sz.width () / 2, 0);
+        m_title->move (frame->width () / 2 - sz.width () / 2, 0);
       else if (pp.titleposition_is ("centerbottom"))
-	m_title->move (frame->width () / 2 - sz.width () / 2,
-		       frame->height () - sz.height ());
+        m_title->move (frame->width () / 2 - sz.width () / 2,
+                       frame->height () - sz.height ());
     }
 }
 
--- a/libgui/graphics/PopupMenuControl.cc	Fri Aug 01 09:06:21 2014 -0400
+++ b/libgui/graphics/PopupMenuControl.cc	Fri Aug 01 12:10:05 2014 -0400
@@ -42,7 +42,7 @@
       Container* container = parent->innerContainer ();
 
       if (container)
-	return new PopupMenuControl (go, new QComboBox (container));
+        return new PopupMenuControl (go, new QComboBox (container));
     }
 
   return 0;
@@ -56,7 +56,7 @@
   box->addItems (Utils::fromStdString (up.get_string_string ()).split ('|'));
 
   connect (box, SIGNAL (currentIndexChanged (int)),
-	   SLOT (currentIndexChanged (int)));
+           SLOT (currentIndexChanged (int)));
 }
 
 PopupMenuControl::~PopupMenuControl (void)
@@ -72,43 +72,43 @@
     {
     case uicontrol::properties::ID_STRING:
       m_blockUpdate = true;
-	{
-	  int oldCurrent = box->currentIndex ();
+        {
+          int oldCurrent = box->currentIndex ();
 
-	  box->clear ();
-	  box->addItems (Utils::fromStdString
-			 (up.get_string_string ()).split ('|'));
-	  if (box->count() > 0
-	      && oldCurrent >= 0
-	      && oldCurrent < box->count ())
-	    {
-	      box->setCurrentIndex (oldCurrent);
-	    }
-	  else
-	    {
-	      gh_manager::post_set (m_handle, "value",
-				    octave_value (box->count () > 0
-						  ? 1.0 : 0.0),
-				    false);
-	    }
-	}
+          box->clear ();
+          box->addItems (Utils::fromStdString
+                         (up.get_string_string ()).split ('|'));
+          if (box->count() > 0
+              && oldCurrent >= 0
+              && oldCurrent < box->count ())
+            {
+              box->setCurrentIndex (oldCurrent);
+            }
+          else
+            {
+              gh_manager::post_set (m_handle, "value",
+                                    octave_value (box->count () > 0
+                                                  ? 1.0 : 0.0),
+                                    false);
+            }
+        }
       m_blockUpdate = false;
       break;
     case uicontrol::properties::ID_VALUE:
-	{
-	  Matrix value = up.get_value ().matrix_value ();
+        {
+          Matrix value = up.get_value ().matrix_value ();
 
-	  if (value.numel () > 0)
-	    {
-	      int newIndex = int (value(0)) - 1;
+          if (value.numel () > 0)
+            {
+              int newIndex = int (value(0)) - 1;
 
-	      if (newIndex >= 0 && newIndex < box->count ()
-		  && newIndex != box->currentIndex ())
-		{
-		  box->setCurrentIndex (newIndex);
-		}
-	    }
-	}
+              if (newIndex >= 0 && newIndex < box->count ()
+                  && newIndex != box->currentIndex ())
+                {
+                  box->setCurrentIndex (newIndex);
+                }
+            }
+        }
       break;
     default:
       BaseControl::update (pId);
@@ -121,8 +121,8 @@
   if (! m_blockUpdate)
     {
       gh_manager::post_set (m_handle, "value",
-			    octave_value (double (index + 1)),
-			    false);
+                            octave_value (double (index + 1)),
+                            false);
       gh_manager::post_callback (m_handle, "callback");
     }
 }
--- a/libgui/graphics/PushButtonControl.cc	Fri Aug 01 09:06:21 2014 -0400
+++ b/libgui/graphics/PushButtonControl.cc	Fri Aug 01 12:10:05 2014 -0400
@@ -43,7 +43,7 @@
       Container* container = parent->innerContainer ();
 
       if (container)
-	return new PushButtonControl (go, new QPushButton (container));
+        return new PushButtonControl (go, new QPushButton (container));
     }
 
   return 0;
--- a/libgui/graphics/PushTool.cc	Fri Aug 01 09:06:21 2014 -0400
+++ b/libgui/graphics/PushTool.cc	Fri Aug 01 12:10:05 2014 -0400
@@ -40,7 +40,7 @@
       QWidget* parentWidget = parent->qWidget<QWidget> ();
 
       if (parentWidget)
-	return new PushTool (go, new QAction (parentWidget));
+        return new PushTool (go, new QAction (parentWidget));
     }
 
   return 0;
--- a/libgui/graphics/QtHandlesUtils.cc	Fri Aug 01 09:06:21 2014 -0400
+++ b/libgui/graphics/QtHandlesUtils.cc	Fri Aug 01 12:10:05 2014 -0400
@@ -108,9 +108,9 @@
 }
 
 template QFont computeFont<uicontrol> (const uicontrol::properties& props,
-				       int height);
+                                       int height);
 template QFont computeFont<uipanel> (const uipanel::properties& props,
-				     int height);
+                                     int height);
 
 QColor fromRgb (const Matrix& rgb)
 {
@@ -142,26 +142,26 @@
       Qt::KeyboardModifiers mods = event->modifiers ();
 
       if (mods == Qt::NoModifier)
-	{
-	  if (buttons == Qt::LeftButton)
-	    return std::string ("normal");
-	  else if (buttons == Qt::RightButton)
-	    return std::string ("alt");
+        {
+          if (buttons == Qt::LeftButton)
+            return std::string ("normal");
+          else if (buttons == Qt::RightButton)
+            return std::string ("alt");
 #if defined (Q_WS_WIN)
-	  else if (buttons == (Qt::LeftButton|Qt::RightButton))
-	    return std::string ("extend");
+          else if (buttons == (Qt::LeftButton|Qt::RightButton))
+            return std::string ("extend");
 #elif defined (Q_WS_X11)
-	  else if (buttons == Qt::MidButton)
-	    return std::string ("extend");
+          else if (buttons == Qt::MidButton)
+            return std::string ("extend");
 #endif
-	}
+        }
       else if (buttons == Qt::LeftButton)
-	{
-	  if (mods == Qt::ShiftModifier)
-	    return std::string ("extend");
-	  else if (mods == Qt::ControlModifier)
-	    return std::string ("alt");
-	}
+        {
+          if (mods == Qt::ShiftModifier)
+            return std::string ("extend");
+          else if (mods == Qt::ControlModifier)
+            return std::string ("alt");
+        }
     }
 
   return std::string ("normal");
@@ -176,20 +176,20 @@
       Container* c = tkFig->innerContainer ();
 
       if (c)
-	{
-	  QPoint qp = c->mapFromGlobal (event->globalPos ());
+        {
+          QPoint qp = c->mapFromGlobal (event->globalPos ());
 
-	  return
-	    tkFig->properties<figure> ().map_from_boundingbox (qp.x (),
-							       qp.y ());
-	}
+          return
+            tkFig->properties<figure> ().map_from_boundingbox (qp.x (),
+                                                               qp.y ());
+        }
     }
 
   return Matrix (1, 2, 0.0);
 }
 
 Qt::Alignment fromHVAlign (const caseless_str& halign,
-			   const caseless_str& valign)
+                           const caseless_str& valign)
 {
   Qt::Alignment flags;
 
@@ -230,58 +230,58 @@
       img.fill (qRgba (0, 0, 0, 0));
 
       if (v.is_uint8_type ())
-	{
-	  uint8NDArray d = v.uint8_array_value ();
+        {
+          uint8NDArray d = v.uint8_array_value ();
 
-	  for (int i = 0; i < w; i++)
-	    for (int j = 0; j < h; j++)
-	      {
-		int r = d(j, i, 0);
-		int g = d(j, i, 1);
-		int b = d(j, i, 2);
-		int a = 255;
+          for (int i = 0; i < w; i++)
+            for (int j = 0; j < h; j++)
+              {
+                int r = d(j, i, 0);
+                int g = d(j, i, 1);
+                int b = d(j, i, 2);
+                int a = 255;
 
-		img.setPixel (x_off + i, y_off + j, qRgba (r, g, b, a));
-	      }
-	}
+                img.setPixel (x_off + i, y_off + j, qRgba (r, g, b, a));
+              }
+        }
       else if (v.is_single_type ())
-	{
-	  FloatNDArray f = v.float_array_value ();
+        {
+          FloatNDArray f = v.float_array_value ();
 
-	  for (int i = 0; i < w; i++)
-	    for (int j = 0; j < h; j++)
-	      {
-		float r = f(j, i, 0);
-		float g = f(j, i, 1);
-		float b = f(j, i, 2);
-		int a = (xisnan (r) || xisnan (g) || xisnan (b) ? 0 : 255);
+          for (int i = 0; i < w; i++)
+            for (int j = 0; j < h; j++)
+              {
+                float r = f(j, i, 0);
+                float g = f(j, i, 1);
+                float b = f(j, i, 2);
+                int a = (xisnan (r) || xisnan (g) || xisnan (b) ? 0 : 255);
 
-		img.setPixel (x_off + i, y_off + j,
-			      qRgba (xround (r * 255),
-				     xround (g * 255),
-				     xround (b * 255),
-				     a));
-	      }
-	}
+                img.setPixel (x_off + i, y_off + j,
+                              qRgba (xround (r * 255),
+                                     xround (g * 255),
+                                     xround (b * 255),
+                                     a));
+              }
+        }
       else if (v.is_real_type ())
-	{
-	  NDArray d = v.array_value ();
+        {
+          NDArray d = v.array_value ();
 
-	  for (int i = 0; i < w; i++)
-	    for (int j = 0; j < h; j++)
-	      {
-		double r = d(j, i, 0);
-		double g = d(j, i, 1);
-		double b = d(j, i, 2);
-		int a = (xisnan (r) || xisnan (g) || xisnan (b) ? 0 : 255);
+          for (int i = 0; i < w; i++)
+            for (int j = 0; j < h; j++)
+              {
+                double r = d(j, i, 0);
+                double g = d(j, i, 1);
+                double b = d(j, i, 2);
+                int a = (xisnan (r) || xisnan (g) || xisnan (b) ? 0 : 255);
 
-		img.setPixel (x_off + i, y_off + j,
-			      qRgba (xround (r * 255),
-				     xround (g * 255),
-				     xround (b * 255),
-				     a));
-	      }
-	}
+                img.setPixel (x_off + i, y_off + j,
+                              qRgba (xround (r * 255),
+                                     xround (g * 255),
+                                     xround (b * 255),
+                                     a));
+              }
+        }
 
       return img;
     }
--- a/libgui/graphics/QtHandlesUtils.h	Fri Aug 01 09:06:21 2014 -0400
+++ b/libgui/graphics/QtHandlesUtils.h	Fri Aug 01 12:10:05 2014 -0400
@@ -54,10 +54,10 @@
   Matrix toRgb (const QColor& c);
 
   Qt::Alignment fromHVAlign (const caseless_str& halign,
-			     const caseless_str& valign);
+                             const caseless_str& valign);
 
   std::string figureSelectionType (QMouseEvent* event,
-				   bool isDoubleClick = false);
+                                   bool isDoubleClick = false);
 
   Matrix figureCurrentPoint (const graphics_object& fig, QMouseEvent* event);
 
@@ -72,7 +72,7 @@
     { return Utils::properties<T> (gh_manager::get_object (h)); }
 
   QImage makeImageFromCData (const octave_value& v, int width = -1,
-			     int height = -1);
+                             int height = -1);
 
   octave_scalar_map makeKeyEventStruct (QKeyEvent* event);
 };
--- a/libgui/graphics/RadioButtonControl.cc	Fri Aug 01 09:06:21 2014 -0400
+++ b/libgui/graphics/RadioButtonControl.cc	Fri Aug 01 12:10:05 2014 -0400
@@ -42,14 +42,14 @@
       Container* container = parent->innerContainer ();
 
       if (container)
-	return new RadioButtonControl (go, new QRadioButton (container));
+        return new RadioButtonControl (go, new QRadioButton (container));
     }
 
   return 0;
 }
 
 RadioButtonControl::RadioButtonControl (const graphics_object& go,
-					QRadioButton* radio)
+                                        QRadioButton* radio)
     : ButtonControl (go, radio)
 {
   radio->setAutoFillBackground (true);
--- a/libgui/graphics/SliderControl.cc	Fri Aug 01 09:06:21 2014 -0400
+++ b/libgui/graphics/SliderControl.cc	Fri Aug 01 12:10:05 2014 -0400
@@ -44,14 +44,14 @@
       Container* container = parent->innerContainer ();
 
       if (container)
-	return new SliderControl (go, new QScrollBar (container));
+        return new SliderControl (go, new QScrollBar (container));
     }
 
   return 0;
 }
 
 SliderControl::SliderControl (const graphics_object& go,
-			      QAbstractSlider* slider)
+                              QAbstractSlider* slider)
     : BaseControl (go, slider), m_blockUpdates (false)
 {
   uicontrol::properties& up = properties<uicontrol> ();
@@ -70,7 +70,7 @@
       double dmin = up.get_min (), dmax = up.get_max ();
 
       slider->setValue (xround (((value(0) - dmin) / (dmax - dmin))
-				* RANGE_INT_MAX));
+                                * RANGE_INT_MAX));
     }
 
   connect (slider, SIGNAL (valueChanged (int)), SLOT (valueChanged (int)));
@@ -88,28 +88,28 @@
   switch (pId)
     {
     case uicontrol::properties::ID_SLIDERSTEP:
-	{
-	  Matrix steps = up.get_sliderstep ().matrix_value ();
+        {
+          Matrix steps = up.get_sliderstep ().matrix_value ();
 
-	  slider->setSingleStep (xround (steps(0) * RANGE_INT_MAX));
-	  slider->setPageStep (xround (steps(1) * RANGE_INT_MAX));
-	}
+          slider->setSingleStep (xround (steps(0) * RANGE_INT_MAX));
+          slider->setPageStep (xround (steps(1) * RANGE_INT_MAX));
+        }
       break;
     case uicontrol::properties::ID_VALUE:
-	{
-	  Matrix value = up.get_value ().matrix_value ();
-	  double dmax = up.get_max (), dmin = up.get_min ();
+        {
+          Matrix value = up.get_value ().matrix_value ();
+          double dmax = up.get_max (), dmin = up.get_min ();
 
-	  if (value.numel () > 0)
-	    {
-	      int ival = xround (((value(0) - dmin) / (dmax - dmin))
-				 * RANGE_INT_MAX);
+          if (value.numel () > 0)
+            {
+              int ival = xround (((value(0) - dmin) / (dmax - dmin))
+                                 * RANGE_INT_MAX);
 
-	      m_blockUpdates = true;
-	      slider->setValue (ival);
-	      m_blockUpdates = false;
-	    }
-	}
+              m_blockUpdates = true;
+              slider->setValue (ival);
+              m_blockUpdates = false;
+            }
+        }
       break;
     default:
       BaseControl::update (pId);
@@ -125,25 +125,25 @@
       graphics_object go = object ();
 
       if (go.valid_object ())
-	{
-	  uicontrol::properties& up = Utils::properties<uicontrol> (go);
+        {
+          uicontrol::properties& up = Utils::properties<uicontrol> (go);
 
-	  Matrix value = up.get_value ().matrix_value ();
-	  double dmin = up.get_min (), dmax = up.get_max ();
+          Matrix value = up.get_value ().matrix_value ();
+          double dmin = up.get_min (), dmax = up.get_max ();
 
-	  int ival_tmp = (value.numel () > 0 ?
-			  xround (((value(0) - dmin) / (dmax - dmin))
-				  * RANGE_INT_MAX) :
-			  0);
+          int ival_tmp = (value.numel () > 0 ?
+                          xround (((value(0) - dmin) / (dmax - dmin))
+                                  * RANGE_INT_MAX) :
+                          0);
 
-	  if (ival != ival_tmp || value.numel () > 0)
-	    {
-	      double dval = dmin + (ival * (dmax - dmin) / RANGE_INT_MAX);
+          if (ival != ival_tmp || value.numel () > 0)
+            {
+              double dval = dmin + (ival * (dmax - dmin) / RANGE_INT_MAX);
 
-	      gh_manager::post_set (m_handle, "value", octave_value (dval));
-	      gh_manager::post_callback (m_handle, "callback");
-	    }
-	}
+              gh_manager::post_set (m_handle, "value", octave_value (dval));
+              gh_manager::post_callback (m_handle, "callback");
+            }
+        }
     }
 }
 
--- a/libgui/graphics/TextControl.cc	Fri Aug 01 09:06:21 2014 -0400
+++ b/libgui/graphics/TextControl.cc	Fri Aug 01 12:10:05 2014 -0400
@@ -42,7 +42,7 @@
       Container* container = parent->innerContainer ();
 
       if (container)
-	return new TextControl (go, new QLabel (container));
+        return new TextControl (go, new QLabel (container));
     }
 
   return 0;
@@ -57,7 +57,7 @@
   label->setTextFormat (Qt::PlainText);
   label->setWordWrap (false);
   label->setAlignment (Utils::fromHVAlign (up.get_horizontalalignment (),
-					   up.get_verticalalignment ()));
+                                           up.get_verticalalignment ()));
   // FIXME: support string_vector
   label->setText (Utils::fromStdString (up.get_string_string ()));
 }
@@ -80,7 +80,7 @@
     case uicontrol::properties::ID_HORIZONTALALIGNMENT:
     case uicontrol::properties::ID_VERTICALALIGNMENT:
       label->setAlignment (Utils::fromHVAlign (up.get_horizontalalignment (),
-					       up.get_verticalalignment ()));
+                                               up.get_verticalalignment ()));
       break;
     default:
       BaseControl::update (pId);
--- a/libgui/graphics/TextEdit.cc	Fri Aug 01 09:06:21 2014 -0400
+++ b/libgui/graphics/TextEdit.cc	Fri Aug 01 12:10:05 2014 -0400
@@ -31,20 +31,20 @@
 namespace QtHandles
 {
 
-void TextEdit::focusOutEvent (QFocusEvent* event)
+void TextEdit::focusOutEvent (QFocusEvent* xevent)
 {
-  QTextEdit::focusOutEvent (event);
+  QTextEdit::focusOutEvent (xevent);
 
   emit editingFinished ();
 }
 
-void TextEdit::keyPressEvent (QKeyEvent* event)
+void TextEdit::keyPressEvent (QKeyEvent* xevent)
 {
-  QTextEdit::keyPressEvent (event);
+  QTextEdit::keyPressEvent (xevent);
 
-  if ((event->key () == Qt::Key_Return
-       || event->key () == Qt::Key_Enter)
-      && event->modifiers () == Qt::ControlModifier)
+  if ((xevent->key () == Qt::Key_Return
+       || xevent->key () == Qt::Key_Enter)
+      && xevent->modifiers () == Qt::ControlModifier)
     emit editingFinished ();
 }
 
--- a/libgui/graphics/TextEdit.h	Fri Aug 01 09:06:21 2014 -0400
+++ b/libgui/graphics/TextEdit.h	Fri Aug 01 12:10:05 2014 -0400
@@ -33,7 +33,7 @@
   Q_OBJECT
 
 public:
-  TextEdit (QWidget* parent) : QTextEdit(parent) { }
+  TextEdit (QWidget* xparent) : QTextEdit (xparent) { }
   ~TextEdit (void) { }
 
 signals:
--- a/libgui/graphics/ToggleButtonControl.cc	Fri Aug 01 09:06:21 2014 -0400
+++ b/libgui/graphics/ToggleButtonControl.cc	Fri Aug 01 12:10:05 2014 -0400
@@ -42,14 +42,14 @@
       Container* container = parent->innerContainer ();
 
       if (container)
-	return new ToggleButtonControl (go, new QPushButton (container));
+        return new ToggleButtonControl (go, new QPushButton (container));
     }
 
   return 0;
 }
 
 ToggleButtonControl::ToggleButtonControl (const graphics_object& go,
-					  QPushButton* btn)
+                                          QPushButton* btn)
     : ButtonControl (go, btn)
 {
   btn->setCheckable (true);
--- a/libgui/graphics/ToggleTool.cc	Fri Aug 01 09:06:21 2014 -0400
+++ b/libgui/graphics/ToggleTool.cc	Fri Aug 01 12:10:05 2014 -0400
@@ -40,7 +40,7 @@
       QWidget* parentWidget = parent->qWidget<QWidget> ();
 
       if (parentWidget)
-	return new ToggleTool (go, new QAction (parentWidget));
+        return new ToggleTool (go, new QAction (parentWidget));
     }
 
   return 0;
@@ -55,7 +55,7 @@
   action->setChecked (tp.is_state ());
 
   connect (action, SIGNAL (toggled (bool)),
-	   this, SLOT (triggered (bool)));
+           this, SLOT (triggered (bool)));
 }
 
 ToggleTool::~ToggleTool (void)
@@ -82,9 +82,9 @@
 {
   gh_manager::post_set (m_handle, "state", checked, false);
   gh_manager::post_callback (m_handle,
-			     checked
-			     ? "oncallback"
-			     : "offcallback");
+                             checked
+                             ? "oncallback"
+                             : "offcallback");
   gh_manager::post_callback (m_handle, "clickedcallback");
 }
 
--- a/libgui/graphics/ToolBar.cc	Fri Aug 01 09:06:21 2014 -0400
+++ b/libgui/graphics/ToolBar.cc	Fri Aug 01 12:10:05 2014 -0400
@@ -71,7 +71,7 @@
       QWidget* parentWidget = parent->qWidget<QWidget> ();
 
       if (parentWidget)
-	return new ToolBar (go, new QToolBar (parentWidget));
+        return new ToolBar (go, new QToolBar (parentWidget));
     }
 
   return 0;
@@ -110,7 +110,7 @@
     {
     case base_properties::ID_VISIBLE:
       if (m_figure)
-	m_figure->showCustomToolBar (bar, tp.is_visible ());
+        m_figure->showCustomToolBar (bar, tp.is_visible ());
       break;
     default:
       Object::update (pId);
@@ -118,36 +118,36 @@
     }
 }
 
-bool ToolBar::eventFilter (QObject* watched, QEvent* event)
+bool ToolBar::eventFilter (QObject* watched, QEvent* xevent)
 {
   if (watched == qObject ())
     {
-      switch (event->type ())
-	{
-	case QEvent::ActionAdded:
-	case QEvent::ActionRemoved:
-	    {
-	      QActionEvent* ae = dynamic_cast<QActionEvent*> (event);
-	      QToolBar* bar = qWidget<QToolBar> ();
+      switch (xevent->type ())
+        {
+        case QEvent::ActionAdded:
+        case QEvent::ActionRemoved:
+            {
+              QActionEvent* ae = dynamic_cast<QActionEvent*> (xevent);
+              QToolBar* bar = qWidget<QToolBar> ();
 
-	      if (ae->action () != m_empty)
-		{
-		  if (event->type () == QEvent::ActionAdded)
-		    {
-		      if (bar->actions ().size () == 2)
-			QTimer::singleShot (0, this, SLOT (hideEmpty (void)));
-		    }
-		  else
-		    {
-		      if (bar->actions ().size () == 1)
-			m_empty->setVisible (true);
-		    }
-		}
-	    }
-	  break;
-	default:
-	  break;
-	}
+              if (ae->action () != m_empty)
+                {
+                  if (xevent->type () == QEvent::ActionAdded)
+                    {
+                      if (bar->actions ().size () == 2)
+                        QTimer::singleShot (0, this, SLOT (hideEmpty (void)));
+                    }
+                  else
+                    {
+                      if (bar->actions ().size () == 1)
+                        m_empty->setVisible (true);
+                    }
+                }
+            }
+          break;
+        default:
+          break;
+        }
     }
 
   return false;
@@ -165,7 +165,7 @@
       QToolBar* bar = qWidget<QToolBar> ();
 
       if (bar)
-	m_figure->showCustomToolBar (bar, false);
+        m_figure->showCustomToolBar (bar, false);
     }
 }
 
--- a/libgui/graphics/ToolBarButton.cc	Fri Aug 01 09:06:21 2014 -0400
+++ b/libgui/graphics/ToolBarButton.cc	Fri Aug 01 12:10:05 2014 -0400
@@ -74,38 +74,38 @@
     case base_properties::ID_VISIBLE:
       action->setVisible (tp.is_visible ());
       if (m_separator)
-	m_separator->setVisible (tp.is_visible ());
+        m_separator->setVisible (tp.is_visible ());
       break;
     case T::properties::ID_TOOLTIPSTRING:
       action->setToolTip (Utils::fromStdString (tp.get_tooltipstring ()));
       break;
     case T::properties::ID_CDATA:
-	{
-	  QImage img = Utils::makeImageFromCData (tp.get_cdata (), 16, 16);
+        {
+          QImage img = Utils::makeImageFromCData (tp.get_cdata (), 16, 16);
 
-	  action->setIcon (QIcon (QPixmap::fromImage (img)));
-	}
+          action->setIcon (QIcon (QPixmap::fromImage (img)));
+        }
       break;
     case T::properties::ID_SEPARATOR:
       if (tp.is_separator ())
-	{
-	  if (! m_separator)
-	    {
-	      m_separator = new QAction (action);
-	      m_separator->setSeparator (true);
-	      m_separator->setVisible (tp.is_visible ());
+        {
+          if (! m_separator)
+            {
+              m_separator = new QAction (action);
+              m_separator->setSeparator (true);
+              m_separator->setVisible (tp.is_visible ());
 
-	      QWidget* w = qobject_cast<QWidget*> (action->parent ());
+              QWidget* w = qobject_cast<QWidget*> (action->parent ());
 
-	      w->insertAction (action, m_separator);
-	    }
-	}
+              w->insertAction (action, m_separator);
+            }
+        }
       else
-	{
-	  if (m_separator)
-	    delete m_separator;
-	  m_separator = 0;
-	}
+        {
+          if (m_separator)
+            delete m_separator;
+          m_separator = 0;
+        }
       break;
     case T::properties::ID_ENABLE:
       action->setEnabled (tp.is_enable ());
--- a/libgui/graphics/__init_qt__.cc	Fri Aug 01 09:06:21 2014 -0400
+++ b/libgui/graphics/__init_qt__.cc	Fri Aug 01 12:10:05 2014 -0400
@@ -48,45 +48,45 @@
   if (! qtHandlesInitialized)
     {
       if (qApp)
-	{
-	  qRegisterMetaType<graphics_object> ("graphics_object");
+        {
+          qRegisterMetaType<graphics_object> ("graphics_object");
 
-	  gh_manager::enable_event_processing (true);
+          gh_manager::enable_event_processing (true);
 
-	  graphics_toolkit tk (new Backend ());
+          graphics_toolkit tk (new Backend ());
           gtk_manager::load_toolkit (tk);
 
-	  octave_add_atexit_function ("__shutdown_qt__");
+          octave_add_atexit_function ("__shutdown_qt__");
 
-	  // Change some default settings to use Qt default colors
-	  QPalette p;
-	  graphics_object root = gh_manager::get_object (0);
+          // Change some default settings to use Qt default colors
+          QPalette p;
+          graphics_object root = gh_manager::get_object (0);
 
-	  /*
-	  root.set ("defaultfigurecolor",
-		    octave_value (Utils::toRgb (p.color (QPalette::Window))));
-	  */
-	  root.set ("defaultuicontrolbackgroundcolor",
-		    octave_value (Utils::toRgb (p.color (QPalette::Window))));
-	  root.set ("defaultuicontrolforegroundcolor",
-		    octave_value (Utils::toRgb
-				  (p.color (QPalette::WindowText))));
-	  root.set ("defaultuipanelbackgroundcolor",
-		    octave_value (Utils::toRgb (p.color (QPalette::Window))));
-	  root.set ("defaultuipanelforegroundcolor",
-		    octave_value (Utils::toRgb
-				  (p.color (QPalette::WindowText))));
-	  root.set ("defaultuipanelhighlightcolor",
-		    octave_value (Utils::toRgb (p.color (QPalette::Light))));
-	  root.set ("defaultuipanelshadowcolor",
-		    octave_value (Utils::toRgb (p.color (QPalette::Dark))));
+          /*
+          root.set ("defaultfigurecolor",
+                    octave_value (Utils::toRgb (p.color (QPalette::Window))));
+          */
+          root.set ("defaultuicontrolbackgroundcolor",
+                    octave_value (Utils::toRgb (p.color (QPalette::Window))));
+          root.set ("defaultuicontrolforegroundcolor",
+                    octave_value (Utils::toRgb
+                                  (p.color (QPalette::WindowText))));
+          root.set ("defaultuipanelbackgroundcolor",
+                    octave_value (Utils::toRgb (p.color (QPalette::Window))));
+          root.set ("defaultuipanelforegroundcolor",
+                    octave_value (Utils::toRgb
+                                  (p.color (QPalette::WindowText))));
+          root.set ("defaultuipanelhighlightcolor",
+                    octave_value (Utils::toRgb (p.color (QPalette::Light))));
+          root.set ("defaultuipanelshadowcolor",
+                    octave_value (Utils::toRgb (p.color (QPalette::Dark))));
 
-	  qtHandlesInitialized = true;
+          qtHandlesInitialized = true;
 
-	  return true;
-	}
+          return true;
+        }
       else
-	error ("__init_qt__: QApplication object must exist.");
+        error ("__init_qt__: QApplication object must exist.");
     }
 
   return false;
@@ -213,45 +213,45 @@
       QString filter;
       QStringList files =
         QFileDialog::getOpenFileNames (0, caption, defaultFileName,
-				       filterSpecs.join (";;"), &filter, 0);
+                                       filterSpecs.join (";;"), &filter, 0);
 
       if (! files.isEmpty ())
-	{
-	  Cell cFiles (1, files.length ());
-	  QString dirName;
-	  int i = 0;
+        {
+          Cell cFiles (1, files.length ());
+          QString dirName;
+          int i = 0;
 
-	  foreach (const QString& s, files)
-	    {
-	      QFileInfo fi (s);
+          foreach (const QString& s, files)
+            {
+              QFileInfo fi (s);
 
-	      if (dirName.isEmpty ())
-		dirName = appendDirSep (fi.canonicalPath ());
-	      cFiles(i++) = toStdString (fi.fileName ());
-	    }
+              if (dirName.isEmpty ())
+                dirName = appendDirSep (fi.canonicalPath ());
+              cFiles(i++) = toStdString (fi.fileName ());
+            }
 
-	  retval(0) = cFiles;
-	  retval(1) = toStdString (dirName);
-	  if (! filter.isEmpty ())
-	    retval(2) = static_cast<double> (filterSpecs.indexOf (filter) + 1);
-	}
+          retval(0) = cFiles;
+          retval(1) = toStdString (dirName);
+          if (! filter.isEmpty ())
+            retval(2) = static_cast<double> (filterSpecs.indexOf (filter) + 1);
+        }
     }
   else
     {
       QString filter;
       QString fileName =
         QFileDialog::getOpenFileName (0, caption, defaultFileName,
-				      filterSpecs.join (";;"), &filter, 0);
+                                      filterSpecs.join (";;"), &filter, 0);
 
       if (! fileName.isNull ())
-	{
-	  QFileInfo fi (fileName);
+        {
+          QFileInfo fi (fileName);
 
-	  retval(0) = toStdString (fi.fileName ());
-	  retval(1) = toStdString (appendDirSep (fi.canonicalPath ()));
-	  if (! filter.isEmpty ())
-	    retval(2) = static_cast<double> (filterSpecs.indexOf (filter) + 1);
-	}
+          retval(0) = toStdString (fi.fileName ());
+          retval(1) = toStdString (appendDirSep (fi.canonicalPath ()));
+          if (! filter.isEmpty ())
+            retval(2) = static_cast<double> (filterSpecs.indexOf (filter) + 1);
+        }
     }
 
   return retval;
@@ -289,7 +289,7 @@
   QString filter;
   QString fileName =
     QFileDialog::getSaveFileName (0, caption, defaultFileName,
-				  filterSpecs.join (";;"), &filter, 0);
+                                  filterSpecs.join (";;"), &filter, 0);
 
   if (! fileName.isNull ())
     {
@@ -297,11 +297,11 @@
 
       retval(0) = toStdString (fi.fileName ());
       if (fi.exists ())
-	retval(1) = toStdString (appendDirSep (fi.canonicalPath ()));
+        retval(1) = toStdString (appendDirSep (fi.canonicalPath ()));
       else
-	retval(1) = toStdString (appendDirSep (fi.absolutePath ()));
+        retval(1) = toStdString (appendDirSep (fi.absolutePath ()));
       if (! filter.isEmpty ())
-	retval(2) = static_cast<double> (filterSpecs.indexOf (filter) + 1);
+        retval(2) = static_cast<double> (filterSpecs.indexOf (filter) + 1);
     }
 
   return retval;
@@ -321,7 +321,7 @@
   QString defaultDirectory = fromStdString (args(0).string_value ());
 
   QString dirName = QFileDialog::getExistingDirectory (0, caption,
-						       defaultDirectory);
+                                                       defaultDirectory);
 
   if (! dirName.isNull ())
     retval = toStdString (dirName);
--- a/libgui/qterminal/libqterminal/QTerminal.cc	Fri Aug 01 09:06:21 2014 -0400
+++ b/libgui/qterminal/libqterminal/QTerminal.cc	Fri Aug 01 12:10:05 2014 -0400
@@ -118,5 +118,5 @@
     (cursorUseForegroundColor,
      settings->value ("terminal/color_c",
                       QVariant (colors.at (3))).value<QColor> ());
-  setScrollBufferSize (settings->value ("terminal/history_buffer",1000).toInt() );
+  setScrollBufferSize (settings->value ("terminal/history_buffer",1000).toInt () );
 }
--- a/libgui/qterminal/libqterminal/unix/QUnixTerminalImpl.cpp	Fri Aug 01 09:06:21 2014 -0400
+++ b/libgui/qterminal/libqterminal/unix/QUnixTerminalImpl.cpp	Fri Aug 01 12:10:05 2014 -0400
@@ -1,5 +1,5 @@
 /*  Copyright (C) 2008 e_k (e_k@users.sourceforge.net)
-    Copyright (C) 2012-2013 Jacob Dawid <jacob.dawid@googlemail.com>
+    Copyright (C) 2012-2013 Jacob Dawid <jacob.dawid@cybercatalyst.com>
 
     This library is free software; you can redistribute it and/or
     modify it under the terms of the GNU Library General Public
--- a/libgui/qterminal/libqterminal/unix/QUnixTerminalImpl.h	Fri Aug 01 09:06:21 2014 -0400
+++ b/libgui/qterminal/libqterminal/unix/QUnixTerminalImpl.h	Fri Aug 01 12:10:05 2014 -0400
@@ -1,5 +1,5 @@
 /*  Copyright (C) 2008 e_k (e_k@users.sourceforge.net)
-    Copyright (C) 2012-2013 Jacob Dawid <jacob.dawid@googlemail.com>
+    Copyright (C) 2012-2013 Jacob Dawid <jacob.dawid@cybercatalyst.com>
 
     This library is free software; you can redistribute it and/or
     modify it under the terms of the GNU Library General Public
--- a/libgui/qterminal/libqterminal/unix/SelfListener.cpp	Fri Aug 01 09:06:21 2014 -0400
+++ b/libgui/qterminal/libqterminal/unix/SelfListener.cpp	Fri Aug 01 12:10:05 2014 -0400
@@ -1,5 +1,5 @@
 /* qterminal - a terminal widget for Qt
- * Copyright (C) 2011, 2013 Jacob Dawid (jacob.dawid@googlemail.com)
+ * Copyright (C) 2011, 2013 Jacob Dawid (jacob.dawid@cybercatalyst.com)
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as
--- a/libgui/qterminal/libqterminal/unix/SelfListener.h	Fri Aug 01 09:06:21 2014 -0400
+++ b/libgui/qterminal/libqterminal/unix/SelfListener.h	Fri Aug 01 12:10:05 2014 -0400
@@ -1,5 +1,5 @@
 /* qterminal - a terminal widget for Qt
- * Copyright (C) 2011, 2013 Jacob Dawid (jacob.dawid@googlemail.com)
+ * Copyright (C) 2011, 2013 Jacob Dawid (jacob.dawid@cybercatalyst.com)
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as
--- a/libgui/qterminal/libqterminal/unix/TerminalModel.cpp	Fri Aug 01 09:06:21 2014 -0400
+++ b/libgui/qterminal/libqterminal/unix/TerminalModel.cpp	Fri Aug 01 12:10:05 2014 -0400
@@ -5,7 +5,7 @@
     Copyright (C) 1997,1998 by Lars Doelle <lars.doelle@on-line.de>
 
     Rewritten for QT4 by e_k <e_k at users.sourceforge.net>, Copyright (C)2008
-    Copyright (C) 2012-2013 Jacob Dawid <jacob.dawid@googlemail.com>
+    Copyright (C) 2012-2013 Jacob Dawid <jacob.dawid@cybercatalyst.com>
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
--- a/libgui/qterminal/libqterminal/unix/TerminalModel.h	Fri Aug 01 09:06:21 2014 -0400
+++ b/libgui/qterminal/libqterminal/unix/TerminalModel.h	Fri Aug 01 12:10:05 2014 -0400
@@ -5,7 +5,7 @@
     Copyright (C) 1997,1998 by Lars Doelle <lars.doelle@on-line.de>
 
     Rewritten for QT4 by e_k <e_k at users.sourceforge.net>, Copyright (C)2008
-    Copyright (C) 2012-2013 Jacob Dawid <jacob.dawid@googlemail.com>
+    Copyright (C) 2012-2013 Jacob Dawid <jacob.dawid@cybercatalyst.com>
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
--- a/libgui/qterminal/libqterminal/unix/TerminalView.cpp	Fri Aug 01 09:06:21 2014 -0400
+++ b/libgui/qterminal/libqterminal/unix/TerminalView.cpp	Fri Aug 01 12:10:05 2014 -0400
@@ -5,7 +5,7 @@
     Copyright (C) 1997,1998 by Lars Doelle <lars.doelle@on-line.de>
 
     Rewritten for QT4 by e_k <e_k at users.sourceforge.net>, Copyright (C)2008
-    Copyright (C) 2012-2013 Jacob Dawid <jacob.dawid@googlemail.com>
+    Copyright (C) 2012-2013 Jacob Dawid <jacob.dawid@cybercatalyst.com>
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
--- a/libgui/qterminal/libqterminal/unix/TerminalView.h	Fri Aug 01 09:06:21 2014 -0400
+++ b/libgui/qterminal/libqterminal/unix/TerminalView.h	Fri Aug 01 12:10:05 2014 -0400
@@ -3,7 +3,7 @@
     Copyright (C) 1997,1998 by Lars Doelle <lars.doelle@on-line.de>
 
     Rewritten for QT4 by e_k <e_k at users.sourceforge.net>, Copyright (C)2008
-    Copyright (C) 2012-2013 Jacob Dawid <jacob.dawid@googlemail.com>
+    Copyright (C) 2012-2013 Jacob Dawid <jacob.dawid@cybercatalyst.com>
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
--- a/libgui/src/files-dock-widget.cc	Fri Aug 01 09:06:21 2014 -0400
+++ b/libgui/src/files-dock-widget.cc	Fri Aug 01 12:10:05 2014 -0400
@@ -551,7 +551,7 @@
   QItemSelectionModel *m = _file_tree_view->selectionModel ();
   QModelIndexList rows = m->selectedRows ();
 
-  for ( QModelIndexList::iterator it = rows.begin (); it != rows.end (); it++)
+  for (QModelIndexList::iterator it = rows.begin (); it != rows.end (); it++)
     {
       QFileInfo file = _file_system_model->fileInfo (*it);
       if (file.exists ())
@@ -661,7 +661,7 @@
   QItemSelectionModel *m = _file_tree_view->selectionModel ();
   QModelIndexList rows = m->selectedRows ();
 
-  for ( QModelIndexList::iterator it = rows.begin (); it != rows.end (); it++)
+  for (QModelIndexList::iterator it = rows.begin (); it != rows.end (); it++)
     {
       QModelIndex index = *it;
 
--- a/libgui/src/find-files-model.cc	Fri Aug 01 09:06:21 2014 -0400
+++ b/libgui/src/find-files-model.cc	Fri Aug 01 12:10:05 2014 -0400
@@ -101,7 +101,7 @@
 void
 find_files_model::addFile (const QFileInfo &info)
 {
-  beginInsertRows (QModelIndex (), _files.size (), _files.size () );
+  beginInsertRows (QModelIndex (), _files.size (), _files.size ());
 
   QList<QFileInfo>::Iterator it;
   find_file_less_than less_than (_sortorder);
--- a/libgui/src/history-dock-widget.cc	Fri Aug 01 09:06:21 2014 -0400
+++ b/libgui/src/history-dock-widget.cc	Fri Aug 01 12:10:05 2014 -0400
@@ -214,7 +214,7 @@
   if (_filter_line_edit->hasFocus () && _filter_line_edit->hasSelectedText ())
     {
       QClipboard *clipboard = QApplication::clipboard ();
-      clipboard->setText ( _filter_line_edit->selectedText ());
+      clipboard->setText (_filter_line_edit->selectedText ());
     }
 }
 
--- a/libgui/src/m-editor/file-editor-interface.h	Fri Aug 01 09:06:21 2014 -0400
+++ b/libgui/src/m-editor/file-editor-interface.h	Fri Aug 01 12:10:05 2014 -0400
@@ -40,7 +40,7 @@
 
   virtual ~file_editor_interface () { }
 
-  virtual QMenu *get_mru_menu ( ) = 0;
+  virtual QMenu *get_mru_menu () = 0;
   virtual QMenu *debug_menu () = 0;
   virtual QToolBar *toolbar () = 0;
 
--- a/libgui/src/m-editor/find-dialog.cc	Fri Aug 01 09:06:21 2014 -0400
+++ b/libgui/src/m-editor/find-dialog.cc	Fri Aug 01 12:10:05 2014 -0400
@@ -255,7 +255,8 @@
 void
 find_dialog::find (bool forward)
 {
-  int line = -1, col = -1;
+  int line, col;
+  line = col = -1;
   bool do_wrap = _wrap_check_box->isChecked ();
   bool do_forward = forward;
 
--- a/libgui/src/m-editor/octave-qscintilla.cc	Fri Aug 01 09:06:21 2014 -0400
+++ b/libgui/src/m-editor/octave-qscintilla.cc	Fri Aug 01 12:10:05 2014 -0400
@@ -188,7 +188,7 @@
 octave_qscintilla::contextMenuEvent (QContextMenuEvent *e)
 {
   QPoint global_pos, local_pos;                         // the menu's position
-  QMenu *context_menu = createStandardContextMenu ( );  // standard menu
+  QMenu *context_menu = createStandardContextMenu ();  // standard menu
 
   // fill context menu with editor's standard actions
   emit create_context_menu_signal (context_menu);
@@ -273,7 +273,7 @@
 {
   QStringList commands = selectedText ().split (QRegExp("[\r\n]"),
                                                 QString::SkipEmptyParts);
-  for (int i = 0; i < commands.size (); i++ )
+  for (int i = 0; i < commands.size (); i++)
     emit execute_command_in_terminal_signal (commands.at (i));
 }
 
--- a/libgui/src/main-window.cc	Fri Aug 01 09:06:21 2014 -0400
+++ b/libgui/src/main-window.cc	Fri Aug 01 12:10:05 2014 -0400
@@ -1944,7 +1944,7 @@
 main_window::show_gui_info (void)
 {
   QString gui_info
-    ( QObject::tr ("<p><strong>A Note about Octave's New GUI</strong></p>"
+    (QObject::tr ("<p><strong>A Note about Octave's New GUI</strong></p>"
          "<p>One of the biggest new features for Octave 3.8 is a graphical "
          "user interface.  It is the one thing that users have requested "
          "most often over the last few years and now it is almost ready.  "
@@ -2425,7 +2425,7 @@
 
   QSettings *settings = resource_manager::get_settings ();
 
-  if (settings->value ("prompt_to_exit", false ).toBool())
+  if (settings->value ("prompt_to_exit", false).toBool ())
     {
       int ans = QMessageBox::question (this, tr ("Octave"),
          tr ("Are you sure you want to exit Octave?"),
--- a/libgui/src/octave-dock-widget.cc	Fri Aug 01 09:06:21 2014 -0400
+++ b/libgui/src/octave-dock-widget.cc	Fri Aug 01 12:10:05 2014 -0400
@@ -66,7 +66,7 @@
   _dock_button->setIconSize (QSize (12,12));
 
   _close_action = new QAction
-                   (QIcon (":/actions/icons/widget-close.png"), "", this );
+                   (QIcon (":/actions/icons/widget-close.png"), "", this);
   _close_action-> setToolTip (tr ("Hide widget"));
   connect (_close_action, SIGNAL (triggered (bool)),
            this, SLOT (change_visibility (bool)));
@@ -178,7 +178,7 @@
   _dock_action->setIcon (QIcon (":/actions/icons/widget-dock"+_icon_color+".png"));
   _dock_action->setToolTip (tr ("Dock widget"));
 
-  // restore the last geometry( when floating
+  // restore the last geometry when floating
   setGeometry (settings->value ("DockWidgets/" + objectName ()
                        + "_floating_geometry",QRect(50,100,480,480)).toRect ());
 
@@ -198,11 +198,15 @@
 
 // dock the widget
 void
+#if defined (Q_OS_WIN32)
 octave_dock_widget::make_widget (bool dock)
+#else
+octave_dock_widget::make_widget (bool)
+#endif
 {
 #if defined (Q_OS_WIN32)
 
-  // windows: Since floating widget has no parent, we have to readd it
+  // windows: Since floating widget has no parent, we have to read it
 
   QSettings *settings = resource_manager::get_settings ();
 
--- a/libgui/src/octave-gui.cc	Fri Aug 01 09:06:21 2014 -0400
+++ b/libgui/src/octave-gui.cc	Fri Aug 01 12:10:05 2014 -0400
@@ -89,7 +89,7 @@
 // Disable all Qt messages by default.
 
 static void
-message_handler (QtMsgType type, const char *msg)
+message_handler (QtMsgType, const char *)
 {
 }
 
--- a/libgui/src/octave-qt-link.cc	Fri Aug 01 09:06:21 2014 -0400
+++ b/libgui/src/octave-qt-link.cc	Fri Aug 01 12:10:05 2014 -0400
@@ -100,7 +100,7 @@
     tr ("File\n%1\ndoes not exist. Do you want to create it?").
     arg (QDir::currentPath () + QDir::separator ()
          + QString::fromStdString (file)),
-    tr ("Octave Editor"), "quest", btn, tr ("Yes"), role );
+    tr ("Octave Editor"), "quest", btn, tr ("Yes"), role);
 
   // Wait while the user is responding to message box.
   uiwidget_creator.wait ();
--- a/libgui/src/qtinfo/parser.cc	Fri Aug 01 09:06:21 2014 -0400
+++ b/libgui/src/qtinfo/parser.cc	Fri Aug 01 12:10:05 2014 -0400
@@ -22,7 +22,7 @@
 */
 
 // Author: P. L. Lucas
-// Author: Jacob Dawid <jacob.dawid@gmail.com>
+// Author: Jacob Dawid <jacob.dawid@cybercatalyst.com>
 
 #ifdef HAVE_CONFIG_H
 #include <config.h>
@@ -77,7 +77,7 @@
 parser::open_file (QFileInfo & file_info)
 {
   QIODevice *iodevice = 0;
-  if ( _compressors_map.contains(file_info.suffix ()))
+  if (_compressors_map.contains (file_info.suffix ()))
     {
       QProcess gzip;
       gzip.start (_compressors_map.value (file_info.suffix ()).arg (file_info.absoluteFilePath ()));
@@ -277,7 +277,7 @@
   QRegExp re ("(\\*[N|n]ote|\n\\*)([ |\n]+)([^:]+):([^:\\.,]*)([:,\\.]+)");
   int i = 0, f;
 
-  while ( (i = re.indexIn (text,i)) != -1)
+  while ((i = re.indexIn (text,i)) != -1)
     {
       QString type     = re.cap (1);
       QString note     = re.cap (3);
@@ -330,7 +330,7 @@
 {
   QRegExp re ("`([^']+)'");
   int i = 0, f;
-  while ( (i = re.indexIn (text, i)) != -1)
+  while ((i = re.indexIn (text, i)) != -1)
     {
       QString t = re.cap (1);
       QString bold = "<font style=\"color:SteelBlue;font-weight:bold\">" + t +
@@ -436,7 +436,7 @@
       while (! (nodeText=get_next_node (io)).isEmpty () && foundCount < 2)
         {
           QString first_line = get_first_line (nodeText);
-          if (first_line.startsWith ("Tag") )
+          if (first_line.startsWith ("Tag"))
             {
               foundCount++;
               int pos = 0;
@@ -471,7 +471,7 @@
               foundCount++;
               int pos = 0;
 
-              while ( (pos = re_files.indexIn (nodeText, pos)) != -1)
+              while ((pos = re_files.indexIn (nodeText, pos)) != -1)
                 {
                   QString fileCap = re_files.cap (1).trimmed ();
                   int index = re_files.cap (2).toInt ();
@@ -501,7 +501,8 @@
 void
 parser::real_position (int pos, QFileInfo & file_info, int & real_pos)
 {
-  int header = -1, sum = 0;
+  int header = -1;
+  int sum = 0;
   for (int i = 0; i < _info_file_real_size_list.size (); i++)
     {
       info_file_item item = _info_file_real_size_list.at (i);
@@ -538,7 +539,7 @@
 {
   int pos = 0;
 
-  while ( (pos = re.indexIn (text, pos)) != -1)
+  while ((pos = re.indexIn (text, pos)) != -1)
     {
       QString cap = text.mid (pos,re.matchedLength ());
       QString a (after);
@@ -578,7 +579,7 @@
         }
 
       QString node_text;
-      while ( !(node_text = get_next_node (io)).isEmpty ())
+      while (! (node_text = get_next_node (io)).isEmpty ())
         {
           QString firstLine = get_first_line (node_text);
           QString node = get_node_name (node_text);
--- a/libgui/src/qtinfo/parser.h	Fri Aug 01 09:06:21 2014 -0400
+++ b/libgui/src/qtinfo/parser.h	Fri Aug 01 12:10:05 2014 -0400
@@ -22,7 +22,7 @@
 */
 
 // Author: P. L. Lucas
-// Author: Jacob Dawid <jacob.dawid@gmail.com>
+// Author: Jacob Dawid <jacob.dawid@cybercatalyst.com>
 
 #include <QStringList>
 #include <QIODevice>
--- a/libgui/src/qtinfo/webinfo.cc	Fri Aug 01 09:06:21 2014 -0400
+++ b/libgui/src/qtinfo/webinfo.cc	Fri Aug 01 12:10:05 2014 -0400
@@ -22,7 +22,7 @@
 */
 
 // Author: P. L. Lucas
-// Author: Jacob Dawid <jacob.dawid@gmail.com>
+// Author: Jacob Dawid <jacob.dawid@cybercatalyst.com>
 
 #ifdef HAVE_CONFIG_H
 #include <config.h>
@@ -181,7 +181,7 @@
   _text_browser->show ();
 
   connect (_text_browser, SIGNAL (anchorClicked (const QUrl &)), this,
-           SLOT (link_clicked (const QUrl &)) );
+           SLOT (link_clicked (const QUrl &)));
   disconnect(_tab_bar, SIGNAL (currentChanged(int)), this,
              SLOT (current_tab_changed (int)));
 
--- a/libgui/src/qtinfo/webinfo.h	Fri Aug 01 09:06:21 2014 -0400
+++ b/libgui/src/qtinfo/webinfo.h	Fri Aug 01 12:10:05 2014 -0400
@@ -22,7 +22,7 @@
 */
 
 // Author: P. L. Lucas
-// Author: 2012 Jacob Dawid <jacob.dawid@gmail.com>
+// Author: 2012 Jacob Dawid <jacob.dawid@cybercatalyst.com>
 
 #include <QTextBrowser>
 #include "parser.h"
--- a/libgui/src/settings-dialog.cc	Fri Aug 01 09:06:21 2014 -0400
+++ b/libgui/src/settings-dialog.cc	Fri Aug 01 12:10:05 2014 -0400
@@ -138,7 +138,7 @@
   ui->customFileEditor->setText (
     settings->value ("customFileEditor").toString ());
   ui->editor_showLineNumbers->setChecked (
-    settings->value ("editor/showLineNumbers",true).toBool () );
+    settings->value ("editor/showLineNumbers",true).toBool ());
 
   default_var = QColor (240, 240, 240);
   QColor setting_color = settings->value ("editor/highlight_current_line_color",
@@ -150,7 +150,7 @@
   connect (ui->editor_highlightCurrentLine, SIGNAL (toggled (bool)),
            _editor_current_line_color, SLOT (setEnabled (bool)));
   ui->editor_highlightCurrentLine->setChecked (
-    settings->value ("editor/highlightCurrentLine",true).toBool () );
+    settings->value ("editor/highlightCurrentLine",true).toBool ());
   ui->editor_long_line_marker->setChecked (
     settings->value ("editor/long_line_marker",true).toBool ());
   ui->editor_long_line_column->setValue (
@@ -161,7 +161,7 @@
     settings->value ("editor/code_folding",true).toBool ());
 
   ui->editor_codeCompletion->setChecked (
-    settings->value ("editor/codeCompletion", true).toBool () );
+    settings->value ("editor/codeCompletion", true).toBool ());
   ui->editor_spinbox_ac_threshold->setValue (
     settings->value ("editor/codeCompletion_threshold",2).toInt ());
   ui->editor_checkbox_ac_keywords->setChecked (
@@ -211,7 +211,7 @@
 
   // terminal
   ui->terminal_fontName->setCurrentFont (QFont (
-    settings->value ("terminal/fontName","Courier New").toString ()) );
+    settings->value ("terminal/fontName","Courier New").toString ()));
   ui->terminal_fontSize->setValue (
     settings->value ("terminal/fontSize", 10).toInt ());
   ui->terminal_history_buffer->setValue (
@@ -270,7 +270,7 @@
 
   int currentIndex = 0;
   QString proxyTypeString = settings->value ("proxyType").toString ();
-  while ( (currentIndex < ui->proxyType->count ())
+  while ((currentIndex < ui->proxyType->count ())
           && (ui->proxyType->currentText () != proxyTypeString))
     {
       currentIndex++;
@@ -581,7 +581,7 @@
   settings->setValue ("toolbar_icon_size", ui->toolbar_icon_size->value ());
 
   // promp to exit
-  settings->setValue ( "prompt_to_exit", ui->cb_prompt_to_exit->isChecked ());
+  settings->setValue ("prompt_to_exit", ui->cb_prompt_to_exit->isChecked ());
 
   // status bar
   settings->setValue ( "show_status_bar", ui->cb_status_bar->isChecked ());
@@ -690,7 +690,7 @@
   settings->setValue ("terminal/focus_after_command",
                       ui->terminal_focus_command->isChecked ());
   settings->setValue ("terminal/history_buffer",
-                      ui->terminal_history_buffer->value() );
+                      ui->terminal_history_buffer->value ());
 
   // the cursor
   QString cursorType;
--- a/libgui/src/workspace-model.cc	Fri Aug 01 09:06:21 2014 -0400
+++ b/libgui/src/workspace-model.cc	Fri Aug 01 12:10:05 2014 -0400
@@ -141,7 +141,7 @@
 
       if (role == Qt::DisplayRole
           || (idx.column () == 0 && role == Qt::EditRole)
-          || (idx.column () == 0 && role == Qt::ToolTipRole) )
+          || (idx.column () == 0 && role == Qt::ToolTipRole))
         {
           switch (idx.column ())
             {
--- a/libinterp/corefcn/__contourc__.cc	Fri Aug 01 09:06:21 2014 -0400
+++ b/libinterp/corefcn/__contourc__.cc	Fri Aug 01 12:10:05 2014 -0400
@@ -307,10 +307,10 @@
 
   if (args.length () == 4)
     {
-      RowVector X = args (0).row_vector_value ();
-      RowVector Y = args (1).row_vector_value ();
-      Matrix Z = args (2).matrix_value ();
-      RowVector L = args (3).row_vector_value ();
+      RowVector X = args(0).row_vector_value ();
+      RowVector Y = args(1).row_vector_value ();
+      Matrix Z = args(2).matrix_value ();
+      RowVector L = args(3).row_vector_value ();
 
       if (! error_state)
         {
--- a/libinterp/corefcn/__pchip_deriv__.cc	Fri Aug 01 09:06:21 2014 -0400
+++ b/libinterp/corefcn/__pchip_deriv__.cc	Fri Aug 01 12:10:05 2014 -0400
@@ -59,7 +59,7 @@
   octave_value retval;
   const int nargin = args.length ();
 
-  bool rows = (nargin == 3 && args (2).uint_value () == 2);
+  bool rows = (nargin == 3 && args(2).uint_value () == 2);
 
   if (nargin >= 2)
     {
--- a/libinterp/corefcn/balance.cc	Fri Aug 01 09:06:21 2014 -0400
+++ b/libinterp/corefcn/balance.cc	Fri Aug 01 12:10:05 2014 -0400
@@ -68,7 +68,7 @@
 \n\
 If four output values are requested, compute @code{@var{AA} =\n\
 @var{CC}*@var{A}*@var{DD}} and @code{@var{BB} = @var{CC}*@var{B}*@var{DD}},\n\
-in which @var{AA} and @var{BB} have non-zero elements of approximately the\n\
+in which @var{AA} and @var{BB} have nonzero elements of approximately the\n\
 same magnitude and @var{CC} and @var{DD} are permuted diagonal matrices as\n\
 in @var{DD} for the algebraic eigenvalue problem.\n\
 \n\
@@ -144,7 +144,8 @@
   if (AEPcase)
     {
       // Algebraic eigenvalue problem.
-      bool noperm = false, noscal = false;
+      bool noperm = false;
+      bool noscal = false;
       if (nargin > 1)
         {
           std::string a1s = args(1).string_value ();
--- a/libinterp/corefcn/besselj.cc	Fri Aug 01 09:06:21 2014 -0400
+++ b/libinterp/corefcn/besselj.cc	Fri Aug 01 12:10:05 2014 -0400
@@ -598,7 +598,7 @@
         {
           int idx = nargin == 1 ? 0 : 1;
 
-          if (args (idx).is_single_type ())
+          if (args(idx).is_single_type ())
             {
               FloatComplexNDArray z = args(idx).float_complex_array_value ();
 
--- a/libinterp/corefcn/betainc.cc	Fri Aug 01 09:06:21 2014 -0400
+++ b/libinterp/corefcn/betainc.cc	Fri Aug 01 12:10:05 2014 -0400
@@ -32,8 +32,6 @@
 #include "oct-obj.h"
 #include "utils.h"
 
-// FIXME: These functions do not need to be dynamically loaded.  They should
-//        be placed elsewhere in the Octave code hierarchy.
 
 DEFUN (betainc, args, ,
        "-*- texinfo -*-\n\
--- a/libinterp/corefcn/bitfcns.cc	Fri Aug 01 09:06:21 2014 -0400
+++ b/libinterp/corefcn/bitfcns.cc	Fri Aug 01 12:10:05 2014 -0400
@@ -595,7 +595,7 @@
           int bits_in_type = sizeof (double)
                              * std::numeric_limits<unsigned char>::digits;
           NDArray m = m_arg.array_value ();
-          DO_BITSHIFT ( );
+          DO_BITSHIFT ();
         }
       else if (cname == "single")
         {
--- a/libinterp/corefcn/bsxfun.cc	Fri Aug 01 09:06:21 2014 -0400
+++ b/libinterp/corefcn/bsxfun.cc	Fri Aug 01 12:10:05 2014 -0400
@@ -201,7 +201,8 @@
   bsxfun_builtin_op op = bsxfun_builtin_lookup (name);
   if (op != bsxfun_builtin_unknown)
     {
-      builtin_type_t btyp_a = a.builtin_type (), btyp_b = b.builtin_type ();
+      builtin_type_t btyp_a = a.builtin_type ();
+      builtin_type_t btyp_b = b.builtin_type ();
 
       // Simplify single/double combinations.
       if (btyp_a == btyp_float && btyp_b == btyp_double)
@@ -351,8 +352,8 @@
                || args(0).is_inline_function ()))
         error ("bsxfun: F must be a string or function handle");
 
-      const octave_value A = args (1);
-      const octave_value B = args (2);
+      const octave_value A = args(1);
+      const octave_value B = args(2);
 
       if (func.is_builtin_function ()
           || (func.is_function_handle ()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libinterp/corefcn/cdisplay.c	Fri Aug 01 12:10:05 2014 -0400
@@ -0,0 +1,164 @@
+/*
+
+Copyright (C) 2009-2014 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdlib.h>
+
+#if defined (OCTAVE_USE_WINDOWS_API)
+#include <windows.h>
+#elif defined (HAVE_FRAMEWORK_CARBON)
+#include <Carbon/Carbon.h>
+#elif defined (HAVE_X_WINDOWS)
+#include <X11/Xlib.h>
+#endif
+
+#include "cdisplay.h"
+
+const char *
+octave_get_display_info (int *ht, int *wd, int *dp, double *rx, double *ry,
+                         int *dpy_avail)
+{
+  const char *msg = 0;
+
+  *dpy_avail = 0;
+
+#if defined (OCTAVE_USE_WINDOWS_API)
+
+  HDC hdc = GetDC (0);
+
+  if (hdc)
+    {
+      *dp = GetDeviceCaps (hdc, BITSPIXEL);
+
+      *ht = GetDeviceCaps (hdc, VERTRES);
+      *wd = GetDeviceCaps (hdc, HORZRES);
+
+      double ht_mm = GetDeviceCaps (hdc, VERTSIZE);
+      double wd_mm = GetDeviceCaps (hdc, HORZSIZE);
+
+      *rx = *wd * 25.4 / wd_mm;
+      *ry = *ht * 25.4 / ht_mm;
+
+      *dpy_avail = 1;
+    }
+  else
+    msg = "no graphical display found";
+
+#elif defined (HAVE_FRAMEWORK_CARBON)
+
+  CGDirectDisplayID display = CGMainDisplayID ();
+
+  if (display)
+    {
+#if defined (HAVE_CARBON_CGDISPLAYBITSPERPIXEL)
+
+      *dp = CGDisplayBitsPerPixel (display);
+
+#else
+
+      /* FIXME: This will only work for MacOS > 10.5. For earlier versions
+         this code is not needed (use CGDisplayBitsPerPixel instead).  */
+
+      CGDisplayModeRef mode = CGDisplayCopyDisplayMode (display);
+      CFStringRef pixelEncoding = CGDisplayModeCopyPixelEncoding (mode);
+
+      if (CFStringCompare (pixelEncoding, CFSTR (IO32BitDirectPixels), 0) == 0)
+        *dp = 32;
+      else if (CFStringCompare (pixelEncoding,
+                                CFSTR (IO16BitDirectPixels), 0) == 0)
+        *dp = 16;
+      else
+        *dp = 8;
+
+#endif
+
+      *ht = CGDisplayPixelsHigh (display);
+      *wd = CGDisplayPixelsWide (display);
+
+      CGSize sz_mm = CGDisplayScreenSize (display);
+
+      /* For MacOS >= 10.6, CGSize is a struct keeping 2 CGFloat
+         values, but the CGFloat typedef is not present on older
+         systems, so use double instead.  */
+
+      double ht_mm = sz_mm.height;
+      double wd_mm = sz_mm.width;
+
+      *rx = *wd * 25.4 / wd_mm;
+      *ry = *ht * 25.4 / ht_mm;
+
+      *dpy_avail = 1;
+    }
+  else
+    msg = "no graphical display found";
+
+#elif defined (HAVE_X_WINDOWS)
+
+  const char *display_name = getenv ("DISPLAY");
+
+  if (display_name && *display_name)
+    {
+      Display *display = XOpenDisplay (display_name);
+
+      if (display)
+        {
+          Screen *screen = DefaultScreenOfDisplay (display);
+
+          if (screen)
+            {
+              *dp = DefaultDepthOfScreen (screen);
+
+              *ht = HeightOfScreen (screen);
+              *wd = WidthOfScreen (screen);
+
+              int screen_number = XScreenNumberOfScreen (screen);
+
+              double ht_mm = DisplayHeightMM (display, screen_number);
+              double wd_mm = DisplayWidthMM (display, screen_number);
+
+              *rx = *wd * 25.4 / wd_mm;
+              *ry = *ht * 25.4 / ht_mm;
+            }
+          else
+            msg = "X11 display has no default screen";
+
+          XCloseDisplay (display);
+
+          *dpy_avail = 1;
+        }
+      else
+        msg = "unable to open X11 DISPLAY";
+    }
+  else
+    msg = "X11 DISPLAY environment variable not set";
+
+#else
+
+  msg = "no graphical display found";
+
+#endif
+
+  return msg;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libinterp/corefcn/cdisplay.h	Fri Aug 01 12:10:05 2014 -0400
@@ -0,0 +1,38 @@
+/*
+
+Copyright (C) 2014 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_cdisplay_h)
+#define octave_cdisplay_h 1
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+OCTINTERP_API extern const char *
+octave_get_display_info (int *ht, int *wd, int *dp, double *rx, double *ry,
+                         int *dpy_avail);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
--- a/libinterp/corefcn/cellfun.cc	Fri Aug 01 09:06:21 2014 -0400
+++ b/libinterp/corefcn/cellfun.cc	Fri Aug 01 12:10:05 2014 -0400
@@ -319,9 +319,9 @@
 \n\
 Additionally, @code{cellfun} accepts an arbitrary function @var{func}\n\
 in the form of an inline function, function handle, or the name of a\n\
-function (in a character string). The function can take one or more arguments,\n\
-with the inputs arguments given by @var{C}, @var{D}, etc.  Equally the\n\
-function can return one or more output arguments.  For example:\n\
+function (in a character string).  The function can take one or more\n\
+arguments, with the inputs arguments given by @var{C}, @var{D}, etc.  \n\
+Equally the function can return one or more output arguments.  For example:\n\
 \n\
 @example\n\
 @group\n\
@@ -440,7 +440,7 @@
 
       if (! valid_identifier (name))
         {
-          std::string fcn_name = unique_symbol_name ("__cellfun_fcn_");
+          std::string fcn_name = unique_symbol_name ("__cellfun_fcn__");
           std::string fname = "function y = " + fcn_name + "(x) y = ";
 
           octave_function *ptr_func
@@ -1193,7 +1193,7 @@
 
       if (! valid_identifier (name))
         {
-          std::string fcn_name = unique_symbol_name ("__arrayfun_fcn_");
+          std::string fcn_name = unique_symbol_name ("__arrayfun_fcn__");
           std::string fname = "function y = " + fcn_name + "(x) y = ";
 
           octave_function *ptr_func
@@ -1227,7 +1227,7 @@
       // fewer polymorphic function calls as the function gets called
       // for each value of the array.
 
-      if (! symbol_table_lookup )
+      if (! symbol_table_lookup)
         {
           if (func.is_function_handle ())
             {
@@ -1783,7 +1783,8 @@
 
       NDA parray = array.permute (perm);
 
-      octave_idx_type nela = arraydv.numel (), nelc = celldv.numel ();
+      octave_idx_type nela = arraydv.numel ();
+      octave_idx_type nelc = celldv.numel ();
       parray = parray.reshape (dim_vector (nela, nelc));
 
       Cell retval (celldv);
@@ -1901,7 +1902,7 @@
       octave_value array = args(0);
       Array<int> dimv;
       if (nargin > 1)
-        dimv = args (1).int_vector_value (true);
+        dimv = args(1).int_vector_value (true);
 
       if (error_state)
         ;
@@ -2036,7 +2037,8 @@
   if (ivec >= 0)
     {
       // Vector split. Use 1D indexing.
-      octave_idx_type l = 0, nidx = (ivec == 0 ? nridx : ncidx);
+      octave_idx_type l = 0;
+      octave_idx_type nidx = (ivec == 0 ? nridx : ncidx);
       for (octave_idx_type i = 0; i < nidx; i++)
         {
           octave_idx_type u = l + d[ivec](i);
--- a/libinterp/corefcn/data.cc	Fri Aug 01 09:06:21 2014 -0400
+++ b/libinterp/corefcn/data.cc	Fri Aug 01 12:10:05 2014 -0400
@@ -112,15 +112,15 @@
 @deftypefn  {Built-in Function} {} all (@var{x})\n\
 @deftypefnx {Built-in Function} {} all (@var{x}, @var{dim})\n\
 For a vector argument, return true (logical 1) if all elements of the vector\n\
-are non-zero.\n\
+are nonzero.\n\
 \n\
 For a matrix argument, return a row vector of logical ones and\n\
 zeros with each element indicating whether all of the elements of the\n\
-corresponding column of the matrix are non-zero.  For example:\n\
+corresponding column of the matrix are nonzero.  For example:\n\
 \n\
 @example\n\
 @group\n\
-all ([2, 3; 1, 0]))\n\
+all ([2, 3; 1, 0])\n\
     @result{} [ 1, 0 ]\n\
 @end group\n\
 @end example\n\
@@ -159,11 +159,11 @@
 @deftypefn  {Built-in Function} {} any (@var{x})\n\
 @deftypefnx {Built-in Function} {} any (@var{x}, @var{dim})\n\
 For a vector argument, return true (logical 1) if any element of the vector\n\
-is non-zero.\n\
+is nonzero.\n\
 \n\
 For a matrix argument, return a row vector of logical ones and\n\
 zeros with each element indicating whether any of the elements of the\n\
-corresponding column of the matrix are non-zero.  For example:\n\
+corresponding column of the matrix are nonzero.  For example:\n\
 \n\
 @example\n\
 @group\n\
@@ -333,7 +333,8 @@
 {
   octave_value retval;
 
-  octave_value arg0 = x, arg1 = y;
+  octave_value arg0 = x;
+  octave_value arg1 = y;
   if (! arg0.is_numeric_type ())
     gripe_wrong_type_arg ("hypot", arg0);
   else if (! arg1.is_numeric_type ())
@@ -621,7 +622,7 @@
                     X##NDArray a1 = args(1).X##_array_value (); \
                     retval = binmap<octave_##X,octave_##X,octave_##X> (a0, a1, rem, "rem"); \
                     } \
-                  break
+                  break;
                 MAKE_INT_BRANCH (int8);
                 MAKE_INT_BRANCH (int16);
                 MAKE_INT_BRANCH (int32);
@@ -780,7 +781,7 @@
                     X##NDArray a1 = args(1).X##_array_value (); \
                     retval = binmap<octave_##X,octave_##X,octave_##X> (a0, a1, mod, "mod"); \
                     } \
-                  break
+                  break;
                 MAKE_INT_BRANCH (int8);
                 MAKE_INT_BRANCH (int16);
                 MAKE_INT_BRANCH (int32);
@@ -1262,7 +1263,7 @@
                 retval = arg.X ## _array_value ().cumsum (dim); \
               else \
                 retval = arg.array_value ().cumsum (dim); \
-              break
+              break;
             MAKE_INT_BRANCH (int8);
             MAKE_INT_BRANCH (int16);
             MAKE_INT_BRANCH (int32);
@@ -1438,6 +1439,11 @@
 %!assert (diag ({1}, 2, 3), {1,[],[]; [],[],[]});
 %!assert (diag ({1,2}, 3, 4), {1,[],[],[]; [],2,[],[]; [],[],[],[]});
 
+## Test out-of-range diagonals
+%!assert (diag (ones (3,3), 4), zeros (0, 1))
+%!assert (diag (cell (3,3), 4), cell (0, 1))
+%!assert (diag (sparse (ones (3,3)), 4), sparse (zeros (0, 1)))
+
 %% Test input validation
 %!error <Invalid call to diag> diag ()
 %!error <Invalid call to diag> diag (1,2,3,4)
@@ -1458,12 +1464,144 @@
        "-*- texinfo -*-\n\
 @deftypefn  {Built-in Function} {} prod (@var{x})\n\
 @deftypefnx {Built-in Function} {} prod (@var{x}, @var{dim})\n\
-Product of elements along dimension @var{dim}.  If @var{dim} is\n\
-omitted, it defaults to the first non-singleton dimension.\n\
+@deftypefnx {Built-in Function} {} prod (@dots{}, \"native\")\n\
+@deftypefnx {Built-in Function} {} prod (@dots{}, \"double\")\n\
+Product of elements along dimension @var{dim}.\n\
+\n\
+If @var{dim} is omitted, it defaults to the first non-singleton dimension.\n\
+\n\
+The optional @qcode{\"type\"} input determines the class of the variable\n\
+used for calculations.  If the argument @qcode{\"native\"} is given, then\n\
+the operation is performed in the same type as the original argument, rather\n\
+than the default double type.\n\
+\n\
+For example:\n\
+\n\
+@example\n\
+@group\n\
+prod ([true, true])\n\
+   @result{} 1\n\
+prod ([true, true], \"native\")\n\
+   @result{} true\n\
+@end group\n\
+@end example\n\
+\n\
+On the contrary, if @qcode{\"double\"} is given, the operation is performed\n\
+in double precision even for single precision inputs.\n\
 @seealso{cumprod, sum}\n\
 @end deftypefn")
 {
-  DATA_REDUCTION (prod);
+  octave_value retval;
+
+  int nargin = args.length ();
+
+  bool isnative = false;
+  bool isdouble = false;
+
+  if (nargin > 1 && args(nargin - 1).is_string ())
+    {
+      std::string str = args(nargin - 1).string_value ();
+
+      if (! error_state)
+        {
+          if (str == "native")
+            isnative = true;
+          else if (str == "double")
+            isdouble = true;
+          else
+            error ("prod: unrecognized type argument '%s'", str.c_str ());
+          nargin --;
+        }
+    }
+
+  if (error_state)
+    return retval;
+
+  if (nargin == 1 || nargin == 2)
+    {
+      octave_value arg = args(0);
+
+      int dim = -1;
+      if (nargin == 2)
+        {
+          dim = args(1).int_value () - 1;
+          if (dim < 0)
+            error ("prod: invalid dimension DIM = %d", dim + 1);
+        }
+
+      if (! error_state)
+        {
+          switch (arg.builtin_type ())
+            {
+            case btyp_double:
+              if (arg.is_sparse_type ())
+                retval = arg.sparse_matrix_value ().prod (dim);
+              else
+                retval = arg.array_value ().prod (dim);
+              break;
+            case btyp_complex:
+              if (arg.is_sparse_type ())
+                retval = arg.sparse_complex_matrix_value ().prod (dim);
+              else
+                retval = arg.complex_array_value ().prod (dim);
+              break;
+            case btyp_float:
+              if (isdouble)
+                retval = arg.float_array_value ().dprod (dim);
+              else
+                retval = arg.float_array_value ().prod (dim);
+              break;
+            case btyp_float_complex:
+              if (isdouble)
+                retval = arg.float_complex_array_value ().dprod (dim);
+              else
+                retval = arg.float_complex_array_value ().prod (dim);
+              break;
+
+#define MAKE_INT_BRANCH(X) \
+            case btyp_ ## X: \
+              if (isnative) \
+                retval = arg.X ## _array_value ().prod (dim); \
+              else \
+                retval = arg.array_value ().prod (dim); \
+              break;
+            MAKE_INT_BRANCH (int8);
+            MAKE_INT_BRANCH (int16);
+            MAKE_INT_BRANCH (int32);
+            MAKE_INT_BRANCH (int64);
+            MAKE_INT_BRANCH (uint8);
+            MAKE_INT_BRANCH (uint16);
+            MAKE_INT_BRANCH (uint32);
+            MAKE_INT_BRANCH (uint64);
+#undef MAKE_INT_BRANCH
+
+            // GAGME: Accursed Matlab compatibility...
+            case btyp_char:
+              retval = arg.array_value (true).prod (dim);
+              break;
+            case btyp_bool:
+              if (arg.is_sparse_type ())
+                {
+                  if (isnative)
+                    retval = arg.sparse_bool_matrix_value ().all (dim);
+                  else
+                    retval = arg.sparse_matrix_value ().prod (dim);
+                }
+              else if (isnative)
+                retval = arg.bool_array_value ().all (dim);
+              else
+                retval = NDArray (arg.bool_array_value ().all (dim));
+              break;
+
+            default:
+              gripe_wrong_type_arg ("prod", arg);
+            }
+        }
+    }
+  else
+    print_usage ();
+
+  return retval;
 }
 
 /*
@@ -1477,6 +1615,13 @@
 %!assert (prod (single ([i, 2+i, -3+2i, 4])), single (-4 - 32i))
 %!assert (prod (single ([1, 2, 3; i, 2i, 3i; 1+i, 2+2i, 3+3i])), single ([-1+i, -8+8i, -27+27i]))
 
+%% Test sparse
+%!assert (prod (sparse ([1, 2, 3])), sparse (6))
+%!assert (prod (sparse ([-1; -2; -3])), sparse (-6))
+## Commented out until bug #42290 is fixed
+#%!assert (prod (sparse ([i, 2+i, -3+2i, 4])), sparse (-4 - 32i))
+#%!assert (prod (sparse ([1, 2, 3; i, 2i, 3i; 1+i, 2+2i, 3+3i])), sparse ([-1+i, -8+8i, -27+27i]))
+
 %!assert (prod ([1, 2; 3, 4], 1), [3, 8])
 %!assert (prod ([1, 2; 3, 4], 2), [2; 12])
 %!assert (prod (zeros (1, 0)), 1)
@@ -1507,7 +1652,24 @@
 %!assert (prod (zeros (0, 2, "single"), 1), single ([1, 1]))
 %!assert (prod (zeros (0, 2, "single"), 2), zeros (0, 1, "single"))
 
+%% Test "double" type argument
+%!assert (prod (single ([1, 2, 3]), "double"), 6)
+%!assert (prod (single ([-1; -2; -3]), "double"), -6)
+%!assert (prod (single ([i, 2+i, -3+2i, 4]), "double"), -4 - 32i)
+%!assert (prod (single ([1, 2, 3; i, 2i, 3i; 1+i, 2+2i, 3+3i]), "double"), [-1+i, -8+8i, -27+27i])
+
+%% Test "native" type argument
+%!assert (prod (uint8 ([1, 2, 3]), "native"), uint8 (6))
+%!assert (prod (uint8 ([-1; -2; -3]), "native"), uint8 (0))
+%!assert (prod (int8 ([1, 2, 3]), "native"), int8 (6))
+%!assert (prod (int8 ([-1; -2; -3]), "native"), int8 (-6))
+%!assert (prod ([true false; true true], "native"), [true false])
+%!assert (prod ([true false; true true], 2, "native"), [false; true])
+
+%% Test input validation
 %!error prod ()
+%!error prod (1,2,3)
+%!error <unrecognized type argument 'foobar'> prod (1, "foobar")
 */
 
 static bool
@@ -1921,7 +2083,7 @@
           // and then directly resize. However, for some types there might
           // be some additional setup needed, and so this should be avoided.
 
-          octave_value tmp = args (0);
+          octave_value tmp = args(0);
           tmp = tmp.resize (dim_vector (0,0)).resize (dv);
 
           if (error_state)
@@ -1935,12 +2097,12 @@
               // Can't fast return here to skip empty matrices as something
               // like cat (1,[],single ([])) must return an empty matrix of
               // the right type.
-              tmp = do_cat_op (tmp, args (j), ra_idx);
+              tmp = do_cat_op (tmp, args(j), ra_idx);
 
               if (error_state)
                 return retval;
 
-              dim_vector dv_tmp = args (j).dims ();
+              dim_vector dv_tmp = args(j).dims ();
 
               if (dim >= dv_len)
                 {
@@ -2399,8 +2561,8 @@
 %!assert (cat (3, [], [], [1,2;3,4]), [1,2;3,4])
 %!assert (cat (4, [], [], [1,2;3,4]), [1,2;3,4])
 
-%!assert ([zeros(3,2,2); ones(1,2,2)], repmat ([0;0;0;1],[1,2,2]) )
-%!assert ([zeros(3,2,2); ones(1,2,2)], vertcat (zeros (3,2,2), ones (1,2,2)) )
+%!assert ([zeros(3,2,2); ones(1,2,2)], repmat ([0;0;0;1],[1,2,2]))
+%!assert ([zeros(3,2,2); ones(1,2,2)], vertcat (zeros (3,2,2), ones (1,2,2)))
 
 %!error <dimension mismatch> cat (3, cat (3, [], []), [1,2;3,4])
 %!error <dimension mismatch> cat (3, zeros (0, 0, 2), [1,2;3,4])
@@ -2686,7 +2848,7 @@
 DEFUN (nnz, args, ,
        "-*- texinfo -*-\n\
 @deftypefn {Built-in Function} {@var{n} =} nnz (@var{a})\n\
-Return the number of non-zero elements in @var{a}.\n\
+Return the number of nonzero elements in @var{a}.\n\
 @seealso{nzmax, nonzeros, find}\n\
 @end deftypefn")
 {
@@ -2762,12 +2924,16 @@
 @deftypefnx {Built-in Function} {} sum (@dots{}, \"native\")\n\
 @deftypefnx {Built-in Function} {} sum (@dots{}, \"double\")\n\
 @deftypefnx {Built-in Function} {} sum (@dots{}, \"extra\")\n\
-Sum of elements along dimension @var{dim}.  If @var{dim} is\n\
-omitted, it defaults to the first non-singleton dimension.\n\
-\n\
-If the optional argument @qcode{\"native\"} is given, then the sum is\n\
-performed in the same type as the original argument, rather than in the\n\
-default double type.  For example:\n\
+Sum of elements along dimension @var{dim}.\n\
+\n\
+If @var{dim} is omitted, it defaults to the first non-singleton dimension.\n\
+\n\
+The optional @qcode{\"type\"} input determines the class of the variable\n\
+used for calculations.  If the argument @qcode{\"native\"} is given, then\n\
+the operation is performed in the same type as the original argument, rather\n\
+than the default double type.\n\
+\n\
+For example:\n\
 \n\
 @example\n\
 @group\n\
@@ -2781,8 +2947,8 @@
 On the contrary, if @qcode{\"double\"} is given, the sum is performed in\n\
 double precision even for single precision inputs.\n\
 \n\
-For double precision inputs, @qcode{\"extra\"} indicates that a more accurate\n\
-algorithm than straightforward summation is to be used.  For single precision\n\
+For double precision inputs, the @qcode{\"extra\"} option will use a more\n\
+accurate algorithm than straightforward summation.  For single precision\n\
 inputs, @qcode{\"extra\"} is the same as @qcode{\"double\"}.  Otherwise,\n\
 @qcode{\"extra\"} has no effect.\n\
 @seealso{cumsum, sumsq, prod}\n\
@@ -2809,7 +2975,7 @@
           else if (str == "extra")
             isextra = true;
           else
-            error ("sum: unrecognized string argument");
+            error ("sum: unrecognized type argument '%s'", str.c_str ());
           nargin --;
         }
     }
@@ -2876,7 +3042,7 @@
                 retval = arg.X ## _array_value ().sum (dim); \
               else \
                 retval = arg.X ## _array_value ().dsum (dim); \
-              break
+              break;
             MAKE_INT_BRANCH (int8);
             MAKE_INT_BRANCH (int16);
             MAKE_INT_BRANCH (int32);
@@ -2886,7 +3052,8 @@
             MAKE_INT_BRANCH (uint32);
             MAKE_INT_BRANCH (uint64);
 #undef MAKE_INT_BRANCH
-              // GAGME: Accursed Matlab compatibility...
+            
+            // GAGME: Accursed Matlab compatibility...
             case btyp_char:
               if (isextra)
                 retval = arg.array_value (true).xsum (dim);
@@ -2919,11 +3086,6 @@
 }
 
 /*
-%!assert (sum ([true,true]), 2)
-%!assert (sum ([true,true],"native"), true)
-%!assert (sum (int8 ([127,10,-20])), 117)
-%!assert (sum (int8 ([127,10,-20]),'native'), int8 (107))
-
 %!assert (sum ([1, 2, 3]), 6)
 %!assert (sum ([-1; -2; -3]), -6)
 %!assert (sum ([i, 2+i, -3+2i, 4]), 3+4i)
@@ -2974,10 +3136,18 @@
 %!assert (sum (zeros (2, 2, 0, 3, "single"), 4), zeros (2, 2, 0, "single"))
 %!assert (sum (zeros (2, 2, 0, 3, "single"), 7), zeros (2, 2, 0, 3, "single"))
 
+## Test "native"
+%!assert (sum ([true,true]), 2)
+%!assert (sum ([true,true], "native"), true)
+%!assert (sum (int8 ([127,10,-20])), 117)
+%!assert (sum (int8 ([127,10,-20]), "native"), int8 (107))
+
 ;-)
 %!assert (sum ("Octave") + "8", sumsq (primes (17)))
 
 %!error sum ()
+%!error sum (1,2,3)
+%!error <unrecognized type argument 'foobar'> sum (1, "foobar")
 */
 
 DEFUN (sumsq, args, ,
@@ -3488,6 +3658,164 @@
 %!assert (isnumeric (sparse ([true, false])), false)
 */
 
+DEFUN (isscalar, args, ,
+  "-*- texinfo -*-\n\
+@deftypefn {Built-in Function} {} isscalar (@var{x})\n\
+Return true if @var{x} is a scalar.\n\
+@seealso{isvector, ismatrix}\n\
+@end deftypefn")
+{
+  octave_value retval;
+
+  if (args.length () == 1)
+    retval = args(0).numel () == 1;
+  else
+    print_usage ();
+
+  return retval;
+}
+
+/*
+%!assert (isscalar (1))
+%!assert (isscalar ([1, 2]), false)
+%!assert (isscalar ([]), false)
+%!assert (isscalar ([1, 2; 3, 4]), false)
+
+%!assert (isscalar ("t"))
+%!assert (isscalar ("test"), false)
+%!assert (isscalar (["test"; "ing"]), false)
+
+%!test
+%! s.a = 1;
+%! assert (isscalar (s));
+
+%% Test input validation
+%!error isscalar ()
+%!error isscalar (1, 2)
+*/
+
+DEFUN (isvector, args, ,
+  "-*- texinfo -*-\n\
+@deftypefn {Function File} {} isvector (@var{x})\n\
+Return true if @var{x} is a vector.\n\
+\n\
+A vector is a 2-D array where one of the dimensions is equal to 1.  As a\n\
+consequence a 1x1 array, or scalar, is also a vector.\n\
+@seealso{isscalar, ismatrix, size, rows, columns, length}\n\
+@end deftypefn")
+{
+  octave_value retval;
+
+  if (args.length () == 1)
+    {
+      dim_vector sz = args(0).dims ();
+      retval = sz.length () == 2 && (sz(0) == 1 || sz(1) == 1);
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+
+/*
+%!assert (isvector (1))
+%!assert (isvector ([1; 2; 3]))
+%!assert (isvector ([]), false)
+%!assert (isvector ([1, 2; 3, 4]), false)
+
+%!assert (isvector ("t"))
+%!assert (isvector ("test"))
+%!assert (isvector (["test"; "ing"]), false)
+
+%!test
+%! s.a = 1;
+%! assert (isvector (s));
+
+%% Test input validation
+%!error isvector ()
+%!error isvector ([1, 2], 2)
+*/
+
+DEFUN (isrow, args, ,
+  "-*- texinfo -*-\n\
+@deftypefn {Function File} {} isrow (@var{x})\n\
+Return true if @var{x} is a row vector.\n\
+@seealso{iscolumn, isscalar, isvector, ismatrix}\n\
+@end deftypefn")
+{
+  octave_value retval;
+
+  if (args.length () == 1)
+    {
+      dim_vector sz = args(0).dims ();
+      retval = sz.length () == 2 && sz(0) == 1;
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+
+/*
+%!assert (isrow ([1, 2, 3]))
+%!assert (isrow ([1; 2; 3]), false)
+%!assert (isrow (1))
+%!assert (isrow ([]), false)
+%!assert (isrow ([1, 2; 3, 4]), false)
+
+%!assert (isrow ("t"))
+%!assert (isrow ("test"))
+%!assert (isrow (["test"; "ing"]), false)
+
+%!test
+%! s.a = 1;
+%! assert (isrow (s));
+
+%% Test input validation
+%!error isrow ()
+%!error isrow ([1, 2], 2)
+*/
+
+DEFUN (iscolumn, args, ,
+  "-*- texinfo -*-\n\
+@deftypefn {Function File} {} iscolumn (@var{x})\n\
+Return true if @var{x} is a column vector.\n\
+@seealso{isrow, isscalar, isvector, ismatrix}\n\
+@end deftypefn")
+{
+  octave_value retval;
+
+  if (args.length () == 1)
+    {
+      dim_vector sz = args(0).dims ();
+      retval = sz.length () == 2 && sz(1) == 1;
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+
+/*
+%!assert (iscolumn ([1, 2, 3]), false)
+%!assert (iscolumn ([1; 2; 3]))
+%!assert (iscolumn (1))
+%!assert (iscolumn ([]), false)
+%!assert (iscolumn ([1, 2; 3, 4]), false)
+
+%!assert (iscolumn ("t"))
+%!assert (iscolumn ("test"), false)
+%!assert (iscolumn (["test"; "ing"]), false)
+
+%!test
+%! s.a = 1;
+%! assert (iscolumn (s));
+
+%% Test input validation
+%!error iscolumn ()
+%!error iscolumn ([1, 2], 2)
+*/
+
 DEFUN (ismatrix, args, ,
        "-*- texinfo -*-\n\
 @deftypefn {Built-in Function} {} ismatrix (@var{a})\n\
@@ -3538,6 +3866,47 @@
 %!error ismatrix ([1, 2; 3, 4], 2)
 */
 
+DEFUN (issquare, args, ,
+  "-*- texinfo -*-\n\
+@deftypefn {Function File} {} issquare (@var{x})\n\
+Return true if @var{x} is a square matrix.\n\
+@seealso{isscalar, isvector, ismatrix, size}\n\
+@end deftypefn")
+{
+  octave_value retval;
+
+  if (args.length () == 1)
+    {
+      dim_vector sz = args(0).dims ();
+      retval = sz.length () == 2 && sz(0) == sz(1);
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+
+/*
+%!assert (issquare ([]))
+%!assert (issquare (1))
+%!assert (! issquare ([1, 2]))
+%!assert (issquare ([1, 2; 3, 4]))
+%!assert (! issquare ([1, 2; 3, 4; 5, 6]))
+%!assert (! issquare (ones (3,3,3)))
+%!assert (issquare ("t"))
+%!assert (! issquare ("test"))
+%!assert (issquare (["test"; "ing"; "1"; "2"]))
+%!test
+%! s.a = 1;
+%! assert (issquare (s));
+%!assert (issquare ({1, 2; 3, 4}))
+%!assert (sparse (([1, 2; 3, 4])))
+
+%% Test input validation
+%!error issquare ()
+%!error issquare ([1, 2; 3, 4], 2)
+*/
+
 static octave_value
 fill_matrix (const octave_value_list& args, int val, const char *fcn)
 {
@@ -4683,7 +5052,7 @@
 @equiv{}\n\
 eye (2, 2)\n\
 @equiv{}\n\
-eye (size ([1, 2; 3, 4])\n\
+eye (size ([1, 2; 3, 4]))\n\
 @end group\n\
 @end example\n\
 \n\
@@ -5429,7 +5798,7 @@
 %!assert (norm (x,"inf"), single (7))
 %!assert (norm (x,"fro"), single (10), -eps ("single"))
 %!assert (norm (x), single (10))
-%!assert (norm (single ([1e200, 1])), single (1e200))
+%!assert (norm (single ([1e38, 1])), single (1e38))
 %!assert (norm (single ([3+4i, 3-4i, sqrt(31)])), single (9), -4*eps ("single"))
 %!shared m
 %! m = single (magic (4));
@@ -6646,7 +7015,7 @@
 #define MAKE_INT_BRANCH(X) \
         case btyp_ ## X: \
           retval = argx.X ## _array_value ().nth_element (n, dim); \
-          break
+          break;
 
         MAKE_INT_BRANCH (int8);
         MAKE_INT_BRANCH (int16);
@@ -6790,7 +7159,8 @@
 
       if (! error_state)
         {
-          octave_value vals = args(1), zero = args (2);
+          octave_value vals = args(1);
+          octave_value zero = args(2);
 
           switch (vals.builtin_type ())
             {
@@ -6817,7 +7187,7 @@
               retval = do_accumarray_minmax (idx, vals.X ## _array_value (), \
                                              n, ismin, \
                                              zero.X ## _scalar_value ()); \
-              break
+              break;
 
             MAKE_INT_BRANCH (int8);
             MAKE_INT_BRANCH (int16);
@@ -6872,7 +7242,8 @@
   else if (idx.extent (n) > n)
     error ("accumdim: index out of range");
 
-  dim_vector vals_dim = vals.dims (), rdv = vals_dim;
+  dim_vector vals_dim = vals.dims ();
+  dim_vector rdv = vals_dim;
 
   if (dim < 0)
     dim = vals.dims ().first_non_singleton ();
@@ -6951,7 +7322,8 @@
   dim_vector dv = mask.dims ();
   NDT retval (dv);
 
-  bool tscl = tval.numel () == 1, fscl = fval.numel () == 1;
+  bool tscl = tval.numel () == 1;
+  bool fscl = fval.numel () == 1;
 
   if ((! tscl && tval.dims () != dv)
       || (! fscl && fval.dims () != dv))
@@ -6961,14 +7333,16 @@
       T *rv = retval.fortran_vec ();
       octave_idx_type n = retval.numel ();
 
-      const T *tv = tval.data (), *fv = fval.data ();
+      const T *tv = tval.data ();
+      const T *fv = fval.data ();
       const bool *mv = mask.data ();
 
       if (tscl)
         {
           if (fscl)
             {
-              T ts = tv[0], fs = fv[0];
+              T ts = tv[0];
+              T fs = fv[0];
               for (octave_idx_type i = 0; i < n; i++)
                 rv[i] = mv[i] ? ts : fs;
             }
@@ -7045,7 +7419,8 @@
       else
         {
           boolNDArray mask = mask_val.bool_array_value ();
-          octave_value tval = args(1), fval = args(2);
+          octave_value tval = args(1);
+          octave_value fval = args(2);
           if (tval.is_double_type () && fval.is_double_type ())
             {
               if (tval.is_complex_type () || fval.is_complex_type ())
@@ -7323,7 +7698,8 @@
 
   assert (rep.ndims () == 2 && rep.rows () == 2);
 
-  octave_idx_type n = rep.columns (), l = 0;
+  octave_idx_type n = rep.columns ();
+  octave_idx_type l = 0;
   for (octave_idx_type i = 0; i < n; i++)
     {
       octave_idx_type k = rep(1, i);
@@ -7410,7 +7786,7 @@
 #define BTYP_BRANCH(X, EX) \
             case btyp_ ## X: \
               retval = do_repelems (x.EX ## _value (), r); \
-              break
+              break;
 
               BTYP_BRANCH (double, array);
               BTYP_BRANCH (float, float_array);
--- a/libinterp/corefcn/debug.cc	Fri Aug 01 09:06:21 2014 -0400
+++ b/libinterp/corefcn/debug.cc	Fri Aug 01 12:10:05 2014 -0400
@@ -85,7 +85,6 @@
           if (file.eof ())
             {
               // Expected to read the entire file.
-
               retval = buf;
             }
           else
@@ -99,8 +98,7 @@
 static std::deque<size_t>
 get_line_offsets (const std::string& buf)
 {
-  // This could maybe be smarter.  Is deque the right thing to use
-  // here?
+  // This could maybe be smarter.  Is deque the right thing to use here?
 
   std::deque<size_t> offsets;
 
@@ -207,28 +205,47 @@
   if (args.length () == 0)
     return;
 
-  // If we are already in a debugging function.
-  if (octave_call_stack::caller_user_code ())
-    {
-      idx = 0;
-      symbol_name = get_user_code ()->name ();
-    }
+  if (args(0).is_string ())
+  {
+    // string could be function name or line number
+    int isint = atoi (args(0).string_value ().c_str ());
+
+    if (error_state)
+      return;
+
+    if (isint == 0)
+      {
+        // It was a function name
+        symbol_name = args(0).string_value ();
+        if (error_state)
+          return;
+        idx = 1;
+      }
+    else
+      {
+        // It was a line number.  Need to get function name from debugger.
+        if (Vdebugging)
+          {
+            symbol_name = get_user_code ()->name ();
+            idx = 0;
+          }
+        else
+          {
+            error ("%s: no function specified", who);
+          }
+      }
+  }
   else if (args(0).is_map ())
     {
-      // Problem because parse_dbfunction_params() can only pass out a
-      // single function
-    }
-  else if (args(0).is_string ())
-    {
-      symbol_name = args(0).string_value ();
-      if (error_state)
-        return;
-      idx = 1;
+      // This is a problem because parse_dbfunction_params()
+      // can only pass out a single function.
+      error ("%s: struct input not implemented", who);
+      return;
     }
   else
     error ("%s: invalid parameter specified", who);
 
-  for (int i = idx; i < nargin; i++ )
+  for (int i = idx; i < nargin; i++)
     {
       if (args(i).is_string ())
         {
@@ -238,7 +255,7 @@
           lines[list_idx++] = line;
         }
       else if (args(i).is_map ())
-        octave_stdout << who << ": accepting a struct" << std::endl;
+        octave_stdout << who << ": skipping struct input" << std::endl;
       else
         {
           const NDArray arg = args(i).array_value ();
@@ -356,7 +373,6 @@
   return retval;
 }
 
-
 int
 bp_table::do_remove_breakpoint_1 (octave_user_code *fcn,
                                   const std::string& fname,
@@ -522,9 +538,12 @@
 void
 bp_table::do_remove_all_breakpoints (void)
 {
-  for (const_bp_set_iterator it = bp_set.begin (); it != bp_set.end (); it++)
-    remove_all_breakpoints_in_file (*it);
-
+  // Odd loop structure required because delete will invalidate bp_set iterators
+  for (const_bp_set_iterator it=bp_set.begin (), it_next=it; it != bp_set.end (); it=it_next)
+    {
+      ++it_next;
+      remove_all_breakpoints_in_file (*it);
+    }
 
   tree_evaluator::debug_mode = bp_table::have_breakpoints () || Vdebugging;
 }
@@ -537,7 +556,7 @@
 
   for (int i = 0; i < slist.length (); i++)
     {
-      if (slist (i).string_value () == match)
+      if (slist(i).string_value () == match)
         {
           retval = slist(i).string_value ();
           break;
@@ -547,7 +566,6 @@
   return retval;
 }
 
-
 bp_table::fname_line_map
 bp_table::do_get_breakpoint_list (const octave_value_list& fname_list)
 {
@@ -576,7 +594,7 @@
                       bp_table::intmap bkpts_vec;
 
                       for (int i = 0; i < len; i++)
-                        bkpts_vec[i] = bkpts (i).double_value ();
+                        bkpts_vec[i] = bkpts(i).double_value ();
 
                       std::string symbol_name = f->name ();
 
@@ -615,31 +633,36 @@
 
 DEFUN (dbstop, args, ,
        "-*- texinfo -*-\n\
-@deftypefn  {Built-in Function} {@var{rline} =} dbstop (\"@var{func}\")\n\
+@deftypefn  {Command} dbstop @var{func}\n\
+@deftypefnx {Command} dbstop @var{func} @var{line}\n\
+@deftypefnx {Command} dbstop @var{func} @var{line1} @var{line2} @dots{}\n\
+@deftypefnx {Command} {} dbstop @var{line} @dots{}\n\
+@deftypefnx {Built-in Function} {@var{rline} =} dbstop (\"@var{func}\")\n\
 @deftypefnx {Built-in Function} {@var{rline} =} dbstop (\"@var{func}\", @var{line})\n\
 @deftypefnx {Built-in Function} {@var{rline} =} dbstop (\"@var{func}\", @var{line1}, @var{line2}, @dots{})\n\
-Set a breakpoint in function @var{func}.\n\
+@deftypefnx {Built-in Function} {} dbstop (\"@var{func}\", [@var{line1}, @dots{}])\n\
+@deftypefnx {Built-in Function} {} dbstop (@var{line}, @dots{})\n\
+Set a breakpoint at line number @var{line} in function @var{func}.\n\
 \n\
 Arguments are\n\
 \n\
 @table @var\n\
 @item func\n\
-Function name as a string variable.  When already in debug\n\
-mode this should be left out and only the line should be given.\n\
+Function name as a string variable.  When already in debug mode this argument\n\
+can be omitted and the current function will be used.\n\
 \n\
 @item line\n\
-Line number where the breakpoint should be set.  Multiple\n\
-lines may be given as separate arguments or as a vector.\n\
+Line number where the breakpoint should be set.  Multiple lines may be given\n\
+as separate arguments or as a vector.\n\
 @end table\n\
 \n\
-When called with a single argument @var{func}, the breakpoint\n\
-is set at the first executable line in the named function.\n\
+When called with a single argument @var{func}, the breakpoint is set at the\n\
+first executable line in the named function.\n\
 \n\
-The optional output @var{rline} is the real line number where the\n\
-breakpoint was set.  This can differ from specified line if\n\
-the line is not executable.  For example, if a breakpoint attempted on a\n\
-blank line then Octave will set the real breakpoint at the\n\
-next executable line.\n\
+The optional output @var{rline} is the real line number where the breakpoint\n\
+was set.  This can differ from the specified line if the line is not\n\
+executable.  For example, if a breakpoint attempted on a blank line then\n\
+Octave will set the real breakpoint at the next executable line.\n\
 @seealso{dbclear, dbstatus, dbstep, debug_on_error, debug_on_warning, debug_on_interrupt}\n\
 @end deftypefn")
 {
@@ -660,28 +683,38 @@
 
 DEFUN (dbclear, args, ,
        "-*- texinfo -*-\n\
-@deftypefn  {Built-in Function} {} dbclear (\"@var{func}\")\n\
-@deftypefnx {Built-in Function} {} dbclear (\"@var{func}\", @var{line}, @dots{})\n\
+@deftypefn  {Command} {} dbclear @var{func}\n\
+@deftypefnx {Command} {} dbclear @var{func} @var{line}\n\
+@deftypefnx {Command} {} dbclear @var{func} @var{line1} @var{line2} @dots{}\n\
+@deftypefnx {Command} {} dbclear @var{line} @dots{}\n\
+@deftypefnx {Command} {} dbclear all\n\
+@deftypefnx {Built-in Function} {} dbclear (\"@var{func}\")\n\
+@deftypefnx {Built-in Function} {} dbclear (\"@var{func}\", @var{line})\n\
+@deftypefnx {Built-in Function} {} dbclear (\"@var{func}\", @var{line1}, @var{line2}, @dots{})\n\
+@deftypefnx {Built-in Function} {} dbclear (\"@var{func}\", [@var{line1}, @dots{}])\n\
 @deftypefnx {Built-in Function} {} dbclear (@var{line}, @dots{})\n\
-Delete a breakpoint in the function @var{func}.\n\
+@deftypefnx {Built-in Function} {} dbclear (\"all\")\n\
+Delete a breakpoint at line number @var{line} in the function @var{func}.\n\
 \n\
 Arguments are\n\
 \n\
 @table @var\n\
 @item func\n\
-Function name as a string variable.  When already in debug\n\
-mode this argument should be omitted and only the line number should be\n\
-given.\n\
+Function name as a string variable.  When already in debug mode this argument\n\
+can be omitted and the current function will be used.\n\
 \n\
 @item line\n\
-Line number from which to remove a breakpoint.  Multiple\n\
-lines may be given as separate arguments or as a vector.\n\
+Line number from which to remove a breakpoint.  Multiple lines may be given\n\
+as separate arguments or as a vector.\n\
 @end table\n\
 \n\
-When called without a line number specification all breakpoints\n\
-in the named function are cleared.\n\
+When called without a line number specification all breakpoints in the named\n\
+function are cleared.\n\
 \n\
 If the requested line is not a breakpoint no action is performed.\n\
+\n\
+The special keyword @qcode{\"all\"} will clear all breakpoints from all\n\
+files.\n\
 @seealso{dbstop, dbstatus, dbwhere}\n\
 @end deftypefn")
 {
@@ -689,10 +722,17 @@
   std::string symbol_name = "";
   bp_table::intmap lines;
 
+  int nargin = args.length (); 
+
   parse_dbfunction_params ("dbclear", args, symbol_name, lines);
 
-  if (! error_state)
-    bp_table::remove_breakpoint (symbol_name, lines);
+  if (nargin == 1 && symbol_name == "all")
+    bp_table::remove_all_breakpoints ();
+  else
+  {
+    if (! error_state)
+      bp_table::remove_breakpoint (symbol_name, lines);
+  }
 
   return retval;
 }
@@ -724,6 +764,9 @@
 A line number, or vector of line numbers, with a breakpoint.\n\
 @end table\n\
 \n\
+Note: When @code{dbstatus} is called from the debug prompt within a function,\n\
+the list of breakpoints is automatically trimmed to the breakpoints in the\n\
+current function.\n\
 @seealso{dbclear, dbwhere}\n\
 @end deftypefn")
 {
@@ -752,11 +795,14 @@
     }
   else
     {
-      octave_user_code *dbg_fcn = get_user_code ();
-      if (dbg_fcn)
+      if (Vdebugging)
         {
-          symbol_name = dbg_fcn->name ();
-          fcn_list(0) = symbol_name;
+          octave_user_code *dbg_fcn = get_user_code ();
+          if (dbg_fcn)
+            {
+              symbol_name = dbg_fcn->name ();
+              fcn_list(0) = symbol_name;
+            }
         }
 
       bp_list = bp_table::get_breakpoint_list (fcn_list);
@@ -844,7 +890,7 @@
 
       if (l > 0)
         {
-          octave_stdout << " line " << l << std::endl;
+          octave_stdout << "line " << l << std::endl;
 
           if (have_file)
             {
@@ -855,7 +901,7 @@
             }
         }
       else
-        octave_stdout << " <unknown line>" << std::endl;
+        octave_stdout << "<unknown line>" << std::endl;
     }
   else
     error ("dbwhere: must be inside a user function to use dbwhere\n");
@@ -863,8 +909,6 @@
   return retval;
 }
 
-// Copied and modified from the do_type command in help.cc
-// Maybe we could share some code?
 void
 do_dbtype (std::ostream& os, const std::string& name, int start, int end)
 {
@@ -876,30 +920,16 @@
 
       if (fs)
         {
-          char ch;
           int line = 1;
-          bool isnewline = true;
+          std::string text;  
 
-          // FIXME: Why not use line-oriented input here [getline()]?
-          while (fs.get (ch) && line <= end)
-            {
-              if (isnewline && line >= start)
-                {
-                  os << line << "\t";
-                  isnewline = false;
-                }
-
-              if (line >= start)
-                {
-                  os << ch;
-                }
-
-              if (ch == '\n')
-                {
-                  line++;
-                  isnewline = true;
-                }
-            }
+          while (std::getline (fs, text) && line <= end)
+          {
+            if (line >= start)
+              os << line << "\t" << text << "\n";
+            
+            line++;
+          }
         }
       else
         os << "dbtype: unable to open '" << ff << "' for reading!\n";
@@ -946,13 +976,14 @@
           dbg_fcn = get_user_code ();
 
           if (dbg_fcn)
-            do_dbtype (octave_stdout, dbg_fcn->name (), 0,
-                       std::numeric_limits<int>::max ());
+            do_dbtype (octave_stdout, dbg_fcn->fcn_file_name (),
+                       0, std::numeric_limits<int>::max ());
           else
             error ("dbtype: must be inside a user function to give no arguments to dbtype\n");
+
           break;
 
-        case 1: // (dbtype func) || (dbtype start:end)
+        case 1: // (dbtype start:end) || (dbtype func) || (dbtype lineno)
           {
             std::string arg = argv[1];
 
@@ -975,28 +1006,51 @@
                       end = atoi (end_str.c_str ());
 
                     if (std::min (start, end) <= 0)
-                      error ("dbtype: start and end lines must be >= 1\n");
+                      {
+                        error ("dbtype: start and end lines must be >= 1\n");
+                        break;
+                      }
 
                     if (start <= end)
-                      do_dbtype (octave_stdout, dbg_fcn->name (), start, end);
+                      do_dbtype (octave_stdout, dbg_fcn->fcn_file_name (),
+                                 start, end);
                     else
                       error ("dbtype: start line must be less than end line\n");
                   }
               }
-            else  // (dbtype func)
+            else  // (dbtype func) || (dbtype lineno)
               {
-                dbg_fcn = get_user_code (arg);
+                int line = atoi (arg.c_str ());
+
+                if (line == 0)  // (dbtype func)
+                  {
+                    dbg_fcn = get_user_code (arg);
 
-                if (dbg_fcn)
-                  do_dbtype (octave_stdout, dbg_fcn->name (), 0,
-                             std::numeric_limits<int>::max ());
-                else
-                  error ("dbtype: function <%s> not found\n", arg.c_str ());
+                    if (dbg_fcn)
+                      do_dbtype (octave_stdout, dbg_fcn->fcn_file_name (),
+                                 0, std::numeric_limits<int>::max ());
+                    else
+                      error ("dbtype: function <%s> not found\n", arg.c_str ());
+                  }
+                else  // (dbtype lineno)
+                  {
+                    if (line <= 0)
+                      {
+                        error ("dbtype: start and end lines must be >= 1\n");
+                        break;
+                      }
+
+                    dbg_fcn = get_user_code ();
+
+                    if (dbg_fcn)
+                      do_dbtype (octave_stdout, dbg_fcn->fcn_file_name (),
+                                 line, line);
+                  }
               }
           }
           break;
 
-        case 2: // (dbtype func start:end) , (dbtype func start)
+        case 2: // (dbtype func start:end) || (dbtype func start)
           dbg_fcn = get_user_code (argv[1]);
 
           if (dbg_fcn)
@@ -1023,10 +1077,14 @@
                 }
 
               if (std::min (start, end) <= 0)
-                error ("dbtype: start and end lines must be >= 1\n");
+                {
+                  error ("dbtype: start and end lines must be >= 1\n");
+                  break;
+                }
 
               if (start <= end)
-                do_dbtype (octave_stdout, dbg_fcn->name (), start, end);
+                do_dbtype (octave_stdout, dbg_fcn->fcn_file_name (),
+                           start, end);
               else
                 error ("dbtype: start line must be less than end line\n");
             }
@@ -1096,13 +1154,13 @@
             {
               int l_min = std::max (l - n/2, 0);
               int l_max = l + n/2;
-              do_dbtype (octave_stdout, dbg_fcn->name (), l_min, l-1);
+              do_dbtype (octave_stdout, name, l_min, l-1);
 
               std::string line = get_file_line (name, l);
               if (! line.empty ())
                 octave_stdout << l << "-->\t" << line << std::endl;
 
-              do_dbtype (octave_stdout, dbg_fcn->name (), l+1, l_max);
+              do_dbtype (octave_stdout, name, l+1, l_max);
             }
         }
       else
@@ -1166,10 +1224,9 @@
 
   if (! error_state)
     {
-      octave_map stk = octave_call_stack::backtrace (nskip, curr_frame);
-
       if (nargout == 0)
         {
+          octave_map stk = octave_call_stack::backtrace (nskip, curr_frame);
           octave_idx_type nframes_to_display = stk.numel ();
 
           if (nframes_to_display > 0)
@@ -1215,6 +1272,10 @@
         }
       else
         {
+          octave_map stk = octave_call_stack::backtrace (nskip,
+                                                         curr_frame,
+                                                         false);
+
           retval(1) = curr_frame < 0 ? 1 : curr_frame + 1;
           retval(0) = stk;
         }
@@ -1309,8 +1370,8 @@
 
 DEFUN (dbup, args, ,
        "-*- texinfo -*-\n\
-@deftypefn  {Built-in Function} {} dbup\n\
-@deftypefnx {Built-in Function} {} dbup (@var{n})\n\
+@deftypefn  {Command} {} dbup\n\
+@deftypefnx {Command} {} dbup @var{n}\n\
 In debugging mode, move up the execution stack @var{n} frames.\n\
 If @var{n} is omitted, move up one frame.\n\
 @seealso{dbstack, dbdown}\n\
@@ -1325,8 +1386,8 @@
 
 DEFUN (dbdown, args, ,
        "-*- texinfo -*-\n\
-@deftypefn  {Built-in Function} {} dbdown\n\
-@deftypefnx {Built-in Function} {} dbdown (@var{n})\n\
+@deftypefn  {Command} {} dbdown\n\
+@deftypefnx {Command} {} dbdown @var{n}\n\
 In debugging mode, move down the execution stack @var{n} frames.\n\
 If @var{n} is omitted, move down one frame.\n\
 @seealso{dbstack, dbup}\n\
--- a/libinterp/corefcn/display.cc	Fri Aug 01 09:06:21 2014 -0400
+++ b/libinterp/corefcn/display.cc	Fri Aug 01 12:10:05 2014 -0400
@@ -24,143 +24,28 @@
 #include <config.h>
 #endif
 
-#include <cstdlib>
-
-#if defined (OCTAVE_USE_WINDOWS_API)
-#include <windows.h>
-#elif defined (HAVE_FRAMEWORK_CARBON)
-#include <Carbon/Carbon.h>
-#elif defined (HAVE_X_WINDOWS)
-#include <X11/Xlib.h>
-#endif
-
 #include "singleton-cleanup.h"
 
+#include "cdisplay.h"
 #include "display.h"
 #include "error.h"
 
 display_info *display_info::instance = 0;
 
-#if defined (HAVE_FRAMEWORK_CARBON) && ! defined (HAVE_CARBON_CGDISPLAYBITSPERPIXEL)
-// FIXME: This will only work for MacOS > 10.5. For earlier versions
-// this code is not needed (use CGDisplayBitsPerPixel instead).
-size_t DisplayBitsPerPixel (CGDirectDisplayID display)
-{
-  CGDisplayModeRef mode = CGDisplayCopyDisplayMode (display);
-  CFStringRef pixelEncoding = CGDisplayModeCopyPixelEncoding (mode);
-
-  if (CFStringCompare (pixelEncoding, CFSTR (IO32BitDirectPixels), 0) == 0)
-    return 32;
-  else if (CFStringCompare (pixelEncoding, CFSTR (IO16BitDirectPixels), 0) == 0)
-    return 16;
-  else
-    return 8;
-}
-#endif
-
 void
 display_info::init (bool query)
 {
   if (query)
     {
-#if defined (OCTAVE_USE_WINDOWS_API)
-
-      HDC hdc = GetDC (0);
-
-      if (hdc)
-        {
-          dp = GetDeviceCaps (hdc, BITSPIXEL);
-
-          ht = GetDeviceCaps (hdc, VERTRES);
-          wd = GetDeviceCaps (hdc, HORZRES);
-
-          double ht_mm = GetDeviceCaps (hdc, VERTSIZE);
-          double wd_mm = GetDeviceCaps (hdc, HORZSIZE);
-
-          rx = wd * 25.4 / wd_mm;
-          ry = ht * 25.4 / ht_mm;
-
-          dpy_avail = true;
-        }
-      else
-        err_msg = "no graphical display found";
-
-#elif defined (HAVE_FRAMEWORK_CARBON)
+      int avail = 0;
 
-      CGDirectDisplayID display = CGMainDisplayID ();
-
-      if (display)
-        {
-#  if defined (HAVE_CARBON_CGDISPLAYBITSPERPIXEL)
-          // For MacOS < 10.7 use the line below
-          dp = CGDisplayBitsPerPixel (display);
-#  else
-          // For MacOS > 10.5 use the line below
-          dp = DisplayBitsPerPixel (display);
-#  endif
-
-          ht = CGDisplayPixelsHigh (display);
-          wd = CGDisplayPixelsWide (display);
-
-          CGSize sz_mm = CGDisplayScreenSize (display);
-          // For MacOS >= 10.6, CGSize is a struct keeping 2 CGFloat values,
-          // but the CGFloat typedef is not present on older systems,
-          // so use double instead.
-          double ht_mm = sz_mm.height;
-          double wd_mm = sz_mm.width;
-
-          rx = wd * 25.4 / wd_mm;
-          ry = ht * 25.4 / ht_mm;
+      const char *msg = octave_get_display_info (&ht, &wd, &dp, &rx, &ry,
+                                                 &avail);
 
-          dpy_avail = true;
-        }
-      else
-        err_msg = "no graphical display found";
-
-#elif defined (HAVE_X_WINDOWS)
-
-      const char *display_name = getenv ("DISPLAY");
-
-      if (display_name && *display_name)
-        {
-          Display *display = XOpenDisplay (display_name);
-
-          if (display)
-            {
-              Screen *screen = DefaultScreenOfDisplay (display);
-
-              if (screen)
-                {
-                  dp = DefaultDepthOfScreen (screen);
-
-                  ht = HeightOfScreen (screen);
-                  wd = WidthOfScreen (screen);
+      dpy_avail = avail;
 
-                  int screen_number = XScreenNumberOfScreen (screen);
-
-                  double ht_mm = DisplayHeightMM (display, screen_number);
-                  double wd_mm = DisplayWidthMM (display, screen_number);
-
-                  rx = wd * 25.4 / wd_mm;
-                  ry = ht * 25.4 / ht_mm;
-                }
-              else
-                err_msg = "X11 display has no default screen";
-
-              XCloseDisplay (display);
-
-              dpy_avail = true;
-            }
-          else
-            err_msg = "unable to open X11 DISPLAY";
-        }
-      else
-        err_msg = "X11 DISPLAY environment variable not set";
-#else
-
-      err_msg = "no graphical display found";
-
-#endif
+      if (msg)
+        err_msg = msg;
     }
 }
 
--- a/libinterp/corefcn/dlmread.cc	Fri Aug 01 09:06:21 2014 -0400
+++ b/libinterp/corefcn/dlmread.cc	Fri Aug 01 12:10:05 2014 -0400
@@ -264,12 +264,15 @@
     }
 
   // Take a subset if a range was given.
-  octave_idx_type r0 = 0, c0 = 0, r1 = idx_max-1, c1 = idx_max-1;
+  octave_idx_type r0 = 0;
+  octave_idx_type c0 = 0;
+  octave_idx_type r1 = idx_max-1;
+  octave_idx_type c1 = idx_max-1;
   if (nargin > 2)
     {
       if (nargin == 3)
         {
-          if (!parse_range_spec (args (2), r0, c0, r1, c1))
+          if (!parse_range_spec (args(2), r0, c0, r1, c1))
             error ("dlmread: error parsing RANGE");
         }
       else if (nargin == 4)
@@ -287,7 +290,12 @@
 
   if (!error_state)
     {
-      octave_idx_type i = 0, j = 0, r = 1, c = 1, rmax = 0, cmax = 0;
+      octave_idx_type i = 0;
+      octave_idx_type j = 0;
+      octave_idx_type r = 1;
+      octave_idx_type c = 1;
+      octave_idx_type rmax = 0;
+      octave_idx_type cmax = 0;
 
       Matrix rdata;
       ComplexMatrix cdata;
--- a/libinterp/corefcn/dot.cc	Fri Aug 01 09:06:21 2014 -0400
+++ b/libinterp/corefcn/dot.cc	Fri Aug 01 12:10:05 2014 -0400
@@ -128,11 +128,13 @@
       return retval;
     }
 
-  octave_value argx = args(0), argy = args(1);
+  octave_value argx = args(0);
+  octave_value argy = args(1);
 
   if (argx.is_numeric_type () && argy.is_numeric_type ())
     {
-      dim_vector dimx = argx.dims (), dimy = argy.dims ();
+      dim_vector dimx = argx.dims ();
+      dim_vector dimy = argy.dims ();
       bool match = dimx == dimy;
       if (! match && nargin == 2
           && dimx.is_vector () && dimy.is_vector ())
@@ -301,13 +303,18 @@
       return retval;
     }
 
-  octave_value argx = args(0), argy = args(1);
+  octave_value argx = args(0);
+  octave_value argy = args(1);
 
   if (argx.is_numeric_type () && argy.is_numeric_type ())
     {
-      const dim_vector dimx = argx.dims (), dimy = argy.dims ();
+      const dim_vector dimx = argx.dims ();
+      const dim_vector dimy = argy.dims ();
       int nd = dimx.length ();
-      octave_idx_type m = dimx(0), k = dimx(1), n = dimy(1), np = 1;
+      octave_idx_type m = dimx(0);
+      octave_idx_type k = dimx(1);
+      octave_idx_type n = dimy(1);
+      octave_idx_type np = 1;
       bool match = dimy(0) == k && nd == dimy.length ();
       dim_vector dimz = dim_vector::alloc (nd);
       dimz(0) = m;
--- a/libinterp/corefcn/eig.cc	Fri Aug 01 09:06:21 2014 -0400
+++ b/libinterp/corefcn/eig.cc	Fri Aug 01 12:10:05 2014 -0400
@@ -62,8 +62,8 @@
 
   octave_value arg_a, arg_b;
 
-  octave_idx_type nr_a = 0, nr_b = 0;
-  octave_idx_type nc_a = 0, nc_b = 0;
+  octave_idx_type nr_a, nr_b, nc_a, nc_b;
+  nr_a = nr_b = nc_a = nc_b = 0;
 
   arg_a = args(0);
   nr_a = arg_a.rows ();
--- a/libinterp/corefcn/error.cc	Fri Aug 01 09:06:21 2014 -0400
+++ b/libinterp/corefcn/error.cc	Fri Aug 01 12:10:05 2014 -0400
@@ -40,6 +40,7 @@
 #include "utils.h"
 #include "ov.h"
 #include "ov-usr-fcn.h"
+#include "pt-eval.h"
 #include "pt-pr-code.h"
 #include "pt-stmt.h"
 #include "toplev.h"
@@ -66,8 +67,7 @@
 // TRUE means that Octave will print a verbose warning.  Currently unused.
 static bool Vverbose_warning;
 
-// TRUE means that Octave will print no warnings, but lastwarn will be
-//updated
+// TRUE means that Octave will print no warnings, but lastwarn will be updated
 static bool Vquiet_warning = false;
 
 // A structure containing (most of) the current state of warnings.
@@ -469,6 +469,10 @@
 
       pr_where ("error");
 
+      tree_evaluator::debug_mode = true;
+
+      tree_evaluator::current_frame = octave_call_stack::current_frame ();
+
       do_keyboard (octave_value_list ());
     }
 }
@@ -657,6 +661,10 @@
           frame.protect_var (Vdebug_on_warning);
           Vdebug_on_warning = false;
 
+          tree_evaluator::debug_mode = true;
+
+          tree_evaluator::current_frame = octave_call_stack::current_frame ();
+
           do_keyboard (octave_value_list ());
         }
     }
--- a/libinterp/corefcn/file-io.cc	Fri Aug 01 09:06:21 2014 -0400
+++ b/libinterp/corefcn/file-io.cc	Fri Aug 01 12:10:05 2014 -0400
@@ -271,7 +271,7 @@
 
   if (nargin == 1)
     {
-      int fid = octave_stream_list::get_file_number (args (0));
+      int fid = octave_stream_list::get_file_number (args(0));
 
       octave_stream os = octave_stream_list::lookup (fid, "fclear");
 
@@ -305,7 +305,7 @@
     {
       // FIXME: any way to avoid special case for stdout?
 
-      int fid = octave_stream_list::get_file_number (args (0));
+      int fid = octave_stream_list::get_file_number (args(0));
 
       if (fid == 1)
         {
@@ -1338,7 +1338,7 @@
 
   tmp_args (0) = 0.0;
   for (int i = 0; i < nargin; i++)
-    tmp_args (i+1) = args (i);
+    tmp_args(i+1) = args(i);
 
   return Ffscanf (tmp_args, nargout);
 }
@@ -1404,9 +1404,13 @@
 
 DEFUN (fread, args, ,
        "-*- texinfo -*-\n\
-@deftypefn {Built-in Function} {[@var{val}, @var{count}] =} fread (@var{fid}, @var{size}, @var{precision}, @var{skip}, @var{arch})\n\
-Read binary data of type @var{precision} from the specified file ID\n\
-@var{fid}.\n\
+@deftypefn  {Built-in Function} {@var{val} =} fread (@var{fid})\n\
+@deftypefnx {Built-in Function} {@var{val} =} fread (@var{fid}, @var{size})\n\
+@deftypefnx {Built-in Function} {@var{val} =} fread (@var{fid}, @var{size}, @var{precision})\n\
+@deftypefnx {Built-in Function} {@var{val} =} fread (@var{fid}, @var{size}, @var{precision}, @var{skip})\n\
+@deftypefnx {Built-in Function} {@var{val} =} fread (@var{fid}, @var{size}, @var{precision}, @var{skip}, @var{arch})\n\
+@deftypefnx {Built-in Function} {[@var{val}, @var{count}] =} fread (@dots{})\n\
+Read binary data from the specified file ID @var{fid}.\n\
 \n\
 The optional argument @var{size} specifies the amount of data to read\n\
 and may be one of\n\
@@ -1559,8 +1563,8 @@
 IEEE little endian.\n\
 @end table\n\
 \n\
-The data read from the file is returned in @var{val}, and the number of\n\
-values read is returned in @code{count}\n\
+The output argument @var{val} contains the data read from the file.\n\
+The optional return value @var{count} contains the number of elements read.\n\
 @seealso{fwrite, fgets, fgetl, fscanf, fopen}\n\
 @end deftypefn")
 {
@@ -1833,6 +1837,7 @@
    @print{} drwxrwxrwt  15 root  root  2048 Feb 17 14:53 tmp\n\
 @end group\n\
 @end example\n\
+@seealso{popen2}\n\
 @end deftypefn")
 {
   octave_value retval = -1;
--- a/libinterp/corefcn/filter.cc	Fri Aug 01 09:06:21 2014 -0400
+++ b/libinterp/corefcn/filter.cc	Fri Aug 01 12:10:05 2014 -0400
@@ -77,7 +77,7 @@
 
   if (norm == static_cast<T>(0.0))
     {
-      error ("filter: the first element of A must be non-zero");
+      error ("filter: the first element of A must be nonzero");
       return y;
     }
 
--- a/libinterp/corefcn/find.cc	Fri Aug 01 09:06:21 2014 -0400
+++ b/libinterp/corefcn/find.cc	Fri Aug 01 12:10:05 2014 -0400
@@ -61,7 +61,8 @@
     case 2:
       {
         Array<octave_idx_type> jdx (idx.dims ());
-        octave_idx_type n = idx.length (), nr = nda.rows ();
+        octave_idx_type n = idx.length ();
+        octave_idx_type nr = nda.rows ();
         for (octave_idx_type i = 0; i < n; i++)
           {
             jdx.xelem (i) = idx.xelem (i) / nr;
@@ -165,7 +166,7 @@
       // Search for elements to return.  Only search the region where there
       // are elements to be found using the count that we want to find.
       for (octave_idx_type j = start_nc, cx = 0; j < end_nc; j++)
-        for (octave_idx_type i = v.cidx (j); i < v.cidx (j+1); i++ )
+        for (octave_idx_type i = v.cidx (j); i < v.cidx (j+1); i++)
           {
             OCTAVE_QUIT;
             if (direction < 0 && i < nz - count)
@@ -241,7 +242,6 @@
   if (n_to_find < 0 || n_to_find >= nc)
     {
       start_nc = 0;
-      n_to_find = nc;
       count = nc;
     }
   else if (direction > 0)
@@ -263,33 +263,15 @@
 
   if (count > 0)
     {
-      const octave_idx_type* p = v.data ();
-      if (v.is_col_perm ())
+      const Array<octave_idx_type>& p = v.col_perm_vec ();
+      for (octave_idx_type k = 0; k < count; k++)
         {
-          for (octave_idx_type k = 0; k < count; k++)
-            {
-              OCTAVE_QUIT;
-              const octave_idx_type j = start_nc + k;
-              const octave_idx_type i = p[j];
-              i_idx(k) = static_cast<double> (1+i);
-              j_idx(k) = static_cast<double> (1+j);
-              idx(k) = j * nc + i + 1;
-            }
-        }
-      else
-        {
-          for (octave_idx_type k = 0; k < count; k++)
-            {
-              OCTAVE_QUIT;
-              const octave_idx_type i = start_nc + k;
-              const octave_idx_type j = p[i];
-              // Scatter into the index arrays according to
-              // j adjusted by the start point.
-              const octave_idx_type koff = j - start_nc;
-              i_idx(koff) = static_cast<double> (1+i);
-              j_idx(koff) = static_cast<double> (1+j);
-              idx(koff) = j * nc + i + 1;
-            }
+          OCTAVE_QUIT;
+          const octave_idx_type j = start_nc + k;
+          const octave_idx_type i = p(j);
+          i_idx(k) = static_cast<double> (1+i);
+          j_idx(k) = static_cast<double> (1+j);
+          idx(k) = j * nc + i + 1;
         }
     }
   else
@@ -394,7 +376,7 @@
 ascending order.\n\
 \n\
 Note that this function is particularly useful for sparse matrices, as\n\
-it extracts the non-zero elements as vectors, which can then be used to\n\
+it extracts the nonzero elements as vectors, which can then be used to\n\
 create the original matrix.  For example:\n\
 \n\
 @example\n\
--- a/libinterp/corefcn/gcd.cc	Fri Aug 01 09:06:21 2014 -0400
+++ b/libinterp/corefcn/gcd.cc	Fri Aug 01 12:10:05 2014 -0400
@@ -125,8 +125,9 @@
   double aa = fabs (a);
   double bb = fabs (b);
 
-  double xx = 0, yy = 1;
-  double lx = 1, ly = 0;
+  double xx, lx, yy, ly;
+  xx = 0, lx = 1;
+  yy = 1, ly = 0;
 
   while (bb != 0)
     {
@@ -161,7 +162,8 @@
     (*current_liboctave_error_handler)
       ("gcd: all complex parts must be integers");
 
-  std::complex<FP> aa = a, bb = b;
+  std::complex<FP> aa = a;
+  std::complex<FP> bb = b;
   bool swapped = false;
   if (abs (aa) < abs (bb))
     {
@@ -169,8 +171,9 @@
       swapped = true;
     }
 
-  std::complex<FP> xx = 0, lx = 1;
-  std::complex<FP> yy = 1, ly = 0;
+  std::complex<FP> xx, lx, yy, ly;
+  xx = 0, lx = 1;
+  yy = 1, ly = 0;
 
   while (abs(bb) != 0)
     {
@@ -204,8 +207,9 @@
 {
   T aa = a.abs ().value ();
   T bb = b.abs ().value ();
-  T xx = 0, lx = 1;
-  T yy = 1, ly = 0;
+  T xx, lx, yy, ly;
+  xx = 0, lx = 1;
+  yy = 1, ly = 0;
 
   while (bb != 0)
     {
@@ -347,7 +351,8 @@
       bool incb = bb.numel () != 1;
 
       T *gptr = gg.fortran_vec ();
-      T *xptr = xx.fortran_vec (), *yptr = yy.fortran_vec ();
+      T *xptr = xx.fortran_vec ();
+      T *yptr = yy.fortran_vec ();
 
       octave_idx_type n = gg.numel ();
       for (octave_idx_type i = 0; i < n; i++)
--- a/libinterp/corefcn/gl-render.cc	Fri Aug 01 09:06:21 2014 -0400
+++ b/libinterp/corefcn/gl-render.cc	Fri Aug 01 12:10:05 2014 -0400
@@ -37,6 +37,28 @@
 
 #define LIGHT_MODE GL_FRONT_AND_BACK
 
+// Use symbolic names for axes
+enum {
+  X_AXIS,
+  Y_AXIS,
+  Z_AXIS
+};
+
+// Use symbolic names for color mode
+enum {
+  UNIFORM,
+  FLAT,
+  INTERP,
+  TEXTURE
+};
+
+// Use symbolic names for lighting
+enum {
+  NONE,
+  //FLAT,  // Already declared in anonymous enum for color mode
+  GOURAUD = 2
+};
+
 // Win32 API requires the CALLBACK attributes for
 // GLU callback functions. Define it to empty on
 // other platforms.
@@ -147,7 +169,8 @@
     {
       // FIXME: dim_vectors hold octave_idx_type values.
       //        Should we check for dimensions larger than intmax?
-      int h = dv(0), w = dv(1), tw, th;
+      int h, w, tw, th;
+      h = dv(0), w = dv(1);
       GLuint id;
       bool ok = true;
 
@@ -400,7 +423,7 @@
 opengl_renderer::patch_tesselator : public opengl_tesselator
 {
 public:
-  patch_tesselator (opengl_renderer *r, int cmode, int lmode, int idx = 0)
+  patch_tesselator (opengl_renderer *r, int cmode, int lmode, float idx = 0.0)
     : opengl_tesselator (), renderer (r),
       color_mode (cmode), light_mode (lmode), index (idx),
       first (true), tmp_vdata ()
@@ -412,13 +435,13 @@
     //printf ("patch_tesselator::begin (%d)\n", type);
     first = true;
 
-    if (color_mode == 2 || light_mode == 2)
+    if (color_mode == INTERP || light_mode == GOURAUD)
       glShadeModel (GL_SMOOTH);
     else
       glShadeModel (GL_FLAT);
 
     if (is_filled ())
-      renderer->set_polygon_offset (true, 1+index);
+      renderer->set_polygon_offset (true, index);
 
     glBegin (type);
   }
@@ -436,12 +459,10 @@
       = reinterpret_cast<vertex_data::vertex_data_rep *> (data);
     //printf ("patch_tesselator::vertex (%g, %g, %g)\n", v->coords(0), v->coords(1), v->coords(2));
 
-    // FIXME: why did I need to keep the first vertex of the face
-    // in JHandles? I think it's related to the fact that the
-    // tessellation process might re-order the vertices, such that
-    // the first one you get here might not be the first one of the face;
-    // but I can't figure out the actual reason.
-    if (color_mode > 0 && (first || color_mode == 2))
+    // NOTE: OpenGL can re-order vertices.  For "flat" coloring of FaceColor
+    // the first vertex must be identified in the draw_patch routine.
+
+    if (color_mode == INTERP || (color_mode == FLAT && ! is_filled ()))
       {
         Matrix col = v->color;
 
@@ -458,12 +479,12 @@
 
                 for (int k = 0; k < 3; k++)
                   buf[k] = (v->diffuse * col(k));
-                glMaterialfv (LIGHT_MODE, GL_AMBIENT, buf);
+                glMaterialfv (LIGHT_MODE, GL_DIFFUSE, buf);
               }
           }
       }
 
-    if (light_mode > 0 && (first || light_mode == 2))
+    if (light_mode > 0 && (first || light_mode == GOURAUD))
       glNormal3dv (v->normal.data ());
 
     glVertex3dv (v->coords.data ());
@@ -471,8 +492,7 @@
     first = false;
   }
 
-  void combine (GLdouble xyz[3], void *data[4], GLfloat w[4],
-                void **out_data)
+  void combine (GLdouble xyz[3], void *data[4], GLfloat w[4], void **out_data)
   {
     //printf ("patch_tesselator::combine\n");
 
@@ -530,8 +550,8 @@
   patch_tesselator& operator = (const patch_tesselator&);
 
   opengl_renderer *renderer;
-  int color_mode;       // 0: uni,  1: flat, 2: interp
-  int light_mode;       // 0: none, 1: flat, 2: gouraud
+  int color_mode;
+  int light_mode;
   int index;
   bool first;
   std::list<vertex_data> tmp_vdata;
@@ -624,7 +644,17 @@
   if (enhanced)
     {
       glEnable (GL_BLEND);
-      glEnable (GL_LINE_SMOOTH);
+      glEnable (GL_MULTISAMPLE);
+      GLint iMultiSample, iNumSamples;
+      glGetIntegerv (GL_SAMPLE_BUFFERS, &iMultiSample);
+      glGetIntegerv (GL_SAMPLES, &iNumSamples);
+      if (iMultiSample != GL_TRUE || iNumSamples == 0)
+        {
+          // MultiSample not implemented.  Use old-style anti-aliasing
+          glDisable (GL_MULTISAMPLE);
+          glEnable (GL_LINE_SMOOTH);
+          glHint (GL_LINE_SMOOTH_HINT, GL_NICEST);
+        }
     }
   else
     {
@@ -654,7 +684,7 @@
       double val = ticks(i);
       if (lim1 <= val && val <= lim2)
         {
-          if (xyz == 0) // X
+          if (xyz == X_AXIS)
             {
               glVertex3d (val, p1N, p2);
               glVertex3d (val, p1, p2);
@@ -664,7 +694,7 @@
                   glVertex3d (val, p1, p2);
                 }
             }
-          else if (xyz == 1) // Y
+          else if (xyz == Y_AXIS)
             {
               glVertex3d (p1N, val, p2);
               glVertex3d (p1, val, p2);
@@ -674,7 +704,7 @@
                   glVertex3d (p1, val, p2);
                 }
             }
-          else if (xyz == 2) // Z
+          else if (xyz == Z_AXIS)
             {
               glVertex3d (p1N, p2, val);
               glVertex3d (p1, p2, val);
@@ -703,7 +733,7 @@
 
       if (lim1 <= val && val <= lim2)
         {
-          if (xyz == 0) // X
+          if (xyz == X_AXIS)
             {
               glVertex3d (val, p1, p2);
               glVertex3d (val, p1+dy, p2+dz);
@@ -713,7 +743,7 @@
                   glVertex3d (val, p1N-dy, p2N-dz);
                 }
             }
-          else if (xyz == 1) // Y
+          else if (xyz == Y_AXIS)
             {
               glVertex3d (p1, val, p2);
               glVertex3d (p1+dx, val, p2+dz);
@@ -723,7 +753,7 @@
                   glVertex3d (p1N-dx, val, p2N-dz);
                 }
             }
-          else if (xyz == 2) // Z
+          else if (xyz == Z_AXIS)
             {
               glVertex3d (p1, p2, val);
               glVertex3d (p1+dx, p2+dy, val);
@@ -765,17 +795,17 @@
           label.erase (0, label.find_first_not_of (" "));
           label = label.substr (0, label.find_last_not_of (" ")+1);
 
-          // FIXME: as tick text is transparent, shouldn't it be
+          // FIXME: As tick text is transparent, shouldn't it be
           //        drawn after axes object, for correct rendering?
-          if (xyz == 0) // X
+          if (xyz == X_AXIS)
             {
               b = render_text (label, val, p1, p2, ha, va);
             }
-          else if (xyz == 1) // Y
+          else if (xyz == Y_AXIS)
             {
               b = render_text (label, p1, val, p2, ha, va);
             }
-          else if (xyz == 2) // Z
+          else if (xyz == Z_AXIS)
             {
               b = render_text (label, p1, p2, val, ha, va);
             }
@@ -819,8 +849,6 @@
 
   glClear (GL_DEPTH_BUFFER_BIT);
 
-  glDisable (GL_LINE_SMOOTH);
-
   // store axes transformation data
 
   xform = props.get_transform ();
@@ -829,6 +857,10 @@
 void
 opengl_renderer::draw_axes_planes (const axes::properties& props)
 {
+  Matrix axe_color = props.get_color_rgb ();
+  if (axe_color.numel () == 0 || ! props.is_visible ())
+    return;
+
   double xPlane = props.get_xPlane ();
   double yPlane = props.get_yPlane ();
   double zPlane = props.get_zPlane ();
@@ -837,42 +869,43 @@
   double zPlaneN = props.get_zPlaneN ();
 
   // Axes planes
-  Matrix axe_color = props.get_color_rgb ();
-  if (axe_color.numel () > 0 && props.is_visible ())
-    {
-      set_color (axe_color);
-      set_polygon_offset (true, 2.5);
-
-      glBegin (GL_QUADS);
-
-      // X plane
-      glVertex3d (xPlane, yPlaneN, zPlaneN);
-      glVertex3d (xPlane, yPlane, zPlaneN);
-      glVertex3d (xPlane, yPlane, zPlane);
-      glVertex3d (xPlane, yPlaneN, zPlane);
-
-      // Y plane
-      glVertex3d (xPlaneN, yPlane, zPlaneN);
-      glVertex3d (xPlane, yPlane, zPlaneN);
-      glVertex3d (xPlane, yPlane, zPlane);
-      glVertex3d (xPlaneN, yPlane, zPlane);
-
-      // Z plane
-      glVertex3d (xPlaneN, yPlaneN, zPlane);
-      glVertex3d (xPlane, yPlaneN, zPlane);
-      glVertex3d (xPlane, yPlane, zPlane);
-      glVertex3d (xPlaneN, yPlane, zPlane);
-
-      glEnd ();
-
-      set_polygon_offset (false);
-    }
+  set_color (axe_color);
+  set_polygon_offset (true, 2.5);
+
+  glBegin (GL_QUADS);
+
+  // X plane
+  glVertex3d (xPlane, yPlaneN, zPlaneN);
+  glVertex3d (xPlane, yPlane, zPlaneN);
+  glVertex3d (xPlane, yPlane, zPlane);
+  glVertex3d (xPlane, yPlaneN, zPlane);
+
+  // Y plane
+  glVertex3d (xPlaneN, yPlane, zPlaneN);
+  glVertex3d (xPlane, yPlane, zPlaneN);
+  glVertex3d (xPlane, yPlane, zPlane);
+  glVertex3d (xPlaneN, yPlane, zPlane);
+
+  // Z plane
+  glVertex3d (xPlaneN, yPlaneN, zPlane);
+  glVertex3d (xPlane, yPlaneN, zPlane);
+  glVertex3d (xPlane, yPlane, zPlane);
+  glVertex3d (xPlaneN, yPlane, zPlane);
+
+  glEnd ();
+
+  set_polygon_offset (false);
 }
 
 void
 opengl_renderer::draw_axes_boxes (const axes::properties& props)
 {
+  if (! props.is_visible ())
+    return;
+
   bool xySym = props.get_xySym ();
+  bool layer2Dtop = props.get_layer2Dtop ();
+  bool is2d = props.get_is2D ();
   double xPlane = props.get_xPlane ();
   double yPlane = props.get_yPlane ();
   double zPlane = props.get_zPlane ();
@@ -893,106 +926,114 @@
   set_linestyle ("-", true);
   set_linewidth (props.get_linewidth ());
 
-  if (props.is_visible ())
+  glBegin (GL_LINES);
+
+  if (layer2Dtop)
+    std::swap (zpTick, zpTickN);
+
+  // X box
+  set_color (props.get_xcolor_rgb ());
+  glVertex3d (xPlaneN, ypTick, zpTick);
+  glVertex3d (xPlane, ypTick, zpTick);
+
+  if (props.is_box ())
     {
-      glBegin (GL_LINES);
-
-      // X box
-      set_color (props.get_xcolor_rgb ());
-      glVertex3d (xPlaneN, ypTick, zpTick);
-      glVertex3d (xPlane, ypTick, zpTick);
-
-      if (props.is_box ())
+      glVertex3d (xPlaneN, ypTickN, zpTick);
+      glVertex3d (xPlane, ypTickN, zpTick);
+      if (! is2d)
         {
-          glVertex3d (xPlaneN, ypTickN, zpTick);
-          glVertex3d (xPlane, ypTickN, zpTick);
           glVertex3d (xPlaneN, ypTickN, zpTickN);
           glVertex3d (xPlane, ypTickN, zpTickN);
           glVertex3d (xPlaneN, ypTick, zpTickN);
           glVertex3d (xPlane, ypTick, zpTickN);
         }
-
-      // Y box
-      set_color (props.get_ycolor_rgb ());
-      glVertex3d (xpTick, yPlaneN, zpTick);
-      glVertex3d (xpTick, yPlane, zpTick);
-
-      if (props.is_box () && ! plotyy)
+    }
+
+  // Y box
+  set_color (props.get_ycolor_rgb ());
+  glVertex3d (xpTick, yPlaneN, zpTick);
+  glVertex3d (xpTick, yPlane, zpTick);
+
+  if (props.is_box () && ! plotyy)
+    {
+      glVertex3d (xpTickN, yPlaneN, zpTick);
+      glVertex3d (xpTickN, yPlane, zpTick);
+
+      if (! is2d)
         {
-          glVertex3d (xpTickN, yPlaneN, zpTick);
-          glVertex3d (xpTickN, yPlane, zpTick);
           glVertex3d (xpTickN, yPlaneN, zpTickN);
           glVertex3d (xpTickN, yPlane, zpTickN);
           glVertex3d (xpTick, yPlaneN, zpTickN);
           glVertex3d (xpTick, yPlane, zpTickN);
         }
-
-      // Z box
-      set_color (props.get_zcolor_rgb ());
+    }
+
+  // Z box
+  set_color (props.get_zcolor_rgb ());
+
+  if (xySym)
+    {
+      glVertex3d (xPlaneN, yPlane, zPlaneN);
+      glVertex3d (xPlaneN, yPlane, zPlane);
+    }
+  else
+    {
+      glVertex3d (xPlane, yPlaneN, zPlaneN);
+      glVertex3d (xPlane, yPlaneN, zPlane);
+    }
+
+  if (props.is_box ())
+    {
+      glVertex3d (xPlane, yPlane, zPlaneN);
+      glVertex3d (xPlane, yPlane, zPlane);
 
       if (xySym)
         {
-          glVertex3d (xPlaneN, yPlane, zPlaneN);
-          glVertex3d (xPlaneN, yPlane, zPlane);
-        }
-      else
-        {
           glVertex3d (xPlane, yPlaneN, zPlaneN);
           glVertex3d (xPlane, yPlaneN, zPlane);
         }
-
-      if (props.is_box ())
+      else
         {
-          glVertex3d (xPlane, yPlane, zPlaneN);
-          glVertex3d (xPlane, yPlane, zPlane);
-
-          if (xySym)
-            {
-              glVertex3d (xPlane, yPlaneN, zPlaneN);
-              glVertex3d (xPlane, yPlaneN, zPlane);
-            }
-          else
-            {
-              glVertex3d (xPlaneN, yPlane, zPlaneN);
-              glVertex3d (xPlaneN, yPlane, zPlane);
-            }
-
-          glVertex3d (xPlaneN, yPlaneN, zPlaneN);
-          glVertex3d (xPlaneN, yPlaneN, zPlane);
+          glVertex3d (xPlaneN, yPlane, zPlaneN);
+          glVertex3d (xPlaneN, yPlane, zPlane);
         }
 
-      glEnd ();
+      glVertex3d (xPlaneN, yPlaneN, zPlaneN);
+      glVertex3d (xPlaneN, yPlaneN, zPlane);
     }
+
+  glEnd ();
 }
 
 void
 opengl_renderer::draw_axes_x_grid (const axes::properties& props)
 {
   int xstate = props.get_xstate ();
-  int zstate = props.get_zstate ();
-  bool x2Dtop = props.get_x2Dtop ();
-  bool layer2Dtop = props.get_layer2Dtop ();
-  bool xyzSym = props.get_xyzSym ();
-  bool nearhoriz = props.get_nearhoriz ();
-  double xticklen = props.get_xticklen ();
-  double xtickoffset = props.get_xtickoffset ();
-  double fy = props.get_fy ();
-  double fz = props.get_fz ();
-  double x_min = props.get_x_min ();
-  double x_max = props.get_x_max ();
-  double yPlane = props.get_yPlane ();
-  double yPlaneN = props.get_yPlaneN ();
-  double ypTick = props.get_ypTick ();
-  double ypTickN = props.get_ypTickN ();
-  double zPlane = props.get_zPlane ();
-  double zPlaneN = props.get_zPlaneN ();
-  double zpTick = props.get_zpTick ();
-  double zpTickN = props.get_zpTickN ();
-
-  // X grid
 
   if (props.is_visible () && xstate != AXE_DEPTH_DIR)
     {
+      int zstate = props.get_zstate ();
+      bool x2Dtop = props.get_x2Dtop ();
+      bool layer2Dtop = props.get_layer2Dtop ();
+      bool xyzSym = props.get_xyzSym ();
+      bool nearhoriz = props.get_nearhoriz ();
+      double xticklen = props.get_xticklen ();
+      double xtickoffset = props.get_xtickoffset ();
+      double fy = props.get_fy ();
+      double fz = props.get_fz ();
+      double x_min = props.get_x_min ();
+      double x_max = props.get_x_max ();
+      double yPlane = props.get_yPlane ();
+      double yPlaneN = props.get_yPlaneN ();
+      double ypTick = props.get_ypTick ();
+      double ypTickN = props.get_ypTickN ();
+      double zPlane = props.get_zPlane ();
+      double zPlaneN = props.get_zPlaneN ();
+      double zpTick = props.get_zpTick ();
+      double zpTickN = props.get_zpTickN ();
+
+      // X grid
+
       std::string gridstyle = props.get_gridlinestyle ();
       std::string minorgridstyle = props.get_minorgridlinestyle ();
       bool do_xgrid = (props.is_xgrid () && (gridstyle != "none"));
@@ -1002,7 +1043,8 @@
       Matrix xticks = xform.xscale (props.get_xtick ().matrix_value ());
       Matrix xmticks = xform.xscale (props.get_xmtick ().matrix_value ());
       string_vector xticklabels = props.get_xticklabel ().all_strings ();
-      int wmax = 0, hmax = 0;
+      int wmax = 0;
+      int hmax = 0;
       bool tick_along_z = nearhoriz || xisinf (fy);
       bool mirror = props.is_box () && xstate != AXE_ANY_DIR;
 
@@ -1077,30 +1119,31 @@
 opengl_renderer::draw_axes_y_grid (const axes::properties& props)
 {
   int ystate = props.get_ystate ();
-  int zstate = props.get_zstate ();
-  bool y2Dright = props.get_y2Dright ();
-  bool layer2Dtop = props.get_layer2Dtop ();
-  bool xyzSym = props.get_xyzSym ();
-  bool nearhoriz = props.get_nearhoriz ();
-  double yticklen = props.get_yticklen ();
-  double ytickoffset = props.get_ytickoffset ();
-  double fx = props.get_fx ();
-  double fz = props.get_fz ();
-  double xPlane = props.get_xPlane ();
-  double xPlaneN = props.get_xPlaneN ();
-  double xpTick = props.get_xpTick ();
-  double xpTickN = props.get_xpTickN ();
-  double y_min = props.get_y_min ();
-  double y_max = props.get_y_max ();
-  double zPlane = props.get_zPlane ();
-  double zPlaneN = props.get_zPlaneN ();
-  double zpTick = props.get_zpTick ();
-  double zpTickN = props.get_zpTickN ();
-
-  // Y grid
 
   if (ystate != AXE_DEPTH_DIR && props.is_visible ())
     {
+      int zstate = props.get_zstate ();
+      bool y2Dright = props.get_y2Dright ();
+      bool layer2Dtop = props.get_layer2Dtop ();
+      bool xyzSym = props.get_xyzSym ();
+      bool nearhoriz = props.get_nearhoriz ();
+      double yticklen = props.get_yticklen ();
+      double ytickoffset = props.get_ytickoffset ();
+      double fx = props.get_fx ();
+      double fz = props.get_fz ();
+      double xPlane = props.get_xPlane ();
+      double xPlaneN = props.get_xPlaneN ();
+      double xpTick = props.get_xpTick ();
+      double xpTickN = props.get_xpTickN ();
+      double y_min = props.get_y_min ();
+      double y_max = props.get_y_max ();
+      double zPlane = props.get_zPlane ();
+      double zPlaneN = props.get_zPlaneN ();
+      double zpTick = props.get_zpTick ();
+      double zpTickN = props.get_zpTickN ();
+
+      // Y grid
+
       std::string gridstyle = props.get_gridlinestyle ();
       std::string minorgridstyle = props.get_minorgridlinestyle ();
       bool do_ygrid = (props.is_ygrid () && (gridstyle != "none"));
@@ -1110,7 +1153,8 @@
       Matrix yticks = xform.yscale (props.get_ytick ().matrix_value ());
       Matrix ymticks = xform.yscale (props.get_ymtick ().matrix_value ());
       string_vector yticklabels = props.get_yticklabel ().all_strings ();
-      int wmax = 0, hmax = 0;
+      int wmax = 0;
+      int hmax = 0;
       bool tick_along_z = nearhoriz || xisinf (fx);
       bool mirror = props.is_box () && ystate != AXE_ANY_DIR
                     && (! props.has_property ("__plotyy_axes__"));
@@ -1183,23 +1227,24 @@
 opengl_renderer::draw_axes_z_grid (const axes::properties& props)
 {
   int zstate = props.get_zstate ();
-  bool xySym = props.get_xySym ();
-  bool zSign = props.get_zSign ();
-  double zticklen = props.get_zticklen ();
-  double ztickoffset = props.get_ztickoffset ();
-  double fx = props.get_fx ();
-  double fy = props.get_fy ();
-  double xPlane = props.get_xPlane ();
-  double xPlaneN = props.get_xPlaneN ();
-  double yPlane = props.get_yPlane ();
-  double yPlaneN = props.get_yPlaneN ();
-  double z_min = props.get_z_min ();
-  double z_max = props.get_z_max ();
-
-  // Z Grid
 
   if (zstate != AXE_DEPTH_DIR && props.is_visible ())
     {
+      bool xySym = props.get_xySym ();
+      bool zSign = props.get_zSign ();
+      double zticklen = props.get_zticklen ();
+      double ztickoffset = props.get_ztickoffset ();
+      double fx = props.get_fx ();
+      double fy = props.get_fy ();
+      double xPlane = props.get_xPlane ();
+      double xPlaneN = props.get_xPlaneN ();
+      double yPlane = props.get_yPlane ();
+      double yPlaneN = props.get_yPlaneN ();
+      double z_min = props.get_z_min ();
+      double z_max = props.get_z_max ();
+
+      // Z Grid
+
       std::string gridstyle = props.get_gridlinestyle ();
       std::string minorgridstyle = props.get_minorgridlinestyle ();
       bool do_zgrid = (props.is_zgrid () && (gridstyle != "none"));
@@ -1209,7 +1254,8 @@
       Matrix zticks = xform.zscale (props.get_ztick ().matrix_value ());
       Matrix zmticks = xform.zscale (props.get_zmtick ().matrix_value ());
       string_vector zticklabels = props.get_zticklabel ().all_strings ();
-      int wmax = 0, hmax = 0;
+      int wmax = 0;
+      int hmax = 0;
       bool mirror = props.is_box () && zstate != AXE_ANY_DIR;
 
       set_color (props.get_zcolor_rgb ());
@@ -1324,12 +1370,6 @@
 {
   // Children
 
-  GLboolean antialias;
-  glGetBooleanv (GL_LINE_SMOOTH, &antialias);
-
-  if (antialias == GL_TRUE)
-    glEnable (GL_LINE_SMOOTH);
-
   Matrix children = props.get_all_children ();
   std::list<graphics_object> obj_list;
   std::list<graphics_object>::iterator it;
@@ -1337,11 +1377,11 @@
   // 1st pass: draw light objects
 
   // Start with the last element of the array of child objects to
-  // display them in the oder they were added to the array.
+  // display them in the order they were added to the array.
 
   for (octave_idx_type i = children.numel () - 1; i >= 0; i--)
     {
-      graphics_object go = gh_manager::get_object (children (i));
+      graphics_object go = gh_manager::get_object (children(i));
 
       if (go.get_properties ().is_visible ())
         {
@@ -1407,12 +1447,18 @@
   if (x_max > floatmax || y_max > floatmax || z_max > floatmax
       || x_min < -floatmax || y_min < -floatmax || z_min < -floatmax)
     {
-      warning ("gl-render: data values greater than float capacity.  (1) Scale data, or (2) Use gnuplot");
+      warning ("opengl_renderer: data values greater than float capacity.  (1) Scale data, or (2) Use gnuplot");
       return;
     }
 
   setup_opengl_transformation (props);
 
+  // Disable line smoothing for axes 
+  GLboolean antialias;
+  glGetBooleanv (GL_LINE_SMOOTH, &antialias);
+  if (antialias == GL_TRUE)
+    glDisable (GL_LINE_SMOOTH);
+
   // draw axes object
 
   draw_axes_planes (props);
@@ -1428,6 +1474,10 @@
 
   set_clipbox (x_min, x_max, y_min, y_max, z_min, z_max);
 
+  // Re-enable line smoothing for children
+  if (antialias == GL_TRUE)
+    glEnable (GL_LINE_SMOOTH);
+
   draw_axes_children (props);
 }
 
@@ -1545,7 +1595,7 @@
         {
           if (clip[i] == clip_ok)
             draw_marker (x(i), y(i),
-                         has_z ? z(i) : static_cast<double> (i) / n,
+                         has_z ? z(i) : 0.0,
                          lc, fc);
         }
 
@@ -1562,7 +1612,8 @@
   const Matrix y = xform.yscale (props.get_ydata ().matrix_value ());
   const Matrix z = xform.zscale (props.get_zdata ().matrix_value ());
 
-  int zr = z.rows (), zc = z.columns ();
+  int zr = z.rows ();
+  int zc = z.columns ();
 
   NDArray c;
   const NDArray n = props.get_vertexnormals ().array_value ();
@@ -1571,7 +1622,7 @@
   Matrix a;
 
   if (props.facelighting_is ("phong") || props.edgelighting_is ("phong"))
-    warning ("opengl_renderer::draw: phong light model not supported");
+    warning ("opengl_renderer: phong light model not supported");
 
   int fc_mode = (props.facecolor_is_rgb () ? 0 :
                  (props.facecolor_is ("flat") ? 1 :
@@ -1589,8 +1640,8 @@
   int ea_mode = (props.edgealpha_is_double () ? 0 :
                  (props.edgealpha_is ("flat") ? 1 : 2));
 
-  Matrix fcolor = (fc_mode == 3 ? Matrix (1, 3, 1.0)
-                                : props.get_facecolor_rgb ());
+  Matrix fcolor = (fc_mode == TEXTURE ? Matrix (1, 3, 1.0)
+                                      : props.get_facecolor_rgb ());
   Matrix ecolor = props.get_edgecolor_rgb ();
 
   float as = props.get_ambientstrength ();
@@ -1641,16 +1692,16 @@
       glMaterialf (LIGHT_MODE, GL_SHININESS, se);
     }
 
-  // FIXME: good candidate for caching, transfering pixel
-  // data to OpenGL is time consuming.
-  if (fc_mode == 3)
+  // FIXME: good candidate for caching,
+  //        transferring pixel data to OpenGL is time consuming.
+  if (fc_mode == TEXTURE)
     tex = opengl_texture::create (props.get_color_data ());
 
   if (! props.facecolor_is ("none"))
     {
       if (props.get_facealpha_double () == 1)
         {
-          if (fc_mode == 0 || fc_mode == 3)
+          if (fc_mode == UNIFORM || fc_mode == TEXTURE)
             {
               glColor3dv (fcolor.data ());
               if (fl_mode > 0)
@@ -1667,9 +1718,10 @@
 
           if (fl_mode > 0)
             glEnable (GL_LIGHTING);
-          glShadeModel ((fc_mode == 2 || fl_mode == 2) ? GL_SMOOTH : GL_FLAT);
+          glShadeModel ((fc_mode == INTERP || fl_mode == GOURAUD) ? GL_SMOOTH
+                                                                  : GL_FLAT);
           set_polygon_offset (true, 1);
-          if (fc_mode == 3)
+          if (fc_mode == TEXTURE)
             glEnable (GL_TEXTURE_2D);
 
           for (int i = 1; i < zc; i++)
@@ -1687,13 +1739,13 @@
                       || clip(j-1, i) || clip(j, i))
                     continue;
 
-                  if (fc_mode == 1)
+                  if (fc_mode == FLAT)
                     {
                       // "flat" only needs color at lower-left vertex
                       if (! xfinite (c(j-1,i-1)))
                         continue;
                     }
-                  else if (fc_mode == 2)
+                  else if (fc_mode == INTERP)
                     {
                       // "interp" needs valid color at all 4 vertices
                       if (! (xfinite (c(j-1, i-1)) && xfinite (c(j, i-1))
@@ -1710,7 +1762,7 @@
                   glBegin (GL_QUADS);
 
                   // Vertex 1
-                  if (fc_mode == 3)
+                  if (fc_mode == TEXTURE)
                     tex.tex_coord (double (i-1) / (zc-1),
                                    double (j-1) / (zr-1));
                   else if (fc_mode > 0)
@@ -1743,9 +1795,9 @@
                   glVertex3d (x(j1,i-1), y(j-1,i1), z(j-1,i-1));
 
                   // Vertex 2
-                  if (fc_mode == 3)
+                  if (fc_mode == TEXTURE)
                     tex.tex_coord (double (i) / (zc-1), double (j-1) / (zr-1));
-                  else if (fc_mode == 2)
+                  else if (fc_mode == INTERP)
                     {
                       for (int k = 0; k < 3; k++)
                         cb[k] = c(j-1, i, k);
@@ -1763,7 +1815,7 @@
                         }
                     }
 
-                  if (fl_mode == 2)
+                  if (fl_mode == GOURAUD)
                     {
                       d = sqrt (n(j-1,i,0) * n(j-1,i,0)
                                 + n(j-1,i,1) * n(j-1,i,1)
@@ -1774,9 +1826,9 @@
                   glVertex3d (x(j1,i), y(j-1,i2), z(j-1,i));
 
                   // Vertex 3
-                  if (fc_mode == 3)
+                  if (fc_mode == TEXTURE)
                     tex.tex_coord (double (i) / (zc-1), double (j) / (zr-1));
-                  else if (fc_mode == 2)
+                  else if (fc_mode == INTERP)
                     {
                       for (int k = 0; k < 3; k++)
                         cb[k] = c(j, i, k);
@@ -1793,7 +1845,7 @@
                           glMaterialfv (LIGHT_MODE, GL_DIFFUSE, cb);
                         }
                     }
-                  if (fl_mode == 2)
+                  if (fl_mode == GOURAUD)
                     {
                       d = sqrt (n(j,i,0) * n(j,i,0)
                                 + n(j,i,1) * n(j,i,1)
@@ -1803,9 +1855,9 @@
                   glVertex3d (x(j2,i), y(j,i2), z(j,i));
 
                   // Vertex 4
-                  if (fc_mode == 3)
+                  if (fc_mode == TEXTURE)
                     tex.tex_coord (double (i-1) / (zc-1), double (j) / (zr-1));
-                  else if (fc_mode == 2)
+                  else if (fc_mode == INTERP)
                     {
                       for (int k = 0; k < 3; k++)
                         cb[k] = c(j, i-1, k);
@@ -1822,7 +1874,7 @@
                           glMaterialfv (LIGHT_MODE, GL_DIFFUSE, cb);
                         }
                     }
-                  if (fl_mode == 2)
+                  if (fl_mode == GOURAUD)
                     {
                       d = sqrt (n(j,i-1,0) * n(j,i-1,0)
                                 + n(j,i-1,1) * n(j,i-1,1)
@@ -1836,7 +1888,7 @@
             }
 
           set_polygon_offset (false);
-          if (fc_mode == 3)
+          if (fc_mode == TEXTURE)
             glDisable (GL_TEXTURE_2D);
 
           if (fl_mode > 0)
@@ -1852,7 +1904,7 @@
     {
       if (props.get_edgealpha_double () == 1)
         {
-          if (ec_mode == 0)
+          if (ec_mode == UNIFORM)
             {
               glColor3dv (ecolor.data ());
               if (fl_mode > 0)
@@ -1869,7 +1921,8 @@
 
           if (el_mode > 0)
             glEnable (GL_LIGHTING);
-          glShadeModel ((ec_mode == 2 || el_mode == 2) ? GL_SMOOTH : GL_FLAT);
+          glShadeModel ((ec_mode == INTERP || el_mode == GOURAUD) ? GL_SMOOTH
+                                                                  : GL_FLAT);
 
           set_linestyle (props.get_linestyle (), false);
           set_linewidth (props.get_linewidth ());
@@ -1891,13 +1944,13 @@
                       if (clip(j-1,i) || clip(j,i))
                         continue;
 
-                      if (ec_mode == 1)
+                      if (ec_mode == FLAT)
                         {
                           // "flat" only needs color at lower-left vertex
                           if (! xfinite (c(j-1,i)))
                             continue;
                         }
-                      else if (ec_mode == 2)
+                      else if (ec_mode == INTERP)
                         {
                           // "interp" needs valid color at both vertices
                           if (! (xfinite (c(j-1, i)) && xfinite (c(j, i))))
@@ -1940,7 +1993,7 @@
                       glVertex3d (x(j1,i), y(j-1,i2), z(j-1,i));
 
                       // Vertex 2
-                      if (ec_mode == 2)
+                      if (ec_mode == INTERP)
                         {
                           for (int k = 0; k < 3; k++)
                             cb[k] = c(j, i, k);
@@ -1957,7 +2010,7 @@
                               glMaterialfv (LIGHT_MODE, GL_DIFFUSE, cb);
                             }
                         }
-                      if (el_mode == 2)
+                      if (el_mode == GOURAUD)
                         {
                           d = sqrt (n(j,i,0) * n(j,i,0)
                                     + n(j,i,1) * n(j,i,1)
@@ -1988,13 +2041,13 @@
                       if (clip(j,i-1) || clip(j,i))
                         continue;
 
-                      if (ec_mode == 1)
+                      if (ec_mode == FLAT)
                         {
                           // "flat" only needs color at lower-left vertex
                           if (! xfinite (c(j,i-1)))
                             continue;
                         }
-                      else if (ec_mode == 2)
+                      else if (ec_mode == INTERP)
                         {
                           // "interp" needs valid color at both vertices
                           if (! (xfinite (c(j, i-1)) && xfinite (c(j, i))))
@@ -2037,7 +2090,7 @@
                       glVertex3d (x(j2,i-1), y(j,i1), z(j,i-1));
 
                       // Vertex 2
-                      if (ec_mode == 2)
+                      if (ec_mode == INTERP)
                         {
                           for (int k = 0; k < 3; k++)
                             cb[k] = c(j, i, k);
@@ -2054,7 +2107,7 @@
                               glMaterialfv (LIGHT_MODE, GL_DIFFUSE, cb);
                             }
                         }
-                      if (el_mode == 2)
+                      if (el_mode == GOURAUD)
                         {
                           d = sqrt (n(j,i,0) * n(j,i,0)
                                     + n(j,i,1) * n(j,i,1)
@@ -2150,11 +2203,19 @@
     }
 }
 
-// FIXME: global optimization (rendering, data structures...), there
-// is probably a smarter/faster/less-memory-consuming way to do this.
+// FIXME: global optimization (rendering, data structures...),
+// there is probably a smarter/faster/less-memory-consuming way to do this.
 void
 opengl_renderer::draw_patch (const patch::properties &props)
 {
+  // Do not render if the patch has incoherent data
+  std::string msg;
+  if (props.has_bad_data (msg))
+    {
+      warning ("opengl_renderer: %s. Not rendering.", msg.c_str ());
+      return;
+    }
+
   const Matrix f = props.get_faces ().matrix_value ();
   const Matrix v = xform.scale (props.get_vertices ().matrix_value ());
   Matrix c;
@@ -2162,7 +2223,6 @@
   Matrix a;
 
   int nv = v.rows ();
-  // int vmax = v.columns ();
   int nf = f.rows ();
   int fcmax = f.columns ();
 
@@ -2228,13 +2288,13 @@
           if (fc_mode > 0)
             {
               fcolor = c;
-              fc_mode = 0;
+              fc_mode = UNIFORM;
             }
 
           if (ec_mode > 0)
             {
               ecolor = c;
-              ec_mode = 0;
+              ec_mode = UNIFORM;
             }
 
           c = Matrix ();
@@ -2260,7 +2320,7 @@
 
         Matrix vv (1, 3, 0.0);
         Matrix cc;
-        Matrix nn(1, 3, 0.0);
+        Matrix nn (1, 3, 0.0);
         double aa = 1.0;
 
         vv(0) = v(idx,0); vv(1) = v(idx,1);
@@ -2284,8 +2344,7 @@
               aa = a(idx);
           }
 
-        vdata[i+j*fr] =
-          vertex_data (vv, cc, nn, aa, as, ds, ss, se);
+        vdata[i+j*fr] = vertex_data (vv, cc, nn, aa, as, ds, ss, se);
       }
 
   if (fl_mode > 0 || el_mode > 0)
@@ -2301,7 +2360,7 @@
       // FIXME: adapt to double-radio property
       if (props.get_facealpha_double () == 1)
         {
-          if (fc_mode == 0)
+          if (fc_mode == UNIFORM)
             {
               glColor3dv (fcolor.data ());
               if (fl_mode > 0)
@@ -2321,8 +2380,11 @@
           if (fl_mode > 0)
             glEnable (GL_LIGHTING);
 
-          // FIXME: use __index__ property from patch object
-          patch_tesselator tess (this, fc_mode, fl_mode, 0);
+          // NOTE: Push filled part of patch backwards to avoid Z-fighting with
+          // tesselator outline.  A value of 1.0 seems to work fine.  Value
+          // can't be too large or the patch will be pushed below the axes
+          // planes at +2.5.
+          patch_tesselator tess (this, fc_mode, fl_mode, 1.0);
 
           for (int i = 0; i < nf; i++)
             {
@@ -2332,13 +2394,44 @@
               tess.begin_polygon (true);
               tess.begin_contour ();
 
-              for (int j = 0; j < count_f(i); j++)
+              // Add vertices in reverse order for Matlab compatibility
+              for (int j = count_f(i)-1; j > 0; j--)
                 {
                   vertex_data::vertex_data_rep *vv = vdata[i+j*fr].get_rep ();
 
                   tess.add_vertex (vv->coords.fortran_vec (), vv);
                 }
 
+              if (count_f(i) > 0)
+                {
+                  vertex_data::vertex_data_rep *vv = vdata[i].get_rep ();
+
+                  if (fc_mode == FLAT)
+                    {
+                      // For "flat" shading, use color of 1st vertex.
+                      Matrix col = vv->color;
+
+                      if (col.numel () == 3)
+                        {
+                          glColor3dv (col.data ());
+                          if (fl_mode > 0)
+                            {
+                              float cb[4] = { 0, 0, 0, 1 };
+
+                              for (int k = 0; k < 3; k++)
+                                cb[k] = (vv->ambient * col(k));
+                              glMaterialfv (LIGHT_MODE, GL_AMBIENT, cb);
+
+                              for (int k = 0; k < 3; k++)
+                                cb[k] = (vv->diffuse * col(k));
+                              glMaterialfv (LIGHT_MODE, GL_DIFFUSE, cb);
+                            }
+                        }
+                    }
+
+                  tess.add_vertex (vv->coords.fortran_vec (), vv);
+                }
+
               tess.end_contour ();
               tess.end_polygon ();
             }
@@ -2357,7 +2450,7 @@
       // FIXME: adapt to double-radio property
       if (props.get_edgealpha_double () == 1)
         {
-          if (ec_mode == 0)
+          if (ec_mode == UNIFORM)
             {
               glColor3dv (ecolor.data ());
               if (el_mode > 0)
@@ -2380,19 +2473,25 @@
           set_linestyle (props.get_linestyle (), false);
           set_linewidth (props.get_linewidth ());
 
-
-          // FIXME: use __index__ property from patch object; should we
-          // offset patch contour as well?
+          // NOTE: patch contour cannot be offset.  Offset must occur with the
+          // filled portion of the patch above.  The tesselator uses
+          // GLU_TESS_BOUNDARY_ONLY to get the outline of the patch and OpenGL
+          // automatically sets the glType to GL_LINE_LOOP.  This primitive is
+          // not supported by glPolygonOffset which is used to do Z offsets. 
           patch_tesselator tess (this, ec_mode, el_mode);
 
           for (int i = 0; i < nf; i++)
             {
               if (clip_f(i))
                 {
-                  // This is an unclosed contour. Draw it as a line
+                  // This is an unclosed contour.  Draw it as a line.
                   bool flag = false;
 
-                  for (int j = 0; j < count_f(i); j++)
+                  glShadeModel ((ec_mode == INTERP || el_mode == GOURAUD)
+                                ? GL_SMOOTH : GL_FLAT);
+
+                  // Add vertices in reverse order for Matlab compatibility
+                  for (int j = count_f(i)-1; j >= 0; j--)
                     {
                       if (! clip(int (f(i,j) - 1)))
                         {
@@ -2404,6 +2503,13 @@
                               flag = true;
                               glBegin (GL_LINE_STRIP);
                             }
+                          if (ec_mode != UNIFORM)
+                            {
+                              Matrix col = vv->color;
+
+                              if (col.numel () == 3)
+                                glColor3dv (col.data ());
+                            }
                           glVertex3d (m(0), m(1), m(2));
                         }
                       else if (flag)
@@ -2412,16 +2518,33 @@
                           glEnd ();
                         }
                     }
+                  // Do loop body with vertex N to "close" GL_LINE_STRIP
+                  // from vertex 0 to vertex N.
+                  int j = count_f(i)-1;
+                  if (flag && ! clip(int (f(i,j) - 1)))
+                    {
+                      vertex_data::vertex_data_rep *vv
+                        = vdata[i+j*fr].get_rep ();
+                      const Matrix m = vv->coords;
+                      if (ec_mode != UNIFORM)
+                        {
+                          Matrix col = vv->color;
+
+                          if (col.numel () == 3)
+                            glColor3dv (col.data ());
+                        }
+                      glVertex3d (m(0), m(1), m(2));
+                    }
 
                   if (flag)
                     glEnd ();
                 }
-              else
+              else  // Normal edge contour drawn with tesselator
                 {
                   tess.begin_polygon (false);
                   tess.begin_contour ();
 
-                  for (int j = 0; j < count_f(i); j++)
+                  for (int j = count_f(i)-1; j >= 0; j--)
                     {
                       vertex_data::vertex_data_rep *vv
                         = vdata[i+j*fr].get_rep ();
@@ -2552,7 +2675,8 @@
 {
   octave_value cdata = props.get_color_data ();
   dim_vector dv (cdata.dims ());
-  int h = dv(0), w = dv(1);
+  int h = dv(0);
+  int w = dv(1);
 
   Matrix x = props.get_xdata ().matrix_value ();
   Matrix y = props.get_ydata ().matrix_value ();
@@ -2572,7 +2696,7 @@
 
   if (xisnan (p0(0)) || xisnan (p0(1)) || xisnan (p1(0)) || xisnan (p1(1)))
     {
-      warning ("gl-render: image x,y data too large to draw");
+      warning ("opengl_renderer: image X,Y data too large to draw");
       return;
     }
 
@@ -2605,13 +2729,12 @@
       nor_dy = 1;
     }
 
-
-  // OpenGL won't draw the image if it's origin is outside the
-  // viewport/clipping plane so we must do the clipping
-  // ourselfes - only draw part of the image
-
-  int j0 = 0, j1 = w;
-  int i0 = 0, i1 = h;
+  // OpenGL won't draw any of the image if it's origin is outside the
+  // viewport/clipping plane so we must do the clipping ourselves.
+
+  int j0, j1, i0, i1;
+  j0 = 0, j1 = w;
+  i0 = 0, i1 = h;
 
   float im_xmin = x(0) - nor_dx/2;
   float im_xmax = x(1) + nor_dx/2;
@@ -2644,7 +2767,7 @@
   glRasterPos3d (im_xmin + nor_dx*j0, im_ymin + nor_dy*i0, 0);
 
   // by default this is 4
-  glPixelStorei (GL_UNPACK_ALIGNMENT,1);
+  glPixelStorei (GL_UNPACK_ALIGNMENT, 1);
 
   // Expect RGB data
   if (dv.length () == 3 && dv(2) == 3)
@@ -2668,6 +2791,44 @@
           draw_pixels (j1-j0, i1-i0, GL_RGB, GL_FLOAT, a);
 
         }
+      else if (cdata.is_single_type ())
+        {
+          const FloatNDArray xcdata = cdata.float_array_value ();
+
+          OCTAVE_LOCAL_BUFFER (GLfloat, a, 3*(j1-j0)*(i1-i0));
+
+          for (int i = i0; i < i1; i++)
+            {
+              for (int j = j0, idx = (i-i0)*(j1-j0)*3; j < j1; j++, idx += 3)
+                {
+                  a[idx]   = xcdata(i,j,0);
+                  a[idx+1] = xcdata(i,j,1);
+                  a[idx+2] = xcdata(i,j,2);
+                }
+            }
+
+          draw_pixels (j1-j0, i1-i0, GL_RGB, GL_FLOAT, a);
+
+        }
+      else if (cdata.is_uint8_type ())
+        {
+          const uint8NDArray xcdata = cdata.uint8_array_value ();
+
+          OCTAVE_LOCAL_BUFFER (GLubyte, a, 3*(j1-j0)*(i1-i0));
+
+          for (int i = i0; i < i1; i++)
+            {
+              for (int j = j0, idx = (i-i0)*(j1-j0)*3; j < j1; j++, idx += 3)
+                {
+                  a[idx]   = xcdata(i,j,0);
+                  a[idx+1] = xcdata(i,j,1);
+                  a[idx+2] = xcdata(i,j,2);
+                }
+            }
+
+          draw_pixels (j1-j0, i1-i0, GL_RGB, GL_UNSIGNED_BYTE, a);
+
+        }
       else if (cdata.is_uint16_type ())
         {
           const uint16NDArray xcdata = cdata.uint16_array_value ();
@@ -2687,29 +2848,11 @@
           draw_pixels (j1-j0, i1-i0, GL_RGB, GL_UNSIGNED_SHORT, a);
 
         }
-      else if (cdata.is_uint8_type ())
-        {
-          const uint8NDArray xcdata = cdata.uint8_array_value ();
-
-          OCTAVE_LOCAL_BUFFER (GLubyte, a, 3*(j1-j0)*(i1-i0));
-
-          for (int i = i0; i < i1; i++)
-            {
-              for (int j = j0, idx = (i-i0)*(j1-j0)*3; j < j1; j++, idx += 3)
-                {
-                  a[idx]   = xcdata(i,j,0);
-                  a[idx+1] = xcdata(i,j,1);
-                  a[idx+2] = xcdata(i,j,2);
-                }
-            }
-
-          draw_pixels (j1-j0, i1-i0, GL_RGB, GL_UNSIGNED_BYTE, a);
-        }
       else
-        warning ("opengl_texture::draw: invalid image data type (expected double, uint16, or uint8)");
+        warning ("opengl_renderer: invalid image data type (expected double, single, uint8, or uint16)");
     }
   else
-    warning ("opengl_texture::draw: invalid image size (expected n*m*3 or n*m)");
+    warning ("opengl_renderer: invalid image size (expected MxNx3 or MxN)");
 
   glPixelZoom (1, 1);
 }
@@ -2748,13 +2891,13 @@
 }
 
 void
-opengl_renderer::set_polygon_offset (bool on, double offset)
+opengl_renderer::set_polygon_offset (bool on, float offset)
 {
   if (on)
     {
-      glPolygonOffset (offset, offset);
       glEnable (GL_POLYGON_OFFSET_FILL);
       glEnable (GL_POLYGON_OFFSET_LINE);
+      glPolygonOffset (offset, offset);
     }
   else
     {
@@ -2782,7 +2925,7 @@
   else if (s == ":")
     glLineStipple (1, static_cast<unsigned short> (0x8888));
   else if (s == "--")
-    glLineStipple (1, static_cast<unsigned short> (0x0FFF));
+    glLineStipple (1, static_cast<unsigned short> (0xF0F0));
   else if (s == "-.")
     glLineStipple (1, static_cast<unsigned short> (0x020F));
   else
@@ -2934,30 +3077,30 @@
     {
     case '+':
       glBegin (GL_LINES);
-      glVertex2f (-sz/2, 0);
-      glVertex2f (sz/2, 0);
-      glVertex2f (0, -sz/2);
-      glVertex2f (0, sz/2);
+      glVertex2d (-sz/2, 0);
+      glVertex2d (sz/2, 0);
+      glVertex2d (0, -sz/2);
+      glVertex2d (0, sz/2);
       glEnd ();
       break;
     case 'x':
       glBegin (GL_LINES);
-      glVertex2f (-sz/2, -sz/2);
-      glVertex2f (sz/2, sz/2);
-      glVertex2f (-sz/2, sz/2);
-      glVertex2f (sz/2, -sz/2);
+      glVertex2d (-sz/2, -sz/2);
+      glVertex2d (sz/2, sz/2);
+      glVertex2d (-sz/2, sz/2);
+      glVertex2d (sz/2, -sz/2);
       glEnd ();
       break;
     case '*':
       glBegin (GL_LINES);
-      glVertex2f (-sz/2, 0);
-      glVertex2f (sz/2, 0);
-      glVertex2f (0, -sz/2);
-      glVertex2f (0, sz/2);
-      glVertex2f (-tt, -tt);
-      glVertex2f (+tt, +tt);
-      glVertex2f (-tt, +tt);
-      glVertex2f (+tt, -tt);
+      glVertex2d (-sz/2, 0);
+      glVertex2d (sz/2, 0);
+      glVertex2d (0, -sz/2);
+      glVertex2d (0, sz/2);
+      glVertex2d (-tt, -tt);
+      glVertex2d (+tt, +tt);
+      glVertex2d (-tt, +tt);
+      glVertex2d (+tt, -tt);
       glEnd ();
       break;
     case '.':
@@ -2998,30 +3141,30 @@
       break;
     case 'v':
       glBegin ((filled ? GL_POLYGON : GL_LINE_LOOP));
-      glVertex2f (0, sz/2);
-      glVertex2f (sz/2, -sz/2);
-      glVertex2f (-sz/2, -sz/2);
+      glVertex2d (0, sz/2);
+      glVertex2d (sz/2, -sz/2);
+      glVertex2d (-sz/2, -sz/2);
       glEnd ();
       break;
     case '^':
       glBegin ((filled ? GL_POLYGON : GL_LINE_LOOP));
-      glVertex2f (0, -sz/2);
-      glVertex2f (-sz/2, sz/2);
-      glVertex2f (sz/2, sz/2);
+      glVertex2d (0, -sz/2);
+      glVertex2d (-sz/2, sz/2);
+      glVertex2d (sz/2, sz/2);
       glEnd ();
       break;
     case '>':
       glBegin ((filled ? GL_POLYGON : GL_LINE_LOOP));
-      glVertex2f (sz/2, 0);
-      glVertex2f (-sz/2, sz/2);
-      glVertex2f (-sz/2, -sz/2);
+      glVertex2d (sz/2, 0);
+      glVertex2d (-sz/2, sz/2);
+      glVertex2d (-sz/2, -sz/2);
       glEnd ();
       break;
     case '<':
       glBegin ((filled ? GL_POLYGON : GL_LINE_LOOP));
-      glVertex2f (-sz/2, 0);
-      glVertex2f (sz/2, -sz/2);
-      glVertex2f (sz/2, sz/2);
+      glVertex2d (-sz/2, 0);
+      glVertex2d (sz/2, -sz/2);
+      glVertex2d (sz/2, sz/2);
       glEnd ();
       break;
     case 'p':
@@ -3057,8 +3200,7 @@
       }
       break;
     default:
-      warning ("opengl_renderer: unsupported marker '%s'",
-               marker.c_str ());
+      warning ("opengl_renderer: unsupported marker '%s'", marker.c_str ());
       break;
     }
 
@@ -3106,7 +3248,7 @@
 
   return bbox;
 #else
-  ::warning ("render_text: cannot render text, Freetype library not available");
+  warning ("opengl_renderer: cannot render text, FreeType library not available");
   return Matrix (1, 4, 0.0);
 #endif
 }
--- a/libinterp/corefcn/gl-render.h	Fri Aug 01 09:06:21 2014 -0400
+++ b/libinterp/corefcn/gl-render.h	Fri Aug 01 12:10:05 2014 -0400
@@ -99,7 +99,7 @@
   virtual void setup_opengl_transformation (const axes::properties& props);
 
   virtual void set_color (const Matrix& c);
-  virtual void set_polygon_offset (bool on, double offset = 0.0);
+  virtual void set_polygon_offset (bool on, float offset = 0.0);
   virtual void set_linewidth (float w);
   virtual void set_linestyle (const std::string& s, bool stipple = false);
   virtual void set_clipbox (double x1, double x2, double y1, double y2,
@@ -206,7 +206,7 @@
   ColumnVector camera_pos, camera_dir;
 
 #if HAVE_FREETYPE
-  // freetype render, used for text rendering
+  // FreeType render, used for text rendering
   ft_render text_renderer;
 #endif
 
--- a/libinterp/corefcn/gl2ps-renderer.cc	Fri Aug 01 09:06:21 2014 -0400
+++ b/libinterp/corefcn/gl2ps-renderer.cc	Fri Aug 01 12:10:05 2014 -0400
@@ -44,7 +44,8 @@
     {
       in_draw = true;
 
-      GLint buffsize = 0, state = GL2PS_OVERFLOW;
+      GLint buffsize = 0;
+      GLint state = GL2PS_OVERFLOW;
       GLint viewport[4];
 
       glGetIntegerv (GL_VIEWPORT, viewport);
@@ -52,13 +53,13 @@
       GLint gl2ps_term;
       if (term.find ("eps") != std::string::npos) gl2ps_term = GL2PS_EPS;
       else if (term.find ("pdf") != std::string::npos) gl2ps_term = GL2PS_PDF;
+      else if (term.find ("ps") != std::string::npos) gl2ps_term = GL2PS_PS;
       else if (term.find ("svg") != std::string::npos) gl2ps_term = GL2PS_SVG;
-      else if (term.find ("ps") != std::string::npos) gl2ps_term = GL2PS_PS;
       else if (term.find ("pgf") != std::string::npos) gl2ps_term = GL2PS_PGF;
       else if (term.find ("tex") != std::string::npos) gl2ps_term = GL2PS_TEX;
       else
         {
-          error ("gl2ps-renderer:: Unknown terminal");
+          error ("gl2ps-renderer::draw: Unknown terminal %s", term.c_str ());
           return;
         }
 
@@ -67,7 +68,9 @@
 
       // Default sort order optimizes for 3D plots
       GLint gl2ps_sort = GL2PS_BSP_SORT;
-      if (term.find ("is2D") != std::string::npos) gl2ps_sort = GL2PS_NO_SORT;
+      // For 2D plots we can use a simpler Z-depth sorting algorithm
+      if (term.find ("is2D") != std::string::npos)
+        gl2ps_sort = GL2PS_SIMPLE_SORT;
 
       while (state == GL2PS_OVERFLOW)
         {
@@ -92,16 +95,25 @@
           else
             include_graph = "foobar-inc";
           buffsize += 1024*1024;
-          gl2psBeginPage ("glps_renderer figure", "Octave", viewport,
-                          gl2ps_term, gl2ps_sort,
-                          (GL2PS_SILENT | GL2PS_SIMPLE_LINE_OFFSET
-                           | GL2PS_NO_BLENDING | GL2PS_OCCLUSION_CULL
-                           | GL2PS_BEST_ROOT | gl2ps_text
-                           | GL2PS_NO_PS3_SHADING),
-                          GL_RGBA, 0, NULL, 0, 0, 0,
-                          buffsize, fp, include_graph.c_str ());
+          // GL2PS_SILENT was removed to allow gl2ps printing errors on stderr
+          GLint ret = gl2psBeginPage ("glps_renderer figure", "Octave", viewport,
+                                      gl2ps_term, gl2ps_sort,
+                                      (  GL2PS_NO_BLENDING
+                                       | GL2PS_OCCLUSION_CULL
+                                       | GL2PS_BEST_ROOT
+                                       | gl2ps_text
+                                       | GL2PS_NO_PS3_SHADING),
+                                      GL_RGBA, 0, NULL, 0, 0, 0,
+                                      buffsize, fp, include_graph.c_str ());
+          if (ret == GL2PS_ERROR)
+            error ("gl2ps-renderer::draw: gl2psBeginPage returned GL2PS_ERROR");
           old_print_cmd = print_cmd;
           opengl_renderer::draw (go);
+
+          // Force execution of GL commands in finite time.
+          // Without glFlush () there may primitives be missing in the gl2ps output.
+          glFlush ();
+
           state = gl2psEndPage ();
         }
 
@@ -158,7 +170,7 @@
                 alignment_to_mode (ha, va), rotation);
 
   // FIXME?
-  // We have no way of getting a bounding box from gl2ps, so we use freetype.
+  // We have no way of getting a bounding box from gl2ps, so we use FreeType.
   Matrix bbox;
   uint8NDArray pixels;
   text_to_pixels (txt, pixels, bbox, 0, 0, rotation);
@@ -195,9 +207,9 @@
   OCTAVE_LOCAL_BUFFER (GLfloat, a, 3*w*h);
 
   // Convert to GL_FLOAT as it is the only type gl2ps accepts.
-  for (unsigned int i = 0; i < 3*w*h; i++)
+  for (int i = 0; i < 3*w*h; i++)
     a[i] = data[i] / maxval;
-  
+
   gl2psDrawPixels (w, h, 0, 0, format, GL_FLOAT, a);
 }
 
@@ -225,7 +237,8 @@
   set_color (props.get_color_rgb ());
 
   const Matrix pos = get_transform ().scale (props.get_data_position ());
-  int halign = 0, valign = 0;
+  int halign = 0;
+  int valign = 0;
 
   if (props.horizontalalignment_is ("center"))
     halign = 1;
--- a/libinterp/corefcn/graphics.cc	Fri Aug 01 09:06:21 2014 -0400
+++ b/libinterp/corefcn/graphics.cc	Fri Aug 01 12:10:05 2014 -0400
@@ -58,6 +58,7 @@
 #include "toplev.h"
 #include "txt-eng-ft.h"
 #include "unwind-prot.h"
+#include "octave-default-image.h"
 
 // forward declarations
 static octave_value xget (const graphics_handle& h, const caseless_str& name);
@@ -255,6 +256,93 @@
 }
 
 static Matrix
+default_image_cdata (void)
+{
+  Matrix m (64, 64, 0.0);
+  int i = 0;
+  for (int col = 0; col < 64; col++)
+    for (int row = 0; row < 64; row++)
+      {
+        m(col,row) = static_cast<double> (default_im_data[i]);
+        i++;
+      }
+
+  return m;
+}
+
+static Matrix
+default_surface_xdata (void)
+{
+  Matrix m (3, 3, 0.0);
+  for (int col = 0; col < 3; col++)
+    for (int row = 0; row < 3; row++)
+      m(row,col) = col+1;
+
+  return m;
+}
+
+static Matrix
+default_surface_ydata (void)
+{
+  Matrix m (3, 3, 0.0);
+  for (int row = 0; row < 3; row++)
+    for (int col = 0; col < 3; col++)
+      m(row,col) = row+1;
+
+  return m;
+}
+
+static Matrix
+default_surface_zdata (void)
+{
+  Matrix m (3, 3, 0.0);
+  for (int row = 0; row < 3; row++)
+    m(row,row) = 1.0;
+  return m;
+}
+
+static Matrix
+default_surface_cdata (void)
+{
+  return default_surface_zdata ();
+}
+
+static Matrix
+default_patch_faces (void)
+{
+  Matrix m (1, 3, 1.0);
+  m(1) = 2.0;
+  m(2) = 3.0;
+  return m;
+}
+
+static Matrix
+default_patch_vertices (void)
+{
+  Matrix m (3, 2, 0);
+  m(1) = 1.0;
+  m(3) = 1.0;
+  m(4) = 1.0;
+  return m;
+}
+
+static Matrix
+default_patch_xdata (void)
+{
+  Matrix m (3, 1, 0.0);
+  m(1) = 1.0;
+  return m;
+}
+
+static Matrix
+default_patch_ydata (void)
+{
+  Matrix m (3, 1, 1.0);
+  m(2) = 0.0;
+  return m;
+}
+
+static Matrix
 default_axes_position (void)
 {
   Matrix m (1, 4, 0.0);
@@ -274,6 +362,14 @@
 }
 
 static Matrix
+default_axes_view (void)
+{
+  Matrix m (1, 2, 0.0);
+  m(1) = 90.0;
+  return m;
+}
+
+static Matrix
 default_axes_tick (void)
 {
   Matrix m (1, 6, 0.0);
@@ -668,13 +764,13 @@
 }
 
 static void
-convert_cdata_2 (bool is_scaled, double clim_0, double clim_1,
+convert_cdata_2 (bool is_scaled, bool is_real, double clim_0, double clim_1,
                  const double *cmapv, double x, octave_idx_type lda,
                  octave_idx_type nc, octave_idx_type i, double *av)
 {
   if (is_scaled)
     x = xround ((nc - 1) * (x - clim_0) / (clim_1 - clim_0));
-  else
+  else if (is_real)
     x = xround (x - 1);
 
   if (xisnan (x))
@@ -700,12 +796,13 @@
 
 template <class T>
 void
-convert_cdata_1 (bool is_scaled, double clim_0, double clim_1,
+convert_cdata_1 (bool is_scaled, bool is_real, double clim_0, double clim_1,
                  const double *cmapv, const T *cv, octave_idx_type lda,
                  octave_idx_type nc, double *av)
 {
   for (octave_idx_type i = 0; i < lda; i++)
-    convert_cdata_2 (is_scaled, clim_0, clim_1, cmapv, cv[i], lda, nc, i, av);
+    convert_cdata_2 (is_scaled, is_real,
+                     clim_0, clim_1, cmapv, cv[i], lda, nc, i, av);
 }
 
 static octave_value
@@ -714,6 +811,7 @@
 {
   dim_vector dv (cdata.dims ());
 
+  // TrueColor data doesn't require conversion
   if (dv.length () == cdim && dv(cdim-1) == 3)
     return cdata;
 
@@ -758,22 +856,34 @@
   double clim_0 = clim(0);
   double clim_1 = clim(1);
 
-#define CONVERT_CDATA_1(ARRAY_T, VAL_FN) \
+  // FIXME: There is a lot of processing time spent just on data conversion
+  //        both here in graphics.cc and again in gl-render.cc.  There must
+  //        be room for improvement!  Here a macro expands to a templated
+  //        function which in turn calls another function (covert_cdata_2).
+  //        And in gl-render.cc (opengl_renderer::draw_image), only GLfloat
+  //        is supported anyways so there is another double for loop across
+  //        height and width to convert all of the input data to GLfloat.
+
+#define CONVERT_CDATA_1(ARRAY_T, VAL_FN, IS_REAL) \
   do \
     { \
       ARRAY_T tmp = cdata. VAL_FN ## array_value (); \
  \
-      convert_cdata_1 (is_scaled, clim_0, clim_1, cmapv, \
+      convert_cdata_1 (is_scaled, IS_REAL, clim_0, clim_1, cmapv, \
                        tmp.data (), lda, nc, av); \
     } \
   while (0)
 
   if (cdata.is_uint8_type ())
-    CONVERT_CDATA_1 (uint8NDArray, uint8_);
+    CONVERT_CDATA_1 (uint8NDArray, uint8_, false);
+  else if (cdata.is_uint16_type ())
+    CONVERT_CDATA_1 (uint16NDArray, uint16_, false);
+  else if (cdata.is_double_type ())
+    CONVERT_CDATA_1 (NDArray, , true);
   else if (cdata.is_single_type ())
-    CONVERT_CDATA_1 (FloatNDArray, float_);
-  else if (cdata.is_double_type ())
-    CONVERT_CDATA_1 (NDArray, );
+    CONVERT_CDATA_1 (FloatNDArray, float_, true);
+  else if (cdata.is_bool_type ())
+    CONVERT_CDATA_1 (boolNDArray, bool_, false);
   else
     error ("unsupported type for cdata (= %s)", cdata.type_name ().c_str ());
 
@@ -1012,7 +1122,7 @@
   for (std::set<caseless_str>::const_iterator it = possible_vals.begin ();
        it != possible_vals.end (); it++)
     {
-      if (retval == "")
+      if (retval.empty ())
         {
           if (*it == default_value ())
             retval = "{" + *it + "}";
@@ -1027,8 +1137,10 @@
             retval += " | " + *it;
         }
     }
-  if (retval != "")
+
+  if (! retval.empty ())
     retval = "[ " + retval + " ]";
+
   return retval;
 }
 
@@ -1044,10 +1156,13 @@
 }
 
 bool
-color_values::str2rgb (std::string str)
-{
+color_values::str2rgb (const std::string& str_arg)
+{
+  bool retval = true;
+
   double tmp_rgb[3] = {0, 0, 0};
-  bool retval = true;
+
+  std::string str = str_arg;
   unsigned int len = str.length ();
 
   std::transform (str.begin (), str.end (), str.begin (), tolower);
@@ -1232,7 +1347,7 @@
 
       // check dimensional size constraints until a match is found
       for (std::list<dim_vector>::const_iterator it = size_constraints.begin ();
-           ! xok && it != size_constraints.end (); ++it)
+           ! xok && it != size_constraints.end ();++it)
         {
           dim_vector itdims = (*it);
 
@@ -2640,6 +2755,39 @@
   finalize (go);
 }
 
+static void
+xreset_default_properties (graphics_handle gh,
+                           property_list::pval_map_type factory_pval)
+{
+  graphics_object obj = gh_manager::get_object (gh);
+
+  property_list::pval_map_type pval;
+
+  for (property_list::pval_map_const_iterator it = factory_pval.begin ();
+       it != factory_pval.end (); it++)
+    {
+      std::string pname = it->first;
+
+      // Don't reset internal properties and handle_properties
+      if (! obj.has_readonly_property (pname) &&
+          pname.find ("__") != 0 && pname.find ("current") != 0 &&
+          pname != "uicontextmenu" && pname != "parent")
+        {
+          // Store *mode prop/val in order to set them last 
+          if (pname.find ("mode") == (pname.length () - 4))
+            pval.insert (std::pair<std::string, octave_value>
+                         (pname, it->second));
+          else
+            obj.set (pname, it->second);
+        }
+    }
+
+  // set *mode properties
+  for (property_list::pval_map_const_iterator it = pval.begin ();
+       it != pval.end (); it++)
+    obj.set (it->first, it->second);
+}
+
 // ---------------------------------------------------------------------
 
 void
@@ -2659,7 +2807,7 @@
            q++)
         {
           std::string pname = q->first;
-
+          
           obj.set (pname, q->second);
 
           if (error_state)
@@ -2772,7 +2920,13 @@
               // Remove child from current parent
               graphics_object old_parent_obj;
               old_parent_obj = gh_manager::get_object (get_parent ());
-              old_parent_obj.remove_child (__myhandle__);
+
+               
+              if (old_parent_obj.get_handle () != hnp) 
+                old_parent_obj.remove_child (__myhandle__);
+              else
+                // Do nothing more
+                return;
 
               // Check new parent's parent is not this child to avoid recursion
               graphics_object new_parent_obj;
@@ -2795,6 +2949,18 @@
     error ("set: expecting parent to be a graphics handle");
 }
 
+/*
+%!test
+%! hf = figure ("visible", "off");
+%! unwind_protect
+%!   hax = gca ();
+%!   set (hax, "parent", gcf ())
+%!   assert (gca (), hax)
+%! unwind_protect_cleanup
+%!   close (hf);
+%! end_unwind_protect
+*/
+
 void
 base_properties::mark_modified (void)
 {
@@ -2953,6 +3119,21 @@
     }
 }
 
+void 
+base_graphics_object::reset_default_properties (void)
+  {
+    if (valid_object ())
+      {
+        property_list::pval_map_type factory_pval = 
+          gh_manager::get_object (0).get_factory_defaults_list ()
+          .find (type ())->second;
+        
+        xreset_default_properties (get_handle (), factory_pval);
+
+        override_defaults (*this);
+      }
+  }
+
 std::string
 base_graphics_object::values_as_string (void)
 {
@@ -2961,10 +3142,12 @@
   if (valid_object ())
     {
       octave_map m = get ().map_value ();
+      graphics_object obj = gh_manager::get_object (get_handle ());
 
       for (octave_map::const_iterator pa = m.begin (); pa != m.end (); pa++)
         {
-          if (pa->first != "children")
+          if (pa->first != "children" &&
+              ! obj.has_readonly_property (pa->first))
             {
               property p = get_properties ().get_property (pa->first);
 
@@ -2976,7 +3159,8 @@
                 }
             }
         }
-      if (retval != "")
+
+      if (! retval.empty ())
         retval += "\n";
     }
   else
@@ -2985,6 +3169,35 @@
   return retval;
 }
 
+std::string
+base_graphics_object::value_as_string (const std::string& prop)
+{
+  std::string retval;
+
+  if (valid_object ())
+    {
+      graphics_object obj = gh_manager::get_object (get_handle ());
+
+      if (prop != "children" && ! obj.has_readonly_property (prop))
+        {
+          property p = get_properties ().get_property (prop);
+
+          if (p.ok () && ! p.is_hidden ())
+            {
+              if (p.is_radio ())
+                retval += p.values_as_string ();
+            }
+        }
+
+      if (! retval.empty ())
+        retval += "\n";
+    }
+  else
+    error ("base_graphics_object::value_as_string: invalid graphics object");
+
+  return retval;
+}
+
 octave_scalar_map
 base_graphics_object::values_as_struct (void)
 {
@@ -2993,11 +3206,13 @@
   if (valid_object ())
     {
       octave_scalar_map m = get ().scalar_map_value ();
+      graphics_object obj = gh_manager::get_object (get_handle ());
 
       for (octave_scalar_map::const_iterator pa = m.begin ();
            pa != m.end (); pa++)
         {
-          if (pa->first != "children")
+          if (pa->first != "children"
+              && ! obj.has_readonly_property (pa->first))
             {
               property p = get_properties ().get_property (pa->first);
 
@@ -3017,6 +3232,25 @@
   return retval;
 }
 
+/*
+%!test
+%! hfig = figure ("visible", "off");
+%! unwind_protect
+%!   hax = axes ();
+%!   ret = set (hax, "tightinset");
+%!   assert (isempty (ret));
+%!   ret = set (hax, "type");
+%!   assert (isempty (ret));
+%!   ret = set (hfig, "__graphics_toolkit__");
+%!   assert (isempty (ret));
+%!   ret = set (0, "commandwindowsize");
+%!   assert (isempty (ret));
+%!   ret = set (0);
+%!   assert (! isfield (ret, "commandwindowsize"));
+%! unwind_protect_cleanup
+%!   close (hfig);
+%! end_unwind_protect
+*/
 graphics_object
 graphics_object::get_ancestor (const std::string& obj_type) const
 {
@@ -3038,25 +3272,6 @@
 // ---------------------------------------------------------------------
 
 void
-root_figure::properties::set_currentfigure (const octave_value& v)
-{
-  graphics_handle val (v);
-
-  if (error_state)
-    return;
-
-  if (xisnan (val.value ()) || is_handle (val))
-    {
-      currentfigure = val;
-
-      if (val.ok ())
-        gh_manager::push_figure (val);
-    }
-  else
-    gripe_set_invalid ("currentfigure");
-}
-
-void
 root_figure::properties::set_callbackobject (const octave_value& v)
 {
   graphics_handle val (v);
@@ -3087,6 +3302,189 @@
 }
 
 void
+root_figure::properties::set_currentfigure (const octave_value& v)
+{
+  graphics_handle val (v);
+
+  if (error_state)
+    return;
+
+  if (xisnan (val.value ()) || is_handle (val))
+    {
+      currentfigure = val;
+
+      if (val.ok ())
+        gh_manager::push_figure (val);
+    }
+  else
+    gripe_set_invalid ("currentfigure");
+}
+
+std::string
+root_figure::properties::get_diary (void) const
+{
+  bool is_diary_on = F__diarystate__ ()(0).bool_value ();
+  if (is_diary_on)
+    return std::string ("on");
+  else
+    return std::string ("off");
+}
+
+void
+root_figure::properties::set_diary (const octave_value& val)
+{
+  if (! error_state)
+    {
+      // Input checking and abrev. matching
+      diary.set (val, false);
+      
+      if (! error_state)
+        {
+          Fdiary (ovl (diary.current_value ()));
+
+          diary.run_listeners ();
+        }
+    }
+}
+
+std::string
+root_figure::properties::get_diaryfile (void) const
+{
+  return F__diaryfile__ ()(0).string_value ();
+}
+
+void
+root_figure::properties::set_diaryfile (const octave_value& val)
+{
+  if (! error_state)
+    {
+      // Input checking and abrev. matching
+      diaryfile.set (val, false);
+      
+      if (! error_state)
+        {
+          Fdiary (ovl (diaryfile.string_value ()));
+
+          diaryfile.run_listeners ();
+        }
+    }
+}
+
+std::string
+root_figure::properties::get_echo (void) const
+{
+  bool is_echo_on = F__echostate__ ()(0).bool_value ();
+  if (is_echo_on)
+    return std::string ("on");
+  else
+    return std::string ("off");
+}
+
+void
+root_figure::properties::set_echo (const octave_value& val)
+{
+  if (! error_state)
+    {
+      // Input checking and abrev. matching
+      echo.set (val, false);
+      
+      if (! error_state)
+        {
+          Fecho (ovl (echo.current_value ()));
+
+          echo.run_listeners ();
+        }
+    }
+}
+
+std::string
+root_figure::properties::get_errormessage (void) const
+{
+  return Flasterr ()(0).string_value ();
+}
+
+std::string
+root_figure::properties::get_format (void) const
+{
+  return F__formatstring__ ()(0).string_value ();
+}
+
+void
+root_figure::properties::set_format (const octave_value& val)
+{
+  if (! error_state)
+    {
+      // Input checking and abrev. matching
+      format.set (val, false);
+      
+      if (! error_state)
+        {
+          Fformat (ovl (format.current_value ()));     
+
+          format.run_listeners ();
+        }
+    }
+}
+
+std::string
+root_figure::properties::get_formatspacing (void) const
+{
+  bool iscompact = F__compactformat__ ()(0).bool_value ();
+  if (iscompact)
+    return std::string ("compact");
+  else
+    return std::string ("loose");
+}
+
+void
+root_figure::properties::set_formatspacing (const octave_value& val)
+{
+  if (! error_state)
+    {
+      // Input checking and abrev. matching
+      formatspacing.set (val, false);
+      
+      if (! error_state)
+        {
+          std::string strval = formatspacing.current_value ();
+
+          if (strval == "compact")
+            F__compactformat__ (ovl (true));
+          else
+            F__compactformat__ (ovl (false));
+
+          formatspacing.run_listeners ();
+        }
+    }
+}
+
+
+double
+root_figure::properties::get_recursionlimit (void) const
+{
+  return Fmax_recursion_depth ()(0).double_value ();
+}
+
+void
+root_figure::properties::set_recursionlimit (const octave_value& val)
+{
+  if (! error_state)
+    {
+      // Input checking and abrev. matching
+      recursionlimit.set (val, false);
+      
+      if (! error_state)
+        {
+          double dval = recursionlimit.double_value ();
+
+          Fmax_recursion_depth (ovl (dval));
+
+          recursionlimit.run_listeners ();
+        }
+    }
+}
+
+void
 figure::properties::set_integerhandle (const octave_value& val)
 {
   if (! error_state)
@@ -3220,39 +3618,14 @@
 property_list
 root_figure::factory_properties = root_figure::init_factory_properties ();
 
-static void
-reset_default_properties (property_list& default_properties)
-{
-  property_list new_defaults;
-
-  for (property_list::plist_map_const_iterator p = default_properties.begin ();
-       p != default_properties.end (); p++)
-    {
-      const property_list::pval_map_type pval_map = p->second;
-      std::string prefix = p->first;
-
-      for (property_list::pval_map_const_iterator q = pval_map.begin ();
-           q != pval_map.end ();
-           q++)
-        {
-          std::string s = q->first;
-
-          if (prefix == "axes" && (s == "position" || s == "units"))
-            new_defaults.set (prefix + s, q->second);
-          else if (prefix == "figure" && (s == "position" || s == "units"
-                                          || s == "windowstyle"
-                                          || s == "paperunits"))
-            new_defaults.set (prefix + s, q->second);
-        }
-    }
-
-  default_properties = new_defaults;
-}
-
 void
 root_figure::reset_default_properties (void)
 {
-  ::reset_default_properties (default_properties);
+  // empty list of local defaults
+  default_properties = property_list ();
+
+  xreset_default_properties (get_handle (), 
+                             xproperties.factory_defaults ());
 }
 
 // ---------------------------------------------------------------------
@@ -3409,6 +3782,9 @@
           position.run_listeners (POSTSET);
           mark_modified ();
         }
+      
+      if (paperpositionmode.is ("auto"))
+        paperposition.set (get_auto_paperposition ());
     }
 }
 
@@ -3628,6 +4004,122 @@
   return ret;
 }
 
+
+Matrix
+figure::properties::get_auto_paperposition (void)
+{
+  Matrix pos = get_position ().matrix_value ();
+  Matrix sz;
+  
+  caseless_str funits = get_units ();
+  caseless_str punits = get_paperunits ();
+
+  // Convert position from figure units to paperunits 
+  if (funits == "normalized" || punits == "normalized")
+    {
+      sz = screen_size_pixels ();
+      pos = convert_position (pos, funits, "inches", sz);
+
+      if (punits == "normalized")
+        sz = papersize_from_type ("points", get_papertype ());
+
+      pos = convert_position (pos, "inches", punits, sz);
+    }
+  else
+    pos = convert_position (pos, funits, punits, sz);
+
+  // Center the figure on the page
+  sz = get_papersize ().matrix_value ();
+
+  pos(0) = sz(0)/2 - pos(2)/2;
+  pos(1) = sz(1)/2 - pos(3)/2;
+
+  return pos;
+}
+
+/*
+%!test
+%! hf = figure ("visible", "off", "paperpositionmode", "auto");
+%! in_pos = [0 0 4 5];
+%! tol = 20 * eps ();
+%! unwind_protect
+%!   ## paperpositionmode "auto" converts figure size to paper units 
+%!   set (hf, "units", "inches");
+%!   set (hf, "position", in_pos);
+%!   set (hf, "paperunits", "centimeters");
+%!   psz = get (hf, "papersize");
+%!   fsz = in_pos(3:4) * 2.54;
+%!   pos = [(psz/2 .- fsz/2) fsz];  
+%!   set (hf, "paperpositionmode", "auto");
+%!   assert (get (hf, "paperposition"), pos, tol)
+%! unwind_protect_cleanup
+%!   close (hf);
+%! end_unwind_protect
+
+%!test
+%! hf = figure ("visible", "off", "paperpositionmode", "auto");
+%! in_pos = [0 0 4 5];
+%! tol = 20 * eps ();
+%! unwind_protect
+%!   ## likewise with normalized units 
+%!   set (hf, "units", "inches");
+%!   set (hf, "position", in_pos);
+%!   psz = get (hf, "papersize");
+%!   set (hf, "paperunits", "normalized");
+%!   fsz = in_pos(3:4) ./ psz;
+%!   pos = [([0.5 0.5] .- fsz/2) fsz];  
+%!   assert (get (hf, "paperposition"), pos, tol)
+%! unwind_protect_cleanup
+%!   close (hf);
+%! end_unwind_protect
+
+%!test
+%! hf = figure ("visible", "off", "paperpositionmode", "auto");
+%! in_pos = [0 0 4 5];
+%! tol = 20 * eps ();
+%! unwind_protect
+%!   ## changing papertype updates paperposition 
+%!   set (hf, "units", "inches");
+%!   set (hf, "position", in_pos);
+%!   set  (hf, "papertype", "a4");
+%!   psz = get (hf, "papersize");
+%!   fsz = in_pos(3:4);
+%!   pos = [(psz/2 .- fsz/2) fsz];  
+%!   assert (get (hf, "paperposition"), pos, tol)
+%! unwind_protect_cleanup
+%!   close (hf);
+%! end_unwind_protect
+
+%!test
+%! hf = figure ("visible", "off", "paperpositionmode", "auto");
+%! in_pos = [0 0 4 5];
+%! tol = 20 * eps ();
+%! unwind_protect
+%!   ## lanscape updates paperposition
+%!   set (hf, "units", "inches");
+%!   set (hf, "position", in_pos);
+%!   set (hf, "paperorientation", "landscape");
+%!   psz = get (hf, "papersize");
+%!   fsz = in_pos(3:4);
+%!   pos = [(psz/2 .- fsz/2) fsz];  
+%!   assert (get (hf, "paperposition"), pos, tol)
+%! unwind_protect_cleanup
+%!   close (hf);
+%! end_unwind_protect
+
+%!test
+%! hf = figure ("visible", "off", "paperpositionmode", "auto");
+%! in_pos = [0 0 4 5];
+%! unwind_protect
+%!   ## back to manual mode
+%!   set (hf, "paperposition", in_pos * 1.1)
+%!   assert (get (hf, "paperpositionmode"), "manual")
+%!   assert (get (hf, "paperposition"), in_pos * 1.1)
+%! unwind_protect_cleanup
+%!   close (hf);
+%! end_unwind_protect
+*/
+
 void
 figure::properties::update_paperunits (const caseless_str& old_paperunits)
 {
@@ -3696,6 +4188,9 @@
       // between update_papersize and update_papertype
       papersize.set (octave_value (sz));
     }
+
+  if (paperpositionmode.is ("auto"))
+    paperposition.set (get_auto_paperposition ());
 }
 
 void
@@ -3828,6 +4323,9 @@
       std::swap (sz(0), sz(1));
       papersize.set (octave_value (sz));
     }
+
+  if (paperpositionmode.is ("auto"))
+    paperposition.set (get_auto_paperposition ());
 }
 
 /*
@@ -3879,6 +4377,9 @@
       papersize.set (octave_value (sz));
       paperposition.set (octave_value (pos));
     }
+
+  if (paperpositionmode.is ("auto"))
+    paperposition.set (get_auto_paperposition ());
 }
 
 /*
@@ -3984,7 +4485,23 @@
 void
 figure::reset_default_properties (void)
 {
-  ::reset_default_properties (default_properties);
+  // empty list of local defaults
+  default_properties = property_list ();
+
+  property_list::pval_map_type plist = xproperties.factory_defaults ();
+  plist.erase ("units");
+  plist.erase ("position");
+  plist.erase ("paperunits");
+  plist.erase ("paperposition");
+  plist.erase ("windowstyle");
+  xreset_default_properties (get_handle (), plist);
+
+  // FIXME: the following short sleep is needed in order
+  //        to avoid a crash when using qt toolkit
+  Fsleep (octave_value (0.001));
+
+  // override with parents' defaults
+  override_defaults (*this);
 }
 
 // ---------------------------------------------------------------------
@@ -4405,27 +4922,42 @@
 
   visible = "on";
 
-  // Replace preserves Position and Units properties
-  if (mode != "replace")
+  // Replace/Reset preserves Position and Units properties
+  if (mode != "replace" && mode != "reset")
     {
       outerposition = default_axes_outerposition ();
       position = default_axes_position ();
       activepositionproperty = "outerposition";
     }
-
-  delete_children (true);
-
-  xlabel = gh_manager::make_graphics_handle ("text", __myhandle__,
-                                             false, false);
-
-  ylabel = gh_manager::make_graphics_handle ("text", __myhandle__,
-                                             false, false);
-
-  zlabel = gh_manager::make_graphics_handle ("text", __myhandle__,
-                                             false, false);
-
-  title = gh_manager::make_graphics_handle ("text", __myhandle__,
-                                            false, false);
+  
+  if (mode != "reset")
+    {
+      delete_children (true);
+
+      xlabel = gh_manager::make_graphics_handle ("text", __myhandle__,
+                                                 false, false);
+      ylabel = gh_manager::make_graphics_handle ("text", __myhandle__,
+                                                 false, false);
+      zlabel = gh_manager::make_graphics_handle ("text", __myhandle__,
+                                                 false, false);
+      title = gh_manager::make_graphics_handle ("text", __myhandle__,
+                                                false, false);
+      adopt (xlabel.handle_value ());
+      adopt (ylabel.handle_value ());
+      adopt (zlabel.handle_value ());
+      adopt (title.handle_value ());
+    }
+  else
+    {
+      graphics_object go = gh_manager::get_object (xlabel.handle_value ());
+      go.reset_default_properties ();
+      go = gh_manager::get_object (ylabel.handle_value ());
+      go.reset_default_properties ();
+      go = gh_manager::get_object (zlabel.handle_value ());
+      go.reset_default_properties ();
+      go = gh_manager::get_object (title.handle_value ());
+      go.reset_default_properties ();
+    }
 
   xset (xlabel.handle_value (), "handlevisibility", "off");
   xset (ylabel.handle_value (), "handlevisibility", "off");
@@ -4463,11 +4995,6 @@
   xset (zlabel.handle_value (), "autopos_tag", "zlabel");
   xset (title.handle_value (), "autopos_tag", "title");
 
-  adopt (xlabel.handle_value ());
-  adopt (ylabel.handle_value ());
-  adopt (zlabel.handle_value ());
-  adopt (title.handle_value ());
-
   update_transform ();
   sync_positions ();
   override_defaults (obj);
@@ -4508,13 +5035,25 @@
 axes::properties::remove_child (const graphics_handle& h)
 {
   if (xlabel.handle_value ().ok () && h == xlabel.handle_value ())
-    delete_text_child (xlabel);
+    {
+      delete_text_child (xlabel);
+      update_xlabel_position ();
+    }
   else if (ylabel.handle_value ().ok () && h == ylabel.handle_value ())
-    delete_text_child (ylabel);
+    {
+      delete_text_child (ylabel);
+      update_ylabel_position ();
+    }
   else if (zlabel.handle_value ().ok () && h == zlabel.handle_value ())
-    delete_text_child (zlabel);
+    {
+      delete_text_child (zlabel);
+      update_zlabel_position ();
+    }
   else if (title.handle_value ().ok () && h == title.handle_value ())
-    delete_text_child (title);
+    {
+      delete_text_child (title);
+      update_title_position ();
+    }
   else
     base_properties::remove_child (h);
 }
@@ -4704,7 +5243,8 @@
   if (camerapositionmode_is ("auto"))
     {
       Matrix tview = get_view ().matrix_value ();
-      double az = tview(0), el = tview(1);
+      double az = tview(0);
+      double el = tview(1);
       double d = 5 * sqrt (pb(0)*pb(0)+pb(1)*pb(1)+pb(2)*pb(2));
 
       if (el == 90 || el == -90)
@@ -4729,7 +5269,8 @@
   if (cameraupvectormode_is ("auto"))
     {
       Matrix tview = get_view ().matrix_value ();
-      double az = tview(0), el = tview(1);
+      double az = tview(0);
+      double el = tview(1);
 
       if (el == 90 || el == -90)
         {
@@ -4791,7 +5332,8 @@
   translate (x_view, -0.5, -0.5, -0.5);
 
   Matrix x_cube = x_view * unit_cube ();
-  ColumnVector cmin = x_cube.row_min (), cmax = x_cube.row_max ();
+  ColumnVector cmin = x_cube.row_min ();
+  ColumnVector cmax = x_cube.row_max ();
   double xM = cmax(0)-cmin(0);
   double yM = cmax(1)-cmin(1);
 
@@ -4897,9 +5439,11 @@
   const Matrix xlims = xform.xscale (get_xlim ().matrix_value ());
   const Matrix ylims = xform.yscale (get_ylim ().matrix_value ());
   const Matrix zlims = xform.zscale (get_zlim ().matrix_value ());
-  double x_min = xlims(0), x_max = xlims(1);
-  double y_min = ylims(0), y_max = ylims(1);
-  double z_min = zlims(0), z_max = zlims(1);
+
+  double x_min, x_max, y_min, y_max, z_min, z_max;
+  x_min = xlims(0), x_max = xlims(1);
+  y_min = ylims(0), y_max = ylims(1);
+  z_min = zlims(0), z_max = zlims(1);
 
   ColumnVector p1, p2, dir (3);
 
@@ -5011,18 +5555,14 @@
     {
       if (xaxislocation_is ("top"))
         {
-          double tmp = yPlane;
-          yPlane = yPlaneN;
-          yPlaneN = tmp;
+          std::swap (yPlane, yPlaneN);
           x2Dtop = true;
         }
       ypTick = yPlaneN;
       ypTickN = yPlane;
       if (yaxislocation_is ("right"))
         {
-          double tmp = xPlane;
-          xPlane = xPlaneN;
-          xPlaneN = tmp;
+          std::swap (xPlane, xPlaneN);
           y2Dright = true;
         }
       xpTick = xPlaneN;
@@ -5038,6 +5578,7 @@
 
   Matrix viewmat = get_view ().matrix_value ();
   nearhoriz = std::abs (viewmat(1)) <= 5;
+  is2D = viewmat(1) == 90;
 
   update_ticklength ();
 }
@@ -5139,7 +5680,9 @@
                                    get_xticklabel ().all_strings (),
                                    get_xlim ().matrix_value ());
 
-      double wmax = ext(0), hmax = ext(1), angle = 0;
+      double wmax = ext(0);
+      double hmax = ext(1);
+      double angle = 0;
       ColumnVector p =
         graphics_xform::xform_vector ((xpTickN+xpTick)/2, ypTick, zpTick);
 
@@ -5240,7 +5783,9 @@
                                    get_yticklabel ().all_strings (),
                                    get_ylim ().matrix_value ());
 
-      double wmax = ext(0)+4, hmax = ext(1), angle = 0;
+      double wmax = ext(0)+4;
+      double hmax = ext(1);
+      double angle = 0;
       ColumnVector p =
         graphics_xform::xform_vector (xpTick, (ypTickN+ypTick)/2, zpTick);
 
@@ -5333,7 +5878,9 @@
                                    get_zticklabel ().all_strings (),
                                    get_zlim ().matrix_value ());
 
-      double wmax = ext(0), hmax = ext(1), angle = 0;
+      double wmax = ext(0);
+      double hmax = ext(1);
+      double angle = 0;
       ColumnVector p;
 
       if (xySym)
@@ -5494,12 +6041,13 @@
     s = xmax(s, (limits(1) - limits(0)) / (pbfactor * dafactor));
 }
 
-static bool updating_aspectratios = false;
+static std::set<double> updating_aspectratios;
 
 void
 axes::properties::update_aspectratios (void)
 {
-  if (updating_aspectratios)
+  if (updating_aspectratios.find (get___myhandle__ ().value ()) !=
+      updating_aspectratios.end ())
     return;
 
   Matrix xlimits = get_xlim ().matrix_value ();
@@ -5565,7 +6113,7 @@
           unwind_protect frame;
           frame.protect_var (updating_aspectratios);
 
-          updating_aspectratios = true;
+          updating_aspectratios.insert (get___myhandle__ ().value ());
 
           dx = pba(0) *da(0);
           dy = pba(1) *da(1);
@@ -5889,6 +6437,23 @@
 }
 
 void
+axes::properties::set_rotate3d (const octave_value& v)
+{
+  rotate3d.set (v, false, false);
+  if (rotate3d_is ("on"))
+    {
+      // Disable rotate3d for 2D plots
+      if (get_is2D ())
+        {
+          rotate3d.set ("off", false, false);
+          pan.set ("on", false, false);
+        }
+      else
+       pan.set ("off", false, false);
+    }
+}
+
+void
 axes::properties::set_units (const octave_value& v)
 {
   if (! error_state)
@@ -6248,11 +6813,7 @@
   double tmp;
   // FIXME: should this be checked for somewhere else? (i.e. set{x,y,z}lim)
   if (hi < lo)
-    {
-      tmp = hi;
-      hi = lo;
-      lo = tmp;
-    }
+    std::swap (hi, lo);
 
   if (is_logscale)
     {
@@ -6269,15 +6830,17 @@
         }
     }
 
-  double tick_sep = calc_tick_sep (lo , hi);
-
-  if (is_logscale && ! (xisinf (hi) || xisinf (lo)))
-    {
-      // FIXME: what if (hi-lo) < tick_sep?
-      //         ex: loglog ([1 1.1])
-      tick_sep = std::max (tick_sep, 1.);
-      tick_sep = std::ceil (tick_sep);
-    }
+  double tick_sep;
+  
+  if (is_logscale)
+    {
+      if (! (xisinf (hi) || xisinf (lo)))
+        tick_sep = 1;  // Tick is every order of magnitude (bug #39449)
+      else
+        tick_sep = 0;
+    }
+  else
+    tick_sep = calc_tick_sep (lo , hi);
 
   int i1 = static_cast<int> (gnulib::floor (lo / tick_sep));
   int i2 = static_cast<int> (std::ceil (hi / tick_sep));
@@ -6402,7 +6965,8 @@
 #endif
 
   Matrix ext (1, 2, 0.0);
-  double wmax = 0., hmax = 0.;
+  double wmax, hmax;
+  wmax = hmax = 0.;
   int n = std::min (ticklabels.numel (), ticks.numel ());
   for (int i = 0; i < n; i++)
     {
@@ -6514,13 +7078,14 @@
     }
 }
 
-static bool updating_axis_limits = false;
+static std::set<double> updating_axis_limits;
 
 void
 axes::update_axis_limits (const std::string& axis_type,
                           const graphics_handle& h)
 {
-  if (updating_axis_limits)
+  if (updating_axis_limits.find (get_handle ().value ()) != 
+      updating_axis_limits.end ())
     return;
 
   Matrix kids = Matrix (1, 1, h.value ());
@@ -6679,7 +7244,7 @@
   unwind_protect frame;
   frame.protect_var (updating_axis_limits);
 
-  updating_axis_limits = true;
+  updating_axis_limits.insert (get_handle ().value ());
 
   switch (update_type)
     {
@@ -6722,7 +7287,10 @@
 void
 axes::update_axis_limits (const std::string& axis_type)
 {
-  if (updating_axis_limits || updating_aspectratios)
+  if ((updating_axis_limits.find (get_handle ().value ()) != 
+       updating_axis_limits.end ()) ||
+      (updating_aspectratios.find (get_handle ().value ()) !=
+       updating_aspectratios.end ()))
     return;
 
   Matrix kids = xproperties.get_children ();
@@ -6838,7 +7406,7 @@
   unwind_protect frame;
   frame.protect_var (updating_axis_limits);
 
-  updating_axis_limits = true;
+  updating_axis_limits.insert (get_handle ().value ());
 
   switch (update_type)
     {
@@ -6875,17 +7443,20 @@
     }
 
   xproperties.update_transform ();
+
+  // Disable rotate3d and select pan for 2D plots
+  xproperties.set_rotate3d (xproperties.get_rotate3d ());
 }
 
 inline
-double force_in_range (const double x, const double lower, const double upper)
+double force_in_range (double x, double lower, double upper)
 {
   if (x < lower)
-    { return lower; }
+    return lower;
   else if (x > upper)
-    { return upper; }
-  else
-    { return x; }
+    return upper;
+  else
+    return x;
 }
 
 static Matrix
@@ -7127,7 +7698,11 @@
 void
 axes::reset_default_properties (void)
 {
-  ::reset_default_properties (default_properties);
+  // empty list of local defaults
+  default_properties = property_list ();
+
+  // reset factory defaults
+  set_defaults ("reset");
 }
 
 void
@@ -7225,7 +7800,8 @@
 {
 #ifdef HAVE_FREETYPE
 
-  int halign = 0, valign = 0;
+  int halign = 0;
+  int valign = 0;
 
   if (horizontalalignment_is ("center"))
     halign = 1;
@@ -7340,6 +7916,197 @@
     return convert_cdata (*this, fvc,cdatamapping_is ("scaled"), 2);
 }
 
+static bool updating_patch_data = false;
+
+void
+patch::properties::update_fvc (void)
+{
+  if (updating_patch_data)
+    return;
+
+  Matrix xd = get_xdata ().matrix_value ();
+  Matrix yd = get_ydata ().matrix_value ();
+  Matrix zd = get_zdata ().matrix_value ();
+  NDArray cd = get_cdata ().array_value ();
+
+  bad_data_msg = std::string ();
+  if (xd.dims () != yd.dims () || 
+      (xd.dims () != zd.dims () && ! zd.is_empty ()))
+    {
+      bad_data_msg = "x/y/zdata should have the same dimensions";
+      return;
+    }
+
+  // Faces and Vertices
+  dim_vector dv;
+  bool is3D = false;
+  octave_idx_type nr = xd.rows ();
+  octave_idx_type nc = xd.columns ();
+  if (nr == 1 && nc > 1)
+    {
+      nr = nc;
+      nc = 1;
+      xd = xd.as_column ();
+      yd = yd.as_column ();
+      zd = zd.as_column ();
+    }
+
+  dv(0) = nr * nc;
+  if (zd.is_empty ())
+    dv(1) = 2;
+  else
+    {
+      dv(1) = 3;
+      is3D = true;
+    }
+
+  Matrix vert (dv);
+  Matrix idx (nc, nr);
+
+  octave_idx_type kk = 0;
+  for (octave_idx_type jj = 0; jj < nc; jj++)
+    {
+      for (octave_idx_type ii = 0; ii < nr; ii++)
+        {
+          vert(kk,0) = xd(ii,jj);
+          vert(kk,1) = yd(ii,jj);
+          if (is3D)
+            vert(kk,2) = zd(ii,jj);
+
+          idx(jj,ii) = static_cast<double> (kk+1);
+
+          kk++;
+        }
+    }
+
+  // facevertexcdata
+  Matrix fvc;
+  if (cd.ndims () == 3)
+    {
+      dv(0) = cd.rows () * cd.columns ();
+      dv(1) = cd.dims ()(2);
+      fvc = cd.reshape (dv);
+    }
+  else
+    fvc = cd.as_column ();
+
+  // FIXME: shouldn't we update facevertexalphadata here ?
+
+  unwind_protect frame;
+  frame.protect_var (updating_patch_data);
+  updating_patch_data = true;
+
+  faces.set (idx);
+  vertices.set (vert);
+  facevertexcdata.set (fvc);
+}
+
+
+void
+patch::properties::update_data (void)
+{
+  if (updating_patch_data)
+    return;
+
+  Matrix idx = get_faces ().matrix_value ().transpose ();
+  Matrix vert = get_vertices ().matrix_value ();
+  NDArray fvc = get_facevertexcdata ().array_value ();
+
+  octave_idx_type nfaces = idx.columns ();
+  octave_idx_type nvert = vert.rows ();
+
+  // Check all vertices in faces are defined
+  bad_data_msg = std::string ();
+  if (static_cast<double> (nvert) < idx.row_max ().max ())
+    {
+      bad_data_msg = "some vertices in \"faces\" property are undefined";
+      return;
+    }
+
+  // Replace NaNs
+  if (idx.any_element_is_inf_or_nan ())
+    {
+      for (octave_idx_type jj = 0; jj < idx.columns (); jj++)
+        {
+          double valid_vert = idx(0,jj);
+          bool turn_valid = false;
+          for (octave_idx_type ii = 0; ii < idx.rows (); ii++)
+            {
+              if (xisnan (idx(ii,jj)) || turn_valid)
+                {
+                  idx(ii,jj) = valid_vert;
+                  turn_valid = true;
+                }
+              else
+                valid_vert = idx(ii,jj);
+            }
+        }
+    }
+  
+  // Build cdata
+  dim_vector dv = dim_vector::alloc (3);
+  NDArray cd;
+  bool pervertex = false;
+
+  if (fvc.rows () == nfaces || fvc.rows () == 1)
+    {
+      dv(0) = 1;
+      dv(1) = fvc.rows ();
+      dv(2) = fvc.columns ();
+      cd = fvc.reshape (dv);
+    }
+  else 
+    {
+      if (! fvc.is_empty ())
+        {
+          dv(0) = idx.rows ();
+          dv(1) = nfaces;
+          dv(2) = fvc.columns ();
+          cd.resize (dv);
+          pervertex = true;
+        }
+    }
+
+  // Build x,y,zdata and eventually per vertex cdata 
+  Matrix xd (idx.dims ()); 
+  Matrix yd (idx.dims ());
+  Matrix zd;
+  bool has_zd = false;
+  if (vert.columns () > 2)
+    {
+      zd = Matrix (idx.dims ());
+      has_zd = true;
+    }
+
+  
+  for (octave_idx_type jj = 0; jj < nfaces; jj++)
+    {
+      for (octave_idx_type ii = 0; ii < idx.rows (); ii++)
+        {
+          octave_idx_type row = static_cast<octave_idx_type> (idx(ii,jj)-1);
+          xd(ii,jj) = vert(row,0);
+          yd(ii,jj) = vert(row,1);
+
+          if (has_zd)
+            zd(ii,jj) = vert(row,2);
+          
+          if (pervertex)
+            for (int kk = 0; kk < fvc.columns (); kk++)
+              cd(ii,jj,kk) = fvc(row,kk);
+        }
+    }
+
+
+  unwind_protect frame;
+  frame.protect_var (updating_patch_data);
+  updating_patch_data = true;
+
+  set_xdata (xd);
+  set_ydata (yd);
+  set_zdata (zd);
+  set_cdata (cd);
+}
+
 // ---------------------------------------------------------------------
 
 octave_value
@@ -7367,15 +8134,26 @@
       Matrix y = get_ydata ().matrix_value ();
       Matrix z = get_zdata ().matrix_value ();
 
-
-      int p = z.columns (), q = z.rows ();
-      int i1 = 0, i2 = 0, i3 = 0;
-      int j1 = 0, j2 = 0, j3 = 0;
+      int p = z.columns ();
+      int q = z.rows ();
+
+      // FIXME: There might be a cleaner way to do this.  When data is changed
+      // the update_xdata, update_ydata, update_zdata routines are called in a
+      // serial fashion.  Until the final call to update_zdata the matrices
+      // will be of mismatched dimensions which can cause an out-of-bound
+      // indexing in the code below.  This one-liner prevents calculating
+      // normals until dimensions match.
+      if (x.columns () != p || y.rows () != q)
+        return;
+
+      NDArray n (dim_vector (q, p, 3), 0.0);
 
       bool x_mat = (x.rows () == q);
       bool y_mat = (y.columns () == p);
 
-      NDArray n (dim_vector (q, p, 3), 0.0);
+      int i1, i2, i3, j1, j2, j3;
+      i1 = i2 = i3 = 0;
+      j1 = j2 = j3 = 0;
 
       for (int i = 0; i < p; i++)
         {
@@ -7969,7 +8747,14 @@
 void
 uitoolbar::reset_default_properties (void)
 {
-  ::reset_default_properties (default_properties);
+  // empty list of local defaults
+  default_properties = property_list ();
+
+  xreset_default_properties (get_handle (), 
+                             xproperties.factory_defaults ());
+
+  // override with parents' defaults
+  override_defaults (*this);
 }
 
 // ---------------------------------------------------------------------
@@ -8144,9 +8929,9 @@
 
   // No copying!
 
-  function_event (const function_event &);
-
-  function_event & operator = (const function_event &);
+  function_event (const function_event&);
+
+  function_event & operator = (const function_event&);
 };
 
 class
@@ -8348,7 +9133,7 @@
 }
 
 void
-gh_manager::do_post_callback (const graphics_handle& h, const std::string name,
+gh_manager::do_post_callback (const graphics_handle& h, const std::string& name,
                               const octave_value& data)
 {
   gh_manager::auto_lock guard;
@@ -8398,7 +9183,7 @@
 }
 
 void
-gh_manager::do_post_set (const graphics_handle& h, const std::string name,
+gh_manager::do_post_set (const graphics_handle& h, const std::string& name,
                          const octave_value& value, bool notify_toolkit)
 {
   gh_manager::auto_lock guard;
@@ -8595,12 +9380,17 @@
 
 DEFUN (reset, args, ,
        "-*- texinfo -*-\n\
-@deftypefn {Built-in Function} {} reset (@var{h}, @var{property})\n\
-Remove any defaults set for the handle @var{h}.  The default figure\n\
-properties of @qcode{\"position\"}, @qcode{\"units\"},\n\
-@qcode{\"windowstyle\"} and @qcode{\"paperunits\"} and the default axes\n\
-properties of @qcode{\"position\"} and @qcode{\"units\"} are not reset.\n\
-@seealso{cla, clf}\n\
+@deftypefn {Built-in Function} {} reset (@var{h})\n\
+Reset the properties of the graphic object @var{h} to their default values.\n\
+\n\
+For figures, the properties @qcode{\"position\"}, @qcode{\"units\"},\n\
+@qcode{\"windowstyle\"}, and @qcode{\"paperunits\"} are not affected.\n\
+For axes, the properties @qcode{\"position\"} and @qcode{\"units\"} are\n\
+not affected.\n\
+\n\
+The input @var{h} may also be a vector of graphic handles in which case\n\
+each individual object will be reset.\n\
+@seealso{cla, clf, newplot}\n\
 @end deftypefn")
 {
   int nargin = args.length ();
@@ -8617,20 +9407,148 @@
           // loop over graphics objects
           for (octave_idx_type n = 0; n < hcv.length (); n++)
             gh_manager::get_object (hcv(n)).reset_default_properties ();
+
+          if (! error_state)
+            Fdrawnow ();
         }
     }
 
   return octave_value ();
 }
 
+/*
+
+%!test  # line object
+%! hf = figure ("visible", "off");
+%! unwind_protect
+%!   tol = 20 * eps;
+%!   hax = axes ("defaultlinelinewidth", 3);
+%!   
+%!   hli = line (1:10, 1:10, 1:10, "marker", "o",
+%!               "markerfacecolor", "b", "linestyle", ":");
+%!   
+%!   reset (hli);
+%!   assert (get (hli, "marker"), get (0, "defaultlinemarker"));
+%!   assert (get (hli, "markerfacecolor"), 
+%!           get (0, "defaultlinemarkerfacecolor"));
+%!   assert (get (hli, "linestyle"), 
+%!           get (0, "defaultlinelinestyle"));
+%!   assert (get (hli, "linewidth"), 3, tol);  # parent axes defaults  
+%!   
+%! unwind_protect_cleanup
+%!   close (hf);
+%! end_unwind_protect
+
+%!test  # patch object
+%! hf = figure ("visible", "off");
+%! unwind_protect
+%!   tol = 20 * eps;
+%!   t1 = (1/16:1/8:1)' * 2*pi;
+%!   t2 = ((1/16:1/16:1)' + 1/32) * 2*pi;
+%!   x1 = sin (t1) - 0.8;
+%!   y1 = cos (t1);
+%!   x2 = sin (t2) + 0.8;
+%!   y2 = cos (t2);
+%!   vert = [x1, y1; x2, y2];
+%!   fac = [1:8,NaN(1,8);9:24];
+%!   hpa = patch ("Faces",fac, "Vertices",vert, "FaceColor","r");
+%!
+%!   reset (hpa);
+%!   assert (get (hpa, "faces"), get (0, "defaultpatchfaces"), tol);
+%!   assert (get (hpa, "vertices"), get (0, "defaultpatchvertices"), tol);
+%!   assert (get (hpa, "facevertexcdata"),
+%!           get (0, "defaultpatchfacevertexcdata"), tol);
+%! unwind_protect_cleanup
+%!   close (hf);
+%! end_unwind_protect
+
+%!test  # surface object
+%! hf = figure ("visible", "off");
+%! unwind_protect
+%!   tol = 20 * eps;
+%!   hsu = surface (peaks, "edgecolor", "none");
+%!
+%!   reset (hsu);
+%!   assert (get (hsu, "xdata"), get (0, "defaultsurfacexdata"), tol);
+%!   assert (get (hsu, "ydata"), get (0, "defaultsurfaceydata"), tol);
+%!   assert (get (hsu, "zdata"), get (0, "defaultsurfacezdata"), tol);
+%!   assert (get (hsu, "edgecolor"),
+%!           get (0, "defaultsurfaceedgecolor"), tol);
+%! unwind_protect_cleanup
+%!   close (hf);
+%! end_unwind_protect
+
+%!test  # image object
+%! hf = figure ("visible", "off");
+%! unwind_protect
+%!   tol = 20 * eps;   
+%!   him = image (rand (10,10), "cdatamapping", "scaled");
+%!
+%!   reset (him);
+%!   assert (get (him, "cdata"), get (0, "defaultimagecdata"), tol);
+%!   assert (get (him, "cdatamapping"),
+%!           get (0, "defaultimagecdatamapping"), tol);
+%! unwind_protect_cleanup
+%!   close (hf);
+%! end_unwind_protect
+
+%!test  # text object
+%! hf = figure ("visible", "off");
+%! unwind_protect
+%!   tol = 20 * eps;   
+%!   hte = text (5, 5, "Hi!", "fontsize", 20 ,"color", "r");
+%!
+%!   reset (hte);
+%!   assert (get (hte, "position"), get (0, "defaulttextposition"), tol);
+%!   assert (get (hte, "fontsize"), get (0, "defaulttextfontsize"), tol);
+%!   assert (get (hte, "color"), get (0, "defaulttextcolor"), tol);
+%! unwind_protect_cleanup
+%!   close (hf);
+%! end_unwind_protect
+
+%!test  # axes object  
+%! hf = figure ("visible", "off");
+%! unwind_protect
+%!   tol = 20 * eps;
+%!   pos = get (0, "defaultaxesposition") * .5;
+%!   hax = axes ("linewidth", 2, "position", pos);
+%!   title ("Reset me, please!");
+%! 
+%!   reset (hax);
+%!   assert (get (hax, "linewidth"), get (0, "defaultaxeslinewidth"), tol);
+%!   assert (get (hax, "position"), pos, tol); # axes position is unchanged
+%!   assert (get (hax, "default"), struct ()); # no more axes' defaults
+%!   assert (get (get (hax, "title"), "string"), "");
+%! unwind_protect_cleanup
+%!   close (hf);
+%! end_unwind_protect
+
+%!test  # root figure object
+%! set (0, "defaultfigurevisible", "off");
+%! hf = figure ("visible", "off", "paperunits", "centimeters", 
+%!              "papertype", "a4");
+%! unwind_protect
+%!   reset (hf);
+%!   assert (get (hf, "papertype"), get (0, "defaultfigurepapertype"));
+%!   assert (get (hf, "paperunits"), "centimeters"); # paperunits is unchanged
+%!   assert (get (hf, "visible"), get (0, "defaultfigurevisible"));
+%! unwind_protect_cleanup
+%!   close (hf);
+%!   set (0, "defaultfigurevisible", "remove");
+%! end_unwind_protect
+
+*/
+
 DEFUN (set, args, nargout,
        "-*- texinfo -*-\n\
 @deftypefn  {Built-in Function} {} set (@var{h}, @var{property}, @var{value}, @dots{})\n\
 @deftypefnx {Built-in Function} {} set (@var{h}, @var{properties}, @var{values})\n\
 @deftypefnx {Built-in Function} {} set (@var{h}, @var{pv})\n\
+@deftypefnx {Built-in Function} {@var{value_list} =} set (@var{h}, @var{property})\n\
+@deftypefnx {Built-in Function} {@var{all_value_list} =} set (@var{h})\n\
 Set named property values for the graphics handle (or vector of graphics\n\
 handles) @var{h}.\n\
-There are three ways how to give the property names and values:\n\
+There are three ways to give the property names and values:\n\
 \n\
 @itemize\n\
 @item as a comma separated list of @var{property}, @var{value} pairs\n\
@@ -8656,6 +9574,32 @@
 elements of @var{pv} will be set in all handles in @var{h} independent of\n\
 the dimensions of @var{pv}.\n\
 @end itemize\n\
+\n\
+@code{set} is also used to query the list of values a named property will\n\
+take.  @code{@var{clist} = set (@var{h}, \"property\")} will return the list\n\
+of possible values for @qcode{\"property\"} in the cell list @var{clist}.\n\
+If no output variable is used then the list is formatted and printed to the\n\
+screen.\n\
+\n\
+If no property is specified (@code{@var{slist} = set (@var{h})}) then a\n\
+structure @var{slist} is returned where the fieldnames are the properties of\n\
+the object @var{h} and the fields are the list of possible values for each\n\
+property.  If no output variable is used then the list is formatted and\n\
+printed to the screen.\n\
+\n\
+For example,\n\
+\n\
+@example\n\
+@group\n\
+hf = figure ();\n\
+set (hf, \"paperorientation\")\n\
+@result{}  paperorientation:  [ landscape | @{portrait@} | rotated ]\n\
+@end group\n\
+@end example\n\
+\n\
+@noindent\n\
+shows the paperorientation property can take three values with the default\n\
+being @qcode{\"portrait\"}.\n\
 @seealso{get}\n\
 @end deftypefn")
 {
@@ -8706,6 +9650,35 @@
                     {
                       obj.set (args(1).map_value ());
                     }
+                  else if (nargin == 2 && args(1).is_string ())
+                    {
+                      std::string property = args(1).string_value ();
+                      
+                      octave_map pmap = obj.values_as_struct ();
+
+                      if (obj.has_readonly_property (property))
+                        if (nargout != 0)
+                          retval = Matrix ();
+                        else
+                          octave_stdout << "set: " << property
+                                        <<" is read-only" << std::endl;
+                      else if (pmap.isfield (property))
+                        {
+                          if (nargout != 0)
+                            retval = pmap.getfield (property)(0);
+                          else
+                            {
+                              std::string s = obj.value_as_string (property);
+                              if (! error_state)
+                                octave_stdout << s;
+                            }
+                        }
+                      else
+                        {
+                          error ("set: unknown property");
+                          break;
+                        }
+                    }
                   else if (nargin == 1)
                     {
                       if (nargout != 0)
@@ -8748,7 +9721,7 @@
 }
 
 static std::string
-get_graphics_object_type (const double val)
+get_graphics_object_type (double val)
 {
   std::string retval;
 
@@ -9380,7 +10353,7 @@
     {
       graphics_handle h = octave_NaN;
 
-      const NDArray vals = args (0).array_value ();
+      const NDArray vals = args(0).array_value ();
 
       if (! error_state)
         {
@@ -9657,12 +10630,13 @@
 
           while (pa != available_toolkits.end ())
             {
-              std::string name = *pa++;
-
-              if (name == "qt"
-                  || (name == "fltk"
-                      && available_toolkits.find ("qt") == available_toolkits.end ()))
-                dtk = name;
+              std::string tk_name = *pa++;
+
+              if (tk_name == "qt"
+                  || (tk_name == "fltk"
+                      && available_toolkits.find ("qt")
+                        == available_toolkits.end ()))
+                dtk = tk_name;
             }
         }
     }
@@ -10206,7 +11180,7 @@
 static bool
 compare_property_values (const octave_value& o1, const octave_value& o2)
 {
-  octave_value_list args (2);
+  octave_value_list args(2);
 
   args(0) = o1;
   args(1) = o2;
--- a/libinterp/corefcn/graphics.in.h	Fri Aug 01 09:06:21 2014 -0400
+++ b/libinterp/corefcn/graphics.in.h	Fri Aug 01 12:10:05 2014 -0400
@@ -296,7 +296,7 @@
 
   graphics_handle get_parent (void) const { return parent; }
 
-  void set_parent (const graphics_handle &h) { parent = h; }
+  void set_parent (const graphics_handle& h) { parent = h; }
 
   bool is_hidden (void) const { return hidden; }
 
@@ -1028,7 +1028,7 @@
     validate ();
   }
 
-  color_values (std::string str)
+  color_values (const std::string& str)
     : xrgb (1, 3)
   {
     if (! str2rgb (str))
@@ -1076,7 +1076,7 @@
 private:
   Matrix xrgb;
 
-  OCTINTERP_API bool str2rgb (std::string str);
+  OCTINTERP_API bool str2rgb (const std::string& str);
 };
 
 class color_property : public base_property
@@ -1631,7 +1631,7 @@
   }
 
   children_property (const std::string& nm, const graphics_handle& h,
-                     const Matrix &val)
+                     const Matrix& val)
     : base_property (nm, h), children_list ()
   {
     do_init_children (val);
@@ -1651,12 +1651,12 @@
 
   base_property* clone (void) const { return new children_property (*this); }
 
-  bool remove_child (const double &val)
+  bool remove_child (double val)
   {
     return do_remove_child (val);
   }
 
-  void adopt (const double &val)
+  void adopt (double val)
   {
     do_adopt_child (val);
   }
@@ -1759,14 +1759,14 @@
   }
 
 private:
-  void do_init_children (const Matrix &val)
+  void do_init_children (const Matrix& val)
   {
     children_list.clear ();
     for (octave_idx_type i = 0; i < val.numel (); i++)
       children_list.push_front (val.xelem (i));
   }
 
-  void do_init_children (const std::list<double> &val)
+  void do_init_children (const std::list<double>& val)
   {
     children_list.clear ();
     for (const_children_list_iterator p = val.begin (); p != val.end (); p++)
@@ -1800,7 +1800,7 @@
     return false;
   }
 
-  void do_adopt_child (const double &val)
+  void do_adopt_child (double val)
   {
     children_list.push_front (val);
   }
@@ -2594,7 +2594,7 @@
 protected:
   struct cmp_caseless_str
   {
-    bool operator () (const caseless_str &a, const caseless_str &b) const
+    bool operator () (const caseless_str& a, const caseless_str& b) const
     {
       std::string a1 = a;
       std::transform (a1.begin (), a1.end (), a1.begin (), tolower);
@@ -2698,8 +2698,21 @@
     return octave_value ();
   }
 
+  virtual property_list get_factory_defaults_list (void) const
+  {
+    error ("base_graphics_object::get_factory_defaults_list: invalid graphics object");
+    return property_list ();
+  }
+
+  virtual bool has_readonly_property (const caseless_str& pname) const
+  {
+    return base_properties::has_readonly_property (pname);
+  }
+
   virtual std::string values_as_string (void);
 
+  virtual std::string value_as_string (const std::string& prop);
+
   virtual octave_scalar_map values_as_struct (void);
 
   virtual graphics_handle get_parent (void) const
@@ -2822,16 +2835,7 @@
 
   virtual void remove_all_listeners (void);
 
-  virtual void reset_default_properties (void)
-  {
-    if (valid_object ())
-      {
-        std::string msg = (type () + "::reset_default_properties");
-        gripe_not_implemented (msg.c_str ());
-      }
-    else
-      error ("base_graphics_object::default: invalid graphics object");
-  }
+  virtual void reset_default_properties (void);
 
 protected:
   virtual void initialize (const graphics_object& go)
@@ -2969,8 +2973,23 @@
     return rep->get_factory_defaults ();
   }
 
+  property_list get_factory_defaults_list (void) const
+  {
+    return rep->get_factory_defaults_list ();
+  }
+
+  bool has_readonly_property (const caseless_str& pname) const
+  {
+    return rep->has_readonly_property (pname);
+  }
+
   std::string values_as_string (void) { return rep->values_as_string (); }
 
+  std::string value_as_string (const std::string& prop) 
+  { 
+    return rep->value_as_string (prop); 
+  }
+
   octave_map values_as_struct (void) { return rep->values_as_struct (); }
 
   graphics_handle get_parent (void) const { return rep->get_parent (); }
@@ -3090,20 +3109,10 @@
     // See the genprops.awk script for an explanation of the
     // properties declarations.
 
-    // FIXME: it seems strange to me that the diary, diaryfile,
-    // echo, errormessage, format, formatspacing, language, and
-    // recursionlimit properties are here.
-    // WTF do they have to do with graphics?
-    // Also note that these properties (and the monitorpositions,
-    // pointerlocation, and pointerwindow properties) are not yet used
-    // by Octave, so setting them will have no effect, and changes
-    // made elswhere (say, the diary or format functions) will not
-    // cause these properties to be updated.
-    // ANSWER: Matlab defines these properties and uses them in
-    // the same way that Octave uses an internal static variable to
-    // keep track of state.  set (0, "echo", "on") is equivalent
-    // to Octave's echo ("on").  Maybe someday we can connect callbacks
-    // that actually call Octave's own functions for this.
+    // FIXME: Properties that still dont have callbacks are:
+    // language, monitorpositions, pointerlocation, pointerwindow.
+    // Note that these properties are not yet used by Octave, so setting
+    // them will have no effect.
 
     // Programming note: Keep property list sorted if new ones are added.
 
@@ -3111,18 +3120,18 @@
       handle_property callbackobject Sr , graphics_handle ()
       array_property commandwindowsize r , Matrix (1, 2, 0)
       handle_property currentfigure S , graphics_handle ()
-      bool_property diary , "off"
-      string_property diaryfile , "diary"
-      bool_property echo , "off"
-      string_property errormessage , ""
+      bool_property diary GS , "off"
+      string_property diaryfile GS , "diary"
+      bool_property echo GS , "off"
+      string_property errormessage Gr , ""
       string_property fixedwidthfontname , "Courier"
-      radio_property format , "+|bank|bit|hex|long|longe|longeng|longg|native-bit|native-hex|none|rational|{short}|shorte|shorteng|shortg"
-      radio_property formatspacing , "compact|{loose}"
+      radio_property format GS , "+|bank|bit|hex|long|longe|longeng|longg|native-bit|native-hex|none|rat|{short}|shorte|shorteng|shortg"
+      radio_property formatspacing GS , "compact|{loose}"
       string_property language , "ascii"
       array_property monitorpositions , Matrix (1, 4, 0)
       array_property pointerlocation , Matrix (1, 2, 0)
       double_property pointerwindow r , 0.0
-      double_property recursionlimit , 256.0
+      double_property recursionlimit GS , 256.0
       double_property screendepth r , default_screendepth ()
       double_property screenpixelsperinch r , default_screenpixelsperinch ()
       array_property screensize r , default_screensize ()
@@ -3132,6 +3141,7 @@
 
   private:
     std::list<graphics_handle> cbo_stack;
+
   };
 
 private:
@@ -3217,6 +3227,11 @@
     return factory_properties.as_struct ("factory");
   }
 
+  property_list get_factory_defaults_list (void) const
+  {
+    return factory_properties;
+  }
+
   base_properties& get_properties (void) { return xproperties; }
 
   const base_properties& get_properties (void) const { return xproperties; }
@@ -3224,6 +3239,14 @@
   bool valid_object (void) const { return true; }
 
   void reset_default_properties (void);
+  
+  bool has_readonly_property (const caseless_str& pname) const
+  {
+    bool retval = xproperties.has_readonly_property (pname);
+    if (! retval)
+      retval = base_properties::has_readonly_property (pname);
+    return retval;
+  }
 
 private:
   property_list default_properties;
@@ -3333,8 +3356,8 @@
       bool_property numbertitle , "on"
       array_property outerposition s , Matrix (1, 4, -1.0)
       radio_property paperorientation U , "{portrait}|landscape|rotated"
-      array_property paperposition , default_figure_paperposition ()
-      radio_property paperpositionmode , "auto|{manual}"
+      array_property paperposition m , default_figure_paperposition ()
+      radio_property paperpositionmode au , "auto|{manual}"
       array_property papersize U , default_figure_papersize ()
       radio_property papertype SU , "{usletter}|uslegal|a0|a1|a2|a3|a4|a5|b0|b1|b2|b3|b4|b5|arch-a|arch-b|arch-c|arch-d|arch-e|a|b|c|d|e|tabloid|<custom>"
       radio_property paperunits Su , "{inches}|centimeters|normalized|points"
@@ -3381,7 +3404,15 @@
       position.add_constraint (dim_vector (1, 4));
     }
 
-  private:
+  private:    
+    Matrix get_auto_paperposition (void);
+
+    void update_paperpositionmode (void)
+    {
+      if (paperpositionmode.is ("auto"))
+        paperposition.set (get_auto_paperposition ());
+    }
+
     mutable graphics_toolkit toolkit;
   };
 
@@ -3448,6 +3479,14 @@
   bool valid_object (void) const { return true; }
 
   void reset_default_properties (void);
+  
+  bool has_readonly_property (const caseless_str& pname) const
+  {
+    bool retval = xproperties.has_readonly_property (pname);
+    if (! retval)
+      retval = base_properties::has_readonly_property (pname);
+    return retval;
+  }
 
 private:
   property_list default_properties;
@@ -3633,6 +3672,7 @@
     bool get_x2Dtop (void) const { return x2Dtop; }
     bool get_y2Dright (void) const { return y2Dright; }
     bool get_layer2Dtop (void) const { return layer2Dtop; }
+    bool get_is2D (void) const { return is2D; }
     bool get_xySym (void) const { return xySym; }
     bool get_xyzSym (void) const { return xyzSym; }
     bool get_zSign (void) const { return zSign; }
@@ -3671,11 +3711,11 @@
     double fx, fy, fz;
     double xticklen, yticklen, zticklen;
     double xtickoffset, ytickoffset, ztickoffset;
-    bool x2Dtop, y2Dright, layer2Dtop;
+    bool x2Dtop, y2Dright, layer2Dtop, is2D;
     bool xySym, xyzSym, zSign, nearhoriz;
 
 #if HAVE_FREETYPE
-    // freetype renderer, used for calculation of text (tick labels) size
+    // FreeType renderer, used for calculation of text (tick labels) size
     ft_render text_renderer;
 #endif
 
@@ -3684,6 +3724,13 @@
 
     void delete_text_child (handle_property& h);
 
+    void set_pan (const octave_value& val)
+    {
+      pan.set (val, false, false);
+      if (pan_is ("on") || pan_is ("xon") || pan_is ("yon"))
+        rotate3d.set ("off", false, false);
+    }
+
     // See the genprops.awk script for an explanation of the
     // properties declarations.
     // Programming note: Keep property list sorted if new ones are added.
@@ -3698,7 +3745,7 @@
       radio_property camerapositionmode , "{auto}|manual"
       array_property cameratarget m , Matrix (1, 3, 0.0)
       radio_property cameratargetmode , "{auto}|manual"
-      array_property cameraupvector m , Matrix ()
+      array_property cameraupvector m , Matrix (1, 3, 0.0)
       radio_property cameraupvectormode , "{auto}|manual"
       double_property cameraviewangle m , 10.0
       radio_property cameraviewanglemode , "{auto}|manual"
@@ -3724,12 +3771,15 @@
       any_property linestyleorder S , "-"
       double_property linewidth , 0.5
       radio_property minorgridlinestyle , "-|--|{:}|-.|none"
+      double_property mouse_wheel_zoom , 0.05
       radio_property nextplot , "add|replacechildren|{replace}"
       array_property outerposition u , default_axes_outerposition ()
+      radio_property pan s , "{on}|xon|yon|off"
       array_property plotboxaspectratio mu , Matrix (1, 3, 1.0)
       radio_property plotboxaspectratiomode u , "{auto}|manual"
       array_property position u , default_axes_position ()
       radio_property projection , "{orthographic}|perspective"
+      radio_property rotate3d S , "{off}|on"
       radio_property tickdir mu , "{in}|out"
       radio_property tickdirmode u , "{auto}|manual"
       array_property ticklength u , default_axes_ticklength ()
@@ -3737,7 +3787,7 @@
       handle_property title SOf , gh_manager::make_graphics_handle ("text", __myhandle__, false, false, false)
       // FIXME: uicontextmenu should be moved here.
       radio_property units SU , "{normalized}|inches|centimeters|points|pixels|characters"
-      array_property view u , Matrix ()
+      array_property view u , default_axes_view ()
       radio_property xaxislocation u , "{bottom}|top|zero"
       color_property xcolor , color_values (0, 0, 0)
       radio_property xdir u , "{normal}|reverse"
@@ -4133,7 +4183,6 @@
 
   void set_defaults (const std::string& mode)
   {
-    remove_all_listeners ();
     xproperties.set_defaults (*this, mode);
   }
 
@@ -4170,6 +4219,14 @@
 
   void reset_default_properties (void);
 
+  bool has_readonly_property (const caseless_str& pname) const
+  {
+    bool retval = xproperties.has_readonly_property (pname);
+    if (! retval)
+      retval = base_properties::has_readonly_property (pname);
+    return retval;
+  }
+
 protected:
   void initialize (const graphics_object& go);
 
@@ -4250,6 +4307,14 @@
   const base_properties& get_properties (void) const { return xproperties; }
 
   bool valid_object (void) const { return true; }
+
+  bool has_readonly_property (const caseless_str& pname) const
+  {
+    bool retval = xproperties.has_readonly_property (pname);
+    if (! retval)
+      retval = base_properties::has_readonly_property (pname);
+    return retval;
+  }
 };
 
 // ---------------------------------------------------------------------
@@ -4307,7 +4372,7 @@
       radio_property interpreter u , "{tex}|none|latex"
       radio_property linestyle , "{-}|--|:|-.|none"
       double_property linewidth , 0.5
-      double_property margin , 1
+      double_property margin , 2
       array_property position smu , Matrix (1, 3, 0.0)
       double_property rotation mu , 0
       text_label_property string u , ""
@@ -4333,7 +4398,7 @@
     Matrix get_extent_matrix (void) const;
     const uint8NDArray& get_pixels (void) const { return pixels; }
 #if HAVE_FREETYPE
-    // freetype renderer, used for calculation of text size
+    // FreeType renderer, used for calculation of text size
     ft_render renderer;
 #endif
 
@@ -4415,6 +4480,14 @@
   const base_properties& get_properties (void) const { return xproperties; }
 
   bool valid_object (void) const { return true; }
+
+  bool has_readonly_property (const caseless_str& pname) const
+  {
+    bool retval = xproperties.has_readonly_property (pname);
+    if (! retval)
+      retval = base_properties::has_readonly_property (pname);
+    return retval;
+  }
 };
 
 // ---------------------------------------------------------------------
@@ -4442,13 +4515,14 @@
     // Programming note: Keep property list sorted if new ones are added.
 
     BEGIN_PROPERTIES (image)
-      array_property alphadata u , Matrix ()
-      radio_property alphadatamapping al , "none|direct|{scaled}"
-      array_property cdata u , Matrix ()
+      array_property alphadata u , Matrix (1, 1, 1.0)
+      radio_property alphadatamapping al , "{none}|direct|scaled"
+      array_property cdata u , default_image_cdata ()
       radio_property cdatamapping al , "scaled|{direct}"
+      string_property displayname , ""
       radio_property erasemode , "{normal}|none|xor|background"
-      row_vector_property xdata u , Matrix ()
-      row_vector_property ydata u , Matrix ()
+      row_vector_property xdata mu , Matrix ()
+      row_vector_property ydata mu , Matrix ()
       // hidden properties for limit computation
       row_vector_property alim hlr , Matrix ()
       row_vector_property clim hlr , Matrix ()
@@ -4458,6 +4532,8 @@
       bool_property climinclude hlg , "on"
       bool_property xliminclude hl , "on"
       bool_property yliminclude hl , "on"
+      radio_property xdatamode ha , "{auto}|manual"
+      radio_property ydatamode ha , "{auto}|manual"
     END_PROPERTIES
 
   protected:
@@ -4494,10 +4570,25 @@
         set_clim (cdata.get_limits ());
       else
         clim = cdata.get_limits ();
+
+      if (xdatamode.is ("auto"))
+        update_xdata ();
+      
+      if (ydatamode.is ("auto"))
+        update_ydata ();
     }
 
     void update_xdata (void)
     {
+      if (xdata.get ().is_empty ())
+        set_xdatamode ("auto");
+        
+      if (xdatamode.is ("auto"))
+        {
+          set_xdata (get_auto_xdata ());
+          set_xdatamode ("auto");
+        }
+      
       Matrix limits = xdata.get_limits ();
       float dp = pixel_xsize ();
 
@@ -4508,6 +4599,15 @@
 
     void update_ydata (void)
     {
+      if (ydata.get ().is_empty ())
+        set_ydatamode ("auto");
+        
+      if (ydatamode.is ("auto"))
+        {
+          set_ydata (get_auto_ydata ()); 
+          set_ydatamode ("auto");
+        }
+      
       Matrix limits = ydata.get_limits ();
       float dp = pixel_ysize ();
 
@@ -4516,6 +4616,30 @@
       set_ylim (limits);
     }
 
+    Matrix get_auto_xdata (void)
+    {
+      dim_vector dv = get_cdata ().dims ();
+      Matrix data;
+      if (dv(1) > 0.)
+        {
+          data = Matrix (1, 2, 1);
+          data(1) = dv(1);
+        }
+      return data;
+    }
+
+    Matrix get_auto_ydata (void)
+    {
+      dim_vector dv = get_cdata ().dims ();
+      Matrix data;
+      if (dv(0) > 0.)
+        {
+          data = Matrix (1, 2, 1);
+          data(1) = dv(0);
+        }
+      return data;
+    }
+
     float pixel_size (octave_idx_type dim, const Matrix limits)
     {
       octave_idx_type l = dim - 1;
@@ -4562,6 +4686,14 @@
   const base_properties& get_properties (void) const { return xproperties; }
 
   bool valid_object (void) const { return true; }
+
+  bool has_readonly_property (const caseless_str& pname) const
+  {
+    bool retval = xproperties.has_readonly_property (pname);
+    if (! retval)
+      retval = base_properties::has_readonly_property (pname);
+    return retval;
+  }
 };
 
 // ---------------------------------------------------------------------
@@ -4574,6 +4706,14 @@
   public:
     octave_value get_color_data (void) const;
 
+    // Matlab allows incoherent data to be stored into patch properties.
+    // The patch should then be ignored by the renderer. 
+    bool has_bad_data (std::string &msg) const 
+      { 
+        msg = bad_data_msg;
+        return ! msg.empty ();
+      }
+
     bool is_aliminclude (void) const
     { return (aliminclude.is_on () && alphadatamapping.is ("scaled")); }
     std::string get_aliminclude (void) const
@@ -4603,9 +4743,9 @@
       double_radio_property facealpha , double_radio_property (1.0, radio_values ("flat|interp"))
       color_property facecolor , color_property (color_values (0, 0, 0), radio_values ("none|flat|interp"))
       radio_property facelighting , "{none}|flat|gouraud|phong"
-      array_property faces , Matrix ()
+      array_property faces u , default_patch_faces ()
       array_property facevertexalphadata , Matrix ()
-      array_property facevertexcdata , Matrix ()
+      array_property facevertexcdata u , Matrix ()
       // FIXME: interpreter is not a property of a Matlab patch.
       //        Octave uses this for legend() with the string displayname.
       radio_property interpreter , "{tex}|none|latex"
@@ -4618,11 +4758,11 @@
       radio_property normalmode , "{auto}|manual"
       double_property specularcolorreflectance , 1.0
       double_property specularexponent , 10.0
-      double_property specularstrength , 0.6
+      double_property specularstrength , 0.9
       array_property vertexnormals , Matrix ()
-      array_property vertices , Matrix ()
-      array_property xdata u , Matrix ()
-      array_property ydata u , Matrix ()
+      array_property vertices u , default_patch_vertices ()
+      array_property xdata u , default_patch_xdata ()
+      array_property ydata u , default_patch_ydata ()
       array_property zdata u , Matrix ()
 
       // hidden properties for limit computation
@@ -4656,17 +4796,67 @@
     }
 
   private:
-    void update_xdata (void) { set_xlim (xdata.get_limits ()); }
-    void update_ydata (void) { set_ylim (ydata.get_limits ()); }
-    void update_zdata (void) { set_zlim (zdata.get_limits ()); }
+    std::string bad_data_msg;
+
+    void update_faces (void) { update_data ();}
+
+    void update_vertices (void)  {  update_data ();}
+
+    void update_facevertexcdata (void) { update_data ();}
+
+    void update_fvc (void);
+
+    void update_xdata (void) 
+    { 
+      if (get_xdata ().is_empty ())
+        {
+          // For compatibility with matlab behavior, 
+          // if x/ydata are set empty, silently empty other *data and 
+          // faces properties while vertices remain unchanged. 
+          set_ydata (Matrix ());
+          set_zdata (Matrix ());
+          set_cdata (Matrix ());
+          set_faces (Matrix ());
+        }
+      else
+        update_fvc ();
+
+      set_xlim (xdata.get_limits ());
+    }
+
+    void update_ydata (void) 
+    { 
+      if (get_ydata ().is_empty ())
+        {
+          set_xdata (Matrix ());
+          set_zdata (Matrix ());
+          set_cdata (Matrix ());
+          set_faces (Matrix ());
+        }
+      else
+        update_fvc ();
+
+      set_ylim (ydata.get_limits ());
+    }
+
+    void update_zdata (void) 
+    { 
+      update_fvc ();
+      set_zlim (zdata.get_limits ());
+    }
 
     void update_cdata (void)
     {
+      update_fvc ();
+
       if (cdatamapping_is ("scaled"))
         set_clim (cdata.get_limits ());
       else
         clim = cdata.get_limits ();
     }
+
+
+    void update_data (void);
   };
 
 private:
@@ -4686,6 +4876,14 @@
   const base_properties& get_properties (void) const { return xproperties; }
 
   bool valid_object (void) const { return true; }
+
+  bool has_readonly_property (const caseless_str& pname) const
+  {
+    bool retval = xproperties.has_readonly_property (pname);
+    if (! retval)
+      retval = base_properties::has_readonly_property (pname);
+    return retval;
+  }
 };
 
 // ---------------------------------------------------------------------
@@ -4713,11 +4911,11 @@
     // Programming note: Keep property list sorted if new ones are added.
 
     BEGIN_PROPERTIES (surface)
-      array_property alphadata u , Matrix ()
+      array_property alphadata u , Matrix (1, 1, 1.0)
       radio_property alphadatamapping l , "none|direct|{scaled}"
       double_property ambientstrength , 0.3
       radio_property backfacelighting , "unlit|lit|{reverselit}"
-      array_property cdata u , Matrix ()
+      array_property cdata u , default_surface_cdata ()
       radio_property cdatamapping al , "{scaled}|direct"
       string_property cdatasource , ""
       double_property diffusestrength , 0.6
@@ -4744,11 +4942,11 @@
       double_property specularexponent , 10
       double_property specularstrength , 0.9
       array_property vertexnormals u , Matrix ()
-      array_property xdata u , Matrix ()
+      array_property xdata u , default_surface_xdata ()
       string_property xdatasource , ""
-      array_property ydata u , Matrix ()
+      array_property ydata u , default_surface_ydata ()
       string_property ydatasource , ""
-      array_property zdata u , Matrix ()
+      array_property zdata u , default_surface_zdata ()
       string_property zdatasource , ""
 
       // hidden properties for limit computation
@@ -4778,6 +4976,7 @@
       alphadata.add_constraint ("uint8");
       alphadata.add_constraint (dim_vector (-1, -1));
       vertexnormals.add_constraint (dim_vector (-1, -1, 3));
+      vertexnormals.add_constraint (dim_vector (0, 0));
     }
 
   private:
@@ -4841,6 +5040,14 @@
   const base_properties& get_properties (void) const { return xproperties; }
 
   bool valid_object (void) const { return true; }
+
+  bool has_readonly_property (const caseless_str& pname) const
+  {
+    bool retval = xproperties.has_readonly_property (pname);
+    if (! retval)
+      retval = base_properties::has_readonly_property (pname);
+    return retval;
+  }
 };
 
 // ---------------------------------------------------------------------
@@ -4919,6 +5126,14 @@
   void update_axis_limits (const std::string& axis_type,
                            const graphics_handle& h);
 
+  bool has_readonly_property (const caseless_str& pname) const
+  {
+    bool retval = xproperties.has_readonly_property (pname);
+    if (! retval)
+      retval = base_properties::has_readonly_property (pname);
+    return retval;
+  }
+
 };
 
 // ---------------------------------------------------------------------
@@ -4980,6 +5195,14 @@
 
   bool valid_object (void) const { return true; }
 
+  bool has_readonly_property (const caseless_str& pname) const
+  {
+    bool retval = xproperties.has_readonly_property (pname);
+    if (! retval)
+      retval = base_properties::has_readonly_property (pname);
+    return retval;
+  }
+
 };
 
 // ---------------------------------------------------------------------
@@ -5027,6 +5250,14 @@
 
   bool valid_object (void) const { return true; }
 
+  bool has_readonly_property (const caseless_str& pname) const
+  {
+    bool retval = xproperties.has_readonly_property (pname);
+    if (! retval)
+      retval = base_properties::has_readonly_property (pname);
+    return retval;
+  }
+
 };
 
 // ---------------------------------------------------------------------
@@ -5119,6 +5350,14 @@
   const base_properties& get_properties (void) const { return xproperties; }
 
   bool valid_object (void) const { return true; }
+
+  bool has_readonly_property (const caseless_str& pname) const
+  {
+    bool retval = xproperties.has_readonly_property (pname);
+    if (! retval)
+      retval = base_properties::has_readonly_property (pname);
+    return retval;
+  }
 };
 
 // ---------------------------------------------------------------------
@@ -5186,6 +5425,14 @@
   const base_properties& get_properties (void) const { return xproperties; }
 
   bool valid_object (void) const { return true; }
+
+  bool has_readonly_property (const caseless_str& pname) const
+  {
+    bool retval = xproperties.has_readonly_property (pname);
+    if (! retval)
+      retval = base_properties::has_readonly_property (pname);
+    return retval;
+  }
 };
 
 // ---------------------------------------------------------------------
@@ -5273,6 +5520,14 @@
 
   void reset_default_properties (void);
 
+  bool has_readonly_property (const caseless_str& pname) const
+  {
+    bool retval = xproperties.has_readonly_property (pname);
+    if (! retval)
+      retval = base_properties::has_readonly_property (pname);
+    return retval;
+  }
+
 private:
   property_list default_properties;
 };
@@ -5325,6 +5580,14 @@
 
   bool valid_object (void) const { return true; }
 
+  bool has_readonly_property (const caseless_str& pname) const
+  {
+    bool retval = xproperties.has_readonly_property (pname);
+    if (! retval)
+      retval = base_properties::has_readonly_property (pname);
+    return retval;
+  }
+
 };
 
 // ---------------------------------------------------------------------
@@ -5378,16 +5641,24 @@
 
   bool valid_object (void) const { return true; }
 
+  bool has_readonly_property (const caseless_str& pname) const
+  {
+    bool retval = xproperties.has_readonly_property (pname);
+    if (! retval)
+      retval = base_properties::has_readonly_property (pname);
+    return retval;
+  }
+
 };
 
 // ---------------------------------------------------------------------
 
 octave_value
-get_property_from_handle (double handle, const std::string &property,
-                          const std::string &func);
+get_property_from_handle (double handle, const std::string& property,
+                          const std::string& func);
 bool
-set_property_in_handle (double handle, const std::string &property,
-                        const octave_value &arg, const std::string &func);
+set_property_in_handle (double handle, const std::string& property,
+                        const octave_value& arg, const std::string& func);
 
 // ---------------------------------------------------------------------
 
@@ -5858,12 +6129,12 @@
   void do_execute_callback (const graphics_handle& h, const octave_value& cb,
                             const octave_value& data);
 
-  void do_post_callback (const graphics_handle& h, const std::string name,
+  void do_post_callback (const graphics_handle& h, const std::string& name,
                          const octave_value& data);
 
   void do_post_function (graphics_event::event_fcn fcn, void* fcn_data);
 
-  void do_post_set (const graphics_handle& h, const std::string name,
+  void do_post_set (const graphics_handle& h, const std::string& name,
                     const octave_value& value, bool notify_toolkit = true);
 
   int do_process_events (bool force = false);
--- a/libinterp/corefcn/help.cc	Fri Aug 01 09:06:21 2014 -0400
+++ b/libinterp/corefcn/help.cc	Fri Aug 01 12:10:05 2014 -0400
@@ -230,7 +230,7 @@
 
   pair_type (")",
     "-*- texinfo -*-\n\
-@deftypefn {Operator} {} )\n\
+@deftypefn {Operator} {})\n\
 Array index or function argument delimiter.\n\
 @end deftypefn"),
 
@@ -1078,7 +1078,7 @@
 
   if (args.length () == 1)
     {
-      const std::string name = args (0).string_value ();
+      const std::string name = args(0).string_value ();
 
       if (! error_state)
         {
@@ -1367,7 +1367,7 @@
     retval = Cell (ffl.append (afl));
   else
     {
-      std::string dir = args (0).string_value ();
+      std::string dir = args(0).string_value ();
 
       if (! error_state)
         {
--- a/libinterp/corefcn/input.cc	Fri Aug 01 09:06:21 2014 -0400
+++ b/libinterp/corefcn/input.cc	Fri Aug 01 12:10:05 2014 -0400
@@ -750,10 +750,10 @@
 @noindent\n\
 and waits for the user to enter a value.  The string entered by the user\n\
 is evaluated as an expression, so it may be a literal constant, a\n\
-variable name, or any other valid expression.\n\
+variable name, or any other valid Octave code.\n\
 \n\
-Currently, @code{input} only returns one value, regardless of the number\n\
-of values produced by the evaluation of the expression.\n\
+The number of return arguments, their size, and their class depend on the\n\
+expression entered.\n\
 \n\
 If you are only interested in getting a literal string value, you can\n\
 call @code{input} with the character string @qcode{\"s\"} as the second\n\
@@ -772,7 +772,7 @@
   int nargin = args.length ();
 
   if (nargin == 1 || nargin == 2)
-    retval = get_user_input (args, nargout);
+    retval = get_user_input (args, std::max (nargout, 1));
   else
     print_usage ();
 
@@ -1005,6 +1005,15 @@
   return retval;
 }
 
+DEFUN (__echostate__, , ,
+       "-*- texinfo -*-\n\
+@deftypefn {Built-in Function} {@var{state} =} __echostate__ ()\n\
+Undocumented internal function\n\
+@end deftypefn")
+{
+  return ovl (Vecho_executing_commands == ECHO_SCRIPTS);
+}
+
 DEFUN (completion_matches, args, nargout,
        "-*- texinfo -*-\n\
 @deftypefn {Built-in Function} {} completion_matches (@var{hint})\n\
@@ -1410,11 +1419,12 @@
 DEFUN (filemarker, args, nargout,
        "-*- texinfo -*-\n\
 @deftypefn  {Built-in Function} {@var{val} =} filemarker ()\n\
-@deftypefnx {Built-in Function} {} filemarker (@var{new_val})\n\
+@deftypefnx {Built-in Function} {@var{old_val} =} filemarker (@var{new_val})\n\
 @deftypefnx {Built-in Function} {} filemarker (@var{new_val}, \"local\")\n\
-Query or set the character used to separate filename from the\n\
-the subfunction names contained within the file.  This can be used in\n\
-a generic manner to interact with subfunctions.  For example,\n\
+Query or set the character used to separate the filename from the subfunction\n\
+names contained within the file.  By default this is the character @samp{>}.\n\
+This can be used in a generic manner to interact with subfunctions.\n\
+For example,\n\
 \n\
 @example\n\
 help ([\"myfunc\", filemarker, \"mysubfunc\"])\n\
@@ -1422,8 +1432,10 @@
 \n\
 @noindent\n\
 returns the help string associated with the subfunction @code{mysubfunc}\n\
-of the function @code{myfunc}.  Another use of @code{filemarker} is when\n\
-debugging it allows easier placement of breakpoints within subfunctions.\n\
+located in the file @file{myfunc.m}.\n\
+\n\
+@code{filemarker} is also useful during debugging for placing breakpoints\n\
+within subfunctions or nested functions.\n\
 For example,\n\
 \n\
 @example\n\
@@ -1434,7 +1446,7 @@
 will set a breakpoint at the first line of the subfunction @code{mysubfunc}.\n\
 \n\
 When called from inside a function with the @qcode{\"local\"} option, the\n\
-variable is changed locally for the function and any subroutines it calls.  \n\
+variable is changed locally for the function and any subroutines it calls.\n\
 The original variable value is restored when exiting the function.\n\
 @end deftypefn")
 {
--- a/libinterp/corefcn/jit-typeinfo.cc	Fri Aug 01 09:06:21 2014 -0400
+++ b/libinterp/corefcn/jit-typeinfo.cc	Fri Aug 01 12:10:05 2014 -0400
@@ -34,7 +34,12 @@
 
 #include "jit-typeinfo.h"
 
+#ifdef HAVE_LLVM_IR_VERIFIER_H
+#include <llvm/IR/Verifier.h>
+#else
 #include <llvm/Analysis/Verifier.h>
+#endif
+
 #include <llvm/ExecutionEngine/ExecutionEngine.h>
 
 #ifdef HAVE_LLVM_IR_FUNCTION_H
@@ -1247,6 +1252,8 @@
   destroy_fn.add_overload (create_identity(index));
   destroy_fn.add_overload (create_identity(complex));
 
+  // -------------------- scalar related operations --------------------
+
   // now for binary scalar operations
   add_binary_op (scalar, octave_value::op_add, llvm::Instruction::FAdd);
   add_binary_op (scalar, octave_value::op_sub, llvm::Instruction::FSub);
@@ -1335,6 +1342,7 @@
     val = builder.CreateFMul (val, mone);
     fn.do_return (builder, val);
   }
+  unary_ops[octave_value::op_uminus].add_overload (fn);
 
   fn = create_identity (scalar);
   unary_ops[octave_value::op_uplus].add_overload (fn);
@@ -1842,7 +1850,7 @@
   register_generic ("cos", matrix, matrix);
 
   add_builtin ("exp");
-  register_intrinsic ("exp", llvm::Intrinsic::cos, scalar, scalar);
+  register_intrinsic ("exp", llvm::Intrinsic::exp, scalar, scalar);
   register_generic ("exp", matrix, matrix);
 
   add_builtin ("balance");
--- a/libinterp/corefcn/jit-util.h	Fri Aug 01 09:06:21 2014 -0400
+++ b/libinterp/corefcn/jit-util.h	Fri Aug 01 12:10:05 2014 -0400
@@ -42,8 +42,15 @@
 {
   class Value;
   class Module;
+#ifdef LEGACY_PASSMANAGER
+  namespace legacy {
+    class FunctionPassManager;
+    class PassManager;
+  }
+#else
   class FunctionPassManager;
   class PassManager;
+#endif
   class ExecutionEngine;
   class Function;
   class BasicBlock;
--- a/libinterp/corefcn/kron.cc	Fri Aug 01 09:06:21 2014 -0400
+++ b/libinterp/corefcn/kron.cc	Fri Aug 01 12:10:05 2014 -0400
@@ -55,8 +55,10 @@
   assert (a.ndims () == 2);
   assert (b.ndims () == 2);
 
-  octave_idx_type nra = a.rows (), nrb = b.rows ();
-  octave_idx_type nca = a.cols (), ncb = b.cols ();
+  octave_idx_type nra = a.rows ();
+  octave_idx_type nrb = b.rows ();
+  octave_idx_type nca = a.cols ();
+  octave_idx_type ncb = b.cols ();
 
   MArray<T> c (dim_vector (nra*nrb, nca*ncb));
   T *cv = c.fortran_vec ();
@@ -79,8 +81,11 @@
 {
   assert (b.ndims () == 2);
 
-  octave_idx_type nra = a.rows (), nrb = b.rows (), dla = a.diag_length ();
-  octave_idx_type nca = a.cols (), ncb = b.cols ();
+  octave_idx_type nra = a.rows ();
+  octave_idx_type nrb = b.rows ();
+  octave_idx_type dla = a.diag_length ();
+  octave_idx_type nca = a.cols ();
+  octave_idx_type ncb = b.cols ();
 
   MArray<T> c (dim_vector (nra*nrb, nca*ncb), T ());
 
@@ -129,38 +134,20 @@
 static PermMatrix
 kron (const PermMatrix& a, const PermMatrix& b)
 {
-  octave_idx_type na = a.rows (), nb = b.rows ();
-  const octave_idx_type *pa = a.data (), *pb = b.data ();
-  PermMatrix c(na*nb); // Row permutation.
-  octave_idx_type *pc = c.fortran_vec ();
-
-  bool cola = a.is_col_perm (), colb = b.is_col_perm ();
-  if (cola && colb)
-    {
-      for (octave_idx_type i = 0; i < na; i++)
-        for (octave_idx_type j = 0; j < nb; j++)
-          pc[pa[i]*nb+pb[j]] = i*nb+j;
-    }
-  else if (cola)
+  octave_idx_type na = a.rows ();
+  octave_idx_type nb = b.rows ();
+  const Array<octave_idx_type>& pa = a.col_perm_vec ();
+  const Array<octave_idx_type>& pb = b.col_perm_vec ();
+  Array<octave_idx_type> res_perm;
+  octave_idx_type rescol = 0;
+  for (octave_idx_type i = 0; i < na; i++)
     {
-      for (octave_idx_type i = 0; i < na; i++)
-        for (octave_idx_type j = 0; j < nb; j++)
-          pc[pa[i]*nb+j] = i*nb+pb[j];
-    }
-  else if (colb)
-    {
-      for (octave_idx_type i = 0; i < na; i++)
-        for (octave_idx_type j = 0; j < nb; j++)
-          pc[i*nb+pb[j]] = pa[i]*nb+j;
-    }
-  else
-    {
-      for (octave_idx_type i = 0; i < na; i++)
-        for (octave_idx_type j = 0; j < nb; j++)
-          pc[i*nb+j] = pa[i]*nb+pb[j];
+      octave_idx_type a_add = pa(i) * nb;
+      for (octave_idx_type j = 0; j < nb; j++)
+        res_perm.xelem (rescol++) = a_add + pb(j);
     }
 
-  return c;
+  return PermMatrix (res_perm, true);
 }
 
 template <class MTA, class MTB>
@@ -195,7 +182,7 @@
           // the diagonals as vectors and compute the product.  That
           // will be another vector, which we then use to construct a
           // diagonal matrix object.  Note that this will fail if our
-          // digaonal matrix object is modified to allow the non-zero
+          // digaonal matrix object is modified to allow the nonzero
           // values to be stored off of the principal diagonal (i.e., if
           // diag ([1,2], 3) is modified to return a diagonal matrix
           // object instead of a full matrix object).
@@ -282,7 +269,8 @@
 
   if (nargin >= 2)
     {
-      octave_value a = args(0), b = args(1);
+      octave_value a = args(0);
+      octave_value b = args(1);
       retval = dispatch_kron (a, b);
       for (octave_idx_type i = 2; i < nargin; i++)
         retval = dispatch_kron (retval, args(i));
--- a/libinterp/corefcn/load-path.cc	Fri Aug 01 09:06:21 2014 -0400
+++ b/libinterp/corefcn/load-path.cc	Fri Aug 01 12:10:05 2014 -0400
@@ -38,6 +38,7 @@
 #include "defun.h"
 #include "input.h"
 #include "load-path.h"
+#include "ov-usr-fcn.h"
 #include "pager.h"
 #include "parse.h"
 #include "toplev.h"
@@ -120,6 +121,7 @@
   if (fs)
     {
       method_file_map.clear ();
+      package_dir_map.clear ();
 
       dir_mtime = fs.mtime ();
       dir_time_last_checked = octave_time ();
@@ -181,6 +183,8 @@
                     get_private_file_map (full_name);
                   else if (fname[0] == '@')
                     get_method_file_map (full_name, fname.substr (1));
+                  else if (fname[0] == '+')
+                    get_package_dir (full_name, fname.substr (1));
                 }
               else
                 {
@@ -286,6 +290,13 @@
     method_file_map[class_name].private_file_map = get_fcn_files (pd);
 }
 
+void
+load_path::dir_info::get_package_dir (const std::string& d,
+                                      const std::string& package_name)
+{
+  package_dir_map[package_name] = dir_info (d);
+}
+
 bool
 load_path::instance_ok (void)
 {
@@ -373,8 +384,8 @@
 }
 
 void
-load_path::move_fcn_map (const std::string& dir_name,
-                         const string_vector& fcn_files, bool at_end)
+load_path::loader::move_fcn_map (const std::string& dir_name,
+                                 const string_vector& fcn_files, bool at_end)
 {
   octave_idx_type len = fcn_files.length ();
 
@@ -422,7 +433,7 @@
 }
 
 void
-load_path::move_method_map (const std::string& dir_name, bool at_end)
+load_path::loader::move_method_map (const std::string& dir_name, bool at_end)
 {
   for (method_map_iterator i = method_map.begin ();
        i != method_map.end ();
@@ -466,7 +477,7 @@
 }
 
 void
-load_path::move (dir_info_list_iterator i, bool at_end)
+load_path::do_move (dir_info_list_iterator i, bool at_end)
 {
   if (dir_info_list.size () > 1)
     {
@@ -479,16 +490,56 @@
       else
         dir_info_list.push_front (di);
 
-      std::string dir_name = di.dir_name;
-
-      move_fcn_map (dir_name, di.fcn_files, at_end);
-
-      // No need to move elements of private function map.
-
-      move_method_map (dir_name, at_end);
+      move (di, at_end);
+    }
+}
+
+void
+load_path::move (const dir_info& di, bool at_end, const std::string& pname)
+{
+  loader& l = get_loader (pname);
+
+  l.move (di, at_end);
+
+  dir_info::package_dir_map_type package_dir_map = di.package_dir_map;
+
+  for (dir_info::const_package_dir_map_iterator p = package_dir_map.begin ();
+       p != package_dir_map.end (); ++p)
+    {
+      std::string full_name = p->first;
+
+      if (! pname.empty ())
+        full_name = pname + "." + full_name;
+
+      move (p->second, at_end, full_name);
     }
 }
 
+void
+load_path::loader::move (const dir_info& di, bool at_end)
+{
+  std::string dir_name = di.dir_name;
+
+  std::list<std::string>::iterator s = 
+    std::find (dir_list.begin (), dir_list.end (), dir_name);
+
+  if (s != dir_list.end ())
+    {
+      dir_list.erase (s);
+
+      if (at_end)
+        dir_list.push_back (dir_name);
+      else
+        dir_list.push_front (dir_name);
+    }
+
+  move_fcn_map (dir_name, di.fcn_files, at_end);
+
+  // No need to move elements of private function map.
+
+  move_method_map (dir_name, at_end);
+}
+
 static void
 maybe_add_path_elts (std::string& path, const std::string& dir)
 {
@@ -544,9 +595,10 @@
 load_path::do_clear (void)
 {
   dir_info_list.clear ();
-  fcn_map.clear ();
-  private_fcn_map.clear ();
-  method_map.clear ();
+
+  default_loader.clear ();
+
+  loader_map.clear ();
 }
 
 static std::list<std::string>
@@ -683,7 +735,7 @@
   dir_info_list_iterator i = find_dir_info (dir);
 
   if (i != dir_info_list.end ())
-    move (i, at_end);
+    do_move (i, at_end);
   else
     {
       file_stat fs (dir);
@@ -701,11 +753,7 @@
                   else
                     dir_info_list.push_front (di);
 
-                  add_to_fcn_map (di, at_end);
-
-                  add_to_private_fcn_map (di);
-
-                  add_to_method_map (di, at_end);
+                  add (di, at_end);
 
                   if (add_hook)
                     add_hook (dir);
@@ -726,12 +774,12 @@
   i = find_dir_info (".");
 
   if (i != dir_info_list.end ())
-    move (i, false);
+    do_move (i, false);
 }
 
 void
-load_path::remove_fcn_map (const std::string& dir,
-                           const string_vector& fcn_files)
+load_path::loader::remove_fcn_map (const std::string& dir,
+                                   const string_vector& fcn_files)
 {
   octave_idx_type len = fcn_files.length ();
 
@@ -770,7 +818,7 @@
 }
 
 void
-load_path::remove_private_fcn_map (const std::string& dir)
+load_path::loader::remove_private_fcn_map (const std::string& dir)
 {
   private_fcn_map_iterator p = private_fcn_map.find (dir);
 
@@ -779,7 +827,7 @@
 }
 
 void
-load_path::remove_method_map (const std::string& dir)
+load_path::loader::remove_method_map (const std::string& dir)
 {
   for (method_map_iterator i = method_map.begin ();
        i != method_map.end ();
@@ -847,15 +895,11 @@
               if (remove_hook)
                 remove_hook (dir);
 
-              string_vector fcn_files = i->fcn_files;
+              dir_info& di = *i;
+
+              remove (di);
 
               dir_info_list.erase (i);
-
-              remove_fcn_map (dir, fcn_files);
-
-              remove_private_fcn_map (dir);
-
-              remove_method_map (dir);
             }
         }
     }
@@ -864,17 +908,52 @@
 }
 
 void
+load_path::remove (const dir_info& di, const std::string& pname)
+{
+  loader& l = get_loader (pname);
+
+  l.remove (di);
+
+  dir_info::package_dir_map_type package_dir_map = di.package_dir_map;
+
+  for (dir_info::const_package_dir_map_iterator p = package_dir_map.begin ();
+       p != package_dir_map.end (); ++p)
+    {
+      std::string full_name = p->first;
+
+      if (! pname.empty ())
+        full_name = pname + "." + full_name;
+
+      remove (p->second, full_name);
+    }
+}
+
+void
+load_path::loader::remove (const dir_info& di)
+{
+  std::string dir = di.dir_name;
+
+  string_vector fcn_files = di.fcn_files;
+
+  dir_list.remove (dir);
+
+  remove_fcn_map (dir, fcn_files);
+
+  remove_private_fcn_map (dir);
+
+  remove_method_map (dir);
+}
+
+void
 load_path::do_update (void) const
 {
   // I don't see a better way to do this because we need to
   // preserve the correct directory ordering for new files that
   // have appeared.
 
-  fcn_map.clear ();
-
-  private_fcn_map.clear ();
-
-  method_map.clear ();
+  default_loader.clear ();
+
+  loader_map.clear ();
 
   for (dir_info_list_iterator p = dir_info_list.begin ();
        p != dir_info_list.end ();
@@ -884,11 +963,7 @@
 
       di.update ();
 
-      add_to_fcn_map (di, true);
-
-      add_to_private_fcn_map (di);
-
-      add_to_method_map (di, true);
+      add (di, true);
     }
 }
 
@@ -987,8 +1062,8 @@
 }
 
 std::string
-load_path::do_find_fcn (const std::string& fcn, std::string& dir_name,
-                        int type) const
+load_path::loader::find_fcn (const std::string& fcn, std::string& dir_name,
+                             int type) const
 {
   std::string retval;
 
@@ -1003,7 +1078,7 @@
           std::string class_name = fcn.substr (1, pos-1);
           std::string meth = fcn.substr (pos+1);
 
-          retval = do_find_method (class_name, meth, dir_name);
+          retval = find_method (class_name, meth, dir_name);
         }
       else
         retval = std::string ();
@@ -1042,8 +1117,8 @@
 }
 
 std::string
-load_path::do_find_private_fcn (const std::string& dir,
-                                const std::string& fcn, int type) const
+load_path::loader::find_private_fcn (const std::string& dir,
+                                     const std::string& fcn, int type) const
 {
   std::string retval;
 
@@ -1072,9 +1147,9 @@
 }
 
 std::string
-load_path::do_find_method (const std::string& class_name,
-                           const std::string& meth,
-                           std::string& dir_name, int type) const
+load_path::loader::find_method (const std::string& class_name,
+                                const std::string& meth,
+                                std::string& dir_name, int type) const
 {
   std::string retval;
 
@@ -1120,7 +1195,7 @@
 }
 
 std::list<std::string>
-load_path::do_methods (const std::string& class_name) const
+load_path::loader::methods (const std::string& class_name) const
 {
   std::list<std::string> retval;
 
@@ -1149,13 +1224,67 @@
 
   //  update ();
 
+  default_loader.overloads (meth, retval);
+
+  for (const_loader_map_iterator l = loader_map.begin ();
+       l != loader_map.end (); ++l)
+    l->second.overloads (meth, retval);
+
+  return retval;
+}
+
+void
+load_path::loader::overloads (const std::string& meth,
+                              std::list<std::string>& l) const
+{
   for (const_method_map_iterator q = method_map.begin ();
        q != method_map.end (); q++)
     {
       const fcn_map_type& m = q->second;
 
       if (m.find (meth) != m.end ())
-        retval.push_back (q->first);
+        {
+          std::string class_name = q->first;
+
+          if (! prefix.empty ())
+            class_name = prefix + "." + class_name;
+
+          l.push_back (class_name);
+        }
+    }
+}
+
+// Should we cache all files in private directories, or is it OK to just
+// look them up each time as needed?
+
+std::string
+find_private_file (const std::string& fname)
+{
+  std::string retval;
+
+  // Look in private directory corresponding to current function (if
+  // any).
+
+  octave_user_function *curr_fcn = symbol_table::get_curr_fcn ();
+
+  if (curr_fcn)
+    {
+      // Even for private functions, dir_name doesn't contain the
+      // "private" directory component so we append it here in all
+      // cases.
+
+      std::string dir_name = curr_fcn->dir_name ();
+
+      if (! dir_name.empty ())
+        {
+          std::string pfname = dir_name + file_ops::dir_sep_str ()
+            + "private" + file_ops::dir_sep_str () + fname;
+
+          file_stat fs (pfname);
+
+          if (fs.exists () && fs.is_reg ())
+            retval = pfname;
+        }
     }
 
   return retval;
@@ -1166,33 +1295,42 @@
 {
   std::string retval;
 
+  if (octave_env::absolute_pathname (file)
+      || octave_env::rooted_relative_pathname (file))
+    {
+      file_stat fs (file);
+
+      return fs.exists () ? file : retval;
+    }
+  else
+    {
+      std::string tfile = find_private_file (file);
+
+      if (! tfile.empty ())
+        return tfile;
+    }
+
   if (file.find_first_of (file_ops::dir_sep_chars ()) != std::string::npos)
     {
-      if (octave_env::absolute_pathname (file)
-          || octave_env::rooted_relative_pathname (file))
+      // Given name has a directory separator, so append it to each
+      // element of the load path in turn.
+
+      for (const_dir_info_list_iterator p = dir_info_list.begin ();
+           p != dir_info_list.end ();
+           p++)
         {
-          file_stat fs (file);
+          std::string tfile = file_ops::concat (p->dir_name, file);
+
+          file_stat fs (tfile);
 
           if (fs.exists ())
-            return file;
-        }
-      else
-        {
-          for (const_dir_info_list_iterator p = dir_info_list.begin ();
-               p != dir_info_list.end ();
-               p++)
-            {
-              std::string tfile = file_ops::concat (p->dir_name, file);
-
-              file_stat fs (tfile);
-
-              if (fs.exists ())
-                return tfile;
-            }
+            return tfile;
         }
     }
   else
     {
+      // Look in cache.
+
       for (const_dir_info_list_iterator p = dir_info_list.begin ();
            p != dir_info_list.end ();
            p++)
@@ -1515,6 +1653,12 @@
 string_vector
 load_path::do_fcn_names (void) const
 {
+  return default_loader.fcn_names ();
+}
+
+string_vector
+load_path::loader::fcn_names (void) const
+{
   size_t len = fcn_map.size ();
 
   string_vector retval (len);
@@ -1657,69 +1801,11 @@
         }
     }
 
-  for (const_private_fcn_map_iterator i = private_fcn_map.begin ();
-       i != private_fcn_map.end (); i++)
-    {
-      os << "\n*** private functions in "
-         << file_ops::concat (i->first, "private") << ":\n\n";
-
-      print_fcn_list (os, i->second);
-    }
-
-#if defined (DEBUG_LOAD_PATH)
-
-  for (const_fcn_map_iterator i = fcn_map.begin ();
-       i != fcn_map.end ();
-       i++)
-    {
-      os << i->first << ":\n";
-
-      const file_info_list_type& file_info_list = i->second;
-
-      for (const_file_info_list_iterator p = file_info_list.begin ();
-           p != file_info_list.end ();
-           p++)
-        {
-          os << "  " << p->dir_name << " (";
-
-          print_types (os, p->types);
-
-          os << ")\n";
-        }
-    }
-
-  for (const_method_map_iterator i = method_map.begin ();
-       i != method_map.end ();
-       i++)
-    {
-      os << "CLASS " << i->first << ":\n";
-
-      const fcn_map_type& fm = i->second;
-
-      for (const_fcn_map_iterator q = fm.begin ();
-           q != fm.end ();
-           q++)
-        {
-          os << "  " << q->first << ":\n";
-
-          const file_info_list_type& file_info_list = q->second;
-
-          for (const_file_info_list_iterator p = file_info_list.begin ();
-               p != file_info_list.end ();
-               p++)
-            {
-              os << "  " << p->dir_name << " (";
-
-              print_types (os, p->types);
-
-              os << ")\n";
-            }
-        }
-    }
-
-  os << "\n";
-
-#endif
+  default_loader.display (os);
+
+  for (const_loader_map_iterator l = loader_map.begin ();
+       l != loader_map.end (); ++l)
+    l->second.display (os);
 }
 
 // True if a path is contained in a path list separated by path_sep_char
@@ -1743,7 +1829,29 @@
 }
 
 void
-load_path::add_to_fcn_map (const dir_info& di, bool at_end) const
+load_path::add (const dir_info& di, bool at_end,
+                const std::string& pname) const
+{
+  loader& l = get_loader (pname);
+
+  l.add (di, at_end);
+
+  dir_info::package_dir_map_type package_dir_map = di.package_dir_map;
+
+  for (dir_info::const_package_dir_map_iterator p = package_dir_map.begin ();
+       p != package_dir_map.end (); ++p)
+    {
+      std::string full_name = p->first;
+
+      if (! pname.empty ())
+        full_name = pname + "." + full_name;
+
+      add (p->second, at_end, full_name);
+    }
+}
+
+void
+load_path::loader::add_to_fcn_map (const dir_info& di, bool at_end)
 {
   std::string dir_name = di.dir_name;
 
@@ -1839,7 +1947,7 @@
 }
 
 void
-load_path::add_to_private_fcn_map (const dir_info& di) const
+load_path::loader::add_to_private_fcn_map (const dir_info& di)
 {
   dir_info::fcn_file_map_type private_file_map = di.private_file_map;
 
@@ -1848,7 +1956,7 @@
 }
 
 void
-load_path::add_to_method_map (const dir_info& di, bool at_end) const
+load_path::loader::add_to_method_map (const dir_info& di, bool at_end)
 {
   std::string dir_name = di.dir_name;
 
@@ -1918,6 +2026,81 @@
     }
 }
 
+void
+load_path::loader::display (std::ostream& os) const
+{
+  os << "*** loader: " << (prefix.empty () ? "<top-level>" : prefix) << "\n\n";
+
+  for (std::list<std::string>::const_iterator s = dir_list.begin ();
+       s != dir_list.end (); ++s)
+    os << *s << "\n";
+  os << "\n";
+
+  for (const_private_fcn_map_iterator i = private_fcn_map.begin ();
+       i != private_fcn_map.end (); i++)
+    {
+      os << "\n*** private functions in "
+         << file_ops::concat (i->first, "private") << ":\n\n";
+
+      print_fcn_list (os, i->second);
+    }
+
+#if defined (DEBUG_LOAD_PATH)
+
+  for (const_fcn_map_iterator i = fcn_map.begin ();
+       i != fcn_map.end ();
+       i++)
+    {
+      os << i->first << ":\n";
+
+      const file_info_list_type& file_info_list = i->second;
+
+      for (const_file_info_list_iterator p = file_info_list.begin ();
+           p != file_info_list.end ();
+           p++)
+        {
+          os << "  " << p->dir_name << " (";
+
+          print_types (os, p->types);
+
+          os << ")\n";
+        }
+    }
+
+  for (const_method_map_iterator i = method_map.begin ();
+       i != method_map.end ();
+       i++)
+    {
+      os << "CLASS " << i->first << ":\n";
+
+      const fcn_map_type& fm = i->second;
+
+      for (const_fcn_map_iterator q = fm.begin ();
+           q != fm.end ();
+           q++)
+        {
+          os << "  " << q->first << ":\n";
+
+          const file_info_list_type& file_info_list = q->second;
+
+          for (const_file_info_list_iterator p = file_info_list.begin ();
+               p != file_info_list.end ();
+               p++)
+            {
+              os << "  " << p->dir_name << " (";
+
+              print_types (os, p->types);
+
+              os << ")\n";
+            }
+        }
+    }
+
+  os << "\n";
+
+#endif
+}
+
 std::string
 genpath (const std::string& dirname, const string_vector& skip)
 {
@@ -1929,7 +2112,7 @@
     {
       retval = dirname;
 
-      string_vector dirlist = dir.read ();
+      string_vector dirlist = dir.read ().sort (false);
 
       octave_idx_type len = dirlist.length ();
 
@@ -1937,7 +2120,8 @@
         {
           std::string elt = dirlist[i];
 
-          bool skip_p = (elt == "." || elt == ".." || elt[0] == '@');
+          bool skip_p = (elt == "." || elt == ".." || elt[0] == '@'
+                         || elt[0] == '+');
 
           if (! skip_p)
             {
@@ -1964,6 +2148,21 @@
   return retval;
 }
 
+std::list<std::string>
+load_path::do_get_all_package_names (bool only_top_level) const
+{
+  std::list<std::string> retval;
+
+  for (const_loader_map_iterator l = loader_map.begin ();
+       l != loader_map.end (); ++l)
+    {
+      if (! only_top_level || l->first.find ('.') == std::string::npos)
+        retval.push_back (l->first);
+    }
+
+  return retval;
+}
+
 static void
 execute_pkg_add_or_del (const std::string& dir,
                         const std::string& script_file)
@@ -2339,3 +2538,10 @@
 
   return retval;
 }
+
+DEFUN (__dump_load_path__, , , "")
+{
+  load_path::display (octave_stdout);
+
+  return octave_value_list ();
+}
--- a/libinterp/corefcn/load-path.h	Fri Aug 01 09:06:21 2014 -0400
+++ b/libinterp/corefcn/load-path.h	Fri Aug 01 12:10:05 2014 -0400
@@ -39,8 +39,7 @@
 protected:
 
   load_path (void)
-    : dir_info_list (), fcn_map (), private_fcn_map (), method_map (),
-      init_dirs () { }
+    : loader_map (), default_loader (), dir_info_list (), init_dirs () { }
 
 public:
 
@@ -96,24 +95,29 @@
 
   static std::string find_method (const std::string& class_name,
                                   const std::string& meth,
-                                  std::string& dir_name)
+                                  std::string& dir_name,
+                                  const std::string& pack_name = std::string ())
   {
     return instance_ok ()
-           ? instance->do_find_method (class_name, meth, dir_name)
-           : std::string ();
+      ? instance->get_loader (pack_name).find_method (class_name, meth,
+                                                      dir_name)
+      : std::string ();
   }
 
   static std::string find_method (const std::string& class_name,
-                                  const std::string& meth)
+                                  const std::string& meth,
+                                  const std::string& pack_name = std::string ())
   {
     std::string dir_name;
-    return find_method (class_name, meth, dir_name);
+    return find_method (class_name, meth, dir_name, pack_name);
   }
 
-  static std::list<std::string> methods (const std::string& class_name)
+  static std::list<std::string> methods (const std::string& class_name,
+                                         const std::string& pack_name = std::string ())
   {
     return instance_ok ()
-           ? instance->do_methods (class_name) : std::list<std::string> ();
+      ? instance->get_loader(pack_name).methods (class_name)
+      : std::list<std::string> ();
   }
 
   static std::list<std::string> overloads (const std::string& meth)
@@ -122,47 +126,72 @@
            ? instance->do_overloads (meth) : std::list<std::string> ();
   }
 
-  static std::string find_fcn (const std::string& fcn, std::string& dir_name)
+  static bool find_package (const std::string& package_name)
+  {
+    return instance_ok ()
+      ? instance->do_find_package (package_name) : false;
+  }
+
+  static std::list<std::string>
+  get_all_package_names (bool only_top_level = true)
   {
     return instance_ok ()
-           ? instance->do_find_fcn (fcn, dir_name) : std::string ();
+      ? instance->do_get_all_package_names (only_top_level)
+      : std::list<std::string> ();
   }
 
-  static std::string find_fcn (const std::string& fcn)
+  static std::string find_fcn (const std::string& fcn, std::string& dir_name,
+                               const std::string& pack_name = std::string ())
+  {
+    return instance_ok ()
+      ? instance->get_loader (pack_name).find_fcn (fcn, dir_name)
+      : std::string ();
+  }
+
+  static std::string find_fcn (const std::string& fcn,
+                               const std::string& pack_name = std::string ())
   {
     std::string dir_name;
-    return find_fcn (fcn, dir_name);
+    return find_fcn (fcn, dir_name, pack_name);
   }
 
   static std::string find_private_fcn (const std::string& dir,
-                                       const std::string& fcn)
+                                       const std::string& fcn,
+                                       const std::string& pack_name = std::string ())
   {
     return instance_ok ()
-           ? instance->do_find_private_fcn (dir, fcn) : std::string ();
+      ? instance->get_loader (pack_name).find_private_fcn (dir, fcn)
+      : std::string ();
   }
 
-  static std::string find_fcn_file (const std::string& fcn)
+  static std::string find_fcn_file (const std::string& fcn,
+                                    const std::string& pack_name = std::string ())
   {
     std::string dir_name;
 
-    return instance_ok () ?
-           instance->do_find_fcn (fcn, dir_name, M_FILE) : std::string ();
+    return instance_ok ()
+      ? instance->get_loader (pack_name).find_fcn (fcn, dir_name, M_FILE)
+      : std::string ();
   }
 
-  static std::string find_oct_file (const std::string& fcn)
+  static std::string find_oct_file (const std::string& fcn,
+                                    const std::string& pack_name = std::string ())
   {
     std::string dir_name;
 
-    return instance_ok () ?
-           instance->do_find_fcn (fcn, dir_name, OCT_FILE) : std::string ();
+    return instance_ok ()
+      ? instance->get_loader (pack_name).find_fcn (fcn, dir_name, M_FILE)
+      : std::string ();
   }
 
-  static std::string find_mex_file (const std::string& fcn)
+  static std::string find_mex_file (const std::string& fcn,
+                                    const std::string& pack_name = std::string ())
   {
     std::string dir_name;
 
-    return instance_ok () ?
-           instance->do_find_fcn (fcn, dir_name, MEX_FILE) : std::string ();
+    return instance_ok ()
+      ? instance->get_loader (pack_name).find_fcn (fcn, dir_name, M_FILE)
+      : std::string ();
   }
 
   static std::string find_file (const std::string& file)
@@ -297,19 +326,27 @@
     typedef method_file_map_type::const_iterator const_method_file_map_iterator;
     typedef method_file_map_type::iterator method_file_map_iterator;
 
+    // <PACKAGE_NAME, DIR_INFO>
+    typedef std::map<std::string, dir_info> package_dir_map_type;
+
+    typedef package_dir_map_type::const_iterator const_package_dir_map_iterator;
+    typedef package_dir_map_type::iterator package_dir_map_iterator;
+
     // This default constructor is only provided so we can create a
     // std::map of dir_info objects.  You should not use this
     // constructor for any other purpose.
     dir_info (void)
       : dir_name (), abs_dir_name (), is_relative (false),
         dir_mtime (), dir_time_last_checked (),
-        all_files (), fcn_files (), private_file_map (), method_file_map ()
+        all_files (), fcn_files (), private_file_map (), method_file_map (),
+        package_dir_map ()
     { }
 
     dir_info (const std::string& d)
       : dir_name (d), abs_dir_name (), is_relative (false),
         dir_mtime (), dir_time_last_checked (),
-        all_files (), fcn_files (), private_file_map (), method_file_map ()
+        all_files (), fcn_files (), private_file_map (), method_file_map (),
+        package_dir_map ()
     {
       initialize ();
     }
@@ -321,7 +358,8 @@
         dir_time_last_checked (di.dir_time_last_checked),
         all_files (di.all_files), fcn_files (di.fcn_files),
         private_file_map (di.private_file_map),
-        method_file_map (di.method_file_map) { }
+        method_file_map (di.method_file_map),
+        package_dir_map (di.package_dir_map) { }
 
     ~dir_info (void) { }
 
@@ -338,6 +376,7 @@
           fcn_files = di.fcn_files;
           private_file_map = di.private_file_map;
           method_file_map = di.method_file_map;
+          package_dir_map = di.package_dir_map;
         }
 
       return *this;
@@ -354,6 +393,7 @@
     string_vector fcn_files;
     fcn_file_map_type private_file_map;
     method_file_map_type method_file_map;
+    package_dir_map_type package_dir_map;
 
   private:
 
@@ -366,6 +406,9 @@
     void get_method_file_map (const std::string& d,
                               const std::string& class_name);
 
+    void get_package_dir (const std::string& d,
+                          const std::string& package_name);
+
     friend fcn_file_map_type get_fcn_files (const std::string& d);
   };
 
@@ -442,13 +485,125 @@
   typedef method_map_type::const_iterator const_method_map_iterator;
   typedef method_map_type::iterator method_map_iterator;
 
-  mutable dir_info_list_type dir_info_list;
+  class loader
+  {
+  public:
+    loader (const std::string& pfx = std::string ())
+      : prefix (pfx), dir_list (), fcn_map (), private_fcn_map (),
+        method_map () { }
+
+    loader (const loader& l)
+      : prefix (l.prefix), dir_list (l.dir_list),
+        private_fcn_map (l.private_fcn_map), method_map (l.method_map) { }
+
+    ~loader (void) { }
+
+    loader& operator = (const loader& l)
+    {
+      if (&l != this)
+        {
+          prefix = l.prefix;
+          dir_list = l.dir_list;
+          fcn_map = l.fcn_map;
+          private_fcn_map = l.private_fcn_map;
+          method_map = l.method_map;
+        }
+
+      return *this;
+    }
 
-  mutable fcn_map_type fcn_map;
+    void add (const dir_info& di, bool at_end)
+    {
+      if (at_end)
+        dir_list.push_back (di.dir_name);
+      else
+        dir_list.push_front (di.dir_name);
+
+      add_to_fcn_map (di, at_end);
+
+      add_to_private_fcn_map (di);
+
+      add_to_method_map (di, at_end);
+    }
+
+    void move (const dir_info& di, bool at_end);
+
+    void remove (const dir_info& di);
+
+    void clear (void)
+      {
+        dir_list.clear ();
+
+        fcn_map.clear ();
+
+        private_fcn_map.clear ();
+
+        method_map.clear ();
+      }
+
+    void display (std::ostream& out) const;
 
-  mutable private_fcn_map_type private_fcn_map;
+    std::string find_fcn (const std::string& fcn,
+                          std::string& dir_name,
+                          int type = M_FILE | OCT_FILE | MEX_FILE) const;
+
+    std::string find_private_fcn (const std::string& dir,
+                                  const std::string& fcn,
+                                  int type = M_FILE | OCT_FILE | MEX_FILE) const;
+
+    std::string find_method (const std::string& class_name,
+                             const std::string& meth,
+                             std::string& dir_name,
+                             int type = M_FILE | OCT_FILE | MEX_FILE) const;
+
+    std::list<std::string> methods (const std::string& class_name) const;
+
+    void overloads (const std::string& meth, std::list<std::string>& l) const;
+
+    string_vector fcn_names (void) const;
+
+  private:
+    void add_to_fcn_map (const dir_info& di, bool at_end);
+
+    void add_to_private_fcn_map (const dir_info& di);
+
+    void add_to_method_map (const dir_info& di, bool at_end);
+
+    void move_fcn_map (const std::string& dir,
+                       const string_vector& fcn_files, bool at_end);
+
+    void move_method_map (const std::string& dir, bool at_end);
 
-  mutable method_map_type method_map;
+    void remove_fcn_map (const std::string& dir,
+                         const string_vector& fcn_files);
+
+    void remove_private_fcn_map (const std::string& dir);
+
+    void remove_method_map (const std::string& dir);
+
+  private:
+    std::string prefix;
+
+    std::list<std::string> dir_list;
+
+    fcn_map_type fcn_map;
+
+    private_fcn_map_type private_fcn_map;
+
+    method_map_type method_map;
+  };
+
+  // <PACKAGE_NAME, LOADER>
+  typedef std::map<std::string, loader> loader_map_type;
+
+  typedef loader_map_type::const_iterator const_loader_map_iterator;
+  typedef loader_map_type::iterator loader_map_iterator;
+
+  mutable loader_map_type loader_map;
+
+  mutable loader default_loader;
+
+  mutable dir_info_list_type dir_info_list;
 
   mutable std::set<std::string> init_dirs;
 
@@ -475,12 +630,13 @@
 
   bool do_contains_canonical (const std::string& dir) const;
 
-  void move_fcn_map (const std::string& dir,
-                     const string_vector& fcn_files, bool at_end);
+  void do_move (dir_info_list_iterator i, bool at_end);
 
-  void move_method_map (const std::string& dir, bool at_end);
+  void move (const dir_info& di, bool at_end,
+             const std::string& pname = std::string ());
 
-  void move (std::list<dir_info>::iterator i, bool at_end);
+  void remove (const dir_info& di,
+               const std::string& pname = std::string ());
 
   void do_initialize (bool set_initial_path);
 
@@ -494,12 +650,6 @@
 
   void do_add (const std::string& dir, bool at_end, bool warn);
 
-  void remove_fcn_map (const std::string& dir, const string_vector& fcn_files);
-
-  void remove_private_fcn_map (const std::string& dir);
-
-  void remove_method_map (const std::string& dir);
-
   bool do_remove (const std::string& dir);
 
   void do_update (void) const;
@@ -508,23 +658,31 @@
   check_file_type (std::string& fname, int type, int possible_types,
                    const std::string& fcn, const char *who);
 
-  std::string do_find_fcn (const std::string& fcn,
-                           std::string& dir_name,
-                           int type = M_FILE | OCT_FILE | MEX_FILE) const;
+  loader& get_loader (const std::string& name) const
+  {
+    if (! name.empty ())
+      {
+        loader_map_iterator l = loader_map.find (name);
 
-  std::string do_find_private_fcn (const std::string& dir,
-                                   const std::string& fcn,
-                                   int type = M_FILE | OCT_FILE | MEX_FILE) const;
+        if (l == loader_map.end ())
+          l = loader_map.insert (loader_map.end (),
+                                 loader_map_type::value_type (name, loader (name)));
 
-  std::string do_find_method (const std::string& class_name,
-                              const std::string& meth,
-                              std::string& dir_name,
-                              int type = M_FILE | OCT_FILE | MEX_FILE) const;
+        return l->second;
+      }
 
-  std::list<std::string> do_methods (const std::string& class_name) const;
+    return default_loader;
+  }
 
   std::list<std::string> do_overloads (const std::string& meth) const;
 
+  bool do_find_package (const std::string& package_name) const
+  {
+    return (loader_map.find (package_name) != loader_map.end ());
+  }
+
+  std::list<std::string> do_get_all_package_names (bool only_top_level) const;
+
   std::string do_find_file (const std::string& file) const;
 
   std::string do_find_dir (const std::string& dir) const;
@@ -559,11 +717,8 @@
   std::string do_get_command_line_path (void) const
   { return command_line_path; }
 
-  void add_to_fcn_map (const dir_info& di, bool at_end) const;
-
-  void add_to_private_fcn_map (const dir_info& di) const;
-
-  void add_to_method_map (const dir_info& di, bool at_end) const;
+  void add (const dir_info& di, bool at_end,
+            const std::string& pname = std::string ()) const;
 
   friend dir_info::fcn_file_map_type get_fcn_files (const std::string& d);
 };
--- a/libinterp/corefcn/load-save.cc	Fri Aug 01 09:06:21 2014 -0400
+++ b/libinterp/corefcn/load-save.cc	Fri Aug 01 12:10:05 2014 -0400
@@ -503,17 +503,24 @@
   if (! (octave_env::absolute_pathname (fname)
          || octave_env::rooted_relative_pathname (fname)))
     {
+      // Load path will also search "." first, but we don't want to
+      // issue a warning if the file is found in the current directory,
+      // so do an explicit check for that.
+
       file_stat fs (fname);
 
       if (! (fs.exists () && fs.is_reg ()))
         {
+          // Not directly found; search load path.
+
           std::string tmp
             = octave_env::make_absolute (load_path::find_file (fname));
 
           if (! tmp.empty ())
             {
               warning_with_id ("Octave:load-file-in-path",
-                               "load: file found in load path");
+                               "load: file found in load path: %s",
+                               tmp.c_str ());
               fname = tmp;
             }
         }
@@ -1066,7 +1073,8 @@
   string_vector retval;
   int argc = argv.length ();
 
-  bool do_double = false, do_tabs = false;
+  bool do_double = false;
+  bool do_tabs = false;
 
   for (int i = 0; i < argc; i++)
     {
@@ -1495,9 +1503,10 @@
 @deftypefnx {Command} {} save options file\n\
 @deftypefnx {Command} {} save options file @var{v1} @var{v2} @dots{}\n\
 @deftypefnx {Command} {} save options file -struct @var{STRUCT} @var{f1} @var{f2} @dots{}\n\
+@deftypefnx {Command} {} {@var{s} =} save @samp{-} @var{v1} @var{v2} @dots{}\n\
 Save the named variables @var{v1}, @var{v2}, @dots{}, in the file\n\
-@var{file}.  The special filename @samp{-} may be used to write\n\
-output to the terminal.  If no variable names are listed, Octave saves\n\
+@var{file}.  The special filename @samp{-} may be used to return the\n\
+content of the variables as a string.  If no variable names are listed, Octave saves\n\
 all the variables in the current scope.  Otherwise, full variable names or\n\
 pattern syntax can be used to specify the variables to save.\n\
 If the @option{-struct} modifier is used, fields @var{f1} @var{f2} @dots{}\n\
@@ -1616,8 +1625,6 @@
 {
   octave_value_list retval;
 
-  int argc = args.length ();
-
   string_vector argv = args.make_argv ();
 
   if (error_state)
@@ -1641,7 +1648,7 @@
   // override from command line
   argv = parse_save_options (argv, format, append, save_as_floats,
                              use_zlib);
-  argc = argv.length ();
+  int argc = argv.length ();
   int i = 0;
 
   if (error_state)
@@ -1674,11 +1681,10 @@
           if (append)
             warning ("save: ignoring -append option for output to stdout");
 
-          // FIXME: should things intended for the screen
-          //        end up in an octave_value (string)?
-
-          save_vars (argv, i, argc, octave_stdout, format,
+          std::ostringstream output_buf;
+          save_vars (argv, i, argc, output_buf, format,
                      save_as_floats, true);
+          retval = octave_value (output_buf.str());
         }
     }
 
--- a/libinterp/corefcn/lookup.cc	Fri Aug 01 09:06:21 2014 -0400
+++ b/libinterp/corefcn/lookup.cc	Fri Aug 01 12:10:05 2014 -0400
@@ -115,7 +115,8 @@
   octave_value retval;
 
   Array<octave_idx_type> idx = array.lookup (values);
-  octave_idx_type n = array.numel (), nval = values.numel ();
+  octave_idx_type n = array.numel ();
+  octave_idx_type nval = values.numel ();
 
   // Post-process.
   if (match_bool)
@@ -246,7 +247,8 @@
       return retval;
     }
 
-  octave_value table = args(0), y = args(1);
+  octave_value table = args(0);
+  octave_value y = args(1);
   if (table.ndims () > 2 || (table.columns () > 1 && table.rows () > 1))
     warning ("lookup: table is not a vector");
 
--- a/libinterp/corefcn/ls-hdf5.cc	Fri Aug 01 09:06:21 2014 -0400
+++ b/libinterp/corefcn/ls-hdf5.cc	Fri Aug 01 12:10:05 2014 -0400
@@ -263,7 +263,7 @@
   // Allow identifiers as all digits so we can load lists saved by
   // earlier versions of Octave.
 
-  if (! ident_valid )
+  if (! ident_valid)
     {
       // fix the identifier, replacing invalid chars with underscores
       vname = make_valid_identifier (vname);
@@ -528,6 +528,7 @@
         {
           warning ("load: can't read '%s' (unknown datatype)", name);
           retval = 0; // unknown datatype; skip
+          return retval;
         }
 
       // check for OCTAVE_GLOBAL attribute:
@@ -615,7 +616,7 @@
 
       len = H5Gget_objname_by_idx (hs.file_id, hs.current_item, 0, 0);
       var_name.resize (len+1);
-      H5Gget_objname_by_idx( hs.file_id, hs.current_item, &var_name[0], len+1);
+      H5Gget_objname_by_idx (hs.file_id, hs.current_item, &var_name[0], len+1);
 
       for (int i = argv_idx; i < argc; i++)
         {
@@ -738,7 +739,8 @@
   hsize_t sz = d.length ();
   OCTAVE_LOCAL_BUFFER (octave_idx_type, dims, sz);
   bool empty = false;
-  hid_t space_hid = -1, data_hid = -1;
+  hid_t space_hid = -1;
+  hid_t data_hid = -1;
   int retval;
   for (hsize_t i = 0; i < sz; i++)
     {
@@ -865,7 +867,9 @@
                bool mark_as_global, bool save_as_floats)
 {
   hsize_t dims[3];
-  hid_t type_id = -1, space_id = -1, data_id = -1, data_type_id = -1;
+  hid_t type_id, space_id, data_id, data_type_id;
+  type_id = space_id = data_id = data_type_id = -1;
+
   bool retval = false;
   octave_value val = tc;
   // FIXME: diagonal & permutation matrices currently don't know how to save
--- a/libinterp/corefcn/ls-mat4.cc	Fri Aug 01 09:06:21 2014 -0400
+++ b/libinterp/corefcn/ls-mat4.cc	Fri Aug 01 12:10:05 2014 -0400
@@ -461,7 +461,6 @@
       len = nr * nc;
     }
 
-
   // LEN includes the terminating character, and the file is also
   // supposed to include it.
 
@@ -489,7 +488,10 @@
           for (octave_idx_type j = 0; j < ncol; j++)
             buf[j*nrow+i] = static_cast<double> (*s++ & 0x00FF);
         }
-      os.write (reinterpret_cast<char *> (buf), nrow*ncol*sizeof (double));
+      std::streamsize n_bytes = static_cast<std::streamsize> (nrow) *
+                                static_cast<std::streamsize> (ncol) *
+                                sizeof (double);
+      os.write (reinterpret_cast<char *> (buf), n_bytes);
     }
   else if (tc.is_range ())
     {
@@ -518,7 +520,8 @@
 
           for (octave_idx_type i = 0; i < len; i++)
             dtmp[i] = m.ridx (i) + 1;
-          os.write (reinterpret_cast<const char *> (dtmp), 8 * len);
+          std::streamsize n_bytes = 8 * static_cast<std::streamsize> (len);
+          os.write (reinterpret_cast<const char *> (dtmp), n_bytes);
           ds = nr;
           os.write (reinterpret_cast<const char *> (&ds), 8);
 
@@ -526,19 +529,19 @@
           for (octave_idx_type j = 0; j < nc; j++)
             for (octave_idx_type i = m.cidx (j); i < m.cidx (j+1); i++)
               dtmp[ii++] = j + 1;
-          os.write (reinterpret_cast<const char *> (dtmp), 8 * len);
+          os.write (reinterpret_cast<const char *> (dtmp), n_bytes);
           ds = nc;
           os.write (reinterpret_cast<const char *> (&ds), 8);
 
           for (octave_idx_type i = 0; i < len; i++)
             dtmp[i] = std::real (m.data (i));
-          os.write (reinterpret_cast<const char *> (dtmp), 8 * len);
+          os.write (reinterpret_cast<const char *> (dtmp), n_bytes);
           ds = 0.;
           os.write (reinterpret_cast<const char *> (&ds), 8);
 
           for (octave_idx_type i = 0; i < len; i++)
             dtmp[i] = std::imag (m.data (i));
-          os.write (reinterpret_cast<const char *> (dtmp), 8 * len);
+          os.write (reinterpret_cast<const char *> (dtmp), n_bytes);
           os.write (reinterpret_cast<const char *> (&ds), 8);
         }
       else
@@ -547,7 +550,8 @@
 
           for (octave_idx_type i = 0; i < len; i++)
             dtmp[i] = m.ridx (i) + 1;
-          os.write (reinterpret_cast<const char *> (dtmp), 8 * len);
+          std::streamsize n_bytes = 8 * static_cast<std::streamsize> (len);
+          os.write (reinterpret_cast<const char *> (dtmp), n_bytes);
           ds = nr;
           os.write (reinterpret_cast<const char *> (&ds), 8);
 
@@ -555,11 +559,11 @@
           for (octave_idx_type j = 0; j < nc; j++)
             for (octave_idx_type i = m.cidx (j); i < m.cidx (j+1); i++)
               dtmp[ii++] = j + 1;
-          os.write (reinterpret_cast<const char *> (dtmp), 8 * len);
+          os.write (reinterpret_cast<const char *> (dtmp), n_bytes);
           ds = nc;
           os.write (reinterpret_cast<const char *> (&ds), 8);
 
-          os.write (reinterpret_cast<const char *> (m.data ()), 8 * len);
+          os.write (reinterpret_cast<const char *> (m.data ()), n_bytes);
           ds = 0.;
           os.write (reinterpret_cast<const char *> (&ds), 8);
         }
@@ -567,7 +571,8 @@
   else if (tc.is_real_matrix ())
     {
       Matrix m = tc.matrix_value ();
-      os.write (reinterpret_cast<const char *> (m.data ()), 8 * len);
+      std::streamsize n_bytes = 8 * static_cast<std::streamsize> (len);
+      os.write (reinterpret_cast<const char *> (m.data ()), n_bytes);
     }
   else if (tc.is_complex_scalar ())
     {
@@ -578,9 +583,10 @@
     {
       ComplexMatrix m_cmplx = tc.complex_matrix_value ();
       Matrix m = ::real (m_cmplx);
-      os.write (reinterpret_cast<const char *> (m.data ()), 8 * len);
+      std::streamsize n_bytes = 8 * static_cast<std::streamsize> (len);
+      os.write (reinterpret_cast<const char *> (m.data ()), n_bytes);
       m = ::imag (m_cmplx);
-      os.write (reinterpret_cast<const char *> (m.data ()), 8 * len);
+      os.write (reinterpret_cast<const char *> (m.data ()), n_bytes);
     }
   else
     gripe_wrong_type_arg ("save", tc, false);
--- a/libinterp/corefcn/ls-mat5.cc	Fri Aug 01 09:06:21 2014 -0400
+++ b/libinterp/corefcn/ls-mat5.cc	Fri Aug 01 12:10:05 2014 -0400
@@ -264,7 +264,8 @@
       if (len > 0) \
         { \
           OCTAVE_LOCAL_BUFFER (TYPE, ptr, len); \
-          stream.read (reinterpret_cast<char *> (ptr), size * len); \
+          std::streamsize n_bytes = size * static_cast<std::streamsize> (len); \
+          stream.read (reinterpret_cast<char *> (ptr), n_bytes); \
           if (swap) \
             swap_bytes< size > (ptr, len); \
           for (octave_idx_type i = 0; i < len; i++) \
@@ -439,7 +440,7 @@
   unsigned int upper;
   int32_t temp;
 
-  if (! is.read (reinterpret_cast<char *> (&temp), 4 ))
+  if (! is.read (reinterpret_cast<char *> (&temp), 4))
     goto data_read_error;
 
   if (swap)
@@ -456,7 +457,7 @@
     }
   else
     {
-      if (! is.read (reinterpret_cast<char *> (&temp), 4 ))
+      if (! is.read (reinterpret_cast<char *> (&temp), 4))
         goto data_read_error;
       if (swap)
         swap_bytes<4> (&temp);
@@ -650,7 +651,7 @@
   arrayclass = static_cast<arrayclasstype> (flags & 0xff);
 
   int32_t tmp_nzmax;
-  read_int (is, swap, tmp_nzmax);   // max number of non-zero in sparse
+  read_int (is, swap, tmp_nzmax);   // max number of nonzero in sparse
   nzmax = tmp_nzmax;
 
   // dimensions array subelement
@@ -709,7 +710,7 @@
 
     if (len)
       {
-        if (! is.read (name, len ))
+        if (! is.read (name, len))
           goto data_read_error;
 
         is.seekg (tmp_pos + static_cast<std::streamoff>
@@ -937,7 +938,7 @@
                         std::string dir_name = str.substr (0, xpos);
 
                         octave_function *fcn
-                          = load_fcn_from_file (str, dir_name, "", fname);
+                          = load_fcn_from_file (str, dir_name, "", "", fname);
 
                         if (fcn)
                           {
@@ -966,7 +967,7 @@
                         std::string dir_name = str.substr (0, xpos);
 
                         octave_function *fcn
-                          = load_fcn_from_file (str, dir_name, "", fname);
+                          = load_fcn_from_file (str, dir_name, "", "", fname);
 
                         if (fcn)
                           {
@@ -991,7 +992,7 @@
                     std::string dir_name = fpath.substr (0, xpos);
 
                     octave_function *fcn
-                      = load_fcn_from_file (fpath, dir_name, "", fname);
+                      = load_fcn_from_file (fpath, dir_name, "", "", fname);
 
                     if (fcn)
                       {
@@ -1171,7 +1172,7 @@
 
           if (len)
             {
-              if (! is.read (name, len ))
+              if (! is.read (name, len))
                 goto data_read_error;
 
               is.seekg (tmp_pos + static_cast<std::streamoff>
@@ -1201,7 +1202,7 @@
             goto data_read_error;
           }
 
-        if (! is.read (reinterpret_cast<char *> (&field_name_length), fn_len ))
+        if (! is.read (reinterpret_cast<char *> (&field_name_length), fn_len))
           goto data_read_error;
 
         if (swap)
@@ -1568,7 +1569,8 @@
 read_mat5_binary_file_header (std::istream& is, bool& swap, bool quiet,
                               const std::string& filename)
 {
-  int16_t version=0, magic=0;
+  int16_t version = 0;
+  int16_t magic = 0;
   uint64_t subsys_offset;
 
   is.seekg (116, std::ios::beg);
@@ -1674,7 +1676,8 @@
       OCTAVE_LOCAL_BUFFER (TYPE, ptr, count); \
       for (octave_idx_type i = 0; i < count; i++) \
         ptr[i] = static_cast<TYPE> (data[i]); \
-      stream.write (reinterpret_cast<char *> (ptr), count * sizeof (TYPE)); \
+      std::streamsize n_bytes = sizeof (TYPE) * static_cast<std::streamsize> (count); \
+      stream.write (reinterpret_cast<char *> (ptr), n_bytes); \
     } \
   while (0)
 
--- a/libinterp/corefcn/lu.cc	Fri Aug 01 09:06:21 2014 -0400
+++ b/libinterp/corefcn/lu.cc	Fri Aug 01 12:10:05 2014 -0400
@@ -158,11 +158,11 @@
   int n = 1;
   while (n < nargin && ! error_state)
     {
-      if (args (n).is_string ())
+      if (args(n).is_string ())
         {
           std::string tmp = args(n++).string_value ();
 
-          if (! error_state )
+          if (! error_state)
             {
               if (tmp.compare ("vector") == 0)
                 vecout = true;
@@ -174,7 +174,7 @@
         {
           Matrix tmp = args(n++).matrix_value ();
 
-          if (! error_state )
+          if (! error_state)
             {
               if (!issparse)
                 error ("lu: can not define pivoting threshold THRES for full matrices");
@@ -211,7 +211,7 @@
 
           SparseMatrix m = arg.sparse_matrix_value ();
 
-          if ( nargout < 4 )
+          if (nargout < 4)
             {
 
               ColumnVector Qinit;
@@ -220,7 +220,7 @@
                 Qinit (i) = i;
               SparseLU fact (m, Qinit, thres, false, true);
 
-              if ( nargout < 2 )
+              if (nargout < 2)
                   retval(0) = fact.Y ();
               else
                 {
@@ -233,15 +233,15 @@
 
                   PermMatrix P = fact.Pr_mat ();
                   SparseMatrix L = fact.L ();
-                  if ( nargout < 3 )
+                  if (nargout < 3)
                       retval(0)
-                        = octave_value ( P.transpose () * L,
+                        = octave_value (P.transpose () * L,
                             MatrixType (MatrixType::Permuted_Lower,
                                         nr, fact.row_perm ()));
                   else
                     {
                       retval(0) = L;
-                      if ( vecout )
+                      if (vecout)
                         retval(2) = fact.Pr_vec();
                       else
                         retval(2) = P;
@@ -279,7 +279,7 @@
         {
           SparseComplexMatrix m = arg.sparse_complex_matrix_value ();
 
-          if ( nargout < 4 )
+          if (nargout < 4)
             {
 
               ColumnVector Qinit;
@@ -288,7 +288,7 @@
                 Qinit (i) = i;
               SparseComplexLU fact (m, Qinit, thres, false, true);
 
-              if ( nargout < 2 )
+              if (nargout < 2)
 
                   retval(0) = fact.Y ();
 
@@ -303,15 +303,15 @@
 
                   PermMatrix P = fact.Pr_mat ();
                   SparseComplexMatrix L = fact.L ();
-                  if ( nargout < 3 )
+                  if (nargout < 3)
                       retval(0)
-                        = octave_value ( P.transpose () * L,
+                        = octave_value (P.transpose () * L,
                             MatrixType (MatrixType::Permuted_Lower,
                                         nr, fact.row_perm ()));
                   else
                     {
                       retval(0) = L;
-                      if ( vecout )
+                      if (vecout)
                         retval(2) = fact.Pr_vec();
                       else
                         retval(2) = P;
@@ -592,7 +592,9 @@
 bool check_lu_dims (const octave_value& l, const octave_value& u,
                     const octave_value& p)
 {
-  octave_idx_type m = l.rows (), k = u.rows (), n = u.columns ();
+  octave_idx_type m = l.rows ();
+  octave_idx_type k = u.rows ();
+  octave_idx_type n = u.columns ();
   return ((l.ndims () == 2 && u.ndims () == 2 && k == l.columns ())
           && k == std::min (m, n) &&
           (p.is_undefined () || p.rows () == m));
@@ -840,6 +842,20 @@
 %! assert (norm (vec (P'*L*U - A - u*v.'), Inf) < norm (A)*1e1*eps);
 %!
 %!testif HAVE_QRUPDATE_LUU
+%! [L,U,P] = lu (A);
+%! [~,ordcols] = max (P,[],1);
+%! [~,ordrows] = max (P,[],2);
+%! P1 = eye (size(P))(:,ordcols);
+%! P2 = eye (size(P))(ordrows,:);
+%! assert(P1 == P);
+%! assert(P2 == P);
+%! [L,U,P] = luupdate (L,U,P,u,v);
+%! [L,U,P1] = luupdate (L,U,P1,u,v);
+%! [L,U,P2] = luupdate (L,U,P2,u,v);
+%! assert(P1 == P);
+%! assert(P2 == P);
+%!
+%!testif HAVE_QRUPDATE_LUU
 %! [L,U,P] = lu (Ac);
 %! [L,U,P] = luupdate (L,U,P,uc,vc);
 %! assert (norm (vec (tril (L)-L), Inf) == 0);
--- a/libinterp/corefcn/luinc.cc	Fri Aug 01 09:06:21 2014 -0400
+++ b/libinterp/corefcn/luinc.cc	Fri Aug 01 12:10:05 2014 -0400
@@ -49,7 +49,7 @@
 \n\
 Called with a second argument of @qcode{'0'}, the zero-level incomplete\n\
 LU@tie{}factorization is produced.  This creates a factorization of @var{A}\n\
-where the position of the non-zero arguments correspond to the same\n\
+where the position of the nonzero arguments correspond to the same\n\
 positions as in the matrix @var{A}.\n\
 \n\
 Alternatively, the fill-in of the incomplete LU@tie{}factorization can\n\
@@ -177,7 +177,7 @@
         {
           std::string tmp = args(2).string_value ();
 
-          if (! error_state )
+          if (! error_state)
             {
               if (tmp.compare ("vector") == 0)
                 vecout = true;
--- a/libinterp/corefcn/mappers.cc	Fri Aug 01 09:06:21 2014 -0400
+++ b/libinterp/corefcn/mappers.cc	Fri Aug 01 12:10:05 2014 -0400
@@ -1886,7 +1886,7 @@
 Return logical true if the value of @var{x} has its sign bit set.\n\
 Otherwise return logical false.  This behavior is consistent with the other\n\
 logical functions.  See@ref{Logical Values}.  The behavior differs from the\n\
-C language function which returns non-zero if the sign bit is set.\n\
+C language function which returns nonzero if the sign bit is set.\n\
 \n\
 This is not the same as @code{x < 0.0}, because IEEE 754 floating point\n\
 allows zero to be signed.  The comparison @code{-0.0 < 0.0} is false,\n\
@@ -2156,8 +2156,17 @@
 %!assert (tolower ({"ABC", "DEF", {"GHI", {"JKL"}}}), {"abc", "def", {"ghi", {"jkl"}}})
 %!assert (tolower (["ABC"; "DEF"]), ["abc"; "def"])
 %!assert (tolower ({["ABC"; "DEF"]}), {["abc";"def"]})
-%!assert (tolower (68), "d")
-%!assert (tolower ({[68, 68; 68, 68]}), {["dd";"dd"]})
+%!assert (tolower (68), 68)
+%!assert (tolower ({[68, 68; 68, 68]}), {[68, 68; 68, 68]})
+%!test
+%! classes = {@char, @double, @single, ...
+%!            @int8, @int16, @int32, @int64, ...
+%!            @uint8, @uint16, @uint32, @uint64};
+%! for i = 1:numel (classes)
+%!   cls = classes{i};
+%!   assert (class (tolower (cls (97))), class (cls (97)));
+%!   assert (class (tolower (cls ([98, 99]))), class (cls ([98, 99])));
+%! endfor
 %!test
 %! a(3,3,3,3) = "D";
 %! assert (tolower (a)(3,3,3,3), "d");
@@ -2207,8 +2216,17 @@
 %!assert (toupper ({"abc", "def", {"ghi", {"jkl"}}}), {"ABC", "DEF", {"GHI", {"JKL"}}})
 %!assert (toupper (["abc"; "def"]), ["ABC"; "DEF"])
 %!assert (toupper ({["abc"; "def"]}), {["ABC";"DEF"]})
-%!assert (toupper (100), "D")
-%!assert (toupper ({[100, 100; 100, 100]}), {["DD";"DD"]})
+%!assert (toupper (100), 100)
+%!assert (toupper ({[100, 100; 100, 100]}), {[100, 100; 100, 100]})
+%!test
+%! classes = {@char, @double, @single, ...
+%!            @int8, @int16, @int32, @int64, ...
+%!            @uint8, @uint16, @uint32, @uint64};
+%! for i = 1:numel (classes)
+%!   cls = classes{i};
+%!   assert (class (toupper (cls (97))), class (cls (97)));
+%!   assert (class (toupper (cls ([98, 99]))), class (cls ([98, 99])));
+%! endfor
 %!test
 %! a(3,3,3,3) = "d";
 %! assert (toupper (a)(3,3,3,3), "D");
--- a/libinterp/corefcn/matrix_type.cc	Fri Aug 01 09:06:21 2014 -0400
+++ b/libinterp/corefcn/matrix_type.cc	Fri Aug 01 12:10:05 2014 -0400
@@ -148,7 +148,7 @@
                 {
                   mattyp = args(0).matrix_type ();
 
-                  if (mattyp.is_unknown () && autocomp )
+                  if (mattyp.is_unknown () && autocomp)
                     {
                       SparseComplexMatrix m =
                         args(0).sparse_complex_matrix_value ();
@@ -281,7 +281,7 @@
                           && (str_typ == "upper" || str_typ == "lower"))
                         {
                           const ColumnVector perm =
-                            ColumnVector (args (2).vector_value ());
+                            ColumnVector (args(2).vector_value ());
 
                           if (error_state)
                             error ("matrix_type: Invalid permutation vector PERM");
@@ -454,7 +454,7 @@
                                           || str_typ == "lower"))
                         {
                           const ColumnVector perm =
-                            ColumnVector (args (2).vector_value ());
+                            ColumnVector (args(2).vector_value ());
 
                           if (error_state)
                             error ("matrix_type: Invalid permutation vector PERM");
--- a/libinterp/corefcn/max.cc	Fri Aug 01 09:06:21 2014 -0400
+++ b/libinterp/corefcn/max.cc	Fri Aug 01 12:10:05 2014 -0400
@@ -354,8 +354,10 @@
     }
   else if (nargin == 2)
     {
-      octave_value argx = args(0), argy = args(1);
-      builtin_type_t xtyp = argx.builtin_type (), ytyp = argy.builtin_type ();
+      octave_value argx = args(0);
+      octave_value argy = args(1);
+      builtin_type_t xtyp = argx.builtin_type ();
+      builtin_type_t ytyp = argy.builtin_type ();
       builtin_type_t rtyp;
       if (xtyp == btyp_char && ytyp == btyp_char)
         rtyp = btyp_char;
@@ -560,6 +562,10 @@
 %! assert (ndims(i), 2);
 %! assert (i, [1, 1; 1, 1]);
 
+## Test for bug #40743
+%!assert (max (zeros (1,0), ones (1,1)), zeros (1,0))
+%!assert (max (sparse (zeros (1,0)), sparse (ones (1,1))), sparse (zeros (1,0)))
+
 %!error max ()
 %!error max (1, 2, 3, 4)
 */
--- a/libinterp/corefcn/module.mk	Fri Aug 01 09:06:21 2014 -0400
+++ b/libinterp/corefcn/module.mk	Fri Aug 01 12:10:05 2014 -0400
@@ -44,6 +44,7 @@
 COREFCN_INC = \
   corefcn/Cell.h \
   corefcn/c-file-ptr-stream.h \
+  corefcn/cdisplay.h \
   corefcn/comment-list.h \
   corefcn/cutils.h \
   corefcn/data.h \
@@ -91,6 +92,7 @@
   corefcn/oct-stream.h \
   corefcn/oct-strstrm.h \
   corefcn/oct.h \
+  corefcn/octave-default-image.h \
   corefcn/octave-link.h \
   corefcn/pager.h \
   corefcn/pr-output.h \
@@ -143,6 +145,7 @@
   corefcn/bitfcns.cc \
   corefcn/bsxfun.cc \
   corefcn/c-file-ptr-stream.cc \
+  corefcn/cdisplay.c \
   corefcn/cellfun.cc \
   corefcn/colloc.cc \
   corefcn/comment-list.cc \
--- a/libinterp/corefcn/oct-fstrm.cc	Fri Aug 01 09:06:21 2014 -0400
+++ b/libinterp/corefcn/oct-fstrm.cc	Fri Aug 01 12:10:05 2014 -0400
@@ -77,7 +77,7 @@
   return -1;
 }
 
-// Return non-zero if EOF has been reached on this stream.
+// Return nonzero if EOF has been reached on this stream.
 
 bool
 octave_fstream::eof (void) const
--- a/libinterp/corefcn/oct-fstrm.h	Fri Aug 01 09:06:21 2014 -0400
+++ b/libinterp/corefcn/oct-fstrm.h	Fri Aug 01 12:10:05 2014 -0400
@@ -52,7 +52,7 @@
 
   off_t tell (void);
 
-  // Return non-zero if EOF has been reached on this stream.
+  // Return nonzero if EOF has been reached on this stream.
 
   bool eof (void) const;
 
--- a/libinterp/corefcn/oct-iostrm.cc	Fri Aug 01 09:06:21 2014 -0400
+++ b/libinterp/corefcn/oct-iostrm.cc	Fri Aug 01 12:10:05 2014 -0400
@@ -45,7 +45,7 @@
   return -1;
 }
 
-// Return non-zero if EOF has been reached on this stream.
+// Return nonzero if EOF has been reached on this stream.
 
 bool
 octave_base_iostream::eof (void) const
@@ -60,7 +60,7 @@
   ::error ("%s: invalid operation", stream_type ());
 }
 
-// Return non-zero if EOF has been reached on this stream.
+// Return nonzero if EOF has been reached on this stream.
 
 bool
 octave_istream::eof (void) const
@@ -74,7 +74,7 @@
   return octave_stream (new octave_istream (arg, n));
 }
 
-// Return non-zero if EOF has been reached on this stream.
+// Return nonzero if EOF has been reached on this stream.
 
 bool
 octave_ostream::eof (void) const
--- a/libinterp/corefcn/oct-iostrm.h	Fri Aug 01 09:06:21 2014 -0400
+++ b/libinterp/corefcn/oct-iostrm.h	Fri Aug 01 12:10:05 2014 -0400
@@ -46,7 +46,7 @@
 
   off_t tell (void);
 
-  // Return non-zero if EOF has been reached on this stream.
+  // Return nonzero if EOF has been reached on this stream.
 
   bool eof (void) const;
 
@@ -87,7 +87,7 @@
   static octave_stream
   create (std::istream *arg = 0, const std::string& n = std::string ());
 
-  // Return non-zero if EOF has been reached on this stream.
+  // Return nonzero if EOF has been reached on this stream.
 
   bool eof (void) const;
 
@@ -126,7 +126,7 @@
   static octave_stream
   create (std::ostream *arg, const std::string& n = std::string ());
 
-  // Return non-zero if EOF has been reached on this stream.
+  // Return nonzero if EOF has been reached on this stream.
 
   bool eof (void) const;
 
--- a/libinterp/corefcn/oct-map.cc	Fri Aug 01 09:06:21 2014 -0400
+++ b/libinterp/corefcn/oct-map.cc	Fri Aug 01 12:10:05 2014 -0400
@@ -117,7 +117,8 @@
 {
   bool retval = true;
 
-  iterator p = begin (), q = other.begin ();
+  iterator p = begin ();
+  iterator q = other.begin ();
   for (; p != end () && q != other.end (); p++, q++)
     {
       if (p->first == q->first)
@@ -251,15 +252,6 @@
     }
 }
 
-octave_map::octave_map (const Octave_map& m)
-  : xkeys (m.keys ()), xvals (m.nfields ()), dimensions (m.dims ())
-{
-  for (iterator p = begin (); p != end (); p++)
-    contents(p) = m.contents (key (p));
-
-  optimize_dimensions ();
-}
-
 Cell
 octave_map::getfield (const std::string& k) const
 {
@@ -819,9 +811,9 @@
 %! sr = [s,s];
 %! sc = [s;s];
 %! sm = [s,s;s,s];
-%! assert (nfields (sr), 0);
-%! assert (nfields (sc), 0);
-%! assert (nfields (sm), 0);
+%! assert (numfields (sr), 0);
+%! assert (numfields (sc), 0);
+%! assert (numfields (sm), 0);
 %! assert (size (sr), [1, 2]);
 %! assert (size (sc), [2, 1]);
 %! assert (size (sm), [2, 2]);
@@ -1314,470 +1306,3 @@
 
 }
 
-Octave_map::Octave_map (const dim_vector& dv, const Cell& key_vals)
-  : map (), key_list (), dimensions (dv)
-{
-  Cell c (dv);
-
-  if (key_vals.is_cellstr ())
-    {
-      for (octave_idx_type i = 0; i < key_vals.numel (); i++)
-        {
-          std::string k = key_vals(i).string_value ();
-          map[k] = c;
-          key_list.push_back (k);
-        }
-    }
-  else
-    error ("Octave_map: expecting keys to be cellstr");
-}
-
-Octave_map::Octave_map (const octave_map& m)
-  : map (), key_list (), dimensions (m.dims ())
-{
-  for (octave_map::const_iterator p = m.begin (); p != m.end (); p++)
-    map[m.key (p)] = m.contents (p);
-  const string_vector mkeys = m.fieldnames ();
-  for (octave_idx_type i = 0; i < mkeys.numel (); i++)
-    key_list.push_back (mkeys(i));
-}
-
-Octave_map
-Octave_map::squeeze (void) const
-{
-  Octave_map retval (dims ().squeeze ());
-
-  for (const_iterator pa = begin (); pa != end (); pa++)
-    {
-      Cell tmp = contents (pa).squeeze ();
-
-      if (error_state)
-        break;
-
-      retval.assign (key (pa), tmp);
-    }
-
-  // Preserve order of keys.
-  retval.key_list = key_list;
-
-  return retval;
-}
-
-Octave_map
-Octave_map::permute (const Array<int>& vec, bool inv) const
-{
-  Octave_map retval (dims ());
-
-  for (const_iterator pa = begin (); pa != end (); pa++)
-    {
-      Cell tmp = contents (pa).permute (vec, inv);
-
-      if (error_state)
-        break;
-
-      retval.assign (key (pa), tmp);
-    }
-
-  // Preserve order of keys.
-  retval.key_list = key_list;
-
-  return retval;
-}
-
-Cell&
-Octave_map::contents (const std::string& k)
-{
-  maybe_add_to_key_list (k);
-
-  return map[k];
-}
-
-Cell
-Octave_map::contents (const std::string& k) const
-{
-  const_iterator p = seek (k);
-
-  return p != end () ? p->second : Cell ();
-}
-
-int
-Octave_map::intfield (const std::string& k, int def_val) const
-{
-  int retval = def_val;
-
-  Cell c = contents (k);
-
-  if (! c.is_empty ())
-    retval = c(0).int_value ();
-
-  return retval;
-}
-
-std::string
-Octave_map::stringfield (const std::string& k,
-                         const std::string& def_val) const
-{
-  std::string retval = def_val;
-
-  Cell c = contents (k);
-
-  if (! c.is_empty ())
-    retval = c(0).string_value ();
-
-  return retval;
-}
-
-string_vector
-Octave_map::keys (void) const
-{
-  assert (static_cast<size_t>(nfields ()) == key_list.size ());
-
-  return string_vector (key_list);
-}
-
-Octave_map
-Octave_map::transpose (void) const
-{
-  assert (ndims () == 2);
-
-  dim_vector dv = dims ();
-
-  octave_idx_type nr = dv(0);
-  octave_idx_type nc = dv(1);
-
-  dim_vector new_dims (nc, nr);
-
-  Octave_map retval (new_dims);
-
-  for (const_iterator p = begin (); p != end (); p++)
-    retval.assign (key(p), Cell (contents(p).transpose ()));
-
-  // Preserve order of keys.
-  retval.key_list = key_list;
-
-  return retval;
-}
-
-Octave_map
-Octave_map::reshape (const dim_vector& new_dims) const
-{
-  Octave_map retval;
-
-  if (new_dims != dims ())
-    {
-      for (const_iterator p = begin (); p != end (); p++)
-        retval.assign (key(p), contents(p).reshape (new_dims));
-
-      retval.dimensions = new_dims;
-
-      // Preserve order of keys.
-      retval.key_list = key_list;
-    }
-  else
-    retval = *this;
-
-  return retval;
-}
-
-void
-Octave_map::resize (const dim_vector& dv, bool fill)
-{
-  if (dv != dims ())
-    {
-      if (nfields () == 0)
-        dimensions = dv;
-      else
-        {
-          for (const_iterator p = begin (); p != end (); p++)
-            {
-              Cell tmp = contents(p);
-
-              if (fill)
-                tmp.resize (dv, Matrix ());
-              else
-                tmp.resize (dv);
-
-              dimensions = dv;
-
-              assign (key(p), tmp);
-            }
-        }
-    }
-}
-
-Octave_map
-Octave_map::concat (const Octave_map& rb, const Array<octave_idx_type>& ra_idx)
-{
-  Octave_map retval;
-
-  if (nfields () == rb.nfields ())
-    {
-      for (const_iterator pa = begin (); pa != end (); pa++)
-        {
-          const_iterator pb = rb.seek (key(pa));
-
-          if (pb == rb.end ())
-            {
-              error ("field name mismatch in structure concatenation");
-              break;
-            }
-
-          retval.assign (key(pa),
-                         contents(pa).insert (rb.contents(pb), ra_idx));
-        }
-
-      // Preserve order of keys.
-      retval.key_list = key_list;
-    }
-  else
-    {
-      dim_vector dv = dims ();
-
-      if (dv.all_zero ())
-        retval = rb;
-      else
-        {
-          dv = rb.dims ();
-
-          if (dv.all_zero ())
-            retval = *this;
-          else
-            error ("invalid structure concatenation");
-        }
-    }
-
-  return retval;
-}
-
-static bool
-keys_ok (const Octave_map& a, const Octave_map& b, string_vector& keys)
-{
-  bool retval = false;
-
-  keys = string_vector ();
-
-  if (a.nfields () == 0)
-    {
-      keys = b.keys ();
-      retval = true;
-    }
-  else
-    {
-      string_vector a_keys = a.keys ().sort ();
-      string_vector b_keys = b.keys ().sort ();
-
-      octave_idx_type a_len = a_keys.length ();
-      octave_idx_type b_len = b_keys.length ();
-
-      if (a_len == b_len)
-        {
-          for (octave_idx_type i = 0; i < a_len; i++)
-            {
-              if (a_keys[i] != b_keys[i])
-                goto done;
-            }
-
-          keys = a_keys;
-          retval = true;
-        }
-    }
-
-done:
-  return retval;
-}
-
-Octave_map&
-Octave_map::maybe_delete_elements (const octave_value_list& idx)
-{
-  string_vector t_keys = keys ();
-  octave_idx_type len = t_keys.length ();
-
-  if (len > 0)
-    {
-      for (octave_idx_type i = 0; i < len; i++)
-        {
-          std::string k = t_keys[i];
-
-          contents(k).delete_elements (idx);
-
-          if (error_state)
-            break;
-        }
-
-      if (!error_state)
-        dimensions = contents(t_keys[0]).dims ();
-    }
-
-  return *this;
-}
-
-Octave_map&
-Octave_map::assign (const octave_value_list& idx, const Octave_map& rhs)
-{
-  string_vector t_keys;
-
-  if (keys_ok (*this, rhs, t_keys))
-    {
-      octave_idx_type len = t_keys.length ();
-
-      if (len == 0)
-        {
-          Cell tmp_lhs (dims ());
-          Cell tmp_rhs (rhs.dims ());
-
-          tmp_lhs.assign (idx, tmp_rhs, Matrix ());
-
-          if (! error_state)
-            resize (tmp_lhs.dims ());
-          else
-            error ("size mismatch in structure assignment");
-        }
-      else
-        {
-          for (octave_idx_type i = 0; i < len; i++)
-            {
-              std::string k = t_keys[i];
-
-              Cell t_rhs = rhs.contents (k);
-
-              assign (idx, k, t_rhs);
-
-              if (error_state)
-                break;
-            }
-        }
-    }
-  else
-    error ("field name mismatch in structure assignment");
-
-  return *this;
-}
-
-Octave_map&
-Octave_map::assign (const octave_value_list& idx, const std::string& k,
-                    const Cell& rhs)
-{
-  Cell tmp;
-
-  if (contains (k))
-    tmp = map[k];
-  else
-    tmp = Cell (dimensions);
-
-  tmp.assign (idx, rhs);
-
-  if (! error_state)
-    {
-      dim_vector tmp_dims = tmp.dims ();
-
-      if (tmp_dims != dimensions)
-        {
-          for (iterator p = begin (); p != end (); p++)
-            contents(p).resize (tmp_dims, Matrix ());
-
-          dimensions = tmp_dims;
-        }
-
-      maybe_add_to_key_list (k);
-
-      map[k] = tmp;
-    }
-
-  return *this;
-}
-
-Octave_map&
-Octave_map::assign (const std::string& k, const octave_value& rhs)
-{
-  if (nfields () == 0)
-    {
-      maybe_add_to_key_list (k);
-
-      map[k] = Cell (rhs);
-
-      dimensions = dim_vector (1, 1);
-    }
-  else
-    {
-      dim_vector dv = dims ();
-
-      if (dv.all_ones ())
-        {
-          maybe_add_to_key_list (k);
-
-          map[k] = Cell (rhs);
-        }
-      else
-        error ("invalid structure assignment");
-    }
-
-  return *this;
-}
-
-Octave_map&
-Octave_map::assign (const std::string& k, const Cell& rhs)
-{
-  if (nfields () == 0)
-    {
-      maybe_add_to_key_list (k);
-
-      map[k] = rhs;
-
-      dimensions = rhs.dims ();
-    }
-  else
-    {
-      if (dims () == rhs.dims ())
-        {
-          maybe_add_to_key_list (k);
-
-          map[k] = rhs;
-        }
-      else
-        error ("invalid structure assignment");
-    }
-
-  return *this;
-}
-
-Octave_map
-Octave_map::index (const octave_value_list& idx, bool resize_ok) const
-{
-  Octave_map retval;
-
-  octave_idx_type n_idx = idx.length ();
-
-  if (n_idx > 0)
-    {
-      Array<idx_vector> ra_idx (dim_vector (n_idx, 1));
-
-      for (octave_idx_type i = 0; i < n_idx; i++)
-        {
-          ra_idx(i) = idx(i).index_vector ();
-          if (error_state)
-            break;
-        }
-
-      if (! error_state)
-        {
-          for (const_iterator p = begin (); p != end (); p++)
-            {
-              Cell tmp = contents (p);
-
-              tmp = tmp.Array<octave_value>::index (ra_idx, resize_ok);
-
-              if (error_state)
-                break;
-
-              retval.assign (key(p), tmp);
-            }
-
-          // Preserve order of keys.
-          retval.key_list = key_list;
-        }
-    }
-  else
-    retval = *this;
-
-  return retval;
-}
--- a/libinterp/corefcn/oct-map.h	Fri Aug 01 09:06:21 2014 -0400
+++ b/libinterp/corefcn/oct-map.h	Fri Aug 01 12:10:05 2014 -0400
@@ -287,8 +287,6 @@
 
   octave_map (const octave_scalar_map& m);
 
-  octave_map (const Octave_map& m);
-
   octave_map& operator = (const octave_map& m)
   {
     xkeys = m.xkeys;
@@ -475,189 +473,4 @@
 inline octave_map octave_value_extract<octave_map> (const octave_value& v)
 { return v.map_value (); }
 
-// The original Octave_map object which is now deprecated.
-// It was fully deprecated in version 3.8 and should be removed in 3.12.
-// Octave_map and octave_map are convertible to each other.
-
-class
-OCTINTERP_API
-Octave_map
-{
-public:
-
-  typedef std::map<std::string, Cell>::iterator iterator;
-  typedef std::map<std::string, Cell>::const_iterator const_iterator;
-
-  typedef std::list<std::string>::iterator key_list_iterator;
-  typedef std::list<std::string>::const_iterator const_key_list_iterator;
-
-  // Warning!  You should always use at least two dimensions.
-
-  Octave_map (const dim_vector& dv = dim_vector (0, 0),
-              const Cell& key_vals = Cell ());
-
-  Octave_map (const std::string& k, const octave_value& value)
-    : map (), key_list (), dimensions (1, 1)
-  {
-    map[k] = value;
-    key_list.push_back (k);
-  }
-
-  Octave_map (const string_vector& sv,
-              const dim_vector& dv = dim_vector (0, 0))
-    : map (), key_list (), dimensions (dv)
-  {
-    for (octave_idx_type i = 0; i < sv.length (); i++)
-      {
-        std::string k = sv[i];
-        map[k] = Cell (dv);
-        key_list.push_back (k);
-      }
-  }
-
-  Octave_map (const std::string& k, const Cell& vals)
-    : map (), key_list (), dimensions (vals.dims ())
-  {
-    map[k] = vals;
-    key_list.push_back (k);
-  }
-
-  Octave_map (const std::string& k, const octave_value_list& val_list)
-    : map (), key_list (), dimensions (1, val_list.length ())
-  {
-    map[k] = val_list;
-    key_list.push_back (k);
-  }
-
-  Octave_map (const Octave_map& m)
-    : map (m.map), key_list (m.key_list), dimensions (m.dimensions) { }
-
-  Octave_map (const octave_map& m);
-
-  Octave_map& operator = (const Octave_map& m)
-  {
-    if (this != &m)
-      {
-        map = m.map;
-        key_list = m.key_list;
-        dimensions = m.dimensions;
-      }
-
-    return *this;
-  }
-
-  ~Octave_map (void) { }
-
-  Octave_map squeeze (void) const;
-
-  Octave_map permute (const Array<int>& vec, bool inv = false) const;
-
-  // This is the number of keys.
-  octave_idx_type nfields (void) const { return map.size (); }
-
-  void del (const std::string& k)
-  {
-    iterator p = map.find (k);
-
-    if (p != map.end ())
-      {
-        map.erase (p);
-
-        key_list_iterator q
-          = std::find (key_list.begin (), key_list.end (), k);
-
-        assert (q != key_list.end ());
-
-        key_list.erase (q);
-      }
-  }
-
-  iterator begin (void) { return iterator (map.begin ()); }
-  const_iterator begin (void) const { return const_iterator (map.begin ()); }
-
-  iterator end (void) { return iterator (map.end ()); }
-  const_iterator end (void) const { return const_iterator (map.end ()); }
-
-  std::string key (const_iterator p) const { return p->first; }
-
-  Cell& contents (const std::string& k);
-  Cell contents (const std::string& k) const;
-
-  Cell& contents (iterator p)
-  { return p->second; }
-
-  Cell contents (const_iterator p) const
-  { return p->second; }
-
-  int intfield (const std::string& k, int def_val = 0) const;
-
-  std::string stringfield (const std::string& k,
-                           const std::string& def_val = std::string ()) const;
-
-  iterator seek (const std::string& k) { return map.find (k); }
-  const_iterator seek (const std::string& k) const { return map.find (k); }
-
-  bool contains (const std::string& k) const
-  { return (seek (k) != map.end ()); }
-
-  void clear (void)
-  {
-    map.clear ();
-    key_list.clear ();
-  }
-
-  string_vector keys (void) const;
-
-  octave_idx_type rows (void) const { return dimensions(0); }
-
-  octave_idx_type columns (void) const { return dimensions(1); }
-
-  dim_vector dims (void) const { return dimensions; }
-
-  int ndims (void) const { return dimensions.length (); }
-
-  Octave_map transpose (void) const;
-
-  Octave_map reshape (const dim_vector& new_dims) const;
-
-  void resize (const dim_vector& dv, bool fill = false);
-
-  octave_idx_type numel (void) const { return dimensions.numel (); }
-
-  Octave_map concat (const Octave_map& rb,
-                     const Array<octave_idx_type>& ra_idx);
-
-  Octave_map& maybe_delete_elements (const octave_value_list& idx);
-
-  Octave_map& assign (const octave_value_list& idx, const Octave_map& rhs);
-
-  Octave_map& assign (const octave_value_list& idx, const std::string& k,
-                      const Cell& rhs);
-
-  Octave_map& assign (const std::string& k, const octave_value& rhs);
-
-  Octave_map& assign (const std::string& k, const Cell& rhs);
-
-  Octave_map index (const octave_value_list& idx,
-                    bool resize_ok = false) const;
-
-private:
-
-  // The map of names to values.
-  std::map<std::string, Cell> map;
-
-  // An extra list of keys, so we can keep track of the order the keys
-  // are added for compatibility with you know what.
-  std::list<std::string> key_list;
-
-  // The current size.
-  mutable dim_vector dimensions;
-
-  void maybe_add_to_key_list (const std::string& k)
-  {
-    if (! contains (k))
-      key_list.push_back (k);
-  }
-} GCC_ATTR_DEPRECATED;
-
 #endif
--- a/libinterp/corefcn/oct-obj.cc	Fri Aug 01 09:06:21 2014 -0400
+++ b/libinterp/corefcn/oct-obj.cc	Fri Aug 01 12:10:05 2014 -0400
@@ -35,7 +35,8 @@
 
 octave_value_list::octave_value_list (const std::list<octave_value_list>& lst)
 {
-  octave_idx_type n = 0, nel = 0;
+  octave_idx_type n = 0;
+  octave_idx_type nel = 0;
 
   // Determine number.
   for (std::list<octave_value_list>::const_iterator p = lst.begin ();
--- a/libinterp/corefcn/oct-obj.h	Fri Aug 01 09:06:21 2014 -0400
+++ b/libinterp/corefcn/oct-obj.h	Fri Aug 01 12:10:05 2014 -0400
@@ -107,10 +107,16 @@
   octave_value_list
   slice (octave_idx_type offset, octave_idx_type len, bool tags = false) const
   {
-    octave_value_list retval (data.linear_slice (offset, offset + len));
+    // linear_slice uses begin/end indices instead of offset and
+    // length.  Avoid calling with upper bound out of range.
+    // linear_slice handles the case of len < 0.
+
+    octave_value_list retval
+      = data.linear_slice (offset, std::min (offset + len, length ()));
+
     if (tags && len > 0 && names.length () > 0)
-      retval.names = names.linear_slice (offset,
-                                         std::min (len, names.length ()));
+      retval.names = names.linear_slice (offset, std::min (offset + len,
+                                                           names.length ()));
 
     return retval;
   }
--- a/libinterp/corefcn/oct-stdstrm.h	Fri Aug 01 09:06:21 2014 -0400
+++ b/libinterp/corefcn/oct-stdstrm.h	Fri Aug 01 12:10:05 2014 -0400
@@ -50,7 +50,7 @@
 
   off_t tell (void) { return s ? s->tell () : -1; }
 
-  // Return non-zero if EOF has been reached on this stream.
+  // Return nonzero if EOF has been reached on this stream.
 
   bool eof (void) const { return s ? s->eof () : true; }
 
--- a/libinterp/corefcn/oct-stream.cc	Fri Aug 01 09:06:21 2014 -0400
+++ b/libinterp/corefcn/oct-stream.cc	Fri Aug 01 12:10:05 2014 -0400
@@ -785,11 +785,14 @@
 
   if (i < n)
     {
+      // Accept and record modifier, but don't place it in the format
+      // item text.  All integer conversions are handled as 64-bit
+      // integers.
+
       switch (s[i])
         {
         case 'h': case 'l': case 'L':
-          modifier = s[i];
-          *buf << s[i++];
+          modifier = s[i++];
           break;
 
         default:
@@ -1053,7 +1056,8 @@
     {
       std::istream& is = *isp;
 
-      int c = 0, lastc = -1;
+      int c = 0;
+      int lastc = -1;
       cnt = 0;
 
       while (is && (c = is.get ()) != EOF)
@@ -2159,7 +2163,7 @@
 
   printf_value_cache (const octave_value_list& args, const std::string& who)
     : values (args), val_idx (0), elt_idx (0),
-      n_vals (values.length ()), n_elts (0), data (0),
+      n_vals (values.length ()), n_elts (0), have_data (false),
       curr_state (ok)
   {
     for (octave_idx_type i = 0; i < values.length (); i++)
@@ -2177,7 +2181,7 @@
   ~printf_value_cache (void) { }
 
   // Get the current value as a double and advance the internal pointer.
-  double double_value (void);
+  octave_value get_next_value (void);
 
   // Get the current value as an int and advance the internal pointer.
   int int_value (void);
@@ -2196,8 +2200,8 @@
   int elt_idx;
   int n_vals;
   int n_elts;
-  const double *data;
-  NDArray curr_val;
+  bool have_data;
+  octave_value curr_val;
   state curr_state;
 
   // Must create value cache with values!
@@ -2211,29 +2215,27 @@
   printf_value_cache& operator = (const printf_value_cache&);
 };
 
-double
-printf_value_cache::double_value (void)
+octave_value
+printf_value_cache::get_next_value (void)
 {
-  double retval = 0.0;
+  octave_value retval;
 
   if (exhausted ())
     curr_state = conversion_error;
 
   while (! exhausted ())
     {
-      if (! data)
+      if (! have_data)
         {
-          octave_value tmp_val = values (val_idx);
+          curr_val = values (val_idx);
 
           // Force string conversion here for compatibility.
 
-          curr_val = tmp_val.array_value (true);
-
           if (! error_state)
             {
               elt_idx = 0;
-              n_elts = curr_val.length ();
-              data = curr_val.data ();
+              n_elts = curr_val.numel ();
+              have_data = true;
             }
           else
             {
@@ -2244,13 +2246,13 @@
 
       if (elt_idx < n_elts)
         {
-          retval = data[elt_idx++];
+          retval = curr_val.fast_elem_extract (elt_idx++);
 
           if (elt_idx >= n_elts)
             {
               elt_idx = 0;
               val_idx++;
-              data = 0;
+              have_data = false;
             }
 
           break;
@@ -2258,7 +2260,7 @@
       else
         {
           val_idx++;
-          data = 0;
+          have_data = false;
 
           if (n_elts == 0 && exhausted ())
             curr_state = conversion_error;
@@ -2275,14 +2277,19 @@
 {
   int retval = 0;
 
-  double dval = double_value ();
+  octave_value val = get_next_value ();
 
   if (! error_state)
     {
-      if (D_NINT (dval) == dval)
-        retval = NINT (dval);
-      else
-        curr_state = conversion_error;
+      double dval = val.double_value ();
+
+      if (! error_state)
+        {
+          if (D_NINT (dval) == dval)
+            retval = NINT (dval);
+          else
+            curr_state = conversion_error;
+        }
     }
 
   return retval;
@@ -2357,27 +2364,202 @@
   return retval;
 }
 
-#define DO_DOUBLE_CONV(TQUAL) \
-  do \
-    { \
-      if (val > std::numeric_limits<TQUAL long>::max () \
-          || val < std::numeric_limits<TQUAL long>::min ()) \
-        { \
-          std::string tfmt = fmt; \
- \
-          tfmt.replace (tfmt.rfind (elt->type), 1, ".f"); \
- \
-          if (elt->modifier == 'l') \
-            tfmt.replace (tfmt.rfind (elt->modifier), 1, ""); \
- \
-          retval += do_printf_conv (os, tfmt.c_str (), nsa, sa_1, sa_2, \
-                                    val, who); \
-        } \
-      else \
-        retval += do_printf_conv (os, fmt, nsa, sa_1, sa_2, \
-                                  static_cast<TQUAL long> (val), who); \
-    } \
-  while (0)
+static bool
+is_nan_or_inf (const octave_value& val)
+{
+  octave_value ov_isnan = val.isnan ();
+  octave_value ov_isinf = val.isinf ();
+
+  return (ov_isnan.is_true () || ov_isinf.is_true ());
+}
+
+static bool
+ok_for_signed_int_conv (const octave_value& val)
+{
+  uint64_t limit = std::numeric_limits<int64_t>::max ();
+
+  if (val.is_integer_type ())
+    {
+      if (val.is_uint64_type ())
+        {
+          octave_uint64 ival = val.uint64_scalar_value ();
+
+          if (ival.value () <= limit)
+            return true;
+        }
+      else
+        return true;
+    }
+  else
+    {
+      double dval = val.double_value ();
+
+      if (dval == xround (dval) && dval <= limit)
+        return true;
+    }
+
+  return false;
+}
+
+static bool
+ok_for_unsigned_int_conv (const octave_value& val)
+{
+  if (val.is_integer_type ())
+    {
+      // Easier than dispatching here...
+
+      octave_value ov_is_ge_zero
+        = do_binary_op (octave_value::op_ge, val, octave_value (0.0));
+
+      return ov_is_ge_zero.is_true ();
+    }
+  else
+    {
+      double dval = val.double_value ();
+
+      uint64_t limit = std::numeric_limits<uint64_t>::max ();
+
+      if (dval == xround (dval) && dval >= 0 && dval <= limit)
+        return true;
+    }
+
+  return false;
+}
+
+static std::string
+switch_to_g_format (const printf_format_elt *elt)
+{
+  std::string tfmt = elt->text;
+
+  tfmt.replace (tfmt.rfind (elt->type), 1, "g");
+
+  return tfmt;
+}
+
+int
+octave_base_stream::do_numeric_printf_conv (std::ostream& os,
+                                            const printf_format_elt *elt,
+                                            int nsa, int sa_1, int sa_2,
+                                            const octave_value& val,
+                                            const std::string& who)
+{
+  int retval = 0;
+
+  const char *fmt = elt->text;
+
+  if (is_nan_or_inf (val))
+    {
+      double dval = val.double_value ();
+
+      std::string tfmt = fmt;
+      std::string::size_type i1, i2;
+
+      tfmt.replace ((i1 = tfmt.rfind (elt->type)),
+                   1, 1, 's');
+
+      if ((i2 = tfmt.rfind ('.')) != std::string::npos
+          && i2 < i1)
+        {
+          tfmt.erase (i2, i1-i2);
+          if (elt->prec < 0)
+            nsa--;
+        }
+
+      const char *tval;
+      if (lo_ieee_isinf (dval))
+        {
+          if (elt->flags.find ('+') != std::string::npos)
+            tval = (dval < 0 ? "-Inf" : "+Inf");
+          else
+            tval = (dval < 0 ? "-Inf" : "Inf");
+        }
+      else
+        {
+          if (elt->flags.find ('+') != std::string::npos)
+            tval = (lo_ieee_is_NA (dval) ? "+NA" : "+NaN");
+          else
+            tval = (lo_ieee_is_NA (dval) ? "NA" : "NaN");
+        }
+
+      retval += do_printf_conv (os, tfmt.c_str (), nsa, sa_1, sa_2, tval, who);
+    }
+  else
+    {
+      static std::string llmod
+        = sizeof (long) == sizeof (int64_t) ? "l" : "ll";
+
+      char type = elt->type;
+
+      switch (type)
+        {
+        case 'd': case 'i': case 'c':
+          if (ok_for_signed_int_conv (val))
+            {
+              octave_int64 tval = val.int64_scalar_value ();
+
+              // Insert "long" modifier.
+              std::string tfmt = fmt;
+              tfmt.replace (tfmt.rfind (type), 1, llmod + type);
+
+              retval += do_printf_conv (os, tfmt.c_str (), nsa, sa_1, sa_2,
+                                        tval.value (), who);
+            }
+          else
+            {
+              std::string tfmt = switch_to_g_format (elt);
+
+              double dval = val.double_value ();
+
+              if (! error_state)
+                retval += do_printf_conv (os, tfmt.c_str (), nsa,
+                                          sa_1, sa_2, dval, who);
+            }
+          break;
+
+        case 'o': case 'x': case 'X': case 'u':
+          if (ok_for_unsigned_int_conv (val))
+            {
+              octave_uint64 tval = val.uint64_scalar_value ();
+
+              // Insert "long" modifier.
+              std::string tfmt = fmt;
+              tfmt.replace (tfmt.rfind (type), 1, llmod + type);
+
+              retval += do_printf_conv (os, tfmt.c_str (), nsa, sa_1, sa_2,
+                                        tval.value (), who);
+            }
+          else
+            {
+              std::string tfmt = switch_to_g_format (elt);
+
+              double dval = val.double_value ();
+
+              if (! error_state)
+                retval += do_printf_conv (os, tfmt.c_str (), nsa,
+                                          sa_1, sa_2, dval, who);
+            }
+          break;
+
+        case 'f': case 'e': case 'E':
+        case 'g': case 'G':
+          {
+            double dval = val.double_value ();
+
+            if (! error_state)
+              retval += do_printf_conv (os, fmt, nsa, sa_1, sa_2, dval, who);
+          }
+          break;
+
+        default:
+          error ("%s: invalid format specifier",
+                 who.c_str ());
+          return -1;
+          break;
+        }
+    }
+
+  return retval;
+}
 
 int
 octave_base_stream::do_printf (printf_format_list& fmt_list,
@@ -2432,8 +2614,6 @@
                     }
                 }
 
-              const char *fmt = elt->text;
-
               if (elt->type == '%')
                 {
                   os << "%";
@@ -2449,77 +2629,18 @@
                   std::string val = val_cache.string_value ();
 
                   if (val_cache)
-                    retval += do_printf_conv (os, fmt, nsa, sa_1,
+                    retval += do_printf_conv (os, elt->text, nsa, sa_1,
                                               sa_2, val.c_str (), who);
                   else
                     break;
                 }
               else
                 {
-                  double val = val_cache.double_value ();
+                  octave_value val = val_cache.get_next_value ();
 
                   if (val_cache)
-                    {
-                      if (lo_ieee_isnan (val) || xisinf (val))
-                        {
-                          std::string tfmt = fmt;
-                          std::string::size_type i1, i2;
-
-                          tfmt.replace ((i1 = tfmt.rfind (elt->type)),
-                                        1, 1, 's');
-
-                          if ((i2 = tfmt.rfind ('.')) != std::string::npos
-                              && i2 < i1)
-                            {
-                              tfmt.erase (i2, i1-i2);
-                              if (elt->prec < 0)
-                                nsa--;
-                            }
-
-                          const char *tval;
-                          if (xisinf (val))
-                            if (elt->flags.find ('+') != std::string::npos)
-                              tval = (val < 0 ? "-Inf" : "+Inf");
-                            else
-                              tval = (val < 0 ? "-Inf" : "Inf");
-                          else
-                            if (elt->flags.find ('+') != std::string::npos)
-                              tval = (lo_ieee_is_NA (val) ? "+NA" : "+NaN");
-                            else
-                              tval = (lo_ieee_is_NA (val) ? "NA" : "NaN");
-
-                          retval += do_printf_conv (os, tfmt.c_str (),
-                                                    nsa, sa_1, sa_2,
-                                                    tval, who);
-                        }
-                      else
-                        {
-                          char type = elt->type;
-
-                          switch (type)
-                            {
-                            case 'd': case 'i': case 'c':
-                              DO_DOUBLE_CONV (OCTAVE_EMPTY_CPP_ARG);
-                              break;
-
-                            case 'o': case 'x': case 'X': case 'u':
-                              DO_DOUBLE_CONV (unsigned);
-                              break;
-
-                            case 'f': case 'e': case 'E':
-                            case 'g': case 'G':
-                              retval += do_printf_conv (os, fmt, nsa,
-                                                        sa_1, sa_2, val, who);
-                              break;
-
-                            default:
-                              error ("%s: invalid format specifier",
-                                     who.c_str ());
-                              return -1;
-                              break;
-                            }
-                        }
-                    }
+                    retval += do_numeric_printf_conv (os, elt, nsa, sa_1,
+                                                      sa_2, val, who);
                   else
                     break;
                 }
@@ -3191,8 +3312,7 @@
       if (! error_state)
         {
 
-          octave_idx_type elts_to_read
-            = std::numeric_limits<octave_idx_type>::max ();
+          octave_idx_type elts_to_read;
 
           if (one_elt_size_spec)
             {
@@ -3221,7 +3341,9 @@
                 nr = nc = 0;
             }
 
-          // FIXME: ensure that this does not overflow.
+          // FIXME: Ensure that this does not overflow.
+          //        Maybe try comparing nr * nc computed in double with
+          //        std::numeric_limits<octave_idx_type>::max ();
 
           elts_to_read = nr * nc;
 
--- a/libinterp/corefcn/oct-stream.h	Fri Aug 01 09:06:21 2014 -0400
+++ b/libinterp/corefcn/oct-stream.h	Fri Aug 01 12:10:05 2014 -0400
@@ -479,6 +479,11 @@
 
   int flush (void);
 
+  int do_numeric_printf_conv (std::ostream& os, const printf_format_elt *elt,
+                              int nsa, int sa_1, int sa_2,
+                              const octave_value& val,
+                              const std::string& who);
+
   int do_printf (printf_format_list& fmt_list, const octave_value_list& args,
                  const std::string& who /* = "printf" */);
 
--- a/libinterp/corefcn/oct-strstrm.h	Fri Aug 01 09:06:21 2014 -0400
+++ b/libinterp/corefcn/oct-strstrm.h	Fri Aug 01 12:10:05 2014 -0400
@@ -96,7 +96,7 @@
           oct_mach_info::float_format ff
             = oct_mach_info::native_float_format ());
 
-  // Return non-zero if EOF has been reached on this stream.
+  // Return nonzero if EOF has been reached on this stream.
 
   bool eof (void) const { return is.eof (); }
 
@@ -142,7 +142,7 @@
           oct_mach_info::float_format ff
             = oct_mach_info::native_float_format ());
 
-  // Return non-zero if EOF has been reached on this stream.
+  // Return nonzero if EOF has been reached on this stream.
 
   bool eof (void) const { return os.eof (); }
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libinterp/corefcn/octave-default-image.h	Fri Aug 01 12:10:05 2014 -0400
@@ -0,0 +1,281 @@
+/*
+
+Copyright (C) 2014 Pantxo Diribarne
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+static char default_im_data[] = {
+  31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,
+  31,31,31,31,31,31,20,20,20,20,20,20,21,21,21,21,
+  31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,
+  31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,
+  31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,
+  31,31,31,20,20,20,20,20,20,20,20,20,20,20,21,21,
+  21,21,21,21,31,31,31,31,31,31,31,31,31,31,31,31,
+  31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,
+  31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,
+  31,20,20,20,20,20,20,20,20,20,20,20,20,20,20,21,
+  21,21,21,21,21,21,21,31,31,31,31,31,31,31,31,31,
+  31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,
+  31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,20,
+  20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,
+  21,21,21,21,21,21,21,21,21,31,31,31,31,31,31,31,
+  31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,
+  31,31,31,31,31,31,31,31,31,31,31,31,31,31,20,20,
+  20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,
+  20,21,21,21,21,21,21,21,21,21,21,31,31,31,31,31,
+  31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,
+  31,31,31,31,31,31,31,31,31,31,31,31,20,20,20,20,
+  20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,
+  20,20,21,21,21,21,21,21,21,21,21,21,31,31,31,31,
+  31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,
+  31,31,31,31,31,31,31,31,31,31,31,20,20,20,20,20,
+  20,20,20,20,20,20,20,20,20,20,20,20,31,31,31,31,
+  31,31,31,31,31,31,21,21,21,21,21,21,21,21,31,31,
+  31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,
+  31,31,31,31,31,31,31,31,31,31,31,20,20,20,20,20,
+  20,20,20,20,20,20,20,20,20,31,31,31,31,31,31,31,
+  31,31,31,31,31,31,31,31,31,21,21,21,21,21,21,31,
+  31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,
+  31,31,31,31,31,31,31,31,31,31,20,20,20,20,20,20,
+  20,20,20,20,20,20,20,31,31,31,31,31,31,31,31,31,
+  31,31,31,31,31,31,31,31,31,31,31,21,21,21,21,21,
+  31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,
+  31,31,31,31,31,31,31,31,31,20,20,20,20,20,20,20,
+  20,20,20,20,20,20,31,31,31,31,31,31,31,31,31,31,
+  31,31,31,31,31,31,31,31,31,31,31,31,31,21,21,21,
+  21,21,31,31,31,31,31,31,31,31,31,31,31,31,31,31,
+  31,31,31,31,31,31,31,31,20,20,20,20,20,20,20,20,
+  20,20,20,20,20,31,31,31,31,31,31,31,31,31,31,31,
+  31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,63,
+  49,49,49,49,49,49,49,49,31,31,31,31,31,31,31,31,
+  31,31,31,31,31,31,31,31,20,20,20,20,20,20,20,20,
+  20,20,20,20,31,31,31,31,31,31,31,31,31,31,31,31,
+  31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,49,
+  48,48,48,48,48,48,48,49,31,31,31,31,31,31,31,31,
+  31,31,31,31,31,31,31,20,20,20,20,20,20,20,20,20,
+  20,20,20,31,31,31,31,31,31,31,31,31,31,31,31,31,
+  31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,49,
+  48,47,47,47,47,47,47,48,31,31,31,31,31,31,31,31,
+  31,31,31,31,31,31,31,19,20,20,20,20,20,20,20,20,
+  20,20,31,31,31,31,31,31,31,31,31,31,31,31,31,31,
+  31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,49,
+  48,47,47,47,47,47,47,48,31,31,31,31,31,31,31,31,
+  31,31,31,31,31,31,31,20,19,20,20,20,20,20,20,20,
+  20,20,31,31,31,31,31,31,31,31,31,31,31,31,31,31,
+  31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,49,
+  48,47,47,47,47,47,47,48,31,31,31,31,31,31,31,31,
+  31,31,31,31,31,31,19,19,19,19,20,20,20,20,20,20,
+  20,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,
+  31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,49,
+  48,47,47,47,47,47,47,48,31,31,31,31,31,31,31,31,
+  31,31,31,31,31,31,19,19,19,19,19,20,20,20,20,20,
+  20,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,
+  31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,49,
+  48,47,47,47,47,47,47,48,31,31,31,31,31,31,31,31,
+  31,31,31,31,31,31,19,19,19,19,19,19,19,20,20,20,
+  19,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,
+  31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,49,
+  48,47,47,47,47,47,48,48,63,31,31,31,31,31,31,31,
+  31,31,31,31,31,31,19,19,19,19,19,19,20,19,20,20,
+  31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,
+  31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,49,
+  49,48,48,48,48,48,48,48,21,31,31,31,31,31,31,31,
+  31,31,31,31,31,19,19,19,19,19,19,19,19,19,19,20,
+  31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,
+  31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,
+  31,31,31,31,31,31,31,21,21,21,31,31,31,31,31,31,
+  31,31,31,31,31,20,20,20,20,20,20,20,20,20,20,20,
+  31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,
+  31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,
+  31,31,31,31,31,31,31,31,21,21,31,31,31,31,31,31,
+  31,31,49,49,49,49,49,49,49,49,49,49,49,49,49,49,
+  49,49,49,31,31,31,31,31,31,31,31,31,31,31,31,31,
+  31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,
+  31,31,31,31,31,31,31,31,31,21,21,31,31,31,31,31,
+  31,49,48,48,48,48,48,48,48,48,48,48,48,48,48,48,
+  48,48,48,49,31,31,31,31,31,31,31,31,31,31,31,31,
+  31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,
+  31,31,31,31,31,31,31,31,31,21,21,21,31,31,31,31,
+  49,48,47,47,47,47,47,47,47,47,47,47,47,47,47,47,
+  47,47,47,48,49,31,31,31,31,31,31,31,31,31,31,31,
+  31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,
+  31,31,31,31,31,31,31,31,31,31,21,21,31,31,31,31,
+  49,48,47,47,47,47,47,47,47,47,47,47,47,47,47,47,
+  47,47,47,48,49,31,31,31,31,31,31,31,31,31,31,31,
+  31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,
+  31,31,31,31,31,31,31,31,31,31,21,21,31,31,31,31,
+  49,48,47,47,47,47,47,47,47,47,47,47,47,47,47,47,
+  47,47,47,48,49,31,31,31,31,31,31,31,31,31,31,31,
+  31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,
+  31,31,31,31,31,31,31,31,31,31,31,21,21,31,31,31,
+  49,48,47,47,47,47,47,47,47,47,47,47,47,47,47,47,
+  47,47,47,48,49,31,31,31,31,31,31,31,31,31,31,31,
+  31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,
+  31,31,31,31,31,31,31,31,31,31,31,21,21,31,31,31,
+  49,48,47,47,47,47,47,47,47,47,47,47,47,47,47,47,
+  47,47,47,48,49,31,31,31,31,31,31,31,31,31,31,31,
+  31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,
+  31,31,31,31,31,31,31,31,31,31,31,21,21,21,31,31,
+  49,48,47,47,47,47,47,47,47,47,47,47,47,47,47,47,
+  47,47,47,48,49,31,31,31,31,31,31,31,31,31,31,31,
+  31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,
+  31,31,31,31,31,31,31,31,31,31,31,31,21,21,31,31,
+  49,48,47,47,47,47,47,47,47,47,47,47,47,47,47,47,
+  47,47,47,48,49,31,31,31,31,31,31,31,31,31,31,31,
+  31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,
+  31,31,31,31,31,31,31,31,31,31,31,31,21,21,31,31,
+  49,48,47,47,47,47,47,47,47,47,47,47,47,47,47,47,
+  47,47,47,48,49,31,31,31,31,31,31,31,31,31,31,31,
+  31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,
+  31,31,31,31,31,31,31,31,31,31,31,31,21,21,21,31,
+  49,48,47,47,47,47,47,47,47,47,47,47,47,47,47,47,
+  47,47,47,48,49,31,31,31,31,31,31,31,31,31,31,31,
+  31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,
+  31,31,31,31,31,31,31,31,31,31,31,31,31,21,21,31,
+  49,48,47,47,47,47,47,47,47,47,47,47,47,47,47,47,
+  47,47,47,48,49,31,31,31,31,31,31,31,31,31,31,31,
+  31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,
+  31,31,31,31,31,31,31,31,31,31,31,31,31,21,21,31,
+  49,48,47,47,47,47,47,47,47,47,47,47,47,47,47,47,
+  47,47,47,48,49,31,31,31,31,31,31,31,31,31,31,31,
+  31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,
+  31,31,31,31,31,31,31,31,31,31,31,31,31,20,21,31,
+  49,48,47,47,47,47,47,47,47,47,47,47,47,47,47,47,
+  47,47,47,48,49,31,31,31,31,31,31,31,31,31,31,31,
+  31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,
+  31,31,31,31,31,31,31,31,31,31,31,31,31,21,21,21,
+  49,48,47,47,47,47,47,47,47,47,47,47,47,47,47,47,
+  47,47,47,48,49,31,31,31,31,31,31,31,31,31,31,31,
+  31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,
+  31,31,31,31,31,31,31,31,31,31,31,31,31,20,21,21,
+  49,48,47,47,47,47,47,47,47,47,47,47,47,47,47,47,
+  47,47,47,48,49,31,31,31,31,31,31,31,31,31,31,31,
+  31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,
+  31,31,31,31,31,31,31,31,31,31,31,31,31,20,20,21,
+  49,48,47,47,47,47,47,47,47,47,47,47,47,47,47,47,
+  47,47,47,48,49,31,31,31,31,31,31,31,31,31,31,31,
+  31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,
+  31,31,31,31,31,31,31,31,31,31,31,31,31,20,20,20,
+  49,48,47,47,47,47,47,47,47,47,47,47,47,47,47,47,
+  47,47,47,48,49,31,31,31,31,31,31,31,31,31,31,31,
+  31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,
+  31,31,31,31,31,31,31,31,31,31,31,31,31,20,20,20,
+  31,49,48,47,47,47,47,47,47,47,47,47,47,47,47,47,
+  47,47,48,49,31,31,31,31,31,31,31,31,31,31,31,31,
+  31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,
+  31,31,31,31,31,31,31,31,31,31,31,31,31,20,20,20,
+  31,49,49,48,48,48,48,48,48,48,48,48,48,48,48,48,
+  48,48,49,63,31,31,31,31,31,31,31,31,31,31,31,31,
+  31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,
+  31,31,31,31,31,31,31,31,31,31,31,31,31,20,20,20,
+  31,31,31,49,49,49,49,49,49,47,63,63,63,63,63,63,
+  63,63,20,19,19,31,31,31,31,31,31,31,31,31,31,31,
+  31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,
+  31,31,31,31,31,31,31,31,31,31,31,31,20,20,20,20,
+  31,31,31,31,31,31,31,31,31,31,19,19,19,19,19,19,
+  19,19,19,19,19,31,31,31,31,31,31,31,31,31,31,31,
+  31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,
+  31,31,31,31,31,31,31,31,31,31,31,31,20,20,20,20,
+  31,31,31,31,31,31,31,31,31,31,31,19,19,19,19,19,
+  19,19,19,19,19,19,31,31,31,31,31,31,31,31,31,31,
+  31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,
+  31,31,31,31,31,31,31,31,31,31,31,31,20,20,20,20,
+  31,31,31,31,31,31,31,31,31,31,31,19,19,19,19,19,
+  19,19,19,19,19,19,19,31,31,31,31,31,31,31,31,31,
+  31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,
+  31,31,31,31,31,31,31,31,31,31,31,31,20,20,20,20,
+  31,31,31,31,31,31,31,31,31,31,31,31,19,19,19,19,
+  19,19,19,19,19,19,19,19,31,31,31,31,31,31,31,31,
+  31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,
+  31,31,31,31,31,31,31,31,31,31,31,20,20,20,20,20,
+  31,31,31,31,31,31,31,31,31,31,31,31,31,19,19,19,
+  19,19,19,19,19,19,19,19,19,31,31,31,31,31,31,31,
+  31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,
+  31,31,31,31,31,49,49,49,49,49,47,63,63,63,21,31,
+  31,31,31,31,31,31,31,31,31,31,31,31,31,19,19,19,
+  19,19,19,19,19,19,19,19,19,19,31,31,31,31,31,31,
+  31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,
+  31,31,31,49,49,48,48,48,48,48,48,48,48,48,48,31,
+  31,31,31,31,31,31,31,31,31,31,31,31,31,31,19,19,
+  19,19,19,19,19,19,19,19,19,19,19,31,31,31,31,31,
+  31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,
+  31,31,31,49,48,47,47,47,47,47,47,47,47,47,48,49,
+  31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,19,
+  19,19,19,19,19,19,19,19,19,19,19,19,31,31,31,31,
+  31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,
+  31,31,31,49,47,47,47,47,47,47,47,47,47,47,48,48,
+  31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,
+  19,19,19,19,19,19,19,19,19,19,19,19,19,31,31,31,
+  31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,
+  31,31,31,49,47,47,47,47,47,47,47,47,47,47,48,49,
+  31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,
+  31,19,19,19,19,19,19,19,19,19,19,19,19,19,19,31,
+  31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,
+  31,31,31,49,47,47,47,47,47,47,47,47,47,47,48,49,
+  31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,
+  31,31,19,19,19,19,19,19,19,19,19,19,19,19,19,19,
+  31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,
+  31,31,31,49,47,47,47,47,47,47,47,47,47,47,48,49,
+  31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,
+  31,31,31,19,19,19,19,19,19,19,19,19,19,19,19,19,
+  19,19,19,31,31,31,31,31,31,31,31,31,31,31,31,31,
+  31,31,31,49,47,47,47,47,47,47,47,47,47,47,48,49,
+  31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,
+  31,31,31,31,19,19,19,19,19,19,19,19,19,19,19,19,
+  19,19,19,19,19,31,31,31,31,31,31,31,31,31,31,31,
+  31,19,20,49,47,47,47,47,47,47,47,47,47,47,48,49,
+  31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,
+  31,31,31,31,31,19,19,19,19,19,19,19,19,19,19,19,
+  19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,
+  19,20,20,49,47,47,47,47,47,47,47,47,47,47,48,49,
+  31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,
+  31,31,31,31,31,31,18,19,19,19,19,19,19,19,19,19,
+  19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,
+  19,19,20,49,47,47,47,47,47,47,47,47,47,47,48,48,
+  31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,
+  31,31,31,31,31,31,31,19,19,19,19,19,19,19,19,19,
+  19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,
+  19,20,20,49,48,47,47,47,47,47,47,47,47,47,48,49,
+  31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,
+  31,31,31,31,31,31,31,31,31,19,19,19,19,19,19,19,
+  19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,
+  19,19,20,63,48,48,48,48,48,48,48,48,48,48,49,31,
+  31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,
+  31,31,31,31,31,31,31,31,31,31,19,19,19,19,19,19,
+  19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,
+  19,19,19,20,21,63,63,63,48,49,49,49,49,49,31,31,
+  31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,
+  31,31,31,31,31,31,31,31,31,31,31,31,19,19,19,19,
+  19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,
+  19,19,19,19,19,20,31,31,31,31,31,31,31,31,31,31,
+  31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,
+  31,31,31,31,31,31,31,31,31,31,31,31,31,31,19,19,
+  19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,
+  19,19,19,19,19,31,31,31,31,31,31,31,31,31,31,31,
+  31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,
+  31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,
+  31,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,
+  19,19,31,31,31,31,31,31,31,31,31,31,31,31,31,31,
+  31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,
+  31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,
+  31,31,31,31,31,19,19,19,19,19,19,19,19,19,19,31,
+  31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31
+};
+
--- a/libinterp/corefcn/octave-link.cc	Fri Aug 01 09:06:21 2014 -0400
+++ b/libinterp/corefcn/octave-link.cc	Fri Aug 01 12:10:05 2014 -0400
@@ -225,7 +225,7 @@
       std::string multi_on = args(4).string_value (); // on, off, create
       std::string pathname = args(5).string_value ();
 
-      octave_idx_type nel = flist.numel ();
+      octave_idx_type nel;
       octave_link::filter_list filter_lst;
 
       for (octave_idx_type i = 0; i < flist.rows (); i++)
@@ -432,7 +432,7 @@
 
 DEFUN (__octave_link_show_doc__, args, ,
        "-*- texinfo -*-\n\
-@deftypefn {Built-in Function} {} __octave_link_show_doc__ ( @var{filename} )\n\
+@deftypefn {Built-in Function} {} __octave_link_show_doc__ (@var{filename})\n\
 Undocumented internal function.\n\
 @end deftypefn")
 {
--- a/libinterp/corefcn/pager.cc	Fri Aug 01 09:06:21 2014 -0400
+++ b/libinterp/corefcn/pager.cc	Fri Aug 01 12:10:05 2014 -0400
@@ -52,7 +52,7 @@
 static bool write_to_diary_file = false;
 
 // The name of the current diary file.
-static std::string diary_file;
+static std::string diary_file ("diary");
 
 // The diary file.
 static std::ofstream external_diary_file;
@@ -589,6 +589,24 @@
   return retval;
 }
 
+DEFUN (__diaryfile__, , ,
+       "-*- texinfo -*-\n\
+@deftypefn {Built-in Function} {@var{fname} =} __diaryfile__ ()\n\
+Undocumented internal function\n\
+@end deftypefn")
+{
+  return ovl (diary_file);
+}
+
+DEFUN (__diarystate__, , ,
+       "-*- texinfo -*-\n\
+@deftypefn {Built-in Function} {@var{state} =} __diarystate__ ()\n\
+Undocumented internal function\n\
+@end deftypefn")
+{
+  return ovl (write_to_diary_file);
+}
+
 DEFUN (more, args, ,
        "-*- texinfo -*-\n\
 @deftypefn  {Command} {} more\n\
--- a/libinterp/corefcn/pinv.cc	Fri Aug 01 09:06:21 2014 -0400
+++ b/libinterp/corefcn/pinv.cc	Fri Aug 01 12:10:05 2014 -0400
@@ -76,22 +76,45 @@
 
   if (arg.is_diag_matrix ())
     {
-      if (nargin == 2)
-        warning ("pinv: tol is ignored for diagonal matrices");
-
-      if (arg.is_complex_type ())
+      if (isfloat)
         {
-          if (isfloat)
-            retval = arg.float_complex_diag_matrix_value ().pseudo_inverse ();
+          float tol = 0.0;
+          if (nargin == 2)
+            tol = args(1).float_value ();
+
+          if (error_state)
+            return retval;
+
+          if (tol < 0.0)
+            {
+              error ("pinv: TOL must be greater than zero");
+              return retval;
+            }
+
+          if (arg.is_real_type ())
+            retval = arg.float_diag_matrix_value ().pseudo_inverse (tol);
           else
-            retval = arg.complex_diag_matrix_value ().pseudo_inverse ();
+            retval = arg.float_complex_diag_matrix_value ().pseudo_inverse (tol);
         }
       else
         {
-          if (isfloat)
-            retval = arg.float_diag_matrix_value ().pseudo_inverse ();
+          double tol = 0.0;
+          if (nargin == 2)
+            tol = args(1).double_value ();
+
+          if (error_state)
+            return retval;
+
+          if (tol < 0.0)
+            {
+              error ("pinv: TOL must be greater than zero");
+              return retval;
+            }
+
+          if (arg.is_real_type ())
+            retval = arg.diag_matrix_value ().pseudo_inverse (tol);
           else
-            retval = arg.diag_matrix_value ().pseudo_inverse ();
+            retval = arg.complex_diag_matrix_value ().pseudo_inverse (tol);
         }
     }
   else if (arg.is_perm_matrix ())
@@ -189,4 +212,20 @@
 %!assert (y*x*y, y, -hitol)
 %!assert ((x*y)', x*y, hitol)
 %!assert ((y*x)', y*x, hitol)
+
+## Clear shared variables
+%!shared
+
+## Test pinv for Diagonal matrices
+%!test
+%! x = diag ([3 2 1 0 -0.5]);
+%! y = pinv (x);
+%! assert (typeinfo (y)(1:8), "diagonal");
+%! assert (isa (y, "double"));
+%! assert (diag (y), [1/3, 1/2, 1, 0  1/-0.5]');
+%! y = pinv (x, 1);
+%! assert (diag (y), [1/3 1/2 1 0 0]');
+%! y = pinv (x, 2);
+%! assert (diag (y), [1/3 1/2 0 0 0]');
+
 */
--- a/libinterp/corefcn/pr-output.cc	Fri Aug 01 09:06:21 2014 -0400
+++ b/libinterp/corefcn/pr-output.cc	Fri Aug 01 12:10:05 2014 -0400
@@ -581,13 +581,11 @@
         {
           ld = digits;
           rd = prec > digits ? prec - digits : prec;
-          digits++;
         }
       else
         {
           ld = 1;
           rd = prec > digits ? prec - digits : prec;
-          digits = -digits + 1;
         }
 
       fw = 1 + ld + 1 + rd;
@@ -2487,11 +2485,10 @@
 
       if (pr_as_read_syntax)
         {
-          Array<octave_idx_type> pvec = m.pvec ();
-          bool colp = m.is_col_perm ();
+          Array<octave_idx_type> pvec = m.col_perm_vec ();
 
           os << "eye (";
-          if (colp) os << ":, ";
+          os << ":, ";
 
           octave_idx_type col = 0;
           while (col < nc)
@@ -2522,7 +2519,6 @@
               else
                 os << " ...\n";
             }
-          if (! colp) os << ", :";
           os << ")";
         }
       else
@@ -3387,8 +3383,7 @@
 }
 
 void
-octave_print_internal (std::ostream&, const octave_value&,
-                       bool pr_as_read_syntax)
+octave_print_internal (std::ostream&, const octave_value&, bool)
 {
   panic_impossible ();
 }
@@ -3439,7 +3434,7 @@
               rat_format = true;
 
               std::ostringstream buf;
-              args(0).print (buf);
+              arg.print (buf);
               std::string s = buf.str ();
 
               std::list<std::string> lst;
@@ -3501,11 +3496,12 @@
 
   if (nargin == 1 && nargout < 2)
     {
+      octave_value arg = args(0);
+
       if (nargout == 0)
-        args(0).print (octave_stdout);
+        arg.print (octave_stdout);
       else
         {
-          octave_value arg = args(0);
           std::ostringstream buf;
           arg.print (buf);
           retval = octave_value (buf.str (), arg.is_dq_string () ? '"' : '\'');
@@ -3542,7 +3538,7 @@
 
   if (nargin == 2)
     {
-      int fid = octave_stream_list::get_file_number (args (0));
+      int fid = octave_stream_list::get_file_number (args(0));
 
       octave_stream os = octave_stream_list::lookup (fid, "fdisp");
 
@@ -3550,8 +3546,10 @@
         {
           std::ostream *osp = os.output_stream ();
 
+          octave_value arg = args(1);
+
           if (osp)
-            args(1).print (*osp);
+            arg.print (*osp);
           else
             error ("fdisp: stream FID not open for writing");
         }
@@ -3612,20 +3610,25 @@
   Voutput_max_field_width = fw;
 }
 
+static std::string format_string ("short");
+
 static void
 set_format_style (int argc, const string_vector& argv)
 {
   int idx = 1;
+  std::string format;
 
   if (--argc > 0)
     {
       std::string arg = argv[idx++];
+      format = arg;
 
       if (arg == "short")
         {
           if (--argc > 0)
             {
               arg = argv[idx++];
+              format.append (arg);
 
               if (arg == "e")
                 {
@@ -3666,11 +3669,44 @@
 
           set_output_prec_and_fw (5, 10);
         }
+      else if (arg == "shorte")
+        {
+          init_format_state ();
+          print_e = true;
+          set_output_prec_and_fw (5, 10);
+        }
+      else if (arg == "shortE")
+        {
+          init_format_state ();
+          print_e = true;
+          print_big_e = true;
+          set_output_prec_and_fw (5, 10);
+        }
+      else if (arg == "shortg")
+        {
+          init_format_state ();
+          print_g = true;
+          set_output_prec_and_fw (5, 10);
+        }
+      else if (arg == "shortG")
+        {
+          init_format_state ();
+          print_g = true;
+          print_big_e = true;
+          set_output_prec_and_fw (5, 10);
+        }
+      else if (arg == "shortEng")
+        {
+          init_format_state ();
+          print_eng = true;
+          set_output_prec_and_fw (5, 10);
+        }
       else if (arg == "long")
         {
           if (--argc > 0)
             {
               arg = argv[idx++];
+              format.append (arg);
 
               if (arg == "e")
                 {
@@ -3711,6 +3747,38 @@
 
           set_output_prec_and_fw (15, 20);
         }
+      else if (arg == "longe")
+        {
+          init_format_state ();
+          print_e = true;
+          set_output_prec_and_fw (15, 20);
+        }
+      else if (arg == "longE")
+        {
+          init_format_state ();
+          print_e = true;
+          print_big_e = true;
+          set_output_prec_and_fw (15, 20);
+        }
+      else if (arg == "longg")
+        {
+          init_format_state ();
+          print_g = true;
+          set_output_prec_and_fw (15, 20);
+        }
+      else if (arg == "longG")
+        {
+          init_format_state ();
+          print_g = true;
+          print_big_e = true;
+          set_output_prec_and_fw (15, 20);
+        }
+      else if (arg == "longEng")
+        {
+          init_format_state ();
+          print_eng = true;
+          set_output_prec_and_fw (15, 20);
+        }
       else if (arg == "hex")
         {
           init_format_state ();
@@ -3736,6 +3804,7 @@
           if (--argc > 0)
             {
               arg = argv[idx++];
+              format.append (arg);
 
               if (arg.length () == 3)
                 plus_format_chars = arg;
@@ -3774,21 +3843,30 @@
       else if (arg == "compact")
         {
           Vcompact_format = true;
+          return;
         }
       else if (arg == "loose")
         {
           Vcompact_format = false;
+          return;
         }
       else
-        error ("format: unrecognized format state '%s'", arg.c_str ());
+        {
+          error ("format: unrecognized format state '%s'", arg.c_str ());
+          return;
+        }  
     }
   else
     {
       init_format_state ();
       set_output_prec_and_fw (5, 10);
+      format = std::string ("short");
     }
+
+  format_string = format;
 }
 
+
 DEFUN (format, args, ,
        "-*- texinfo -*-\n\
 @deftypefn  {Command} {} format\n\
@@ -3973,6 +4051,25 @@
   return retval;
 }
 
+DEFUN (__compactformat__, args, nargout,
+       "-*- texinfo -*-\n\
+@deftypefn  {Built-in Function} {@var{val} =} __compactformat__ ()\n\
+@deftypefnx {Built-in Function} {} __compactformat__ (@var{TRUE|FALSE})\n\
+Undocumented internal function\n\
+@end deftypefn")
+{
+  return SET_INTERNAL_VARIABLE (compact_format);
+}
+
+DEFUN (__formatstring__, , ,
+       "-*- texinfo -*-\n\
+@deftypefn {Built-in Function} {@var{val} =} __formatstring__ ()\n\
+Undocumented internal function\n\
+@end deftypefn")
+{
+  return ovl (format_string);
+}
+
 DEFUN (fixed_point_format, args, nargout,
        "-*- texinfo -*-\n\
 @deftypefn  {Built-in Function} {@var{val} =} fixed_point_format ()\n\
@@ -4002,7 +4099,7 @@
 \n\
 @noindent\n\
 Notice that the first value appears to be 0 when it is actually 1.  Because\n\
-of the possibilty for confusion you should be careful about enabling\n\
+of the possibility for confusion you should be careful about enabling\n\
 @code{fixed_point_format}.\n\
 \n\
 When called from inside a function with the @qcode{\"local\"} option, the\n\
--- a/libinterp/corefcn/profiler.cc	Fri Aug 01 09:06:21 2014 -0400
+++ b/libinterp/corefcn/profiler.cc	Fri Aug 01 12:10:05 2014 -0400
@@ -106,7 +106,7 @@
 }
 
 profile_data_accumulator::tree_node*
-profile_data_accumulator::tree_node::exit (octave_idx_type fcn)
+profile_data_accumulator::tree_node::exit (octave_idx_type /* fcn */)
 {
   // FIXME: These assert statements don't make sense if profile() is called
   //        from within a function hierarchy to begin with.  See bug #39587.
--- a/libinterp/corefcn/pt-jit.cc	Fri Aug 01 09:06:21 2014 -0400
+++ b/libinterp/corefcn/pt-jit.cc	Fri Aug 01 12:10:05 2014 -0400
@@ -46,13 +46,26 @@
 
 static int Vjit_startcnt = 1000;
 
+static int Vjit_failure_count = 0;
+
 #include <llvm/Analysis/CallGraph.h>
 #include <llvm/Analysis/Passes.h>
+
+#ifdef HAVE_LLVM_IR_VERIFIER_H
+#include <llvm/IR/Verifier.h>
+#else
 #include <llvm/Analysis/Verifier.h>
+#endif
+
 #include <llvm/Bitcode/ReaderWriter.h>
 #include <llvm/ExecutionEngine/ExecutionEngine.h>
 #include <llvm/ExecutionEngine/JIT.h>
+
+#ifdef LEGACY_PASSMANAGER
+#include <llvm/IR/LegacyPassManager.h>
+#else
 #include <llvm/PassManager.h>
+#endif
 
 #ifdef HAVE_LLVM_IR_FUNCTION_H
 #include <llvm/IR/LLVMContext.h>
@@ -164,7 +177,7 @@
       if (expr)
         {
           jit_variable *retvar = get_variable ("#return");
-          jit_value *retval;
+          jit_value *retval = 0;
           try
             {
               retval = visit (expr);
@@ -230,13 +243,13 @@
 void
 jit_convert::visit_anon_fcn_handle (tree_anon_fcn_handle&)
 {
-  throw jit_fail_exception ();
+  throw jit_fail_exception ("No visit_anon_fcn_handle implementation");
 }
 
 void
 jit_convert::visit_argument_list (tree_argument_list&)
 {
-  throw jit_fail_exception ();
+  throw jit_fail_exception ("No visit_argument_list implementation");
 }
 
 void
@@ -337,25 +350,25 @@
 void
 jit_convert::visit_global_command (tree_global_command&)
 {
-  throw jit_fail_exception ();
+  throw jit_fail_exception ("No visit_global_command implemenation");
 }
 
 void
 jit_convert::visit_persistent_command (tree_persistent_command&)
 {
-  throw jit_fail_exception ();
+  throw jit_fail_exception ("No visit_persistent_command implementation");
 }
 
 void
 jit_convert::visit_decl_elt (tree_decl_elt&)
 {
-  throw jit_fail_exception ();
+  throw jit_fail_exception ("No visit_decl_elt implementation");
 }
 
 void
 jit_convert::visit_decl_init_list (tree_decl_init_list&)
 {
-  throw jit_fail_exception ();
+  throw jit_fail_exception ("No visit_decl_init_list implementation");
 }
 
 void
@@ -464,37 +477,37 @@
 void
 jit_convert::visit_complex_for_command (tree_complex_for_command&)
 {
-  throw jit_fail_exception ();
+  throw jit_fail_exception ("No visit_complex_for_command implementation");
 }
 
 void
 jit_convert::visit_octave_user_script (octave_user_script&)
 {
-  throw jit_fail_exception ();
+  throw jit_fail_exception ("No visit_octave_user_script implementation");
 }
 
 void
 jit_convert::visit_octave_user_function (octave_user_function&)
 {
-  throw jit_fail_exception ();
+  throw jit_fail_exception ("No visit_octave_user_function implementation");
 }
 
 void
 jit_convert::visit_octave_user_function_header (octave_user_function&)
 {
-  throw jit_fail_exception ();
+  throw jit_fail_exception ("No visit_octave_user_function_header implementation");
 }
 
 void
 jit_convert::visit_octave_user_function_trailer (octave_user_function&)
 {
-  throw jit_fail_exception ();
+  throw jit_fail_exception ("No visit_octave_user_function_trailer implementation");
 }
 
 void
 jit_convert::visit_function_def (tree_function_def&)
 {
-  throw jit_fail_exception ();
+  throw jit_fail_exception ("No visit_function_def implementation");
 }
 
 void
@@ -518,7 +531,7 @@
 void
 jit_convert::visit_if_clause (tree_if_clause&)
 {
-  throw jit_fail_exception ();
+  throw jit_fail_exception ("No visit_if_clause implementation");
 }
 
 void
@@ -539,7 +552,6 @@
   // the condition check for the ith clause. For the else, it is simple the
   // else body. If there is no else body, then it is padded with the tail
   std::vector<jit_block *> entry_blocks (lst.size () + 1 - last_else);
-  std::vector<jit_block *> branch_blocks (lst.size (), 0); // final blocks
   entry_blocks[0] = block;
 
   // we need to construct blocks first, because they have jumps to eachother
@@ -630,25 +642,25 @@
 void
 jit_convert::visit_matrix (tree_matrix&)
 {
-  throw jit_fail_exception ();
+  throw jit_fail_exception ("No visit_matrix implementation");
 }
 
 void
 jit_convert::visit_cell (tree_cell&)
 {
-  throw jit_fail_exception ();
+  throw jit_fail_exception ("No visit_cell implementation");
 }
 
 void
 jit_convert::visit_multi_assignment (tree_multi_assignment&)
 {
-  throw jit_fail_exception ();
+  throw jit_fail_exception ("No visit_multi_assignment implementation");
 }
 
 void
 jit_convert::visit_no_op_command (tree_no_op_command&)
 {
-  throw jit_fail_exception ();
+  throw jit_fail_exception ("No visit_no_op_command implementation");
 }
 
 void
@@ -679,13 +691,19 @@
 void
 jit_convert::visit_fcn_handle (tree_fcn_handle&)
 {
+  throw jit_fail_exception ("No visit_fcn_handle implementation");
+}
+
+void
+jit_convert::visit_funcall (tree_funcall&)
+{
   throw jit_fail_exception ();
 }
 
 void
 jit_convert::visit_parameter_list (tree_parameter_list&)
 {
-  throw jit_fail_exception ();
+  throw jit_fail_exception ("No visit_parameter_list implementation");
 }
 
 void
@@ -721,13 +739,13 @@
 void
 jit_convert::visit_return_command (tree_return_command&)
 {
-  throw jit_fail_exception ();
+  throw jit_fail_exception ("No visit_return_command implementation");
 }
 
 void
 jit_convert::visit_return_list (tree_return_list&)
 {
-  throw jit_fail_exception ();
+  throw jit_fail_exception ("No visit_return_list implementation");
 }
 
 void
@@ -805,31 +823,132 @@
 void
 jit_convert::visit_switch_case (tree_switch_case&)
 {
-  throw jit_fail_exception ();
+  throw jit_fail_exception ("No visit_switch_case implementation");
 }
 
 void
 jit_convert::visit_switch_case_list (tree_switch_case_list&)
 {
-  throw jit_fail_exception ();
+  throw jit_fail_exception ("No visit_switch_case_list implementation");
 }
 
 void
-jit_convert::visit_switch_command (tree_switch_command&)
+jit_convert::visit_switch_command (tree_switch_command& cmd)
 {
-  throw jit_fail_exception ();
+  tree_switch_case_list *lst = cmd.case_list ();
+
+  // always visit switch expression
+  tree_expression *expr = cmd.switch_value ();
+  assert (expr && "Switch value can not be null");
+  jit_value *value = visit (expr);
+  assert (value);
+
+  size_t case_blocks_num = lst->size ();
+
+  if (! case_blocks_num)  // there's nothing to do
+    return;
+
+  // check for otherwise, it's interpreted as last 'else' condition
+  size_t has_otherwise = 0;
+  tree_switch_case *last = lst->back ();
+  if (last->is_default_case ())
+    has_otherwise = 1;
+
+  std::vector<jit_block *> entry_blocks (case_blocks_num + 1 - has_otherwise);
+
+  // the first entry point is always the actual block. afterward new blocks
+  // are created for every case and the otherwise branch
+  entry_blocks[0] = block;
+  for (size_t i = 1; i < case_blocks_num; ++i)
+    entry_blocks[i] = factory.create<jit_block> ("case_cond");
+
+  jit_block *tail = factory.create<jit_block> ("switch_tail");
+
+  // if there's no otherwise branch, the the 'else' of the last branch
+  // has to point to the tail
+  if (! has_otherwise)
+    entry_blocks[entry_blocks.size()-1] = tail;
+
+  // each branch in the case statement will have different breaks/continues
+  block_list current_breaks = breaks;
+  block_list current_continues = continues;
+  breaks.clear ();
+  continues.clear ();
+
+  size_t num_incomming = 0; // number of incomming blocks to our tail
+
+  tree_switch_case_list::iterator iter = lst->begin ();
+  for (size_t i = 0; i < case_blocks_num; ++iter, ++i)
+    {
+      tree_switch_case *twc = *iter;
+      block = entry_blocks[i]; // case_cond
+      assert (block);
+
+      if (i)
+        blocks.push_back (entry_blocks[i]);  // first block already pushed
+
+      if (! twc->is_default_case ())
+        {
+          // compare result of switch expression with actual case label
+          tree_expression *te = twc->case_label ();
+          jit_value *label = visit (te);
+          assert(label);
+
+          const jit_operation& fn = jit_typeinfo::binary_op (octave_value::op_eq);
+          jit_value *cond = create_checked (fn, value, label);
+          assert(cond);
+
+          jit_call *check = create_checked (&jit_typeinfo::logically_true,
+                                            cond);
+
+          jit_block *body = factory.create<jit_block> ("case_body");
+          blocks.push_back (body);
+
+          block->append (factory.create<jit_cond_branch> (check, body,
+                                                          entry_blocks[i+1]));
+          block = body; // case_body
+        }
+
+      tree_statement_list *stmt_lst = twc->commands ();
+      assert(stmt_lst);
+
+      try
+        {
+          stmt_lst->accept (*this);
+          num_incomming++;
+          block->append (factory.create<jit_branch> (tail));
+        }
+      catch (const jit_break_exception&)
+        { }
+
+      // each branch in the case statement will have different breaks/continues
+      current_breaks.splice (current_breaks.end (), breaks);
+      current_continues.splice (current_continues.end (), continues);
+    }
+
+  // each branch in the case statement will have different breaks/continues
+  breaks.splice (breaks.end (), current_breaks);
+  continues.splice (continues.end (), current_continues);
+
+  if (num_incomming || ! has_otherwise)
+    {
+      blocks.push_back (tail);
+      block = tail; // switch_tail
+    }
+  else
+    throw jit_break_exception ();   // every branch broke
 }
 
 void
 jit_convert::visit_try_catch_command (tree_try_catch_command&)
 {
-  throw jit_fail_exception ();
+  throw jit_fail_exception ("No visit_try_catch_command implementation");
 }
 
 void
 jit_convert::visit_unwind_protect_command (tree_unwind_protect_command&)
 {
-  throw jit_fail_exception ();
+  throw jit_fail_exception ("No visit_unwind_protect_command implementation");
 }
 
 void
@@ -895,9 +1014,66 @@
 }
 
 void
-jit_convert::visit_do_until_command (tree_do_until_command&)
+jit_convert::visit_do_until_command (tree_do_until_command& duc)
 {
-  throw jit_fail_exception ();
+  unwind_protect prot;
+  prot.protect_var (breaks);
+  prot.protect_var (continues);
+  breaks.clear ();
+  continues.clear ();
+
+  jit_block *body = factory.create<jit_block> ("do_until_body");
+  jit_block *cond_check = factory.create<jit_block> ("do_until_cond_check");
+  jit_block *tail = factory.create<jit_block> ("do_until_tail");
+
+  block->append (factory.create<jit_branch> (body));
+  blocks.push_back (body);
+  block = body;
+
+  tree_statement_list *loop_body = duc.body ();
+  bool all_breaking = false;
+  if (loop_body)
+    {
+      try
+        {
+          loop_body->accept (*this);
+        }
+      catch (const jit_break_exception&)
+        {
+          all_breaking = true;
+        }
+    }
+
+  finish_breaks (tail, breaks);
+
+  if (! all_breaking || continues.size ())
+    {
+      jit_block *interrupt_check
+        = factory.create<jit_block> ("interrupt_check");
+      blocks.push_back (interrupt_check);
+      finish_breaks (interrupt_check, continues);
+      if (! all_breaking)
+        block->append (factory.create<jit_branch> (interrupt_check));
+
+      block = interrupt_check;
+      jit_error_check *ec
+        = factory.create<jit_error_check> (jit_error_check::var_interrupt,
+                                           cond_check, final_block);
+      block->append (ec);
+
+      blocks.push_back (cond_check);
+      block = cond_check;
+
+      tree_expression *expr = duc.condition ();
+      assert (expr && "Do-Until expression can not be null");
+      jit_value *check = visit (expr);
+      check = create_checked (&jit_typeinfo::logically_true, check);
+
+      block->append (factory.create<jit_cond_branch> (check, tail, body));
+    }
+
+  blocks.push_back (tail);
+  block = tail;
 }
 
 void
@@ -1888,10 +2064,15 @@
   if (! engine)
     return false;
 
+#ifdef LEGACY_PASSMANAGER
+  module_pass_manager = new llvm::legacy::PassManager ();
+  pass_manager = new llvm::legacy::FunctionPassManager (module); 
+#else
   module_pass_manager = new llvm::PassManager ();
+  pass_manager = new llvm::FunctionPassManager (module);
+#endif
   module_pass_manager->add (llvm::createAlwaysInlinerPass ());
 
-  pass_manager = new llvm::FunctionPassManager (module);
 #ifdef HAVE_LLVM_DATALAYOUT
   pass_manager->add (new llvm::DataLayout (*engine->getDataLayout ()));
 #else
@@ -2006,8 +2187,13 @@
   if (Vdebug_jit)
     {
       std::string error;
+#ifdef RAW_FD_OSTREAM_ARG_IS_LLVM_SYS_FS
+      llvm::raw_fd_ostream fout ("test.bc", error,
+                                 llvm::sys::fs::F_Binary);
+#else
       llvm::raw_fd_ostream fout ("test.bc", error,
                                  llvm::raw_fd_ostream::F_Binary);
+#endif
       llvm::WriteBitcodeToFile (module, fout);
     }
 }
@@ -2123,6 +2309,8 @@
             std::cout << "jit fail: " << e.what () << std::endl;
         }
 
+      Vjit_failure_count++;
+
       wrapper.erase ();
       raw_fn.erase ();
     }
@@ -2279,6 +2467,9 @@
           if (e.known ())
             std::cout << "jit fail: " << e.what () << std::endl;
         }
+
+      Vjit_failure_count++;
+
     }
 
   if (llvm_function)
@@ -2314,7 +2505,37 @@
 
 #endif
 
-DEFUN (debug_jit, args, nargout,
+#if defined (HAVE_LLVM)
+#define UNUSED_WITHOUT_LLVM(x) x
+#else
+#define UNUSED_WITHOUT_LLVM(x) x GCC_ATTR_UNUSED
+#endif
+
+DEFUN (jit_failure_count, UNUSED_WITHOUT_LLVM (args),
+       UNUSED_WITHOUT_LLVM (nargout),
+       "-*- texinfo -*-\n\
+@deftypefn  {Built-in Function} {@var{val} =} jit_failure_count ()\n\
+@deftypefnx {Built-in Function} {@var{old_val} =} jit_failure_count (@var{new_val})\n\
+@deftypefnx {Built-in Function} {} jit_failure_count (@var{new_val}, \"local\")\n\
+Query or set the internal variable that counts the number of\n\
+JIT fail exceptions for Octave's JIT compiler.\n\
+\n\
+When called from inside a function with the @qcode{\"local\"} option, the\n\
+variable is changed locally for the function and any subroutines it calls.  \n\
+The original variable value is restored when exiting the function.\n\
+@seealso{jit_enable, jit_startcnt, debug_jit}\n\
+@end deftypefn")
+{
+#if defined (HAVE_LLVM)
+  return SET_INTERNAL_VARIABLE (jit_failure_count);
+#else
+  warning ("jit_failure_count: JIT compiling not available in this version of Octave");
+  return octave_value ();
+#endif
+}
+
+DEFUN (debug_jit, UNUSED_WITHOUT_LLVM (args),
+       UNUSED_WITHOUT_LLVM (nargout),
        "-*- texinfo -*-\n\
 @deftypefn  {Built-in Function} {@var{val} =} debug_jit ()\n\
 @deftypefnx {Built-in Function} {@var{old_val} =} debug_jit (@var{new_val})\n\
@@ -2336,7 +2557,8 @@
 #endif
 }
 
-DEFUN (jit_enable, args, nargout,
+DEFUN (jit_enable, UNUSED_WITHOUT_LLVM (args),
+       UNUSED_WITHOUT_LLVM (nargout),
        "-*- texinfo -*-\n\
 @deftypefn  {Built-in Function} {@var{val} =} jit_enable ()\n\
 @deftypefnx {Built-in Function} {@var{old_val} =} jit_enable (@var{new_val})\n\
@@ -2357,7 +2579,8 @@
 #endif
 }
 
-DEFUN (jit_startcnt, args, nargout,
+DEFUN (jit_startcnt, UNUSED_WITHOUT_LLVM (args),
+       UNUSED_WITHOUT_LLVM (nargout),
        "-*- texinfo -*-\n\
 @deftypefn  {Built-in Function} {@var{val} =} jit_startcnt ()\n\
 @deftypefnx {Built-in Function} {@var{old_val} =} jit_startcnt (@var{new_val})\n\
--- a/libinterp/corefcn/pt-jit.h	Fri Aug 01 09:06:21 2014 -0400
+++ b/libinterp/corefcn/pt-jit.h	Fri Aug 01 12:10:05 2014 -0400
@@ -129,6 +129,8 @@
 
   void visit_fcn_handle (tree_fcn_handle&);
 
+  void visit_funcall (tree_funcall&);
+
   void visit_parameter_list (tree_parameter_list&);
 
   void visit_postfix_expression (tree_postfix_expression&);
@@ -384,8 +386,13 @@
   size_t trip_count (const octave_value& bounds) const;
 
   llvm::Module *module;
+#ifdef LEGACY_PASSMANAGER
+  llvm::legacy::PassManager *module_pass_manager;
+  llvm::legacy::FunctionPassManager *pass_manager;
+#else
   llvm::PassManager *module_pass_manager;
   llvm::FunctionPassManager *pass_manager;
+#endif
   llvm::ExecutionEngine *engine;
 };
 
--- a/libinterp/corefcn/quad.cc	Fri Aug 01 09:06:21 2014 -0400
+++ b/libinterp/corefcn/quad.cc	Fri Aug 01 12:10:05 2014 -0400
@@ -235,7 +235,7 @@
         quad_fcn = args(0).function_value ();
       else
         {
-          fcn_name = unique_symbol_name ("__quad_fcn_");
+          fcn_name = unique_symbol_name ("__quad_fcn__");
           std::string fname = "function y = ";
           fname.append (fcn_name);
           fname.append ("(x) y = ");
--- a/libinterp/corefcn/qz.cc	Fri Aug 01 09:06:21 2014 -0400
+++ b/libinterp/corefcn/qz.cc	Fri Aug 01 12:10:05 2014 -0400
@@ -928,7 +928,7 @@
                   std::cout << "  single gen eig:" << std::endl;
                   std::cout << "  alphar(" << jj << ") = " << aa(jj,jj)
                             << std::endl;
-                  std::cout << "  betar( " << jj << ") = " << bb(jj,jj)
+                  std::cout << "  betar(" << jj << ") = " << bb(jj,jj)
                             << std::endl;
                   std::cout << "  alphai(" << jj << ") = 0" << std::endl;
 #endif
@@ -1277,9 +1277,9 @@
 %! [aa, bb, q, z, v, w, lambda] = qz (a, b);
 %! sz = length (lambda);
 %! observed = (b * v * diag ([lambda;0])) (:, 1:sz);
-%! assert ( (a*v) (:, 1:sz), observed, norm (observed) * 1e-14);
+%! assert ((a*v)(:, 1:sz), observed, norm (observed) * 1e-14);
 %! observed = (diag ([lambda;0]) * w' * b) (1:sz, :);
-%! assert ( (w'*a) (1:sz, :) , observed, norm (observed) * 1e-13);
+%! assert ((w'*a)(1:sz, :) , observed, norm (observed) * 1e-13);
 %! assert (q * a * z, aa, norm (aa) * 1e-14);
 %! assert (q * b * z, bb, norm (bb) * 1e-14);
 
--- a/libinterp/corefcn/rand.cc	Fri Aug 01 09:06:21 2014 -0400
+++ b/libinterp/corefcn/rand.cc	Fri Aug 01 12:10:05 2014 -0400
@@ -577,7 +577,7 @@
 Reference: G. Marsaglia and W.W. Tsang,\n\
 @cite{Ziggurat Method for Generating Random Variables},\n\
 J. Statistical Software, vol 5, 2000,\n\
-@url{http://www.jstatsoft.org/v05/i08/})\n\
+@url{http://www.jstatsoft.org/v05/i08/}\n\
 \n\
 @seealso{rand, rande, randg, randp}\n\
 @end deftypefn")
@@ -648,7 +648,7 @@
 Reference: G. Marsaglia and W.W. Tsang,\n\
 @cite{Ziggurat Method for Generating Random Variables},\n\
 J. Statistical Software, vol 5, 2000,\n\
-@url{http://www.jstatsoft.org/v05/i08/})\n\
+@url{http://www.jstatsoft.org/v05/i08/}\n\
 \n\
 @seealso{rand, randn, randg, randp}\n\
 @end deftypefn")
--- a/libinterp/corefcn/sparse-xdiv.cc	Fri Aug 01 09:06:21 2014 -0400
+++ b/libinterp/corefcn/sparse-xdiv.cc	Fri Aug 01 12:10:05 2014 -0400
@@ -302,7 +302,7 @@
   using std::min;
   const octave_idx_type nc = min (d_nr, a_nc);
 
-  if ( ! mx_div_conform (a, d))
+  if (! mx_div_conform (a, d))
     return RT ();
 
   const octave_idx_type nz = a.nnz ();
@@ -569,7 +569,7 @@
   using std::min;
   const octave_idx_type nr = min (d_nc, a_nr);
 
-  if ( ! mx_leftdiv_conform (d, a))
+  if (! mx_leftdiv_conform (d, a))
     return RT ();
 
   const octave_idx_type nz = a.nnz ();
--- a/libinterp/corefcn/sparse.cc	Fri Aug 01 09:06:21 2014 -0400
+++ b/libinterp/corefcn/sparse.cc	Fri Aug 01 12:10:05 2014 -0400
@@ -135,7 +135,7 @@
 
   if (nargin == 1)
     {
-      octave_value arg = args (0);
+      octave_value arg = args(0);
       if (arg.is_bool_type ())
         retval = arg.sparse_bool_matrix_value ();
       else if (arg.is_complex_type ())
@@ -178,7 +178,8 @@
 
       if (! error_state)
         {
-          octave_idx_type m = -1, n = -1, nzmax = -1;
+          octave_idx_type m, n, nzmax;
+          m = n = nzmax = -1;
           if (nargin == 6)
             {
               nzmax = args(5).idx_type_value ();
--- a/libinterp/corefcn/spparms.cc	Fri Aug 01 09:06:21 2014 -0400
+++ b/libinterp/corefcn/spparms.cc	Fri Aug 01 12:10:05 2014 -0400
@@ -86,7 +86,7 @@
 The pivot tolerance of the @sc{umfpack} symmetric solvers (default 0.001)\n\
 \n\
 @item bandden\n\
-The density of non-zero elements in a banded matrix before it is treated\n\
+The density of nonzero elements in a banded matrix before it is treated\n\
 by the @sc{lapack} banded solvers (default 0.5)\n\
 \n\
 @item umfpack\n\
--- a/libinterp/corefcn/sqrtm.cc	Fri Aug 01 09:06:21 2014 -0400
+++ b/libinterp/corefcn/sqrtm.cc	Fri Aug 01 12:10:05 2014 -0400
@@ -101,7 +101,8 @@
 
   typedef typename Matrix::element_type real_type;
 
-  real_type cutoff = 0, one = 1;
+  real_type cutoff = 0;
+  real_type one = 1;
   real_type eps = std::numeric_limits<real_type>::epsilon ();
 
   if (! iscomplex)
--- a/libinterp/corefcn/str2double.cc	Fri Aug 01 09:06:21 2014 -0400
+++ b/libinterp/corefcn/str2double.cc	Fri Aug 01 12:10:05 2014 -0400
@@ -45,7 +45,7 @@
 static double
 single_num (std::istringstream& is)
 {
-  double num;
+  double num = 0.0;
 
   char c = is.peek ();
 
@@ -60,7 +60,8 @@
     {
       // It's infinity.
       is.get ();
-      char c1 = is.get (), c2 = is.get ();
+      char c1 = is.get ();
+      char c2 = is.get ();
       if (std::tolower (c1) == 'n' && std::tolower (c2) == 'f')
         {
           num = octave_Inf;
--- a/libinterp/corefcn/strfind.cc	Fri Aug 01 09:06:21 2014 -0400
+++ b/libinterp/corefcn/strfind.cc	Fri Aug 01 12:10:05 2014 -0400
@@ -209,7 +209,8 @@
 
   if (nargin == 2)
     {
-      octave_value argstr = args(0), argpat = args(1);
+      octave_value argstr = args(0);
+      octave_value argpat = args(1);
       if (argpat.is_string ())
         {
           Array<char> needle = argpat.char_array_value ();
@@ -279,7 +280,9 @@
 {
   Array<char> ret = str;
 
-  octave_idx_type siz = str.numel (), psiz = pat.numel (), rsiz = rep.numel ();
+  octave_idx_type siz = str.numel ();
+  octave_idx_type psiz = pat.numel ();
+  octave_idx_type rsiz = rep.numel ();
 
   if (psiz != 0)
     {
@@ -311,21 +314,27 @@
           else
             retsiz = siz + nidx * (rsiz - psiz);
 
-          ret.clear (dim_vector (1, retsiz));
-          const char *src = str.data (), *reps = rep.data ();
-          char *dest = ret.fortran_vec ();
-
-          octave_idx_type k = 0;
-          for (octave_idx_type i = 0; i < nidx; i++)
+          if (retsiz == 0)
+            ret.clear (dim_vector (0, 0));
+          else 
             {
-              octave_idx_type j = idx(i);
-              if (j >= k)
-                dest = std::copy (src + k, src + j, dest);
-              dest = std::copy (reps, reps + rsiz, dest);
-              k = j + psiz;
+              ret.clear (dim_vector (1, retsiz));
+              const char *src = str.data ();
+              const char *reps = rep.data ();
+              char *dest = ret.fortran_vec ();
+
+              octave_idx_type k = 0;
+              for (octave_idx_type i = 0; i < nidx; i++)
+                {
+                  octave_idx_type j = idx(i);
+                  if (j >= k)
+                    dest = std::copy (src + k, src + j, dest);
+                  dest = std::copy (reps, reps + rsiz, dest);
+                  k = j + psiz;
+                }
+
+              std::copy (src + k, src + siz, dest);
             }
-
-          std::copy (src + k, src + siz, dest);
         }
     }
 
@@ -380,7 +389,9 @@
 
   if (nargin == 3)
     {
-      octave_value argstr = args(0), argpat = args(1), argrep = args(2);
+      octave_value argstr = args(0);
+      octave_value argpat = args(1);
+      octave_value argrep = args(2);
       if (argpat.is_string () && argrep.is_string ())
         {
           const Array<char> pat = argpat.char_array_value ();
@@ -433,6 +444,8 @@
 %!assert (strrep ("abababc", "abab", "xyz"), "xyzxyzc")
 %!assert (strrep ("abababc", "abab", "xyz", "overlaps", false), "xyzabc")
 
+%!assert (size (strrep ("a", "a", "")), [0 0])
+
 %!error strrep ()
 %!error strrep ("foo", "bar", 3, 4)
 */
--- a/libinterp/corefcn/strfns.cc	Fri Aug 01 09:06:21 2014 -0400
+++ b/libinterp/corefcn/strfns.cc	Fri Aug 01 12:10:05 2014 -0400
@@ -585,7 +585,7 @@
 
   if (args.length () == 2)
     {
-      retval = do_strcmp_fun (args (0), args (1), 0,
+      retval = do_strcmp_fun (args(0), args(1), 0,
                               "strcmp", strcmp_array_op, strcmp_str_op);
     }
   else
@@ -647,7 +647,8 @@
 strncmp_array_op (const charNDArray& s1, const charNDArray& s2,
                   octave_idx_type n)
 {
-  octave_idx_type l1 = s1.numel (), l2 = s2.numel ();
+  octave_idx_type l1 = s1.numel ();
+  octave_idx_type l2 = s2.numel ();
   return (n > 0 && n <= l1 && n <= l2
           && std::equal (s1.data (), s1.data () + n, s2.data ()));
 }
@@ -658,7 +659,8 @@
 static bool
 strncmp_str_op (const std::string& s1, const std::string& s2, octave_idx_type n)
 {
-  octave_idx_type l1 = s1.length (), l2 = s2.length ();
+  octave_idx_type l1 = s1.length ();
+  octave_idx_type l2 = s2.length ();
   return (n > 0 && n <= l1 && n <= l2
           && std::equal (s1.data (), s1.data () + n, s2.data ()));
 }
@@ -781,7 +783,7 @@
 
   if (args.length () == 2)
     {
-      retval = do_strcmp_fun (args (0), args (1), 0,
+      retval = do_strcmp_fun (args(0), args(1), 0,
                               "strcmpi", strcmpi_array_op, strcmpi_str_op);
     }
   else
@@ -799,7 +801,8 @@
 strncmpi_array_op (const charNDArray& s1, const charNDArray& s2,
                    octave_idx_type n)
 {
-  octave_idx_type l1 = s1.numel (), l2 = s2.numel ();
+  octave_idx_type l1 = s1.numel ();
+  octave_idx_type l2 = s2.numel ();
   return (n > 0 && n <= l1 && n <= l2
           && std::equal (s1.data (), s1.data () + n, s2.data (),
                          icmp_char_eq ()));
@@ -810,7 +813,8 @@
 strncmpi_str_op (const std::string& s1, const std::string& s2,
                  octave_idx_type n)
 {
-  octave_idx_type l1 = s1.length (), l2 = s2.length ();
+  octave_idx_type l1 = s1.length ();
+  octave_idx_type l2 = s2.length ();
   return (n > 0 && n <= l1 && n <= l2
           && std::equal (s1.data (), s1.data () + n, s2.data (),
                          icmp_char_eq ()));
--- a/libinterp/corefcn/symtab.cc	Fri Aug 01 09:06:21 2014 -0400
+++ b/libinterp/corefcn/symtab.cc	Fri Aug 01 12:10:05 2014 -0400
@@ -38,6 +38,7 @@
 #include "dirfns.h"
 #include "input.h"
 #include "load-path.h"
+#include "ov-classdef.h"
 #include "ov-fcn.h"
 #include "ov-usr-fcn.h"
 #include "pager.h"
@@ -149,6 +150,24 @@
   return retval;
 }
 
+static void
+split_name_with_package (const std::string& name, std::string& fname,
+                         std::string& pname)
+{
+  size_t pos = name.rfind ('.');
+
+  fname.clear ();
+  pname.clear ();
+
+  if (pos != std::string::npos)
+    {
+      fname = name.substr (pos + 1);
+      pname = name.substr (0, pos);
+    }
+  else
+    fname = name;
+}
+
 // Check the load path to see if file that defined this is still
 // visible.  If the file is no longer visible, then erase the
 // definition and move on.  If the file is visible, then we also
@@ -165,11 +184,13 @@
 static inline bool
 load_out_of_date_fcn (const std::string& ff, const std::string& dir_name,
                       octave_value& function,
-                      const std::string& dispatch_type = std::string ())
+                      const std::string& dispatch_type = std::string (),
+                      const std::string& package_name = std::string ())
 {
   bool retval = false;
 
-  octave_function *fcn = load_fcn_from_file (ff, dir_name, dispatch_type);
+  octave_function *fcn = load_fcn_from_file (ff, dir_name, dispatch_type,
+                                             package_name);
 
   if (fcn)
     {
@@ -206,11 +227,13 @@
 
               bool relative = check_relative && fcn->is_relative ();
 
-              if (tc < Vlast_prompt_time
+              if (tc <= Vlast_prompt_time
                   || (relative && tc < Vlast_chdir_time))
                 {
                   bool clear_breakpoints = false;
                   std::string nm = fcn->name ();
+                  std::string pack = fcn->package_name ();
+                  std::string canonical_nm = fcn->canonical_name ();
 
                   bool is_same_file = false;
 
@@ -235,10 +258,13 @@
                           if (! dispatch_type.empty ())
                             {
                               file = load_path::find_method (dispatch_type, nm,
-                                                             dir_name);
+                                                             dir_name, pack);
 
                               if (file.empty ())
                                 {
+                                  std::string s_name;
+                                  std::string s_pack;
+
                                   const std::list<std::string>& plist
                                     = symbol_table::parent_classes (dispatch_type);
                                   std::list<std::string>::const_iterator it
@@ -246,10 +272,17 @@
 
                                   while (it != plist.end ())
                                     {
+                                      split_name_with_package (*it, s_name,
+                                                               s_pack);
+
                                       file = load_path::find_method (*it, nm,
-                                                                     dir_name);
+                                                                     dir_name,
+                                                                     s_pack);
                                       if (! file.empty ())
-                                        break;
+                                        {
+                                          pack = s_pack;
+                                          break;
+                                        }
 
                                       it++;
                                     }
@@ -261,7 +294,7 @@
                             file = lookup_autoload (nm);
 
                           if (file.empty ())
-                            file = load_path::find_fcn (nm, dir_name);
+                            file = load_path::find_fcn (nm, dir_name, pack);
                         }
 
                       if (! file.empty ())
@@ -303,7 +336,8 @@
                                 {
                                   retval = load_out_of_date_fcn (ff, dir_name,
                                                                  function,
-                                                                 dispatch_type);
+                                                                 dispatch_type,
+                                                                 pack);
 
                                   clear_breakpoints = true;
                                 }
@@ -322,7 +356,7 @@
                       // place of the old.
 
                       retval = load_out_of_date_fcn (file, dir_name, function,
-                                                     dispatch_type);
+                                                     dispatch_type, pack);
 
                       clear_breakpoints = true;
                     }
@@ -330,7 +364,8 @@
                   // If the function has been replaced then clear any
                   // breakpoints associated with it
                   if (clear_breakpoints)
-                    bp_table::remove_all_breakpoints_in_file (nm, true);
+                    bp_table::remove_all_breakpoints_in_file (canonical_nm,
+                                                              true);
                 }
             }
         }
@@ -383,11 +418,13 @@
 
   std::string dir_name;
 
-  std::string file_name = load_path::find_method (name, name, dir_name);
+  std::string file_name = load_path::find_method (name, name, dir_name,
+                                                  package_name);
 
   if (! file_name.empty ())
     {
-      octave_function *fcn = load_fcn_from_file (file_name, dir_name, name);
+      octave_function *fcn = load_fcn_from_file (file_name, dir_name, name,
+                                                 package_name);
 
       if (fcn)
         {
@@ -396,6 +433,31 @@
           class_constructors[name] = retval;
         }
     }
+  else
+    {
+      // Classdef constructors can be defined anywhere in the path, not
+      // necessarily in @-folders. Look for a normal function and load it.
+      // If the loaded function is a classdef constructor, store it as such
+      // and restore function_on_path to its previous value.
+
+      octave_value old_function_on_path = function_on_path;
+
+      octave_value maybe_cdef_ctor = find_user_function ();
+
+      if (maybe_cdef_ctor.is_defined ())
+        {
+          octave_function *fcn = maybe_cdef_ctor.function_value (true);
+
+          if (fcn && fcn->is_classdef_constructor ())
+            {
+              retval = maybe_cdef_ctor;
+
+              class_constructors[name] = retval;
+
+              function_on_path = old_function_on_path;
+            }
+        }
+    }
 
   return retval;
 }
@@ -406,47 +468,57 @@
 {
   octave_value retval;
 
-  if (name == dispatch_type)
+  if (full_name () == dispatch_type)
     retval = load_class_constructor ();
   else
     {
-      std::string dir_name;
+      octave_function *cm = cdef_manager::find_method_symbol (name,
+                                                              dispatch_type);
 
-      std::string file_name = load_path::find_method (dispatch_type, name,
-                                                      dir_name);
+      if (cm)
+        retval = octave_value (cm);
 
-      if (! file_name.empty ())
+      if (! retval.is_defined ())
         {
-          octave_function *fcn = load_fcn_from_file (file_name, dir_name,
-                                                     dispatch_type);
+          std::string dir_name;
 
-          if (fcn)
+          std::string file_name = load_path::find_method (dispatch_type, name,
+                                                          dir_name);
+
+          if (! file_name.empty ())
             {
-              retval = octave_value (fcn);
+              octave_function *fcn = load_fcn_from_file (file_name, dir_name,
+                                                         dispatch_type);
 
-              class_methods[dispatch_type] = retval;
-            }
-        }
+              if (fcn)
+                {
+                  retval = octave_value (fcn);
 
-      if (retval.is_undefined ())
-        {
-          // Search parent classes
+                  class_methods[dispatch_type] = retval;
+                }
+            }
 
-          const std::list<std::string>& plist = parent_classes (dispatch_type);
-
-          std::list<std::string>::const_iterator it = plist.begin ();
-
-          while (it != plist.end ())
+          if (retval.is_undefined ())
             {
-              retval = find_method (*it);
+              // Search parent classes
 
-              if (retval.is_defined ())
+              const std::list<std::string>& plist =
+                parent_classes (dispatch_type);
+
+              std::list<std::string>::const_iterator it = plist.begin ();
+
+              while (it != plist.end ())
                 {
-                  class_methods[dispatch_type] = retval;
-                  break;
+                  retval = find_method (*it);
+
+                  if (retval.is_defined ())
+                    {
+                      class_methods[dispatch_type] = retval;
+                      break;
+                    }
+
+                  it++;
                 }
-
-              it++;
             }
         }
     }
@@ -787,6 +859,13 @@
   if (fcn.is_defined ())
     return fcn;
 
+  // Package
+
+  fcn = find_package ();
+
+  if (fcn.is_defined ())
+    return fcn;
+
   // Built-in function (might be undefined).
 
   return built_in_function;
@@ -975,7 +1054,7 @@
 
           std::string dir_name = file_name.substr (0, pos);
 
-          octave_function *fcn = load_fcn_from_file (file_name, dir_name,
+          octave_function *fcn = load_fcn_from_file (file_name, dir_name, "",
                                                      "", name, true);
 
           if (fcn)
@@ -998,11 +1077,13 @@
     {
       std::string dir_name;
 
-      std::string file_name = load_path::find_fcn (name, dir_name);
+      std::string file_name = load_path::find_fcn (name, dir_name,
+                                                   package_name);
 
       if (! file_name.empty ())
         {
-          octave_function *fcn = load_fcn_from_file (file_name, dir_name);
+          octave_function *fcn = load_fcn_from_file (file_name, dir_name, "",
+                                                     package_name);
 
           if (fcn)
             function_on_path = octave_value (fcn);
@@ -1012,6 +1093,25 @@
   return function_on_path;
 }
 
+octave_value
+symbol_table::fcn_info::fcn_info_rep::find_package (void)
+{
+  // FIXME: implement correct way to check out of date package
+  //if (package.is_defined ())
+  //  out_of_date_check (package);
+
+  if (! (error_state || package.is_defined ()))
+    {
+      octave_function * fcn =
+        cdef_manager::find_package_symbol (full_name ());
+
+      if (fcn)
+        package = octave_value (fcn);
+    }
+
+  return package;
+}
+
 // Insert INF_CLASS in the set of class names that are considered
 // inferior to SUP_CLASS.  Return FALSE if INF_CLASS is currently
 // marked as superior to  SUP_CLASS.
@@ -1069,10 +1169,11 @@
 symbol_table::fcn_info::fcn_info_rep::dump (std::ostream& os,
                                             const std::string& prefix) const
 {
-  os << prefix << name
+  os << prefix << full_name ()
      << " ["
      << (cmdline_function.is_defined () ? "c" : "")
      << (built_in_function.is_defined () ? "b" : "")
+     << (package.is_defined () ? "p" : "")
      << "]\n";
 
   std::string tprefix = prefix + "  ";
--- a/libinterp/corefcn/symtab.h	Fri Aug 01 09:06:21 2014 -0400
+++ b/libinterp/corefcn/symtab.h	Fri Aug 01 12:10:05 2014 -0400
@@ -756,10 +756,19 @@
     public:
 
       fcn_info_rep (const std::string& nm)
-        : name (nm), subfunctions (), private_functions (),
+        : name (nm), package_name (), subfunctions (), private_functions (),
           class_constructors (), class_methods (), dispatch_map (),
           cmdline_function (), autoload_function (), function_on_path (),
-          built_in_function (), count (1) { }
+          built_in_function (), count (1)
+      {
+        size_t pos = name.rfind ('.');
+
+        if (pos != std::string::npos)
+          {
+            package_name = name.substr (0, pos);
+            name = name.substr (pos+1);
+          }
+      }
 
       octave_value load_private_function (const std::string& dir_name);
 
@@ -775,6 +784,8 @@
 
       octave_value find_autoload (void);
 
+      octave_value find_package (void);
+
       octave_value find_user_function (void);
 
       bool is_user_function_defined (void) const
@@ -883,6 +894,11 @@
           clear_user_function ();
       }
 
+      void clear_package (void)
+      {
+        package = octave_value ();
+      }
+
       void clear (bool force = false)
       {
         clear_map (subfunctions, force);
@@ -892,6 +908,7 @@
 
         clear_autoload_function (force);
         clear_user_function (force);
+        clear_package ();
       }
 
       void add_dispatch (const std::string& type, const std::string& fname)
@@ -915,8 +932,18 @@
 
       void dump (std::ostream& os, const std::string& prefix) const;
 
+      std::string full_name (void) const
+      {
+        if (package_name.empty ())
+          return name;
+        else
+          return package_name + "." + name;
+      }
+
       std::string name;
 
+      std::string package_name;
+
       // Scope id to function object.
       std::map<scope_id, octave_value> subfunctions;
 
@@ -938,6 +965,8 @@
 
       octave_value function_on_path;
 
+      octave_value package;
+
       octave_value built_in_function;
 
       octave_refcount<size_t> count;
--- a/libinterp/corefcn/syscalls.cc	Fri Aug 01 09:06:21 2014 -0400
+++ b/libinterp/corefcn/syscalls.cc	Fri Aug 01 12:10:05 2014 -0400
@@ -511,7 +511,7 @@
 
   if (nargin == 3)
     {
-      octave_stream strm = octave_stream_list::lookup (args (0), "fcntl");
+      octave_stream strm = octave_stream_list::lookup (args(0), "fcntl");
 
       if (! error_state)
         {
--- a/libinterp/corefcn/toplev.cc	Fri Aug 01 09:06:21 2014 -0400
+++ b/libinterp/corefcn/toplev.cc	Fri Aug 01 12:10:05 2014 -0400
@@ -301,7 +301,8 @@
 
 octave_map
 octave_call_stack::do_backtrace (size_t nskip,
-                                 octave_idx_type& curr_user_frame) const
+                                 octave_idx_type& curr_user_frame,
+                                 bool print_subfn) const
 {
   size_t user_code_frames = do_num_user_code_frames (curr_user_frame);
 
@@ -340,7 +341,7 @@
 
                   file(k) = f->fcn_file_name ();
                   std::string parent_fcn_name = f->parent_fcn_name ();
-                  if (parent_fcn_name == std::string ())
+                  if (! print_subfn || parent_fcn_name == std::string ())
                     name(k) = f->name ();
                   else
                     name(k) = f->parent_fcn_name () + Vfilemarker + f->name ();
@@ -445,6 +446,8 @@
               break;
             }
         }
+      else if (incr == 0)  // Break out of infinite loop by choosing an incr. 
+        incr = -1;
 
       // There is no need to set scope and context here.  That will
       // happen when the dbup/dbdown/keyboard frame is popped and we
@@ -612,7 +615,7 @@
                     {
                       if (! (interactive || forced_interactive))
                         {
-                          // We should exit with a non-zero status.
+                          // We should exit with a nonzero status.
                           retval = 1;
                           break;
                         }
@@ -651,6 +654,8 @@
     }
   while (retval == 0);
 
+  octave_stdout << "\n";
+
   if (retval == EOF)
     retval = 0;
 
@@ -1274,8 +1279,6 @@
     { false, "CAMD_LIBS", OCTAVE_CONF_CAMD_LIBS },
     { false, "CARBON_LIBS", OCTAVE_CONF_CARBON_LIBS },
     { false, "CC", OCTAVE_CONF_CC },
-    // FIXME: CC_VERSION is deprecated.  Remove in version 3.12
-    { false, "CC_VERSION", OCTAVE_CONF_CC_VERSION },
     { false, "CCOLAMD_CPPFLAGS", OCTAVE_CONF_CCOLAMD_CPPFLAGS },
     { false, "CCOLAMD_LDFLAGS", OCTAVE_CONF_CCOLAMD_LDFLAGS },
     { false, "CCOLAMD_LIBS", OCTAVE_CONF_CCOLAMD_LIBS },
@@ -1298,8 +1301,6 @@
     { false, "CXXCPP", OCTAVE_CONF_CXXCPP },
     { false, "CXXFLAGS", OCTAVE_CONF_CXXFLAGS },
     { false, "CXXPICFLAG", OCTAVE_CONF_CXXPICFLAG },
-    // FIXME: CXX_VERSION is deprecated.  Remove in version 3.12
-    { false, "CXX_VERSION", OCTAVE_CONF_CXX_VERSION },
     { false, "DEFAULT_PAGER", OCTAVE_DEFAULT_PAGER },
     { false, "DEFS", OCTAVE_CONF_DEFS },
     { false, "DL_LD", OCTAVE_CONF_DL_LD },
--- a/libinterp/corefcn/toplev.h	Fri Aug 01 09:06:21 2014 -0400
+++ b/libinterp/corefcn/toplev.h	Fri Aug 01 12:10:05 2014 -0400
@@ -278,7 +278,16 @@
   static octave_map backtrace (size_t nskip, octave_idx_type& curr_user_frame)
   {
     return instance_ok ()
-           ? instance->do_backtrace (nskip, curr_user_frame) : octave_map ();
+           ? instance->do_backtrace (nskip, curr_user_frame, true)
+           : octave_map ();
+  }
+
+  static octave_map backtrace (size_t nskip, octave_idx_type& curr_user_frame,
+                               bool print_subfn)
+  {
+    return instance_ok ()
+           ? instance->do_backtrace (nskip, curr_user_frame, print_subfn)
+           : octave_map ();
   }
 
   static octave_map empty_backtrace (void);
@@ -414,7 +423,8 @@
   }
 
   octave_map do_backtrace (size_t nskip,
-                           octave_idx_type& curr_user_frame) const;
+                           octave_idx_type& curr_user_frame,
+                           bool print_subfn) const;
 
   bool do_goto_frame (size_t n, bool verbose);
 
--- a/libinterp/corefcn/tril.cc	Fri Aug 01 09:06:21 2014 -0400
+++ b/libinterp/corefcn/tril.cc	Fri Aug 01 12:10:05 2014 -0400
@@ -42,7 +42,8 @@
 static Array<T>
 do_tril (const Array<T>& a, octave_idx_type k, bool pack)
 {
-  octave_idx_type nr = a.rows (), nc = a.columns ();
+  octave_idx_type nr = a.rows ();
+  octave_idx_type nc = a.columns ();
   const T *avec = a.fortran_vec ();
   octave_idx_type zero = 0;
 
@@ -83,7 +84,8 @@
 static Array<T>
 do_triu (const Array<T>& a, octave_idx_type k, bool pack)
 {
-  octave_idx_type nr = a.rows (), nc = a.columns ();
+  octave_idx_type nr = a.rows ();
+  octave_idx_type nc = a.columns ();
   const T *avec = a.fortran_vec ();
   octave_idx_type zero = 0;
 
@@ -211,7 +213,7 @@
     print_usage ();
   else
     {
-      octave_value arg = args (0);
+      octave_value arg = args(0);
 
       dim_vector dims = arg.dims ();
       if (dims.length () != 2)
@@ -274,7 +276,8 @@
                 if (arg.numel () == 0)
                   return arg;
 
-                octave_idx_type nr = dims(0), nc = dims (1);
+                octave_idx_type nr = dims(0);
+                octave_idx_type nc = dims(1);
 
                 // The sole purpose of the below is to force the correct
                 // matrix size. This would not be necessary if the
--- a/libinterp/corefcn/txt-eng-ft.cc	Fri Aug 01 09:06:21 2014 -0400
+++ b/libinterp/corefcn/txt-eng-ft.cc	Fri Aug 01 12:10:05 2014 -0400
@@ -121,7 +121,7 @@
   typedef std::pair<std::string, double> ft_key;
   typedef std::map<ft_key, FT_Face> ft_cache;
 
-  // Cache the fonts loaded by freetype. This cache only contains
+  // Cache the fonts loaded by FreeType. This cache only contains
   // weak references to the fonts, strong references are only present
   // in class ft_render.
   ft_cache cache;
@@ -138,7 +138,7 @@
     : library (), freetype_initialized (false), fontconfig_initialized (false)
   {
     if (FT_Init_FreeType (&library))
-      ::error ("unable to initialize freetype library");
+      ::error ("unable to initialize FreeType library");
     else
       freetype_initialized = true;
 
@@ -635,7 +635,8 @@
       FT_UInt glyph_index, previous = 0;
 
       std::string str = e.string_value ();
-      size_t n = str.length (), curr = 0;
+      size_t n = str.length ();
+      size_t curr = 0;
       mbstate_t ps;
       memset (&ps, 0, sizeof (ps));  // Initialize state to 0.
       wchar_t wc;
--- a/libinterp/corefcn/txt-eng-ft.h	Fri Aug 01 09:06:21 2014 -0400
+++ b/libinterp/corefcn/txt-eng-ft.h	Fri Aug 01 12:10:05 2014 -0400
@@ -114,7 +114,7 @@
   ft_render& operator = (const ft_render&);
 
   // Class to hold information about fonts and a strong
-  // reference to the font objects loaded by freetype.
+  // reference to the font objects loaded by FreeType.
   class ft_font
   {
   public:
--- a/libinterp/corefcn/urlwrite.cc	Fri Aug 01 09:06:21 2014 -0400
+++ b/libinterp/corefcn/urlwrite.cc	Fri Aug 01 12:10:05 2014 -0400
@@ -391,7 +391,7 @@
         }
 
 
-      if (param.numel () % 2 == 1 )
+      if (param.numel () % 2 == 1)
         {
           error ("urlwrite: number of elements in PARAM must be even");
           return retval;
@@ -539,7 +539,7 @@
           return retval;
         }
 
-      if (param.numel () % 2 == 1 )
+      if (param.numel () % 2 == 1)
         {
           error ("urlread: number of elements in PARAM must be even");
           return retval;
--- a/libinterp/corefcn/utils.cc	Fri Aug 01 09:06:21 2014 -0400
+++ b/libinterp/corefcn/utils.cc	Fri Aug 01 12:10:05 2014 -0400
@@ -238,7 +238,7 @@
   return status;
 }
 
-// Return non-zero if either NR or NC is zero.  Return -1 if this
+// Return nonzero if either NR or NC is zero.  Return -1 if this
 // should be considered fatal; return 1 if this is ok.
 
 int
@@ -303,7 +303,7 @@
 If the second optional argument @qcode{\"all\"} is supplied, return\n\
 a cell array containing the list of all files that have the same\n\
 name in the path.  If no files are found, return an empty cell array.\n\
-@seealso{file_in_path, find_dir_in_path, path}\n\
+@seealso{file_in_path, dir_in_loadpath, path}\n\
 @end deftypefn")
 {
   octave_value retval;
@@ -380,7 +380,7 @@
 If the third optional argument @qcode{\"all\"} is supplied, return\n\
 a cell array containing the list of all files that have the same\n\
 name in the path.  If no files are found, return an empty cell array.\n\
-@seealso{file_in_loadpath, find_dir_in_path, path}\n\
+@seealso{file_in_loadpath, dir_in_loadpath, path}\n\
 @end deftypefn")
 {
   octave_value retval;
@@ -892,10 +892,10 @@
 %!error make_absolute_filename ("foo", "bar")
 */
 
-DEFUN (find_dir_in_path, args, ,
+DEFUN (dir_in_loadpath, args, ,
        "-*- texinfo -*-\n\
-@deftypefn  {Built-in Function} {} find_dir_in_path (@var{dir})\n\
-@deftypefnx {Built-in Function} {} find_dir_in_path (@var{dir}, \"all\")\n\
+@deftypefn  {Built-in Function} {} dir_in_loadpath (@var{dir})\n\
+@deftypefnx {Built-in Function} {} dir_in_loadpath (@var{dir}, \"all\")\n\
 Return the full name of the path element matching @var{dir}.  The\n\
 match is performed at the end of each path element.  For example, if\n\
 @var{dir} is @qcode{\"foo/bar\"}, it matches the path element\n\
@@ -926,7 +926,7 @@
             retval = Cell (load_path::find_matching_dirs (dir));
         }
       else
-        error ("find_dir_in_path: DIR must be a directory name");
+        error ("dir_in_loadpath: DIR must be a directory name");
     }
   else
     print_usage ();
@@ -937,8 +937,8 @@
 /*
 ## FIXME: We need system-dependent tests here.
 
-%!error find_dir_in_path ()
-%!error find_dir_in_path ("foo", "bar", 1)
+%!error dir_in_loadpath ()
+%!error dir_in_loadpath ("foo", "bar", 1)
 */
 
 DEFUNX ("errno", Ferrno, args, ,
--- a/libinterp/corefcn/variables.cc	Fri Aug 01 09:06:21 2014 -0400
+++ b/libinterp/corefcn/variables.cc	Fri Aug 01 12:10:05 2014 -0400
@@ -388,17 +388,7 @@
 int
 symbol_exist (const std::string& name, const std::string& type)
 {
-  std::string struct_elts;
-  std::string symbol_name = name;
-
-  size_t pos = name.find ('.');
-
-  if (pos != std::string::npos && pos > 0)
-    {
-      struct_elts = name.substr (pos+1);
-      symbol_name = name.substr (0, pos);
-    }
-  else if (is_keyword (symbol_name))
+  if (is_keyword (name))
     return 0;
 
   bool search_any = type == "any";
@@ -409,21 +399,38 @@
 
   if (search_any || search_var)
     {
-      bool not_a_struct = struct_elts.empty ();
-      bool var_ok = not_a_struct; // || val.is_map_element (struct_elts)
-
       octave_value val = symbol_table::varval (name);
 
-      if (var_ok && (val.is_constant () || val.is_object ()
-                     || val.is_function_handle ()
-                     || val.is_anonymous_function ()
-                     || val.is_inline_function ()))
+      if (val.is_constant () || val.is_object ()
+          || val.is_function_handle ()
+          || val.is_anonymous_function ()
+          || val.is_inline_function ())
         return 1;
 
       if (search_var)
         return 0;
     }
 
+  // We shouldn't need to look in the global symbol table, since any name
+  // that is visible in the current scope will be in the local symbol table.
+
+  octave_value val;
+
+  if (search_any || search_builtin)
+    {
+      // FIXME: safe_symbol_lookup will attempt unsafe load of .oct/.mex file.
+      // This can cause a segfault.  To catch this would require temporarily
+      // diverting the SIGSEGV exception handler and then restoring it.
+      // See bug #36067.
+      val = safe_symbol_lookup (name);
+
+      if (val.is_defined () && val.is_builtin_function ())
+        return 5;
+
+      if (search_builtin)
+        return 0;
+    }
+
   if (search_any || search_file || search_dir)
     {
       std::string file_name = lookup_autoload (name);
@@ -455,7 +462,18 @@
       if (fs)
         {
           if (search_any || search_file)
-            return fs.is_dir () ? 7 : 2;
+          {
+            if (fs.is_dir ())
+              return 7;
+
+            len = file_name.length ();
+
+            if (len > 4 && (file_name.substr (len-4) == ".oct"
+                            || file_name.substr (len-4) == ".mex"))
+              return 3;
+            else
+              return 2;
+          }
           else if (search_dir && fs.is_dir ())
             return 7;
         }
@@ -464,27 +482,9 @@
         return 0;
     }
 
-  // We shouldn't need to look in the global symbol table, since any
-  // name that is visible in the current scope will be in the local
-  // symbol table.
-
-  octave_value val = safe_symbol_lookup (symbol_name);
-
-  if (val.is_defined () && struct_elts.empty ())
-    {
-      if ((search_any || search_builtin)
-          && val.is_builtin_function ())
-        return 5;
-
-      if ((search_any || search_file)
-          && (val.is_user_function () || val.is_dld_function ()))
-        {
-          octave_function *f = val.function_value (true);
-          std::string s = f ? f->fcn_file_name () : std::string ();
-
-          return s.empty () ? 103 : (val.is_user_function () ? 2 : 3);
-        }
-    }
+  // Command line function which Matlab does not support
+  if (search_any && val.is_defined () && val.is_user_function ())
+    return 103;
 
   return 0;
 }
@@ -515,21 +515,38 @@
 
 DEFUN (exist, args, ,
        "-*- texinfo -*-\n\
-@deftypefn {Built-in Function} {} exist (@var{name}, @var{type})\n\
-Return 1 if the name exists as a variable, 2 if the name is an\n\
-absolute file name, an ordinary file in Octave's @code{path}, or (after\n\
-appending @samp{.m}) a function file in Octave's @code{path}, 3 if the\n\
-name is a @samp{.oct} or @samp{.mex} file in Octave's @code{path},\n\
-5 if the name is a built-in function, 7 if the name is a directory, or 103\n\
-if the name is a function not associated with a file (entered on\n\
-the command line).\n\
+@deftypefn  {Built-in Function} {@var{c} =} exist (@var{name})\n\
+@deftypefnx {Built-in Function} {@var{c} =} exist (@var{name}, @var{type})\n\
+Check for the existence of @var{name} as a variable, function, file,\n\
+directory, or class.\n\
+\n\
+The return code @var{c} is one of\n\
+\n\
+@table @asis\n\
+@item 1\n\
+@var{name} is a variable.\n\
+\n\
+@item 2\n\
+@var{name} is an absolute file name, an ordinary file in Octave's\n\
+@code{path}, or (after appending @samp{.m}) a function file in Octave's\n\
+@code{path}.\n\
 \n\
-Otherwise, return 0.\n\
+@item 3\n\
+@var{name} is a @samp{.oct} or @samp{.mex} file in Octave's @code{path}.\n\
+\n\
+@item 5\n\
+@var{name} is a built-in function.\n\
 \n\
-This function also returns 2 if a regular file called @var{name}\n\
-exists in Octave's search path.  If you want information about\n\
-other types of files, you should use some combination of the functions\n\
-@code{file_in_path} and @code{stat} instead.\n\
+@item 7\n\
+@var{name} is a directory.\n\
+\n\
+@item 103\n\
+@var{name} is a function not associated with a file (entered on the command\n\
+line).\n\
+\n\
+@item 0\n\
+@var{name} does not exist.\n\
+@end table\n\
 \n\
 If the optional argument @var{type} is supplied, check only for\n\
 symbols of the specified type.  Valid types are\n\
@@ -541,14 +558,26 @@
 @item @qcode{\"builtin\"}\n\
 Check only for built-in functions.\n\
 \n\
+@item @qcode{\"dir\"}\n\
+Check only for directories.\n\
+\n\
 @item @qcode{\"file\"}\n\
 Check only for files and directories.\n\
 \n\
-@item @qcode{\"dir\"}\n\
-Check only for directories.\n\
+@item @qcode{\"class\"}\n\
+Check only for classes.  (Note: This option is accepted, but not currently implemented)\n\
 @end table\n\
 \n\
-@seealso{file_in_loadpath, file_in_path, find_dir_in_path, stat}\n\
+If no type is given, and there are multiple possible matches for name,\n\
+@code{exist} will return a code according to the following priority list:\n\
+variable, built-in function, oct-file, directory, file, class. \n\
+\n\
+@code{exist} returns 2 if a regular file called @var{name} is present in\n\
+Octave's search path.  If you want information about other types of files\n\
+not on the search path you should use some combination of the functions\n\
+@code{file_in_path} and @code{stat} instead.\n\
+\n\
+@seealso{file_in_loadpath, file_in_path, dir_in_loadpath, stat}\n\
 @end deftypefn")
 {
   octave_value retval = false;
@@ -557,16 +586,21 @@
 
   if (nargin == 1 || nargin == 2)
     {
-      std::string name = args(0).string_value ();
-
-      if (! error_state)
+      if (args(0).is_string ())
         {
+          std::string name = args(0).string_value ();
+
           if (nargin == 2)
             {
-              std::string type = args(1).string_value ();
-
-              if (! error_state)
-                retval = symbol_exist (name, type);
+              if (args(1).is_string ())
+                {
+                  std::string type = args(1).string_value ();
+
+                  if (type == "class")
+                    warning ("exist: \"class\" type argument is not implemented");
+
+                  retval = symbol_exist (name, type);
+                }
               else
                 error ("exist: TYPE must be a string");
             }
@@ -583,18 +617,62 @@
 }
 
 /*
+%!shared dirtmp, __var1
+%! dirtmp = P_tmpdir ();
+%! __var1 = 1;
+
+%!assert (exist ("__%Highly_unlikely_name%__"), 0)
+%!assert (exist ("__var1"), 1)
+%!assert (exist ("__var1", "var"), 1)
+%!assert (exist ("__var1", "builtin"), 0)
+%!assert (exist ("__var1", "dir"), 0)
+%!assert (exist ("__var1", "file"), 0)
+
 %!test
 %! if (isunix ())
-%!   assert (exist ("/tmp") == 7);
-%!   assert (exist ("/tmp", "file") == 7);
-%!   assert (exist ("/tmp", "dir") == 7);
-%!   assert (exist ("/bin/sh") == 2);
-%!   assert (exist ("/bin/sh", "file") == 2);
-%!   assert (exist ("/bin/sh", "dir") == 0);
-%!   assert (exist ("/dev/null") == 2);
-%!   assert (exist ("/dev/null", "file") == 2);
-%!   assert (exist ("/dev/null", "dir") == 0);
+%!   assert (exist ("/bin/sh"), 2);
+%!   assert (exist ("/bin/sh", "file"), 2);
+%!   assert (exist ("/bin/sh", "dir"), 0);
+%!   assert (exist ("/dev/null"), 2);
+%!   assert (exist ("/dev/null", "file"), 2);
+%!   assert (exist ("/dev/null", "dir"), 0);
 %! endif
+
+%!assert (exist ("colon"), 2)
+%!assert (exist ("colon.m"), 2)
+%!assert (exist ("colon", "file"), 2)
+%!assert (exist ("colon", "dir"), 0)
+
+%!testif HAVE_CHOLMOD
+%! assert (exist ("chol"), 3);
+%! assert (exist ("chol.oct"), 3);
+%! assert (exist ("chol", "file"), 3);
+%! assert (exist ("chol", "builtin"), 0);
+
+%!assert (exist ("sin"), 5)
+%!assert (exist ("sin", "builtin"), 5)
+%!assert (exist ("sin", "file"), 0)
+
+%!assert (exist (dirtmp), 7)
+%!assert (exist (dirtmp, "dir"), 7)
+%!assert (exist (dirtmp, "file"), 7)
+
+%!error exist ()
+%!error exist (1,2,3)
+%!warning <"class" type argument is not implemented> exist ("a", "class");
+%!error <TYPE must be a string> exist ("a", 1)
+%!error <NAME must be a string> exist (1)
+
+%!test
+%! flist = dir ();
+%! fname = flist(3).name;  ## skip . and ..
+%! assert (exist (fullfile (pwd (), fname), "file"), 2)
+%! assert (exist (fullfile (pwd (), "nonexistentfile"), "file"), 0)
+
+%!assert (exist ("plot.m", "file"), 2);
+%!assert (exist ("./plot.m", "file"), 0);
+%!assert (exist ("./nonexistentfile", "file"), 0);
+%!assert (exist ("nonexistentfile", "file"), 0);
 */
 
 octave_value
@@ -1405,7 +1483,9 @@
             param.modifier = 'r';
             param.parameter_length = 0;
 
-            int a = 0, b = -1, balance = 1;
+            int a = 0;
+            int b = -1;
+            int balance = 1;
             unsigned int items;
             size_t pos;
             std::string cmd;
@@ -2255,6 +2335,7 @@
         {
           symbol_table::clear_objects ();
           octave_class::clear_exemplar_map ();
+          symbol_table::clear_all ();
         }
       else
         {
@@ -2464,6 +2545,7 @@
                     {
                       symbol_table::clear_objects ();
                       octave_class::clear_exemplar_map ();
+                      symbol_table::clear_all ();
                     }
                   else
                     {
--- a/libinterp/corefcn/xdiv.cc	Fri Aug 01 09:06:21 2014 -0400
+++ b/libinterp/corefcn/xdiv.cc	Fri Aug 01 12:10:05 2014 -0400
@@ -713,7 +713,9 @@
   if (! mx_div_conform (a, d))
     return MT ();
 
-  octave_idx_type m = a.rows (), n = d.rows (), l = d.length ();
+  octave_idx_type m = a.rows ();
+  octave_idx_type n = d.rows ();
+  octave_idx_type l = d.length ();
   MT x (m, n);
   typedef typename DMT::element_type S;
   typedef typename MT::element_type T;
@@ -794,7 +796,10 @@
   if (! mx_leftdiv_conform (d, a, blas_no_trans))
     return MT ();
 
-  octave_idx_type m = d.cols (), n = a.cols (), k = a.rows (), l = d.length ();
+  octave_idx_type m = d.cols ();
+  octave_idx_type n = a.cols ();
+  octave_idx_type k = a.rows ();
+  octave_idx_type l = d.length ();
   MT x (m, n);
   typedef typename DMT::element_type S;
   typedef typename MT::element_type T;
@@ -871,8 +876,11 @@
   if (! mx_div_conform (a, d))
     return MT ();
 
-  octave_idx_type m = a.rows (), n = d.rows (), k = d.cols ();
-  octave_idx_type l = std::min (m, n), lk = std::min (l, k);
+  octave_idx_type m = a.rows ();
+  octave_idx_type n = d.rows ();
+  octave_idx_type k = d.cols ();
+  octave_idx_type l = std::min (m, n);
+  octave_idx_type lk = std::min (l, k);
   MT x (m, n);
   typedef typename DMT::element_type S;
   typedef typename MT::element_type T;
@@ -943,8 +951,11 @@
   if (! mx_leftdiv_conform (d, a, blas_no_trans))
     return MT ();
 
-  octave_idx_type m = d.cols (), n = a.cols (), k = d.rows ();
-  octave_idx_type l = std::min (m, n), lk = std::min (l, k);
+  octave_idx_type m = d.cols ();
+  octave_idx_type n = a.cols ();
+  octave_idx_type k = d.rows ();
+  octave_idx_type l = std::min (m, n);
+  octave_idx_type lk = std::min (l, k);
   MT x (m, n);
   typedef typename DMT::element_type S;
   typedef typename MT::element_type T;
--- a/libinterp/dldfcn/__delaunayn__.cc	Fri Aug 01 09:06:21 2014 -0400
+++ b/libinterp/dldfcn/__delaunayn__.cc	Fri Aug 01 12:10:05 2014 -0400
@@ -175,7 +175,8 @@
 
           facetT *facet;
           vertexT *vertex, **vertexp;
-          octave_idx_type nf = 0, i = 0;
+          octave_idx_type nf = 0;
+          octave_idx_type i = 0;
 
           FORALLfacets
             {
--- a/libinterp/dldfcn/__eigs__.cc	Fri Aug 01 09:06:21 2014 -0400
+++ b/libinterp/dldfcn/__eigs__.cc	Fri Aug 01 12:10:05 2014 -0400
@@ -211,7 +211,7 @@
         {
           std::string name = args(0).string_value ();
           std::string fname = "function y = ";
-          fcn_name = unique_symbol_name ("__eigs_fcn_");
+          fcn_name = unique_symbol_name ("__eigs_fcn__");
           fname.append (fcn_name);
           fname.append ("(x) y = ");
           eigs_fcn = extract_function (args(0), "eigs", fcn_name, fname,
--- a/libinterp/dldfcn/__init_fltk__.cc	Fri Aug 01 09:06:21 2014 -0400
+++ b/libinterp/dldfcn/__init_fltk__.cc	Fri Aug 01 12:10:05 2014 -0400
@@ -1,6 +1,7 @@
 /*
 
 Copyright (C) 2007-2013 Shai Ayal
+Copyright (C) 2014 Andreas Weber
 
 This file is part of Octave.
 
@@ -61,6 +62,7 @@
 #include <FL/Fl_Choice.H>
 #include <FL/Fl_File_Chooser.H>
 #include <FL/Fl_Gl_Window.H>
+#include <FL/names.h>
 #include <FL/Fl_Menu_Bar.H>
 #include <FL/Fl_Menu_Button.H>
 #include <FL/Fl_Output.H>
@@ -91,9 +93,6 @@
 
 #define FLTK_GRAPHICS_TOOLKIT_NAME "fltk"
 
-// Give FLTK no more than 0.01 sec to do its stuff.
-static double fltk_maxtime = 1e-2;
-
 const char* help_text = "\
 Keyboard Shortcuts\n\
 a - autoscale\n\
@@ -113,7 +112,7 @@
 public:
   OpenGL_fltk (int xx, int yy, int ww, int hh, double num)
     : Fl_Gl_Window (xx, yy, ww, hh, 0), number (num), renderer (),
-      in_zoom (false), zoom_box (),  print_mode (false)
+      in_zoom (false), zoom_box ()
   {
     // Ask for double buffering and a depth buffer.
     mode (FL_DEPTH | FL_DOUBLE | FL_MULTISAMPLE);
@@ -133,16 +132,21 @@
 
   void print (const std::string& cmd, const std::string& term)
   {
-    print_mode  = true;
-    print_cmd = cmd;
-    print_term  = term;
+    //std::cout << "OpenGL_fltk::print(cmd=" << cmd << ", term=" << term << ") canvas size = " << w () << "x" << h () << std::endl;
+#ifdef HAVE_GL2PS_H
+    FILE *fp;
+    fp = octave_popen (cmd.c_str (), "w");
+    glps_renderer rend (fp, term);
+    rend.draw (gh_manager::get_object (number), cmd);
+    octave_pclose (fp);
+#else
+    error ("fltk: printing not available without gl2ps library");
+#endif
   }
 
   void resize (int xx, int yy, int ww, int hh)
   {
     Fl_Gl_Window::resize (xx, yy, ww, hh);
-    setup_viewport (ww, hh);
-    redraw ();
   }
 
   bool renumber (double new_number)
@@ -165,48 +169,19 @@
   // (x1,y1,x2,y2)
   Matrix zoom_box;
 
-  bool print_mode;
-  std::string print_cmd;
-  std::string print_term;
-
-  void setup_viewport (int ww, int hh)
-  {
-    glMatrixMode (GL_PROJECTION);
-    glLoadIdentity ();
-    glViewport (0, 0, ww, hh);
-  }
-
   void draw (void)
   {
     if (! valid ())
       {
-        valid (1);
-        setup_viewport (w (), h ());
+        glMatrixMode (GL_PROJECTION);
+        glLoadIdentity ();
+        glViewport (0, 0, w (), h ());
       }
 
-    if (print_mode)
-      {
-#ifdef HAVE_GL2PS_H
-        FILE *fp = octave_popen (print_cmd.c_str (), "w");
-        glps_renderer rend (fp, print_term);
-
-        rend.draw (gh_manager::get_object (number), print_cmd);
+    renderer.draw (gh_manager::get_object (number));
 
-        octave_pclose (fp);
-        print_mode = false;
-#else
-        print_mode = false;
-        error ("fltk: printing not available without gl2ps library");
-        return;
-#endif
-      }
-    else
-      {
-        renderer.draw (gh_manager::get_object (number));
-
-        if (zoom ())
-          overlay ();
-      }
+    if (zoom ())
+      overlay ();
   }
 
   void zoom_box_vertex (void)
@@ -249,28 +224,20 @@
 
   int handle (int event)
   {
-    int retval = Fl_Gl_Window::handle (event);
-
     switch (event)
       {
       case FL_ENTER:
-        window ()->cursor (FL_CURSOR_CROSS);
+        cursor (FL_CURSOR_CROSS);
         return 1;
 
       case FL_LEAVE:
-        window ()->cursor (FL_CURSOR_DEFAULT);
+        cursor (FL_CURSOR_DEFAULT);
         return 1;
       }
-
-    return retval;
+    return Fl_Gl_Window::handle (event);
   }
 };
 
-// Parameter controlling how fast we zoom when using the scrool wheel.
-static double Vwheel_zoom_speed = 0.05;
-// Parameter controlling the GUI mode.
-static enum { pan_zoom, rotate_zoom, none } gui_mode;
-
 void script_cb (Fl_Widget*, void* data)
 {
   static_cast<uimenu::properties*> (data)->execute_callback ();
@@ -282,8 +249,7 @@
 public:
   fltk_uimenu (int xx, int yy, int ww, int hh)
   {
-    menubar = new
-    Fl_Menu_Bar (xx, yy, ww, hh);
+    menubar = new Fl_Menu_Bar (xx, yy, ww, hh);
   }
 
   int items_to_show (void)
@@ -291,7 +257,7 @@
     //returns the number of visible menu items
     int len = menubar->size ();
     int n = 0;
-    for (int t = 0; t < len; t++ )
+    for (int t = 0; t < len; t++)
       {
         const Fl_Menu_Item *m = static_cast<const Fl_Menu_Item*> (&
                                 (menubar->menu ()[t]));
@@ -305,11 +271,13 @@
   void show (void)
   {
     menubar->show ();
+    menubar->redraw ();
   }
 
   void hide (void)
   {
     menubar->hide ();
+    menubar->redraw ();
   }
 
   bool is_visible (void)
@@ -326,7 +294,7 @@
     // Kai Habel (14.10.2010)
 
     std::string menupath;
-    for (int t = 0; t < menubar->size (); t++ )
+    for (int t = 0; t < menubar->size (); t++)
       {
         Fl_Menu_Item *m = const_cast<Fl_Menu_Item*> (&(menubar->menu ()[t]));
         if (m->submenu ())
@@ -336,7 +304,7 @@
               menupath += "/";
             menupath += m->label ();
 
-            if (menupath.compare (findname) == 0 )
+            if (menupath.compare (findname) == 0)
               return (t);
           }
         else
@@ -692,13 +660,17 @@
   friend class fltk_uimenu;
 public:
   plot_window (int xx, int yy, int ww, int hh, figure::properties& xfp)
-    : Fl_Window (xx, yy - menu_h, ww, hh + menu_h + status_h, "octave"),
-      window_label (), shift (0), ndim (2), fp (xfp), canvas (0),
+    : Fl_Window (xx, yy, ww, hh + menu_h + status_h + 2, "octave"),
+      window_label (), shift (0), fp (xfp), canvas (0),
       autoscale (0), togglegrid (0), panzoom (0), rotate (0), help (0),
-      status (0), ax_obj (), pos_x (0), pos_y (0)
+      status (0), resize_dummy (0), ax_obj (), pos_x (0), pos_y (0)
   {
     callback (window_close, static_cast<void*> (this));
-    size_range (4*status_h, 2*status_h);
+
+    // The size of the resize_dummy box also determines the minimum window size
+    resize_dummy = new Fl_Box(5 * status_h + 1, menu_h + 1, ww - 5 * status_h - 1, hh);
+    // read on http://fltk.org/articles.php?L415+I0+T+M1000+P1 how resizable works
+    resizable (resize_dummy);
 
     // FIXME: The function below is only available in FLTK >= 1.3
     // At some point support for FLTK 1.1 will be dropped in Octave.
@@ -708,114 +680,79 @@
     // windows.  Otherwise, the class is just "FLTK"
     //default_xclass ("Octave");
 
-    begin ();
-    {
-      // bbox of plot canvas = [xx, yy, ww, hh];
-      // (xx, yy) = UL coordinate relative to UL window.
+    uimenu = new fltk_uimenu (0, 0, ww, menu_h);
+    canvas = new OpenGL_fltk (0, menu_h, ww, hh, number ());
 
-      canvas = new OpenGL_fltk (0, menu_h, ww, hh, number ());
+    // The bottom toolbar is a composite of "autoscale", "togglegrid",
+    // "panzoom", "rotate", "help", and "status". Only "status" should be resized.
 
-      uimenu = new fltk_uimenu (0, 0, ww, menu_h);
-      uimenu->hide ();
-
-      // Toolbar is a composite of "bottom", "autoscale", "togglegrid",
-      // "panzoom", "rotate", "help", and "status".
+    int toolbar_y = menu_h + hh + 1;
+    status = new Fl_Output (5 * status_h + 1, toolbar_y, ww - 5 * status_h - 1, status_h, "");
 
-      yy = hh + menu_h;
-      bottom = new Fl_Box (0, yy, ww, status_h);
-      bottom->box (FL_FLAT_BOX);
-
-      ndim = calc_dimensions (gh_manager::get_object (fp.get___myhandle__ ()));
-
-      autoscale = new Fl_Button (0, yy, status_h, status_h, "A");
-      autoscale->callback (button_callback, static_cast<void*> (this));
-      autoscale->tooltip ("Autoscale");
+    status->textcolor (FL_BLACK);
+    status->color (FL_GRAY);
+    status->textfont (FL_COURIER);
+    status->textsize (10);
+    status->box (FL_ENGRAVED_BOX);
 
-      togglegrid = new Fl_Button (status_h, yy, status_h,
-                                  status_h, "G");
-      togglegrid->callback (button_callback, static_cast<void*> (this));
-      togglegrid->tooltip ("Toggle Grid");
+    autoscale = new Fl_Button (0, toolbar_y, status_h, status_h, "A");
+    autoscale->callback (button_callback, static_cast<void*> (this));
+    autoscale->tooltip ("Autoscale");
 
-      panzoom = new Fl_Button (2 * status_h, yy, status_h,
-                               status_h, "P");
-      panzoom->callback (button_callback, static_cast<void*> (this));
-      panzoom->tooltip ("Mouse Pan/Zoom");
+    togglegrid = new Fl_Button (status_h, toolbar_y, status_h, status_h, "G");
+    togglegrid->callback (button_callback, static_cast<void*> (this));
+    togglegrid->tooltip ("Toggle Grid");
 
-      rotate = new Fl_Button (3 * status_h, yy, status_h,
-                              status_h, "R");
-      rotate->callback (button_callback, static_cast<void*> (this));
-      rotate->tooltip ("Mouse Rotate");
-
-      if (ndim == 2)
-        rotate->deactivate ();
+    panzoom = new Fl_Button (2* status_h, toolbar_y, status_h, status_h, "P");
+    panzoom->callback (button_callback, static_cast<void*> (this));
+    panzoom->tooltip ("Mouse Pan/Zoom");
 
-      help = new Fl_Button (4 * status_h, yy, status_h,
-                            status_h, "?");
-      help->callback (button_callback, static_cast<void*> (this));
-      help->tooltip ("Help");
+    rotate = new Fl_Button (3 * status_h, toolbar_y, status_h, status_h, "R");
+    rotate->callback (button_callback, static_cast<void*> (this));
+    rotate->tooltip ("Mouse Rotate");
 
-      status = new Fl_Output (5 * status_h, yy,
-                              ww > 2*status_h ? ww - status_h : 0,
-                              status_h, "");
+    help = new Fl_Button (4 * status_h, toolbar_y, status_h, status_h, "?");
+    help->callback (button_callback, static_cast<void*> (this));
+    help->tooltip ("Help");
 
-      status->textcolor (FL_BLACK);
-      status->color (FL_GRAY);
-      status->textfont (FL_COURIER);
-      status->textsize (10);
-      status->box (FL_ENGRAVED_BOX);
+    end ();
 
-      // This allows us to have a valid OpenGL context right away.
-      canvas->mode (FL_DEPTH | FL_DOUBLE | FL_MULTISAMPLE);
-      if (fp.is_visible ())
-        {
-          // FIXME: This code should be removed when Octave drops support
-          // for FLTK 1.1.  Search for default_xclass in this file to find
-          // code that should be uncommented to take its place.
-          //
-          // Set WM_CLASS which allows window managers to properly group
-          // related windows.  Otherwise, the class is just "FLTK"
-          xclass ("Octave");
+    if (fp.is_visible ())
+      {
+        // FIXME: This code should be removed when Octave drops support
+        // for FLTK 1.1.  Search for default_xclass in this file to find
+        // code that should be uncommented to take its place.
+        //
+        // Set WM_CLASS which allows window managers to properly group
+        // related windows.  Otherwise, the class is just "FLTK"
+        xclass ("Octave");
 
-          show ();
+        show ();
 
 #if defined (HAVE_X_WINDOWS)
-          std::string show_gui_msgs
-            = octave_env::getenv ("OCTAVE_SHOW_GUI_MESSAGES");
+        std::string show_gui_msgs
+          = octave_env::getenv ("OCTAVE_SHOW_GUI_MESSAGES");
 
-          // Installing our handler suppresses the messages.
-          if (show_gui_msgs.empty ())
-            XSetErrorHandler (xerror_handler);
+        // Installing our handler suppresses the messages.
+        if (show_gui_msgs.empty ())
+          XSetErrorHandler (xerror_handler);
 #endif
 
-          if (fp.get_currentaxes ().ok ())
-            show_canvas ();
-          else
-            hide_canvas ();
-        }
-    }
-    end ();
-
-    status->show ();
-    autoscale->show ();
-    togglegrid->show ();
-    panzoom->show ();
-    rotate->show ();
+        if (fp.get_currentaxes ().ok ())
+          show_canvas ();
+        else
+          hide_canvas ();
+      }
 
     set_name ();
-    resizable (canvas);
-    gui_mode = (ndim == 3 ? rotate_zoom : pan_zoom);
+
     uimenu->add_to_menu (fp);
-    if (uimenu->items_to_show ())
-      show_menubar ();
-    else
+    if (!uimenu->items_to_show ())
       hide_menubar ();
   }
 
   ~plot_window (void)
   {
-    canvas->hide ();
-    status->hide ();
-    uimenu->hide ();
     this->hide ();
   }
 
@@ -835,31 +772,18 @@
   void print (const std::string& cmd, const std::string& term)
   {
     canvas->print (cmd, term);
-
-    // Print immediately so the output file will exist when the drawnow
-    // command is done.
-    mark_modified ();
-    Fl::wait (fltk_maxtime);
   }
 
   void show_menubar (void)
   {
-    if (!uimenu->is_visible ())
-      {
-        // FIXME: Toolbar and menubar do not update
-        uimenu->show ();
-        mark_modified ();
-      }
+    uimenu->show ();
+    update_toolbar_position ();
   }
 
   void hide_menubar (void)
   {
-    if (uimenu->is_visible ())
-      {
-        // FIXME: Toolbar and menubar do not update
-        uimenu->hide ();
-        mark_modified ();
-      }
+    uimenu->hide ();
+    update_toolbar_position ();
   }
 
   void uimenu_update (const graphics_handle& gh, int id)
@@ -922,8 +846,6 @@
           show_menubar ();
         else
           hide_menubar ();
-
-        mark_modified ();
       }
   }
 
@@ -941,19 +863,40 @@
     canvas->hide ();
   }
 
+  // Move the toolbar at the bottom of the plot_window.
+  // The only reason for moving the toolbar is hiding and
+  // showing the menubar. All other resizing is done by fltk.
+
+  void update_toolbar_position ()
+  {
+    int old_canvas_h = canvas->h ();
+    size(w (), old_canvas_h + menu_dy () + status_h + 2);
+    canvas->resize (0, menu_dy (), w (), old_canvas_h);
+
+    int toolbar_y = canvas->h () + menu_dy () + 1;
+    autoscale->position (0, toolbar_y);
+    togglegrid->position (status_h, toolbar_y);
+    panzoom->position (2 * status_h, toolbar_y);
+    rotate->position (3 * status_h, toolbar_y);
+    help->position (4 * status_h, toolbar_y);
+    status->resize (5 * status_h + 1, toolbar_y, w () - 5 * status_h - 1, status_h);
+
+    init_sizes();
+    redraw ();
+  }
+
+  // Called from figure::properties::ID_POSITION
+  // (someone has requested a position change with set(h, "position", [...]))
+  // ww and hh refers to the canvas size, not the plot_window size.
+
+  void update_position (int xx, int yy, int ww, int hh)
+  {
+    Fl_Window::resize (xx, yy + menu_dy (), ww, hh + menu_dy () + status_h + 2);
+  }
+
   void mark_modified (void)
   {
-    damage (FL_DAMAGE_ALL);
-    canvas->damage (FL_DAMAGE_ALL);
-    ndim = calc_dimensions (gh_manager::get_object (fp.get___myhandle__ ()));
-
-    if (ndim == 3)
-      rotate->activate ();
-    else if (ndim == 2 && gui_mode == rotate_zoom)
-      {
-        rotate->deactivate ();
-        gui_mode = pan_zoom;
-      }
+    canvas->redraw ();
   }
 
   void set_name (void)
@@ -977,9 +920,6 @@
   // Mod keys status
   int shift;
 
-  // Number of dimensions, 2 or 3.
-  int ndim;
-
   // Figure properties.
   figure::properties& fp;
 
@@ -987,7 +927,7 @@
   static const int status_h = 20;
 
   // Menu height
-  static const int menu_h = 20;
+  static const int menu_h = 25;
 
   // Window callback.
   static void window_close (Fl_Widget*, void* data)
@@ -1007,40 +947,60 @@
   {
     if (widg == autoscale)
       axis_auto ();
-
-    if (widg == togglegrid)
+    else if (widg == togglegrid)
       toggle_grid ();
+    else if (widg == panzoom)
+      set_on_ax_obj ("pan", "on");
+    else if (widg == rotate)
+      set_on_ax_obj ("rotate3d", "on");
+    else if (widg == help)
+      fl_message ("%s", help_text);
+  }
 
-    if (widg == panzoom)
-      gui_mode = pan_zoom;
-
-    if (widg == rotate && ndim == 3)
-      gui_mode = rotate_zoom;
-
-    if (widg == help)
-      fl_message ("%s", help_text);
+  void set_on_ax_obj (const std::string& name, const std::string& value)
+  {
+    // ax_obj is the last clicked axes object
+    if (ax_obj && ax_obj.isa ("axes"))
+      {
+        axes::properties& ap = dynamic_cast<axes::properties&>(ax_obj.get_properties ());
+        ap.set (name, value);
+      }
+    else // no axes object clicked so far, take currentaxes
+      {
+        graphics_handle gh = fp.get_currentaxes ();
+        if (gh.ok ())
+          {
+            graphics_object go = gh_manager::get_object (gh);
+            axes::properties& ap = dynamic_cast<axes::properties&>(go.get_properties ());
+            ap.set (name, value);
+          }
+      }
   }
 
   fltk_uimenu* uimenu;
   OpenGL_fltk* canvas;
-  Fl_Box*    bottom;
   Fl_Button* autoscale;
   Fl_Button* togglegrid;
   Fl_Button* panzoom;
   Fl_Button* rotate;
   Fl_Button* help;
   Fl_Output* status;
+  Fl_Box* resize_dummy;
   graphics_object ax_obj;
   int pos_x;
   int pos_y;
 
+
   void axis_auto (void)
   {
     octave_value_list args;
-    args(0) = fp.get_currentaxes ().as_octave_value ();
-    args(1) = "auto";
-    feval ("axis", args);
-    mark_modified ();
+    if (fp.get_currentaxes ().ok ())
+      {
+        args(0) = fp.get_currentaxes ().as_octave_value ();
+        args(1) = "auto";
+        feval ("axis", args);
+        mark_modified ();
+      }
   }
 
   void toggle_grid (void)
@@ -1056,7 +1016,7 @@
   void pixel2pos (const graphics_handle& ax, int px, int py, double& xx,
                   double& yy) const
   {
-    pixel2pos ( gh_manager::get_object (ax), px, py, xx, yy);
+    pixel2pos (gh_manager::get_object (ax), px, py, xx, yy);
   }
 
   void pixel2pos (graphics_object ax, int px, int py, double& xx,
@@ -1072,7 +1032,7 @@
       }
   }
 
-  graphics_handle pixel2axes_or_ca (int px, int py )
+  graphics_handle pixel2axes_or_ca (int px, int py)
   {
     Matrix kids = fp.get_children ();
     int len = kids.length ();
@@ -1123,7 +1083,6 @@
       }
 
     status->value (cbuf.str ().c_str ());
-    status->redraw ();
   }
 
   void view2status (graphics_object ax)
@@ -1140,7 +1099,6 @@
         cbuf << "[azimuth: " << v(0) << ", elevation: " << v(1) << "]";
 
         status->value (cbuf.str ().c_str ());
-        status->redraw ();
       }
   }
 
@@ -1230,58 +1188,29 @@
     return Cell (mod);
   }
 
-  void resize (int xx,int yy,int ww,int hh)
+  void resize (int xx, int yy, int ww, int hh)
   {
     Fl_Window::resize (xx, yy, ww, hh);
 
     Matrix pos (1,4,0);
     pos(0) = xx;
     pos(1) = yy + menu_dy ();
-    pos(2) = ww;
-    pos(3) = hh - menu_dy () - status_h;
-
-    fp.set_boundingbox (pos, true);
-  }
+    pos(2) = canvas->w ();
+    pos(3) = canvas->h ();
 
-  void draw (void)
-  {
-    // FIXME: Toolbar and menubar do not update properly
-    Matrix pos = fp.get_boundingbox (true);
-    int canvas_h = pos(3);
-    int canvas_w = pos(2);
-    int canvas_y = menu_dy ();
-    int toolbar_y = menu_dy () + canvas_h;
-    pos(1) = pos(1) - menu_dy ();
-    pos(3) = pos(3) + menu_dy () + status_h;
-
-    Fl_Window::resize (pos(0), pos(1), pos(2), pos(3));
-
-    bottom->resize (0, toolbar_y, status_h, status_h);
-    autoscale->resize (0, toolbar_y, status_h, status_h);
-    togglegrid->resize (status_h, toolbar_y, status_h, status_h);
-    panzoom->resize (2 * status_h, toolbar_y, status_h, status_h);
-    rotate->resize (3 * status_h, toolbar_y, status_h, status_h);
-    help->resize (4 * status_h, toolbar_y, status_h, status_h);
-    status->resize (5 * status_h, toolbar_y, pos(2) - 4 * status_h, status_h);
-    if (canvas->valid ())
-      canvas->resize (0, canvas_y, canvas_w, canvas_h);
-
-    return Fl_Window::draw ();
+    fp.set_position (pos, false);
   }
 
   int handle (int event)
   {
-    graphics_handle gh;
+    if (event == FL_FOCUS)
+      return 1;
 
-    graphics_object fig = gh_manager::get_object (fp.get___myhandle__ ());
-    int retval = Fl_Window::handle (event);
-
-    // We only handle events which are in the canvas area.
-    if (!Fl::event_inside (canvas))
-      return retval;
+    graphics_handle gh;
 
     if (!fp.is_beingdeleted ())
       {
+        //std::cout << "plot_window::handle event = " <<  fl_eventnames[event] << std::endl;
         switch (event)
           {
           case FL_KEYDOWN:
@@ -1303,22 +1232,22 @@
                 case 'a':
                 case 'A':
                   axis_auto ();
-                  break;
+                  return 1;
 
                 case 'g':
                 case 'G':
                   toggle_grid ();
-                  break;
+                  return 1;
 
                 case 'p':
                 case 'P':
-                  gui_mode = pan_zoom;
-                  break;
+                  set_on_ax_obj ("pan", "on");
+                  return 1;
 
                 case 'r':
                 case 'R':
-                  gui_mode = rotate_zoom;
-                  break;
+                  set_on_ax_obj ("rotate3d", "on");
+                  return 1;
                 }
             }
             break;
@@ -1336,21 +1265,30 @@
                   evt.assign ("Key", octave_value (std::tolower (key_a)));
                   evt.assign ("Modifier", octave_value (modifier2cell ()));
                   fp.execute_keyreleasefcn (evt);
+                  return 1;
                 }
             }
             break;
+          }
 
+      // Events we only handle if they are in the canvas area.
+      if (Fl::event_inside (canvas))
+        switch (event)
+          {
           case FL_MOVE:
             pixel2status (pixel2axes_or_ca (Fl::event_x (),
                                             Fl::event_y () - menu_dy ()),
                           Fl::event_x (), Fl::event_y () - menu_dy ());
-            break;
+            return 1;
 
           case FL_PUSH:
             pos_x = Fl::event_x ();
             pos_y = Fl::event_y () - menu_dy ();
 
-            set_currentpoint (Fl::event_x (), Fl::event_y () - menu_dy ());
+            set_currentpoint (pos_x, pos_y);
+
+            if (fp.get_windowbuttonupfcn ().is_defined ())
+              fp.execute_windowbuttondownfcn (Fl::event_button());
 
             gh = pixel2axes_or_ca (pos_x, pos_y);
 
@@ -1358,12 +1296,18 @@
               {
                 ax_obj = gh_manager::get_object (gh);
                 set_axes_currentpoint (ax_obj, pos_x, pos_y);
-              }
+
+                int ndim = calc_dimensions (ax_obj);
 
-            fp.execute_windowbuttondownfcn (Fl::event_button());
+                if (ndim == 3)
+                  rotate->activate ();
+                else // ndim == 2
+                  rotate->deactivate ();
 
-            if (Fl::event_button () == 1 || Fl::event_button () == 3)
-              return 1;
+                fp.set_currentobject (ax_obj.get_handle ().value ());
+
+                return 1;
+              }
 
             break;
 
@@ -1378,32 +1322,48 @@
               {
                 if (ax_obj && ax_obj.isa ("axes"))
                   {
-                    if (gui_mode == pan_zoom)
-                      pixel2status (ax_obj, pos_x, pos_y,
-                                    Fl::event_x (),
-                                    Fl::event_y () - menu_dy ());
-                    else
-                      view2status (ax_obj);
                     axes::properties& ap =
                       dynamic_cast<axes::properties&>
                       (ax_obj.get_properties ());
 
-                    double x0, y0, x1, y1;
-                    Matrix pos = fp.get_boundingbox (true);
-                    pixel2pos (ax_obj, pos_x, pos_y, x0, y0);
-                    pixel2pos (ax_obj, Fl::event_x (),
-                                       Fl::event_y () - menu_dy (),
-                                       x1, y1);
+                    // Don't pan or rotate legend
+                    if (ap.get_tag().compare ("legend") < 0)
+                      {
+                        if (ap.rotate3d_is ("on"))
+                          view2status (ax_obj);
+                        else
+                          pixel2status (ax_obj, pos_x, pos_y,
+                                        Fl::event_x (),
+                                        Fl::event_y () - menu_dy ());
+
+                        double x0, y0, x1, y1;
+                        Matrix pos = fp.get_boundingbox (true);
+                        pixel2pos (ax_obj, pos_x, pos_y, x0, y0);
+                        pixel2pos (ax_obj, Fl::event_x (),
+                                           Fl::event_y () - menu_dy (),
+                                           x1, y1);
 
-                    if (gui_mode == pan_zoom)
-                      ap.translate_view (x0, x1, y0, y1);
-                    else if (gui_mode == rotate_zoom)
-                      {
-                        double daz, del;
-                        daz = (Fl::event_x () - pos_x) / pos(2) * 360;
-                        del = (Fl::event_y () - menu_dy () - pos_y)
-                              / pos(3) * 360;
-                        ap.rotate_view (del, daz);
+                        if (ap.pan_is ("on"))
+                          ap.translate_view (x0, x1, y0, y1);
+                        else if (ap.pan_is ("xon"))
+                          ap.translate_view (x0, x1, y1, y1);
+                        else if (ap.pan_is ("yon"))
+                          ap.translate_view (x1, x1, y0, y1);
+                        else if (ap.rotate3d_is ("on"))
+                          {
+                            double daz, del;
+                            daz = (Fl::event_x () - pos_x) / pos(2) * 360;
+                            del = (Fl::event_y () - menu_dy () - pos_y)
+                                  / pos(3) * 360;
+                            ap.rotate_view (del, daz);
+                          }
+                      }
+                    else
+                      {  // move the position of the legend
+                        Matrix pos = ap.get_position ().matrix_value ();
+                        pos(0) += double (Fl::event_x () - pos_x) / canvas->w();
+                        pos(1) -= double (Fl::event_y () - menu_dy () - pos_y) / canvas->h();
+                        ap.set_position (pos);
                       }
 
                     pos_x = Fl::event_x ();
@@ -1423,7 +1383,8 @@
                 zoom_box (3) =  Fl::event_y () - menu_dy ();
                 canvas->set_zoom_box (zoom_box);
                 canvas->zoom (true);
-                canvas->redraw ();
+                mark_modified ();
+                return 1;
               }
 
             break;
@@ -1439,6 +1400,9 @@
                   axes::properties& ap =
                     dynamic_cast<axes::properties&> (ax.get_properties ());
 
+                  // Parameter controlling how fast we zoom when using the scrool wheel.
+                  double Vwheel_zoom_speed = ap.get_mouse_wheel_zoom ();
+
                   // Determine if we're zooming in or out.
                   const double factor =
                     (Fl::event_dy () > 0) ? 1 / (1.0 - Vwheel_zoom_speed)
@@ -1451,9 +1415,9 @@
 
                   ap.zoom_about_point (x1, y1, factor, false);
                   mark_modified ();
+                  return 1;
                 }
             }
-            return 1;
 
           case FL_RELEASE:
             if (fp.get_windowbuttonupfcn ().is_defined ())
@@ -1462,20 +1426,12 @@
                 fp.execute_windowbuttonupfcn ();
               }
 
-            if (Fl::event_button () == 1)
+            if ((Fl::event_button () == 1) && Fl::event_clicks ()) //double click
               {
-                if ( Fl::event_clicks () == 1)
-                  {
-                    if (ax_obj && ax_obj.isa ("axes"))
-                      {
-                        axes::properties& ap = dynamic_cast<axes::properties&>
-                                               (ax_obj.get_properties ());
-                        ap.set_xlimmode ("auto");
-                        ap.set_ylimmode ("auto");
-                        ap.set_zlimmode ("auto");
-                        mark_modified ();
-                      }
-                  }
+                set_on_ax_obj ("xlimmode", "auto");
+                set_on_ax_obj ("ylimmode", "auto");
+                set_on_ax_obj ("zlimmode", "auto");
+                return 1;
               }
             if (Fl::event_button () == 3)
               {
@@ -1522,14 +1478,15 @@
                             ap.zoom (xl, yl);
                           }
                         mark_modified ();
+                        return 1;
                       }
                   }
               }
             break;
           }
       }
-
-    return retval;
+    //std::cout << "plot_window::handle wasn't interested in event " <<  fl_eventnames[event] << std::endl;
+    return Fl_Window::handle (event);
   }
 };
 
@@ -1653,16 +1610,18 @@
       instance->do_update_canvas (hnd2idx (gh), ca);
   }
 
-  static void toggle_menubar_visibility (int fig_idx, bool menubar_is_figure)
+  static void update_position (const std::string& fig_idx_str,
+                               const Matrix pos)
   {
     if (instance_ok ())
-      instance->do_toggle_menubar_visibility (fig_idx, menubar_is_figure);
+      instance->do_update_position (str2idx (fig_idx_str), pos);
   }
 
   static void toggle_menubar_visibility (const std::string& fig_idx_str,
                                          bool menubar_is_figure)
   {
-    toggle_menubar_visibility (str2idx (fig_idx_str), menubar_is_figure);
+    if (instance_ok ())
+      instance->do_toggle_menubar_visibility (str2idx (fig_idx_str), menubar_is_figure);
   }
 
 private:
@@ -1765,7 +1724,9 @@
     wm_iterator win = windows.find (idx);
 
     if (win != windows.end ())
-      win->second->mark_modified ();
+      {
+        win->second->mark_modified ();
+      }
   }
 
   void do_set_name (int idx)
@@ -1820,6 +1781,14 @@
       }
   }
 
+  void do_update_position (int idx, Matrix pos)
+  {
+    wm_iterator win = windows.find (idx);
+
+    if (win != windows.end ())
+      win->second->update_position (pos(0), pos(1), pos(2), pos(3));
+  }
+
   static int str2idx (const caseless_str& clstr)
   {
     int ind;
@@ -1905,9 +1874,6 @@
                 }
             }
         }
-
-      // it seems that we have to call Fl::check twice to get everything drawn
-      Fl::check ();
       Fl::check ();
     }
 
@@ -2014,6 +1980,14 @@
                   figure_manager::set_name (tmp);
                 }
                 break;
+
+              case figure::properties::ID_POSITION:
+                {
+                  std::string tmp = ov.string_value ();
+                  Matrix pos = fp.get_position ().matrix_value ();
+                  figure_manager::update_position (tmp, pos);
+                }
+                break;
               }
           }
       }
@@ -2030,8 +2004,6 @@
   void redraw_figure (const graphics_object& go) const
   {
     figure_manager::mark_modified (go.get_handle ());
-
-    __fltk_redraw__ ();
   }
 
   void print_figure (const graphics_object& go,
@@ -2040,7 +2012,6 @@
                      const std::string& /*debug_file*/) const
   {
     figure_manager::print (go.get_handle (), file_cmd, term);
-    redraw_figure (go);
   }
 
   Matrix get_canvas_size (const graphics_handle& fh) const
@@ -2048,11 +2019,16 @@
     return figure_manager::get_size (fh);
   }
 
+/*
   double get_screen_resolution (void) const
   {
     // FLTK doesn't give this info.
     return 72.0;
+
+    // FIXME: FLTK >= 1.3.0 could do this with  Fl::screen_dpi (h, v, n)
+    // but do we need it?
   }
+*/
 
   Matrix get_screen_size (void) const
   {
@@ -2068,16 +2044,12 @@
       {
         munlock ("__init_fltk__");
 
-        figure_manager::close_all ();
-
         octave_value_list args = input_event_hook_fcn_id;
         args.append (false);
         Fremove_input_event_hook (args, 0);
-
         input_event_hook_fcn_id = octave_value_list ();
 
-        // FIXME: ???
-        Fl::wait (fltk_maxtime);
+        figure_manager::close_all ();
       }
   }
 
@@ -2140,31 +2112,6 @@
   return octave_value ();
 }
 
-DEFUN_DLD (__fltk_maxtime__, args, ,
-           "-*- texinfo -*-\n\
-@deftypefn  {Loadable Function} {@var{maxtime} =} __fltk_maxtime__ ()\n\
-@deftypefnx {Loadable Function} {} __fltk_maxtime__ (@var{maxtime})\n\
-Undocumented internal function.\n\
-@end deftypefn")
-{
-#ifdef HAVE_FLTK
-  octave_value retval = fltk_maxtime;
-
-  if (args.length () == 1)
-    {
-      if (args(0).is_real_scalar ())
-        fltk_maxtime = args(0).double_value ();
-      else
-        error ("argument must be a real scalar");
-    }
-
-  return retval;
-#else
-  error ("__fltk_maxtime__: not available without OpenGL and FLTK libraries");
-  return octave_value ();
-#endif
-}
-
 DEFUN_DLD (__have_fltk__, , ,
            "-*- texinfo -*-\n\
 @deftypefn {Loadable Function} {@var{FLTK_available} =} __have_fltk__ ()\n\
@@ -2181,101 +2128,3 @@
 
   return retval;
 }
-
-// FIXME: This function should be abstracted and made potentially
-// available to all graphics toolkits.  This suggests putting it in
-// graphics.cc as is done for drawnow() and having the master
-// mouse_wheel_zoom function call fltk_mouse_wheel_zoom.  The same
-// should be done for gui_mode and fltk_gui_mode.  For now (2011.01.30),
-// just changing function names and docstrings.
-
-DEFUN_DLD (mouse_wheel_zoom, args, nargout,
-           "-*- texinfo -*-\n\
-@deftypefn  {Loadable Function} {@var{val} =} mouse_wheel_zoom ()\n\
-@deftypefnx {Loadable Function} {@var{old_val} =} mouse_wheel_zoom (@var{new_val})\n\
-@deftypefnx {Loadable Function} {} mouse_wheel_zoom (@var{new_val}, \"local\")\n\
-Query or set the mouse wheel zoom factor.\n\
-\n\
-The zoom factor is a number in the range (0,1) which is the percentage of the\n\
-current axis limits that will be used when zooming.  For example, if the\n\
-current x-axis limits are [0, 50] and @code{mouse_wheel_zoom} is 0.4 (40%),\n\
-then a zoom operation will change the limits by 20.\n\
-\n\
-When called from inside a function with the @qcode{\"local\"} option, the\n\
-variable is changed locally for the function and any subroutines it calls.  \n\
-The original variable value is restored when exiting the function.\n\
-\n\
-This function is currently implemented only for the FLTK graphics toolkit.\n\
-@seealso{gui_mode}\n\
-@end deftypefn")
-{
-#ifdef HAVE_FLTK
-  return SET_INTERNAL_VARIABLE_WITH_LIMITS(wheel_zoom_speed, 0.0001, 0.9999);
-#else
-  error ("mouse_wheel_zoom: not available without OpenGL and FLTK libraries");
-  return octave_value ();
-#endif
-}
-
-DEFUN_DLD (gui_mode, args, ,
-           "-*- texinfo -*-\n\
-@deftypefn  {Built-in Function} {@var{mode} =} gui_mode ()\n\
-@deftypefnx {Built-in Function} {} gui_mode (@var{mode})\n\
-Query or set the GUI mode for the current graphics toolkit.\n\
-The @var{mode} argument can be one of the following strings:\n\
-\n\
-@table @asis\n\
-@item @qcode{\"2d\"}\n\
-Allows panning and zooming of current axes.\n\
-\n\
-@item @qcode{\"3d\"}\n\
-Allows rotating and zooming of current axes.\n\
-\n\
-@item @qcode{\"none\"}\n\
-Mouse inputs have no effect.\n\
-@end table\n\
-\n\
-This function is currently implemented only for the FLTK graphics toolkit.\n\
-@seealso{mouse_wheel_zoom}\n\
-@end deftypefn")
-{
-#ifdef HAVE_FLTK
-  caseless_str mode_str;
-
-  if (gui_mode == pan_zoom)
-    mode_str = "2d";
-  else if (gui_mode == rotate_zoom)
-    mode_str = "3d";
-  else
-    mode_str = "none";
-
-  bool failed = false;
-
-  if (args.length () == 1)
-    {
-      if (args(0).is_string ())
-        {
-          mode_str = args(0).string_value ();
-
-          if (mode_str.compare ("2d"))
-            gui_mode = pan_zoom;
-          else if (mode_str.compare ("3d"))
-            gui_mode = rotate_zoom;
-          else if (mode_str.compare ("none"))
-            gui_mode = none;
-          else
-            failed = true;
-        }
-      else
-        failed = true;
-    }
-
-  if (failed)
-    error ("MODE must be one of the strings: \"2D\", \"3D\", or \"none\"");
-
-  return octave_value (mode_str);
-#else
-  error ("gui_mode: not available without OpenGL and FLTK libraries");
-  return octave_value ();
-#endif
-}
--- a/libinterp/dldfcn/amd.cc	Fri Aug 01 09:06:21 2014 -0400
+++ b/libinterp/dldfcn/amd.cc	Fri Aug 01 12:10:05 2014 -0400
@@ -67,8 +67,8 @@
 @table @asis\n\
 @item @var{opts}.dense\n\
 Determines what @code{amd} considers to be a dense row or column of the\n\
-input matrix.  Rows or columns with more than @code{max(16, (dense *\n\
-sqrt (@var{n})} entries, where @var{n} is the order of the matrix @var{S},\n\
+input matrix.  Rows or columns with more than @code{max (16, (dense *\n\
+sqrt (@var{n})))} entries, where @var{n} is the order of the matrix @var{S},\n\
 are ignored by @code{amd} during the calculation of the permutation\n\
 The value of dense must be a positive scalar and its default value is 10.0\n\
 \n\
--- a/libinterp/dldfcn/ccolamd.cc	Fri Aug 01 09:06:21 2014 -0400
+++ b/libinterp/dldfcn/ccolamd.cc	Fri Aug 01 12:10:05 2014 -0400
@@ -100,10 +100,9 @@
 @var{cmember} is an optional vector of length @math{n}.  It defines the\n\
 constraints on the column ordering.  If @code{@var{cmember}(j) = @var{c}},\n\
 then column @var{j} is in constraint set @var{c} (@var{c} must be in the\n\
-range 1 to\n\
-n).  In the output permutation @var{p}, all columns in set 1 appear\n\
-first, followed by all columns in set 2, and so on.  @code{@var{cmember} =\n\
-ones (1,n)} if not present or empty.\n\
+range 1 to n).  In the output permutation @var{p}, all columns in set 1\n\
+appear first, followed by all columns in set 2, and so on.\n\
+@code{@var{cmember} = ones (1,n)} if not present or empty.\n\
 @code{ccolamd (@var{S}, [], 1 : n)} returns @code{1 : n}\n\
 \n\
 @code{@var{p} = ccolamd (@var{S})} is about the same as\n\
--- a/libinterp/dldfcn/chol.cc	Fri Aug 01 09:06:21 2014 -0400
+++ b/libinterp/dldfcn/chol.cc	Fri Aug 01 12:10:05 2014 -0400
@@ -155,7 +155,7 @@
     {
       std::string tmp = args(n++).string_value ();
 
-      if (! error_state )
+      if (! error_state)
         {
           if (tmp.compare ("vector") == 0)
             vecout = true;
--- a/libinterp/dldfcn/fftw.cc	Fri Aug 01 09:06:21 2014 -0400
+++ b/libinterp/dldfcn/fftw.cc	Fri Aug 01 12:10:05 2014 -0400
@@ -303,7 +303,7 @@
                   if (args(1).is_real_scalar ())
                     {
                       int nthreads = args(1).int_value();
-                      if ( nthreads >= 1)
+                      if (nthreads >= 1)
                         {
 #if defined (HAVE_FFTW3_THREADS)
                           octave_fftw_planner::threads (nthreads);
--- a/libinterp/dldfcn/qr.cc	Fri Aug 01 09:06:21 2014 -0400
+++ b/libinterp/dldfcn/qr.cc	Fri Aug 01 12:10:05 2014 -0400
@@ -744,7 +744,9 @@
 bool check_qr_dims (const octave_value& q, const octave_value& r,
                     bool allow_ecf = false)
 {
-  octave_idx_type m = q.rows (), k = r.rows (), n = r.columns ();
+  octave_idx_type m = q.rows ();
+  octave_idx_type k = r.rows ();
+  octave_idx_type n = r.columns ();
   return ((q.ndims () == 2 && r.ndims () == 2 && k == q.columns ())
           && (m == k || (allow_ecf && k == n && k < m)));
 }
--- a/libinterp/dldfcn/symrcm.cc	Fri Aug 01 09:06:21 2014 -0400
+++ b/libinterp/dldfcn/symrcm.cc	Fri Aug 01 12:10:05 2014 -0400
@@ -322,7 +322,7 @@
   return x.id;
 }
 
-// Calculates the node's degrees. This means counting the non-zero elements
+// Calculates the node's degrees. This means counting the nonzero elements
 // in the symmetric matrix' rows. This works for non-symmetric matrices
 // as well.
 
@@ -341,7 +341,7 @@
         {
           OCTAVE_QUIT;
           octave_idx_type k = ridx[i];
-          // there is a non-zero element (k,j)
+          // there is a nonzero element (k,j)
           D[k]++;
           if (D[k] > max_deg)
             max_deg = D[k];
@@ -487,7 +487,8 @@
   octave_idx_type s = 0;
 
   // head- and tail-indices for the queue
-  octave_idx_type qt = 0, qh = 0;
+  octave_idx_type qt = 0;
+  octave_idx_type qh = 0;
   CMK_Node v, w;
   // dimension of the matrix
   octave_idx_type N = nr;
--- a/libinterp/dldfcn/tsearch.cc	Fri Aug 01 09:06:21 2014 -0400
+++ b/libinterp/dldfcn/tsearch.cc	Fri Aug 01 12:10:05 2014 -0400
@@ -110,8 +110,10 @@
   const octave_idx_type np = xi.length ();
   ColumnVector values (np);
 
-  double x0 = 0.0, y0 = 0.0;
-  double a11 = 0.0, a12 = 0.0, a21 = 0.0, a22 = 0.0, det = 0.0;
+  double x0, y0, a11, a12, a21, a22, det;
+  x0 = y0 = 0.0;
+  a11 = a12 = a21 = a22 = 0.0;
+  det = 0.0;
 
   octave_idx_type k = nelem; // k is a counter of elements
   for (octave_idx_type kp = 0; kp < np; kp++)
--- a/libinterp/genprops.awk	Fri Aug 01 09:06:21 2014 -0400
+++ b/libinterp/genprops.awk	Fri Aug 01 12:10:05 2014 -0400
@@ -290,7 +290,7 @@
   if (class_name && ! base)
     emit_common_declarations();
 
-  printf ("public:\n\n\n  static std::set<std::string> core_property_names (void);\n\n  static bool has_core_property (const caseless_str& pname);\n\n  std::set<std::string> all_property_names (void) const;\n\n");
+  printf ("public:\n\n\n  static std::set<std::string> core_property_names (void);\n\n  static std::set<std::string> readonly_property_names (void);\n\n  static bool has_core_property (const caseless_str& pname);\n\n  static bool has_readonly_property (const caseless_str& pname);\n\n  std::set<std::string> all_property_names (void) const;\n\n");
 
   if (! base)
     printf ("  bool has_property (const caseless_str& pname) const;\n\n");
@@ -470,7 +470,7 @@
               class_name);
 
     if (! base)
-      printf ("  const std::set<std::string>& pnames = all_property_names ();\n\n  caseless_str pname = validate_property_name (\"get\", go_name, pnames, pname_arg);\n\n  if (error_state)\n    return;\n\n");
+        printf ("  const std::set<std::string>& pnames = all_property_names ();\n\n  caseless_str pname = validate_property_name (\"get\", go_name, pnames, pname_arg);\n\n  if (error_state)\n    return;\n  else if (has_readonly_property (pname))\n    {\n      error (\"set: \\\"%%s\\\" is read-only\", pname.c_str ());\n      return;\n    }\n\n");
 
     first = 1;
 
@@ -611,6 +611,7 @@
       printf ("std::string %s::properties::go_name (\"%s\");\n\n",
               class_name, object_name);
 
+    ## core_property_names
     printf ("std::set<std::string>\n");
     if (base)
       printf ("base_properties");
@@ -622,7 +623,7 @@
     if (! base)
       printf ("\n      std::set<std::string> base_pnames = base_properties::core_property_names ();\n      all_pnames.insert (base_pnames.begin (), base_pnames.end ());\n");
     printf ("\n      initialized = true;\n    }\n\n  return all_pnames;\n}\n\n");
-
+    ## has_core_property
     printf ("bool\n");
     if (base)
       printf ("base_properties");
@@ -630,6 +631,30 @@
       printf ("%s::properties", class_name);
     printf ("::has_core_property (const caseless_str& pname)\n{\n  std::set<std::string> pnames = core_property_names ();\n\n  return pnames.find (pname) != pnames.end ();\n}\n\n", class_name);
 
+    ## readonly_property_names
+    printf ("std::set<std::string>\n");
+    if (base)
+      printf ("base_properties");
+    else
+      printf ("%s::properties", class_name);
+    printf ("::readonly_property_names (void)\n{\n  static std::set<std::string> all_pnames;\n\n  static bool initialized = false;\n\n  if (! initialized)\n    {\n");
+    for (i = 1; i <= idx; i++)
+        if (readonly[i])
+        {
+            printf ("      all_pnames.insert (\"%s\");\n", name[i]);
+        }
+    if (! base)
+      printf ("\n      std::set<std::string> base_pnames = base_properties::readonly_property_names ();\n      all_pnames.insert (base_pnames.begin (), base_pnames.end ());\n");
+    printf ("\n      initialized = true;\n    }\n\n  return all_pnames;\n}\n\n");
+    ## has_readonly_property
+    printf ("bool\n");
+    if (base)
+      printf ("base_properties");
+    else
+      printf ("%s::properties", class_name);
+    printf ("::has_readonly_property (const caseless_str& pname)\n{\n  std::set<std::string> pnames = readonly_property_names ();\n\n  return pnames.find (pname) != pnames.end ();\n}\n\n", class_name);
+
+    ## all_property_names
     printf ("std::set<std::string>\n");
     if (base)
         printf ("base_properties");
--- a/libinterp/octave-value/module.mk	Fri Aug 01 09:06:21 2014 -0400
+++ b/libinterp/octave-value/module.mk	Fri Aug 01 12:10:05 2014 -0400
@@ -36,6 +36,7 @@
   octave-value/ov-cell.h \
   octave-value/ov-ch-mat.h \
   octave-value/ov-class.h \
+  octave-value/ov-classdef.h \
   octave-value/ov-colon.h \
   octave-value/ov-complex.h \
   octave-value/ov-cs-list.h \
@@ -94,6 +95,7 @@
   octave-value/ov-cell.cc \
   octave-value/ov-ch-mat.cc \
   octave-value/ov-class.cc \
+  octave-value/ov-classdef.cc \
   octave-value/ov-colon.cc \
   octave-value/ov-complex.cc \
   octave-value/ov-cs-list.cc \
--- a/libinterp/octave-value/ov-base-diag.cc	Fri Aug 01 09:06:21 2014 -0400
+++ b/libinterp/octave-value/ov-base-diag.cc	Fri Aug 01 12:10:05 2014 -0400
@@ -100,7 +100,6 @@
                                         bool resize_ok)
 {
   octave_value retval;
-  typedef typename DMT::element_type el_type;
 
   if (idx.length () == 2 && ! resize_ok)
     {
@@ -441,7 +440,8 @@
 bool
 octave_base_diag<DMT, MT>::load_ascii (std::istream& is)
 {
-  octave_idx_type r = 0, c = 0;
+  octave_idx_type r = 0;
+  octave_idx_type c = 0;
   bool success = true;
 
   if (extract_keyword (is, "rows", r, true)
@@ -505,8 +505,7 @@
 
 template <class DMT, class MT>
 void
-octave_base_diag<DMT, MT>::print (std::ostream& os,
-                                  bool pr_as_read_syntax) const
+octave_base_diag<DMT, MT>::print (std::ostream& os, bool pr_as_read_syntax)
 {
   print_raw (os, pr_as_read_syntax);
   newline (os);
@@ -531,6 +530,23 @@
 
 template <class DMT, class MT>
 octave_value
+octave_base_diag<DMT, MT>::fast_elem_extract (octave_idx_type n) const
+{
+  if (n < matrix.numel ())
+    {
+      octave_idx_type nr = matrix.rows ();
+
+      octave_idx_type r = n % nr;
+      octave_idx_type c = n / nr;
+
+      return octave_value (matrix.elem (r, c));
+    }
+  else
+    return octave_value ();
+}
+
+template <class DMT, class MT>
+octave_value
 octave_base_diag<DMT, MT>::to_dense (void) const
 {
   if (! dense_cache.is_defined ())
--- a/libinterp/octave-value/ov-base-diag.h	Fri Aug 01 09:06:21 2014 -0400
+++ b/libinterp/octave-value/ov-base-diag.h	Fri Aug 01 12:10:05 2014 -0400
@@ -203,10 +203,12 @@
 
   bool print_as_scalar (void) const;
 
-  void print (std::ostream& os, bool pr_as_read_syntax = false) const;
+  void print (std::ostream& os, bool pr_as_read_syntax = false);
 
   void print_info (std::ostream& os, const std::string& prefix) const;
 
+  octave_value fast_elem_extract (octave_idx_type n) const;
+
 protected:
 
   DMT matrix;
--- a/libinterp/octave-value/ov-base-int.cc	Fri Aug 01 09:06:21 2014 -0400
+++ b/libinterp/octave-value/ov-base-int.cc	Fri Aug 01 12:10:05 2014 -0400
@@ -266,7 +266,7 @@
 template <class T>
 bool
 octave_base_int_matrix<T>::load_binary (std::istream& is, bool swap,
-                                        oct_mach_info::float_format )
+                                        oct_mach_info::float_format)
 {
   int32_t mdims;
   if (! is.read (reinterpret_cast<char *> (&mdims), 4))
@@ -347,7 +347,8 @@
     return (empty > 0);
 
   int rank = dv.length ();
-  hid_t space_hid = -1, data_hid = -1;
+  hid_t space_hid, data_hid;
+  space_hid = data_hid = -1;
   OCTAVE_LOCAL_BUFFER (hsize_t, hdims, rank);
 
   // Octave uses column-major, while HDF5 uses row-major ordering
@@ -550,7 +551,8 @@
   hid_t save_type_hid = HDF5_SAVE_TYPE;
   bool retval = true;
   hsize_t dimens[3];
-  hid_t space_hid = -1, data_hid = -1;
+  hid_t space_hid, data_hid;
+  space_hid = data_hid = -1;
 
   space_hid = H5Screate_simple (0, dimens, 0);
   if (space_hid < 0) return false;
--- a/libinterp/octave-value/ov-base-int.h	Fri Aug 01 09:06:21 2014 -0400
+++ b/libinterp/octave-value/ov-base-int.h	Fri Aug 01 12:10:05 2014 -0400
@@ -74,10 +74,10 @@
 
   bool load_ascii (std::istream& is);
 
-  bool save_binary (std::ostream& os, bool& );
+  bool save_binary (std::ostream& os, bool&);
 
   bool load_binary (std::istream& is, bool swap,
-                    oct_mach_info::float_format );
+                    oct_mach_info::float_format);
 
 #if defined (HAVE_HDF5)
   bool save_hdf5 (hid_t loc_id, const char *name, bool);
@@ -119,13 +119,13 @@
 
   bool load_ascii (std::istream& is);
 
-  bool save_binary (std::ostream& os, bool& );
+  bool save_binary (std::ostream& os, bool&);
 
   bool load_binary (std::istream& is, bool swap,
-                    oct_mach_info::float_format );
+                    oct_mach_info::float_format);
 
 #if defined (HAVE_HDF5)
-  bool save_hdf5 (hid_t loc_id, const char *name, bool );
+  bool save_hdf5 (hid_t loc_id, const char *name, bool);
 
   bool load_hdf5 (hid_t loc_id, const char *name);
 #endif
--- a/libinterp/octave-value/ov-base-mat.cc	Fri Aug 01 09:06:21 2014 -0400
+++ b/libinterp/octave-value/ov-base-mat.cc	Fri Aug 01 12:10:05 2014 -0400
@@ -351,7 +351,8 @@
               {
                 // optimize all scalar indices. Don't construct an index array,
                 // but rather calc a scalar index directly.
-                octave_idx_type k = 1, j = 0;
+                octave_idx_type k = 1;
+                octave_idx_type j = 0;
                 for (octave_idx_type i = 0; i < n_idx; i++)
                   {
                     j += idx_vec(i)(0) * k;
@@ -435,7 +436,7 @@
 
 template <class MT>
 void
-octave_base_matrix<MT>::print (std::ostream& os, bool pr_as_read_syntax) const
+octave_base_matrix<MT>::print (std::ostream& os, bool pr_as_read_syntax)
 {
   print_raw (os, pr_as_read_syntax);
   newline (os);
--- a/libinterp/octave-value/ov-base-mat.h	Fri Aug 01 09:06:21 2014 -0400
+++ b/libinterp/octave-value/ov-base-mat.h	Fri Aug 01 12:10:05 2014 -0400
@@ -153,7 +153,7 @@
 
   bool print_as_scalar (void) const;
 
-  void print (std::ostream& os, bool pr_as_read_syntax = false) const;
+  void print (std::ostream& os, bool pr_as_read_syntax = false);
 
   void print_info (std::ostream& os, const std::string& prefix) const;
 
--- a/libinterp/octave-value/ov-base-scalar.cc	Fri Aug 01 09:06:21 2014 -0400
+++ b/libinterp/octave-value/ov-base-scalar.cc	Fri Aug 01 12:10:05 2014 -0400
@@ -143,7 +143,7 @@
 
 template <class ST>
 void
-octave_base_scalar<ST>::print (std::ostream& os, bool pr_as_read_syntax) const
+octave_base_scalar<ST>::print (std::ostream& os, bool pr_as_read_syntax)
 {
   print_raw (os, pr_as_read_syntax);
   newline (os);
@@ -180,6 +180,13 @@
 }
 
 template <class ST>
+octave_value
+octave_base_scalar<ST>::fast_elem_extract (octave_idx_type n) const
+{
+  return (n == 0) ? octave_value (scalar) : octave_value ();
+}
+
+template <class ST>
 bool
 octave_base_scalar<ST>::fast_elem_insert_self (void *where,
                                                builtin_type_t btyp) const
--- a/libinterp/octave-value/ov-base-scalar.h	Fri Aug 01 09:06:21 2014 -0400
+++ b/libinterp/octave-value/ov-base-scalar.h	Fri Aug 01 12:10:05 2014 -0400
@@ -132,7 +132,7 @@
 
   bool is_true (void) const;
 
-  void print (std::ostream& os, bool pr_as_read_syntax = false) const;
+  void print (std::ostream& os, bool pr_as_read_syntax = false);
 
   void print_raw (std::ostream& os, bool pr_as_read_syntax = false) const;
 
@@ -148,6 +148,8 @@
 
   ST& scalar_ref (void) { return scalar; }
 
+  octave_value fast_elem_extract (octave_idx_type n) const;
+
   bool fast_elem_insert_self (void *where, builtin_type_t btyp) const;
 
 protected:
--- a/libinterp/octave-value/ov-base-sparse.cc	Fri Aug 01 09:06:21 2014 -0400
+++ b/libinterp/octave-value/ov-base-sparse.cc	Fri Aug 01 12:10:05 2014 -0400
@@ -288,7 +288,7 @@
 
 template <class T>
 void
-octave_base_sparse<T>::print (std::ostream& os, bool pr_as_read_syntax) const
+octave_base_sparse<T>::print (std::ostream& os, bool pr_as_read_syntax)
 {
   print_raw (os, pr_as_read_syntax);
   newline (os);
@@ -436,31 +436,73 @@
   return success;
 }
 
+
+template <class T>
+octave_value
+octave_base_sparse<T>::fast_elem_extract (octave_idx_type n) const
+{
+  octave_idx_type nr = matrix.rows ();
+  octave_idx_type nc = matrix.cols ();
+
+  octave_idx_type i = n % nr;
+  octave_idx_type j = n / nr;
+
+  return (i < nr && j < nc) ? octave_value (matrix(i,j)) : octave_value ();
+}
+
 template <class T>
 octave_value
 octave_base_sparse<T>::map (octave_base_value::unary_mapper_t umap) const
 {
+  if (umap == umap_xtolower || umap == umap_xtoupper)
+    return matrix;
+
   // Try the map on the dense value.
+  // FIXME: We should probably be smarter about this, especially for the
+  // cases that are expected to return sparse matrices.
   octave_value retval = this->full_value ().map (umap);
 
   // Sparsify the result if possible.
-  // FIXME: intentionally skip this step for string mappers. Is this wanted?
-  if (umap >= umap_xisalnum && umap <= umap_xtoupper)
-    return retval;
 
-  switch (retval.builtin_type ())
+  switch (umap)
     {
-    case btyp_double:
-      retval = retval.sparse_matrix_value ();
+    case umap_xisalnum:
+    case umap_xisalpha:
+    case umap_xisascii:
+    case umap_xiscntrl:
+    case umap_xisdigit:
+    case umap_xisgraph:
+    case umap_xislower:
+    case umap_xisprint:
+    case umap_xispunct:
+    case umap_xisspace:
+    case umap_xisupper:
+    case umap_xisxdigit:
+    case umap_xtoascii:
+      // FIXME: intentionally skip this step for string mappers.
+      // Is this wanted?
       break;
-    case btyp_complex:
-      retval = retval.sparse_complex_matrix_value ();
-      break;
-    case btyp_bool:
-      retval = retval.sparse_bool_matrix_value ();
-      break;
+
     default:
-      break;
+      {
+        switch (retval.builtin_type ())
+          {
+          case btyp_double:
+            retval = retval.sparse_matrix_value ();
+            break;
+
+          case btyp_complex:
+            retval = retval.sparse_complex_matrix_value ();
+            break;
+
+          case btyp_bool:
+            retval = retval.sparse_bool_matrix_value ();
+            break;
+
+          default:
+            break;
+          }
+      }
     }
 
   return retval;
--- a/libinterp/octave-value/ov-base-sparse.h	Fri Aug 01 09:06:21 2014 -0400
+++ b/libinterp/octave-value/ov-base-sparse.h	Fri Aug 01 12:10:05 2014 -0400
@@ -147,7 +147,7 @@
 
   bool print_as_scalar (void) const;
 
-  void print (std::ostream& os, bool pr_as_read_syntax = false) const;
+  void print (std::ostream& os, bool pr_as_read_syntax = false);
 
   void print_info (std::ostream& os, const std::string& prefix) const;
 
@@ -165,6 +165,8 @@
 
   octave_idx_type *mex_get_jc (void) const { return matrix.mex_get_jc (); }
 
+  octave_value fast_elem_extract (octave_idx_type n) const;
+
 protected:
 
   octave_value map (octave_base_value::unary_mapper_t umap) const;
--- a/libinterp/octave-value/ov-base.cc	Fri Aug 01 09:06:21 2014 -0400
+++ b/libinterp/octave-value/ov-base.cc	Fri Aug 01 12:10:05 2014 -0400
@@ -52,6 +52,7 @@
 #include "parse.h"
 #include "pr-output.h"
 #include "utils.h"
+#include "toplev.h"
 #include "variables.h"
 
 builtin_type_t btyp_mixed_numeric (builtin_type_t x, builtin_type_t y)
@@ -396,7 +397,7 @@
 }
 
 void
-octave_base_value::print (std::ostream&, bool) const
+octave_base_value::print (std::ostream&, bool)
 {
   gripe_wrong_type_arg ("octave_base_value::print ()", type_name ());
 }
@@ -1536,6 +1537,111 @@
   return new octave_cell ();
 }
 
+static inline octave_value_list
+sanitize (const octave_value_list& ovl)
+{
+  octave_value_list retval = ovl;
+
+  for (octave_idx_type i = 0; i < ovl.length (); i++)
+    {
+      if (retval(i).is_magic_colon ())
+        retval(i) = ":";
+    }
+
+  return retval;
+}
+
+octave_value
+make_idx_args (const std::string& type,
+               const std::list<octave_value_list>& idx,
+               const std::string& who)
+{
+  octave_value retval;
+
+  size_t len = type.length ();
+
+  if (len == idx.size ())
+    {
+      Cell type_field (1, len);
+      Cell subs_field (1, len);
+
+      std::list<octave_value_list>::const_iterator p = idx.begin ();
+
+      for (size_t i = 0; i < len; i++)
+        {
+          char t = type[i];
+
+          switch (t)
+            {
+            case '(':
+              type_field(i) = "()";
+              subs_field(i) = Cell (sanitize (*p++));
+              break;
+
+            case '{':
+              type_field(i) = "{}";
+              subs_field(i) = Cell (sanitize (*p++));
+              break;
+
+            case '.':
+              {
+                type_field(i) = ".";
+
+                octave_value_list vlist = *p++;
+
+                if (vlist.length () == 1)
+                  {
+                    octave_value val = vlist(0);
+
+                    if (val.is_string ())
+                      subs_field(i) = val;
+                    else
+                      {
+                        error ("expecting character string argument for '.' index");
+                        return retval;
+                      }
+                  }
+                else
+                  {
+                    error ("expecting single argument for '.' index");
+                    return retval;
+                  }
+              }
+              break;
+
+            default:
+              panic_impossible ();
+              break;
+            }
+        }
+
+      octave_map m;
+
+      m.assign ("type", type_field);
+      m.assign ("subs", subs_field);
+
+      retval = m;
+    }
+  else
+    error ("invalid index for %s", who.c_str ());
+
+  return retval;
+}
+
+bool
+called_from_builtin (void)
+{
+  octave_function *fcn = octave_call_stack::caller ();
+
+  // FIXME: we probably need a better check here, or some other
+  // mechanism to avoid overloaded functions when builtin is used.
+  // For example, what if someone overloads the builtin function?
+  // Also, are there other places where using builtin is not properly
+  // avoiding dispatch?
+
+  return (fcn && fcn->name () == "builtin");
+}
+
 void
 install_base_type_conversions (void)
 {
--- a/libinterp/octave-value/ov-base.h	Fri Aug 01 09:06:21 2014 -0400
+++ b/libinterp/octave-value/ov-base.h	Fri Aug 01 12:10:05 2014 -0400
@@ -606,7 +606,7 @@
 
   virtual bool print_as_scalar (void) const { return false; }
 
-  virtual void print (std::ostream& os, bool pr_as_read_syntax = false) const;
+  virtual void print (std::ostream& os, bool pr_as_read_syntax = false);
 
   virtual void
   print_raw (std::ostream& os, bool pr_as_read_syntax = false) const;
@@ -828,4 +828,16 @@
 // is memory to be saved
 extern OCTINTERP_API bool Vsparse_auto_mutate;
 
+// Utility function to convert C++ arguments used in subsref/subsasgn into an
+// octave_value_list object that can be used to call a function/method in the
+// interpreter.
+extern OCTINTERP_API octave_value
+make_idx_args (const std::string& type,
+               const std::list<octave_value_list>& idx,
+               const std::string& who);
+
+// Tells whether some regular octave_value_base methods are being called from
+// within the "builtin" function.
+extern OCTINTERP_API bool called_from_builtin (void);
+
 #endif
--- a/libinterp/octave-value/ov-bool-mat.cc	Fri Aug 01 09:06:21 2014 -0400
+++ b/libinterp/octave-value/ov-bool-mat.cc	Fri Aug 01 12:10:05 2014 -0400
@@ -421,7 +421,8 @@
     return (empty > 0);
 
   int rank = dv.length ();
-  hid_t space_hid = -1, data_hid = -1;
+  hid_t space_hid, data_hid;
+  space_hid = data_hid = -1;
   bool retval = true;
   boolNDArray m = bool_array_value ();
 
@@ -551,7 +552,7 @@
 @deftypefn {Built-in Function} {} logical (@var{x})\n\
 Convert the numeric object @var{x} to logical type.\n\
 \n\
-Any non-zero values will be converted to true (1) while zero values\n\
+Any nonzero values will be converted to true (1) while zero values\n\
 will be converted to false (0).  The non-numeric value NaN cannot be\n\
 converted and will produce an error.\n\
 \n\
--- a/libinterp/octave-value/ov-bool-mat.h	Fri Aug 01 09:06:21 2014 -0400
+++ b/libinterp/octave-value/ov-bool-mat.h	Fri Aug 01 12:10:05 2014 -0400
@@ -151,10 +151,10 @@
   FloatComplex float_complex_value (bool = false) const;
 
   ComplexMatrix complex_matrix_value (bool = false) const
-  { return ComplexMatrix (matrix.matrix_value ( )); }
+  { return ComplexMatrix (matrix.matrix_value ()); }
 
   FloatComplexMatrix float_complex_matrix_value (bool = false) const
-  { return FloatComplexMatrix (matrix.matrix_value ( )); }
+  { return FloatComplexMatrix (matrix.matrix_value ()); }
 
   ComplexNDArray complex_array_value (bool = false) const
   { return ComplexNDArray (matrix); }
--- a/libinterp/octave-value/ov-bool-sparse.cc	Fri Aug 01 09:06:21 2014 -0400
+++ b/libinterp/octave-value/ov-bool-sparse.cc	Fri Aug 01 12:10:05 2014 -0400
@@ -225,16 +225,16 @@
 
   int32_t itmp;
   // Use negative value for ndims to be consistent with other formats
-  itmp= -2;
+  itmp = -2;
   os.write (reinterpret_cast<char *> (&itmp), 4);
 
-  itmp= nr;
+  itmp = nr;
   os.write (reinterpret_cast<char *> (&itmp), 4);
 
-  itmp= nc;
+  itmp = nc;
   os.write (reinterpret_cast<char *> (&itmp), 4);
 
-  itmp= nz;
+  itmp = nz;
   os.write (reinterpret_cast<char *> (&itmp), 4);
 
   // add one to the printed indices to go from
@@ -358,7 +358,8 @@
   if (group_hid < 0)
     return false;
 
-  hid_t space_hid = -1, data_hid = -1;
+  hid_t space_hid, data_hid;
+  space_hid = data_hid = -1;
   bool retval = true;
   SparseBoolMatrix m = sparse_bool_matrix_value ();
   octave_idx_type tmp;
@@ -567,7 +568,7 @@
 #else
   group_hid = H5Gopen (loc_id, name);
 #endif
-  if (group_hid < 0 ) return false;
+  if (group_hid < 0) return false;
 
 #if HAVE_HDF5_18
   data_hid = H5Dopen (group_hid, "nr", H5P_DEFAULT);
--- a/libinterp/octave-value/ov-bool.cc	Fri Aug 01 09:06:21 2014 -0400
+++ b/libinterp/octave-value/ov-bool.cc	Fri Aug 01 12:10:05 2014 -0400
@@ -165,7 +165,8 @@
                         bool /* save_as_floats */)
 {
   hsize_t dimens[3];
-  hid_t space_hid = -1, data_hid = -1;
+  hid_t space_hid, data_hid;
+  space_hid = data_hid = -1;
   bool retval = true;
 
   space_hid = H5Screate_simple (0, dimens, 0);
--- a/libinterp/octave-value/ov-cell.cc	Fri Aug 01 09:06:21 2014 -0400
+++ b/libinterp/octave-value/ov-cell.cc	Fri Aug 01 12:10:05 2014 -0400
@@ -687,7 +687,7 @@
 }
 
 void
-octave_cell::print (std::ostream& os, bool) const
+octave_cell::print (std::ostream& os, bool)
 {
   print_raw (os);
 }
@@ -1077,7 +1077,8 @@
     return (empty > 0);
 
   hsize_t rank = dv.length ();
-  hid_t space_hid = -1, data_hid = -1, size_hid = -1;
+  hid_t space_hid, data_hid, size_hid;
+  space_hid = data_hid = size_hid = -1;
 
 #if HAVE_HDF5_18
   data_hid = H5Gcreate (loc_id, name, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
--- a/libinterp/octave-value/ov-cell.h	Fri Aug 01 09:06:21 2014 -0400
+++ b/libinterp/octave-value/ov-cell.h	Fri Aug 01 12:10:05 2014 -0400
@@ -147,7 +147,7 @@
 
   bool print_as_scalar (void) const;
 
-  void print (std::ostream& os, bool pr_as_read_syntax = false) const;
+  void print (std::ostream& os, bool pr_as_read_syntax = false);
 
   void print_raw (std::ostream& os, bool pr_as_read_syntax = false) const;
 
--- a/libinterp/octave-value/ov-class.cc	Fri Aug 01 09:06:21 2014 -0400
+++ b/libinterp/octave-value/ov-class.cc	Fri Aug 01 12:10:05 2014 -0400
@@ -268,97 +268,6 @@
   error ("assignment to class element failed");
 }
 
-static inline octave_value_list
-sanitize (const octave_value_list& ovl)
-{
-  octave_value_list retval = ovl;
-
-  for (octave_idx_type i = 0; i < ovl.length (); i++)
-    {
-      if (retval(i).is_magic_colon ())
-        retval(i) = ":";
-    }
-
-  return retval;
-}
-
-static inline octave_value
-make_idx_args (const std::string& type,
-               const std::list<octave_value_list>& idx,
-               const std::string& who)
-{
-  octave_value retval;
-
-  size_t len = type.length ();
-
-  if (len == idx.size ())
-    {
-      Cell type_field (1, len);
-      Cell subs_field (1, len);
-
-      std::list<octave_value_list>::const_iterator p = idx.begin ();
-
-      for (size_t i = 0; i < len; i++)
-        {
-          char t = type[i];
-
-          switch (t)
-            {
-            case '(':
-              type_field(i) = "()";
-              subs_field(i) = Cell (sanitize (*p++));
-              break;
-
-            case '{':
-              type_field(i) = "{}";
-              subs_field(i) = Cell (sanitize (*p++));
-              break;
-
-            case '.':
-              {
-                type_field(i) = ".";
-
-                octave_value_list vlist = *p++;
-
-                if (vlist.length () == 1)
-                  {
-                    octave_value val = vlist(0);
-
-                    if (val.is_string ())
-                      subs_field(i) = val;
-                    else
-                      {
-                        error ("expecting character string argument for '.' index");
-                        return retval;
-                      }
-                  }
-                else
-                  {
-                    error ("expecting single argument for '.' index");
-                    return retval;
-                  }
-              }
-              break;
-
-            default:
-              panic_impossible ();
-              break;
-            }
-        }
-
-      octave_map m;
-
-      m.assign ("type", type_field);
-      m.assign ("subs", subs_field);
-
-      retval = m;
-    }
-  else
-    error ("invalid index for %s", who.c_str ());
-
-  return retval;
-}
-
 Cell
 octave_class::dotref (const octave_value_list& idx)
 {
@@ -398,20 +307,6 @@
   return retval;
 }
 
-static bool
-called_from_builtin (void)
-{
-  octave_function *fcn = octave_call_stack::caller ();
-
-  // FIXME: we probably need a better check here, or some other
-  // mechanism to avoid overloaded functions when builtin is used.
-  // For example, what if someone overloads the builtin function?
-  // Also, are there other places where using builtin is not properly
-  // avoiding dispatch?
-
-  return (fcn && fcn->name () == "builtin");
-}
-
 Matrix
 octave_class::size (void)
 {
@@ -1150,7 +1045,7 @@
 
 
 void
-octave_class::print (std::ostream& os, bool) const
+octave_class::print (std::ostream& os, bool)
 {
   print_raw (os);
 }
@@ -1279,7 +1174,8 @@
 bool
 octave_class::reconstruct_parents (void)
 {
-  bool retval = true, might_have_inheritance = false;
+  bool retval = true;
+  bool might_have_inheritance = false;
   std::string dbgstr = "dork";
 
   // First, check to see if there might be an issue with inheritance.
@@ -1287,10 +1183,10 @@
     {
       std::string  key = map.key (p);
       Cell         val = map.contents (p);
-      if ( val(0).is_object () )
+      if (val(0).is_object ())
         {
           dbgstr = "blork";
-          if ( key == val(0).class_name () )
+          if (key == val(0).class_name ())
             {
               might_have_inheritance = true;
               dbgstr = "cork";
@@ -1429,7 +1325,7 @@
                   success = false;
                 }
             }
-          else if (len == 0 )
+          else if (len == 0)
             {
               map = octave_map (dim_vector (1, 1));
               c_name = classname;
@@ -1573,7 +1469,7 @@
           success = false;
         }
     }
-  else if (len == 0 )
+  else if (len == 0)
     map = octave_map (dim_vector (1, 1));
   else
     panic_impossible ();
@@ -2054,7 +1950,7 @@
   const Array<std::string> cls = args(1).cellstr_value ();
   if (error_state)
     {
-      error ("isa: CLASSNAME must be a string or cell attay of strings");
+      error ("isa: CLASSNAME must be a string or cell array of strings");
       return retval;
     }
 
@@ -2148,7 +2044,7 @@
        "-*- texinfo -*-\n\
 @deftypefn {Built-in Function} {} isobject (@var{x})\n\
 Return true if @var{x} is a class object.\n\
-@seealso{class, typeinfo, isa, ismethod}\n\
+@seealso{class, typeinfo, isa, ismethod, isprop}\n\
 @end deftypefn")
 {
   octave_value retval;
@@ -2163,8 +2059,8 @@
 
 DEFUN (ismethod, args, ,
        "-*- texinfo -*-\n\
-@deftypefn {Built-in Function} {} ismethod (@var{x}, @var{method})\n\
-Return true if @var{x} is a class object and the string @var{method}\n\
+@deftypefn {Built-in Function} {} ismethod (@var{obj}, @var{method})\n\
+Return true if @var{obj} is a class object and the string @var{method}\n\
 is a method of this class.\n\
 @seealso{isprop, isobject}\n\
 @end deftypefn")
--- a/libinterp/octave-value/ov-class.h	Fri Aug 01 09:06:21 2014 -0400
+++ b/libinterp/octave-value/ov-class.h	Fri Aug 01 12:10:05 2014 -0400
@@ -169,7 +169,7 @@
 
   string_vector all_strings (bool pad) const;
 
-  void print (std::ostream& os, bool pr_as_read_syntax = false) const;
+  void print (std::ostream& os, bool pr_as_read_syntax = false);
 
   void print_raw (std::ostream& os, bool pr_as_read_syntax = false) const;
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libinterp/octave-value/ov-classdef.cc	Fri Aug 01 12:10:05 2014 -0400
@@ -0,0 +1,3910 @@
+/*
+
+Copyright (C) 2012-2013 Michael Goffioul
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <algorithm>
+
+#include "defun.h"
+#include "load-path.h"
+#include "ov-builtin.h"
+#include "ov-classdef.h"
+#include "ov-fcn-handle.h"
+#include "ov-typeinfo.h"
+#include "ov-usr-fcn.h"
+#include "pt-assign.h"
+#include "pt-classdef.h"
+#include "pt-funcall.h"
+#include "pt-misc.h"
+#include "pt-stmt.h"
+#include "pt-walk.h"
+#include "singleton-cleanup.h"
+#include "symtab.h"
+#include "toplev.h"
+
+#include "Array.cc"
+
+static void
+gripe_method_access (const std::string& from, const cdef_method& meth)
+{
+  octave_value acc = meth.get ("Access");
+  std::string acc_s;
+
+  if (acc.is_string ())
+    acc_s = acc.string_value ();
+  else
+    acc_s = "class-restricted";
+
+  error ("%s: method `%s' has %s access and cannot be run in this context",
+         from.c_str (), meth.get_name ().c_str (), acc_s.c_str ());
+}
+
+static void
+gripe_property_access (const std::string& from, const cdef_property& prop,
+                       bool is_set = false)
+{
+  octave_value acc = prop.get (is_set ? "SetAccess" : "GetAccess");
+  std::string acc_s;
+
+  if (acc.is_string ())
+    acc_s = acc.string_value ();
+  else
+    acc_s = "class-restricted";
+
+  if (is_set)
+    error ("%s: property `%s' has %s access and cannot be set in this context",
+           from.c_str (), prop.get_name ().c_str (), acc_s.c_str ());
+  else
+    error ("%s: property `%s' has %s access and cannot be obtained in this context",
+           from.c_str (), prop.get_name ().c_str (), acc_s.c_str ());
+}
+
+static std::string
+get_base_name (const std::string& nm)
+{
+  std::string::size_type pos = nm.find_last_of ('.');
+
+  if (pos != std::string::npos)
+    return nm.substr (pos + 1);
+
+  return nm;
+}
+
+static void
+make_function_of_class (const std::string& class_name,
+                        const octave_value& fcn)
+{
+  octave_function *of = fcn.function_value ();
+
+  if (! error_state)
+    {
+      of->stash_dispatch_class (class_name);
+
+      octave_user_function *uf = of->user_function_value (true);
+
+      if (! error_state && uf)
+        {
+          if (get_base_name (class_name) == uf->name ())
+            {
+              uf->mark_as_class_constructor ();
+              uf->mark_as_classdef_constructor ();
+            }
+          else
+            uf->mark_as_class_method ();
+        }
+    }
+}
+
+static void
+make_function_of_class (const cdef_class& cls, const octave_value& fcn)
+{
+  make_function_of_class (cls.get_name (), fcn);
+}
+
+static octave_value
+make_fcn_handle (octave_builtin::fcn ff, const std::string& nm)
+{
+  octave_value fcn (new octave_builtin (ff, nm));
+
+  octave_value fcn_handle (new octave_fcn_handle (fcn, nm));
+
+  return fcn_handle;
+}
+
+static octave_value
+make_fcn_handle (const octave_value& fcn, const std::string& nm)
+{
+  octave_value retval;
+
+  if (fcn.is_defined ())
+    retval = octave_value (new octave_fcn_handle (fcn, nm));
+
+  return retval;
+}
+
+inline octave_value_list
+execute_ov (octave_value val, const octave_value_list& args, int nargout)
+{
+  std::list<octave_value_list> idx (1, args);
+
+  std::string type ("(");
+
+  return val.subsref (type, idx, nargout);
+}
+
+static cdef_class
+lookup_class (const std::string& name, bool error_if_not_found = true,
+              bool load_if_not_found = true)
+{
+  return cdef_manager::find_class (name, error_if_not_found,
+                                   load_if_not_found);
+}
+
+static cdef_class
+lookup_class (const cdef_class& cls)
+{
+  // FIXME: placeholder for the time being, the purpose
+  //        is to centralized any class update activity here.
+
+  return cls;
+}
+
+static cdef_class
+lookup_class (const octave_value& ov)
+{
+  if (ov.is_string())
+    return lookup_class (ov.string_value ());
+  else
+    {
+      cdef_class cls (to_cdef (ov));
+
+      if (! error_state)
+        return lookup_class (cls);
+    }
+
+  return cdef_class ();
+}
+
+static std::list<cdef_class>
+lookup_classes (const Cell& cls_list)
+{
+  std::list<cdef_class> retval;
+
+  for (int i = 0; i < cls_list.numel (); i++)
+    {
+      cdef_class c = lookup_class (cls_list(i));
+
+      if (! error_state)
+        retval.push_back (c);
+      else
+        {
+          retval.clear ();
+          break;
+        }
+    }
+
+  return retval;
+}
+
+static octave_value
+to_ov (const std::list<cdef_class>& class_list)
+{
+  Cell cls (class_list.size (), 1);
+  int i = 0;
+
+  for (std::list<cdef_class>::const_iterator it = class_list.begin ();
+       it != class_list.end (); ++it, ++i)
+    cls(i) = to_ov (*it);
+
+  return octave_value (cls);
+}
+
+static bool
+is_superclass (const cdef_class& clsa, const cdef_class& clsb,
+               bool allow_equal = true, int max_depth = -1)
+{
+  bool retval = false;
+
+  if (allow_equal && clsa == clsb)
+    retval = true;
+  else if (max_depth != 0)
+    {
+      Cell c = clsb.get ("SuperClasses").cell_value ();
+
+      for (int i = 0; ! error_state && ! retval && i < c.numel (); i++)
+        {
+          cdef_class cls = lookup_class (c(i));
+
+          if (! error_state)
+            retval = is_superclass (clsa, cls, true,
+                                    max_depth < 0 ? max_depth : max_depth-1);
+        }
+    }
+
+  return retval;
+}
+
+inline bool
+is_strict_superclass (const cdef_class& clsa, const cdef_class& clsb)
+{ return is_superclass (clsa, clsb, false); }
+
+inline bool
+is_direct_superclass (const cdef_class& clsa, const cdef_class& clsb)
+{ return is_superclass (clsa, clsb, false, 1); }
+
+static octave_value_list
+class_get_properties (const octave_value_list& args, int /* nargout */)
+{
+  octave_value_list retval;
+
+  if (args.length () == 1 && args(0).type_name () == "object")
+    {
+      cdef_class cls (to_cdef (args(0)));
+
+      retval(0) = cls.get_properties ();
+    }
+
+  return retval;
+}
+
+static cdef_class
+get_class_context (std::string& name, bool& in_constructor)
+{
+  cdef_class cls;
+
+  octave_function* fcn = octave_call_stack::current ();
+
+  in_constructor = false;
+
+  if (fcn &&
+      (fcn->is_class_method ()
+       || fcn->is_classdef_constructor ()
+       || fcn->is_anonymous_function_of_class ()
+       || (fcn->is_private_function ()
+           && ! fcn->dispatch_class ().empty ())))
+    {
+      cls = lookup_class (fcn->dispatch_class ());
+      if (! error_state)
+        {
+          name = fcn->name ();
+          in_constructor = fcn->is_classdef_constructor ();
+        }
+    }
+
+  return cls;
+}
+
+inline cdef_class
+get_class_context (void)
+{
+  std::string dummy_string;
+  bool dummy_bool;
+
+  return get_class_context (dummy_string, dummy_bool);
+}
+
+static bool
+in_class_method (const cdef_class& cls)
+{
+  cdef_class ctx = get_class_context ();
+
+  return (ctx.ok () && is_superclass (ctx, cls));
+}
+
+static bool
+check_access (const cdef_class& cls, const octave_value& acc,
+              const std::string& meth_name = std::string (),
+              const std::string& prop_name = std::string (),
+              bool is_prop_set = false)
+{
+  if (acc.is_string ())
+    {
+      std::string acc_s = acc.string_value ();
+
+      if (acc_s == "public")
+        return true;
+
+      cdef_class ctx = get_class_context ();
+
+      // The access is private or protected, this requires a
+      // valid class context.
+
+      if (! error_state && ctx.ok ())
+        {
+          if (acc_s == "private")
+            return (ctx == cls);
+          else if (acc_s == "protected")
+            {
+              if (is_superclass (cls, ctx))
+                // Calling a protected method in a superclass.
+                return true;
+              else if (is_strict_superclass (ctx, cls))
+                {
+                  // Calling a protected method or property in a derived class.
+                  // This is only allowed if the context class knows about it
+                  // and has access to it.
+
+                  if (! meth_name.empty ())
+                    {
+                      cdef_method m = ctx.find_method (meth_name);
+
+                      if (m.ok ())
+                        return check_access (ctx, m.get ("Access"), meth_name);
+
+                      return false;
+                    }
+                  else if (! prop_name.empty ())
+                    {
+                      cdef_property p = ctx.find_property (prop_name);
+
+                      if (p.ok ())
+                        {
+                          octave_value p_access = p.get (is_prop_set ?
+                                                         "SetAccess" :
+                                                         "GetAccess");
+
+                          return check_access (ctx, p_access, meth_name,
+                                               prop_name, is_prop_set);
+                        }
+
+                      return false;
+                    }
+                  else
+                    panic_impossible ();
+                }
+
+              return false;
+            }
+          else
+            panic_impossible ();
+        }
+    }
+  else if (acc.is_cell ())
+    {
+      Cell acc_c = acc.cell_value ();
+
+      cdef_class ctx = get_class_context ();
+
+      // At this point, a class context is always required.
+
+      if (! error_state && ctx.ok ())
+        {
+          if (ctx == cls)
+            return true;
+
+          for (int i = 0; ! error_state && i < acc.numel (); i++)
+            {
+              cdef_class acc_cls (to_cdef (acc_c(i)));
+
+              if (! error_state)
+                {
+                  if (is_superclass (acc_cls, ctx))
+                    return true;
+                }
+            }
+        }
+    }
+  else
+    error ("invalid property/method access in class `%s'",
+           cls.get_name ().c_str ());
+  
+  return false;
+}
+
+static bool
+is_dummy_method (const octave_value& fcn)
+{
+  bool retval = false;
+
+  if (fcn.is_defined ())
+    {
+      if (fcn.is_user_function ())
+        {
+          octave_user_function *uf = fcn.user_function_value (true);
+
+          if (! uf || ! uf->body ())
+            retval = true;
+        }
+    }
+  else
+    retval = true;
+
+  return retval;
+}
+
+bool
+is_method_executing (const octave_value& ov, const cdef_object& obj)
+{
+  octave_function* stack_fcn = octave_call_stack::current ();
+
+  octave_function* method_fcn = ov.function_value (true);
+
+  // Does the top of the call stack match our target function?
+
+  if (stack_fcn && stack_fcn == method_fcn)
+    {
+      octave_user_function* uf = method_fcn->user_function_value (true);
+
+      // We can only check the context object for user-function (not builtin),
+      // where we have access to the parameters (arguments and return values).
+      // That's ok as there's no need to call this function for builtin
+      // methods.
+
+      if (uf)
+        {
+          // At this point, the method is executing, but we still need to
+          // check the context object for which the method is executing. For
+          // methods, it's the first argument of the function; for ctors, it
+          // is the first return value.
+
+          tree_parameter_list* pl = uf->is_classdef_constructor ()
+            ? uf->return_list () : uf->parameter_list ();
+
+          if (pl && pl->size () > 0)
+            {
+              octave_value arg0 = pl->front ()->lvalue ().value ();
+
+              if (arg0.is_defined () && arg0.type_name () == "object")
+                {
+                  cdef_object arg0_obj = to_cdef (arg0);
+
+                  return obj.is (arg0_obj);
+                }
+            }
+        }
+    }
+
+  return false;
+}
+
+static octave_value_list
+class_get_methods (const octave_value_list& args, int /* nargout */)
+{
+  octave_value_list retval;
+
+  if (args.length () == 1 && args(0).type_name () == "object")
+    {
+      cdef_class cls (to_cdef (args(0)));
+
+      retval(0) = cls.get_methods ();
+    }
+
+  return retval;
+}
+
+static octave_value_list
+class_get_superclasses (const octave_value_list& args, int /* nargout */)
+{
+  octave_value_list retval;
+
+  if (args.length () == 1 && args(0).type_name () == "object"
+      && args(0).class_name () == "meta.class")
+    {
+      cdef_class cls (to_cdef (args(0)));
+
+      Cell classes = cls.get ("SuperClasses").cell_value ();
+
+      retval(0) = to_ov (lookup_classes (classes));
+    }
+
+  return retval;
+}
+
+static octave_value_list
+class_get_inferiorclasses (const octave_value_list& args, int /* nargout */)
+{
+  octave_value_list retval;
+
+  if (args.length () == 1 && args(0).type_name () == "object"
+      && args(0).class_name () == "meta.class")
+    {
+      cdef_class cls (to_cdef (args(0)));
+
+      Cell classes = cls.get ("InferiorClasses").cell_value ();
+
+      retval(0) = to_ov (lookup_classes (classes));
+    }
+
+  return retval;
+}
+
+static octave_value_list
+class_fromName (const octave_value_list& args, int /* nargout */)
+{
+  octave_value_list retval;
+
+  if (args.length () == 1)
+    {
+      std::string name = args(0).string_value ();
+
+      if (! error_state)
+        retval(0) = to_ov (lookup_class (name));
+      else
+        error ("fromName: invalid class name, expected a string value");
+    }
+  else
+    error ("fromName: invalid number of parameters");
+
+  return retval;
+}
+
+static octave_value_list
+class_fevalStatic (const octave_value_list& args, int nargout)
+{
+  octave_value_list retval;
+
+  if (args.length () > 1 && args(0).type_name () == "object")
+    {
+      cdef_class cls (to_cdef (args(0)));
+
+      if (! error_state)
+        {
+          std::string meth_name = args(1).string_value ();
+
+          if (! error_state)
+            {
+              cdef_method meth = cls.find_method (meth_name);
+
+              if (meth.ok ())
+                {
+                    if (meth.is_static ())
+                      retval = meth.execute (args.splice (0, 2), nargout,
+                                             true, "fevalStatic");
+                    else
+                      error ("fevalStatic: method `%s' is not static",
+                             meth_name.c_str ());
+                }
+              else
+                error ("fevalStatic: method not found: %s",
+                       meth_name.c_str ());
+            }
+          else
+            error ("fevalStatic: invalid method name, expected a string value");
+        }
+      error ("fevalStatic: invalid object, expected a meta.class object");
+    }
+  else
+    error ("fevalStatic: invalid arguments");
+
+  return retval;
+}
+
+static octave_value_list
+class_getConstant (const octave_value_list& args, int /* nargout */)
+{
+  octave_value_list retval;
+
+  if (args.length () == 2 && args(0).type_name () == "object"
+      && args(0).class_name () == "meta.class")
+    {
+      cdef_class cls = to_cdef (args(0));
+
+      if (! error_state)
+        {
+          std::string prop_name = args(1).string_value ();
+
+          if (! error_state)
+            {
+              cdef_property prop = cls.find_property (prop_name);
+
+              if (prop.ok ())
+                {
+                  if (prop.is_constant ())
+                    retval(0) = prop.get_value (true, "getConstant");
+                  else
+                    error ("getConstant: property `%s' is not constant",
+                           prop_name.c_str ());
+                }
+              else
+                error ("getConstant: property not found: %s",
+                       prop_name.c_str ());
+            }
+          else
+            error ("getConstant: invalid property name, expected a string value");
+        }
+      else
+        error ("getConstant: invalid object, expected a meta.class object");
+    }
+  else
+    error ("getConstant: invalid arguments");
+
+  return retval;
+}
+
+#define META_CLASS_CMP(OP, CLSA, CLSB, FUN) \
+static octave_value_list \
+class_ ## OP (const octave_value_list& args, int /* nargout */) \
+{ \
+  octave_value_list retval; \
+\
+  if (args.length () == 2 \
+      && args(0).type_name () == "object" && args(1).type_name () == "object" \
+      && args(0).class_name () == "meta.class" && args(1).class_name () == "meta.class") \
+    { \
+      cdef_class clsa = to_cdef (args(0)); \
+\
+      cdef_class clsb = to_cdef (args(1)); \
+\
+      if (! error_state) \
+        retval(0) = FUN (CLSA, CLSB); \
+      else \
+        error (#OP ": invalid objects, expected meta.class objects"); \
+    } \
+  else \
+    error (#OP ": invalid arguments"); \
+\
+  return retval; \
+}
+
+META_CLASS_CMP (lt, clsb, clsa, is_strict_superclass)
+META_CLASS_CMP (le, clsb, clsa, is_superclass)
+META_CLASS_CMP (gt, clsa, clsb, is_strict_superclass)
+META_CLASS_CMP (ge, clsa, clsb, is_superclass)
+META_CLASS_CMP (eq, clsa, clsb, operator==)
+META_CLASS_CMP (ne, clsa, clsb, operator!=)
+
+octave_value_list
+property_get_defaultvalue (const octave_value_list& args, int /* nargout */)
+{
+  octave_value_list retval;
+
+  if (args.length () == 1 && args(0).type_name () == "object")
+    {
+      cdef_property prop (to_cdef (args(0)));
+
+      retval(0) = prop.get ("DefaultValue");
+
+      if (! retval(0).is_defined ())
+        error_with_id ("Octave:class:NotDefaultDefined",
+                       "no default value for property `%s'",
+                       prop.get_name ().c_str ());
+    }
+
+  return retval;
+}
+
+static octave_value_list
+handle_delete (const octave_value_list& /* args */, int /* nargout */)
+{
+  octave_value_list retval;
+
+  // FIXME: implement this
+
+  return retval;
+}
+
+static cdef_class
+make_class (const std::string& name,
+            const std::list<cdef_class>& super_list = std::list<cdef_class> ())
+{
+  cdef_class cls (name, super_list);
+
+  cls.set_class (cdef_class::meta_class ());
+  cls.put ("Abstract", false);
+  cls.put ("ConstructOnLoad", false);
+  cls.put ("ContainingPackage", Matrix ());
+  cls.put ("Description", std::string ());
+  cls.put ("DetailedDescription", std::string ());
+  cls.put ("Events", Cell ());
+  cls.put ("Hidden", false);
+  cls.put ("InferiorClasses", Cell ());
+  cls.put ("Methods", Cell ());
+  cls.put ("Properties", Cell ());
+  cls.put ("Sealed", false);
+
+  if (name == "handle")
+    {
+      cls.put ("HandleCompatible", true);
+      cls.mark_as_handle_class ();
+    }
+  else if (super_list.empty ())
+    {
+      cls.put ("HandleCompatible", false);
+    }
+  else
+    {
+      bool all_handle_compatible = true;
+      bool has_handle_class = false;
+
+      for (std::list<cdef_class>::const_iterator it = super_list.begin ();
+           it != super_list.end (); ++it)
+        {
+          all_handle_compatible = all_handle_compatible && it->get ("HandleCompatible").bool_value ();
+          has_handle_class = has_handle_class || it->is_handle_class ();
+        }
+
+      if (has_handle_class && ! all_handle_compatible)
+        ::error ("%s: cannot mix handle and non-HandleCompatible classes",
+                 name.c_str ());
+      else
+        {
+          cls.put ("HandleCompatible", all_handle_compatible);
+          if (has_handle_class)
+            cls.mark_as_handle_class ();
+        }
+    }
+
+  if (error_state)
+    return cdef_class ();
+
+  if (! name.empty ())
+    cdef_manager::register_class (cls);
+
+  return cls;
+}
+
+static cdef_class
+make_class (const std::string& name, const cdef_class& super)
+{
+  return make_class (name, std::list<cdef_class> (1, super));
+}
+
+static cdef_class
+make_meta_class (const std::string& name, const cdef_class& super)
+{
+  cdef_class cls = make_class (name, super);
+
+  cls.put ("Sealed", true);
+  cls.mark_as_meta_class ();
+
+  return cls;
+}
+
+static cdef_property
+make_property (const cdef_class& cls, const std::string& name,
+               const octave_value& get_method = Matrix (),
+               const std::string& get_access = "public",
+               const octave_value& set_method = Matrix (),
+               const std::string& set_access = "public")
+{
+  cdef_property prop (name);
+
+  prop.set_class (cdef_class::meta_property ());
+  prop.put ("Description", std::string ());
+  prop.put ("DetailedDescription", std::string ());
+  prop.put ("Abstract", false);
+  prop.put ("Constant", false);
+  prop.put ("GetAccess", get_access);
+  prop.put ("SetAccess", set_access);
+  prop.put ("Dependent", false);
+  prop.put ("Transient", false);
+  prop.put ("Hidden", false);
+  prop.put ("GetObservable", false);
+  prop.put ("SetObservable", false);
+  prop.put ("GetMethod", get_method);
+  prop.put ("SetMethod", set_method);
+  prop.put ("DefiningClass", to_ov (cls));
+  prop.put ("DefaultValue", octave_value ());
+  prop.put ("HasDefault", false);
+
+  std::string class_name = cls.get_name ();
+
+  if (! get_method.is_empty ())
+    make_function_of_class (class_name, get_method);
+  if (! set_method.is_empty ())
+    make_function_of_class (class_name, set_method);
+
+  return prop;
+}
+
+inline cdef_property
+make_attribute (const cdef_class& cls, const std::string& name)
+{
+  return make_property (cls, name, Matrix (), "public", Matrix (), "private");
+}
+
+static cdef_method
+make_method (const cdef_class& cls, const std::string& name,
+             const octave_value& fcn,const std::string& m_access = "public",
+             bool is_static = false)
+{
+  cdef_method meth (name);
+
+  meth.set_class (cdef_class::meta_method ());
+  meth.put ("Abstract", false);
+  meth.put ("Access", m_access);
+  meth.put ("DefiningClass", to_ov (cls));
+  meth.put ("Description", std::string ());
+  meth.put ("DetailedDescription", std::string ());
+  meth.put ("Hidden", false);
+  meth.put ("Sealed", true);
+  meth.put ("Static", is_static);
+
+  if (fcn.is_defined ())
+    make_function_of_class (cls, fcn);
+
+  meth.set_function (fcn);
+
+  if (is_dummy_method (fcn))
+    meth.mark_as_external (cls.get_name ());
+
+  return meth;
+}
+
+inline cdef_method
+make_method (const cdef_class& cls, const std::string& name,
+             octave_builtin::fcn ff, const std::string& m_access = "public",
+             bool is_static = false)
+{
+  octave_value fcn (new octave_builtin (ff, name));
+
+  return make_method (cls, name, fcn, m_access, is_static);
+}
+
+static cdef_package
+make_package (const std::string& nm,
+              const std::string& parent = std::string ())
+{
+  cdef_package pack (nm);
+
+  pack.set_class (cdef_class::meta_package ());
+  if (parent.empty ())
+    pack.put ("ContainingPackage", Matrix ());
+  else
+    pack.put ("ContainingPackage", to_ov (cdef_manager::find_package (parent)));
+
+  if (! nm.empty ())
+    cdef_manager::register_package (pack);
+
+  return pack;
+}
+
+//----------------------------------------------------------------------------
+
+DEFINE_OCTAVE_ALLOCATOR (octave_classdef);
+
+int octave_classdef::t_id (-1);
+
+const std::string octave_classdef::t_name ("object");
+
+void
+octave_classdef::register_type (void)
+{
+  t_id = octave_value_typeinfo::register_type
+    (octave_classdef::t_name, "<unknown>", octave_value (new octave_classdef ()));
+}
+
+octave_value_list
+octave_classdef::subsref (const std::string& type,
+                          const std::list<octave_value_list>& idx,
+                          int nargout)
+{
+  size_t skip = 0;
+  octave_value_list retval;
+
+  cdef_class cls = object.get_class ();
+
+  if (! in_class_method (cls) && ! called_from_builtin ())
+    {
+      cdef_method meth = cls.find_method ("subsref");
+
+      if (meth.ok ())
+        {
+          octave_value_list args;
+
+          args(1) = make_idx_args (type, idx, "subsref");
+
+          if (! error_state)
+            {
+              count++;
+              args(0) = octave_value (this);
+
+              retval = meth.execute (args, nargout, true, "subsref");
+            }
+
+          return retval;
+        }
+    }
+
+  // At this point, the default subsref mechanism must be used.
+
+  retval = object.subsref (type, idx, nargout, skip, cdef_class ());
+
+  if (! error_state)
+    {
+      if (type.length () > skip && idx.size () > skip)
+        retval = retval(0).next_subsref (nargout, type, idx, skip);
+    }
+
+  return retval;
+}
+
+octave_value
+octave_classdef::subsref (const std::string& type,
+                          const std::list<octave_value_list>& idx,
+                          bool auto_add)
+{
+  size_t skip = 0;
+  octave_value_list retval;
+
+  // This variant of subsref is used to create temporary values when doing
+  // assignment with multi-level indexing. AFAIK this is only used for internal
+  // purpose (not sure we should even implement this) and any overload subsref
+  // should not be called.
+
+  retval = object.subsref (type, idx, 1, skip, cdef_class (), auto_add);
+
+  if (! error_state)
+    {
+      if (type.length () > skip && idx.size () > skip)
+        retval = retval(0).next_subsref (1, type, idx, skip);
+    }
+
+  return retval.length () > 0 ? retval(0) : octave_value ();
+}
+
+octave_value
+octave_classdef::subsasgn (const std::string& type,
+                           const std::list<octave_value_list>& idx,
+                           const octave_value& rhs)
+{
+  octave_value retval;
+
+  cdef_class cls = object.get_class ();
+
+  if (! in_class_method (cls) && ! called_from_builtin ())
+    {
+      cdef_method meth = cls.find_method ("subsasgn");
+
+      if (meth.ok ())
+        {
+          octave_value_list args;
+
+          args(1) = make_idx_args (type, idx, "subsasgn");
+
+          if (! error_state)
+            {
+              count++;
+              args(0) = octave_value (this);
+              args(2) = rhs;
+
+              octave_value_list retlist;
+
+              retlist = meth.execute (args, 1, true, "subsasgn");
+
+              if (! error_state)
+                {
+                  if (retlist.length () > 0)
+                    retval = retlist(0);
+                  else
+                    ::error ("overloaded method `subsasgn' did not return any value");
+                }
+            }
+        }
+    }
+
+  if (! error_state && ! retval.is_defined ())
+    retval = object.subsasgn (type, idx, rhs);
+
+  return retval;
+}
+
+octave_value
+octave_classdef::undef_subsasgn (const std::string& type,
+                                 const std::list<octave_value_list>& idx,
+                                 const octave_value& rhs)
+{
+  if (type.length () == 1 && type[0] == '(')
+    {
+      object = object.make_array ();
+
+      if (! error_state)
+        return subsasgn (type, idx, rhs);
+    }
+  else
+    return octave_base_value::undef_subsasgn (type, idx, rhs);
+
+  return octave_value ();
+}
+
+void
+octave_classdef::print (std::ostream& os, bool)
+{
+  if (! called_from_builtin ())
+    {
+      cdef_method meth = object.get_class ().find_method ("disp");
+
+      if (meth.ok ())
+        {
+          octave_value_list args;
+
+          count++;
+          args(0) = octave_value (this);
+
+          indent (os);
+          meth.execute (args, 0, true, "disp");
+
+          return;
+        }
+    }
+
+  print_raw (os);
+}
+
+void
+octave_classdef::print_raw (std::ostream& os, bool) const
+{
+  indent (os);
+  os << "<object ";
+  if (object.is_array ())
+    os << "array ";
+  os << class_name () << ">";
+  newline (os);
+}
+
+bool
+octave_classdef::print_name_tag (std::ostream& os,
+                                 const std::string& name) const
+{
+  return octave_base_value::print_name_tag (os, name);
+}
+
+void
+octave_classdef::print_with_name (std::ostream& os, const std::string& name,
+                                  bool print_padding)
+{
+  cdef_method meth = object.get_class ().find_method ("display");
+
+  if (meth.ok ())
+    {
+      octave_value_list args;
+
+      count++;
+      args(0) = octave_value (this);
+
+      string_vector arg_names (1);
+
+      arg_names[0] = name;
+      args.stash_name_tags (arg_names);
+
+      indent (os);
+      meth.execute (args, 0, true, "display");
+    }
+  else
+    octave_base_value::print_with_name (os, name, print_padding);
+}
+
+//----------------------------------------------------------------------------
+
+class octave_classdef_meta : public octave_function
+{
+public:
+  octave_classdef_meta (const cdef_meta_object& obj)
+    : object (obj) { }
+
+  ~octave_classdef_meta (void)
+    { object.meta_release (); }
+
+  octave_function* function_value (bool = false) { return this; }
+
+  octave_value_list
+  subsref (const std::string& type,
+           const std::list<octave_value_list>& idx,
+           int nargout)
+    { return object.meta_subsref (type, idx, nargout); }
+
+  octave_value
+  subsref (const std::string& type,
+           const std::list<octave_value_list>& idx)
+    {
+      octave_value_list retval;
+
+      retval = subsref (type, idx, 1);
+
+      return (retval.length () > 0 ? retval(0) : octave_value ());
+    }
+
+  octave_value_list
+  do_multi_index_op (int nargout, const octave_value_list& idx)
+    {
+      // Emulate ()-type meta subsref
+
+      std::list<octave_value_list> l (1, idx);
+      std::string type ("(");
+
+      return subsref (type, l, nargout);
+    }
+
+  bool is_postfix_index_handled (char type) const
+    { return object.meta_is_postfix_index_handled (type); }
+
+  bool
+  is_classdef_constructor (const std::string& cname = std::string ()) const
+    {
+      bool retval = false;
+
+      if (object.is_class ())
+        {
+          if (cname.empty ())
+            retval = true;
+          else
+            {
+              cdef_class cls (object);
+
+              if (cls.get_name () == cname)
+                retval = true;
+            }
+        }
+
+      return retval;
+    }
+
+private:
+  cdef_meta_object object;
+};
+
+//----------------------------------------------------------------------------
+
+class octave_classdef_superclass_ref : public octave_function
+{
+public:
+  octave_classdef_superclass_ref (const octave_value_list& a)
+    : octave_function (), args (a) { }
+
+  ~octave_classdef_superclass_ref (void) { }
+
+  octave_function* function_value (bool = false) { return this; }
+
+  octave_value_list
+  subsref (const std::string& type,
+           const std::list<octave_value_list>& idx,
+           int nargout)
+    {
+      size_t skip = 0;
+      octave_value_list retval;
+
+      switch (type[0])
+        {
+        case '(':
+          skip = 1;
+          retval = do_multi_index_op (type.length () > 1 ? 1 : nargout,
+                                      idx.front ());
+          break;
+        default:
+          retval = do_multi_index_op (1, octave_value_list ());
+          break;
+        }
+
+      if (! error_state)
+        {
+          if (type.length () > skip && idx.size () > skip
+              && retval.length () > 0)
+            retval = retval(0).next_subsref (nargout, type, idx, skip);
+        }
+
+      return retval;
+    }
+
+  octave_value
+  subsref (const std::string& type,
+           const std::list<octave_value_list>& idx)
+    {
+      octave_value_list retval;
+
+      retval = subsref (type, idx, 1);
+
+      return (retval.length () > 0 ? retval(0) : octave_value ());
+    }
+
+  octave_value_list
+  do_multi_index_op (int nargout, const octave_value_list& idx)
+    {
+      octave_value_list retval;
+
+      std::string meth_name;
+      bool in_constructor;
+      cdef_class ctx;
+
+      ctx = get_class_context (meth_name, in_constructor);
+
+      if (! error_state && ctx.ok ())
+        {
+          std::string mname = args(0).string_value ();
+          std::string cname = args(1).string_value ();
+
+          cdef_class cls = lookup_class (cname);
+
+          if (! error_state)
+            {
+              if (in_constructor)
+                {
+                  if (is_direct_superclass (cls, ctx))
+                    {
+                      if (is_constructed_object (mname))
+                        {
+                          octave_value sym = symbol_table::varval (mname);
+
+                          cls.run_constructor (to_cdef_ref (sym), idx);
+
+                          retval(0) = sym;
+                        }
+                      else
+                        ::error ("cannot call superclass constructor with "
+                                 "variable `%s'", mname.c_str ());
+                    }
+                  else
+                    ::error ("`%s' is not a direct superclass of `%s'",
+                             cname.c_str (), ctx.get_name ().c_str ());
+                }
+              else
+                {
+                  if (mname == meth_name)
+                    {
+                      if (is_strict_superclass (cls, ctx))
+                        {
+                          // I see 2 possible implementations here:
+                          // 1) use cdef_object::subsref with a different class
+                          //    context; this avoids duplicating code, but
+                          //    assumes the object is always the first argument
+                          // 2) lookup the method manually and call
+                          //    cdef_method::execute; this duplicates part of
+                          //    logic in cdef_object::subsref, but avoid the
+                          //    assumption of 1)
+                          // Not being sure about the assumption of 1), I
+                          // go with option 2) for the time being.
+
+                          cdef_method meth = cls.find_method (meth_name, false);
+
+                          if (meth.ok ())
+                            retval = meth.execute (idx, nargout, true,
+                                                   meth_name);
+                          else
+                            ::error ("no method `%s' found in superclass `%s'",
+                                     meth_name.c_str (), cname.c_str ());
+                        }
+                      else
+                        ::error ("`%s' is not a superclass of `%s'",
+                                 cname.c_str (), ctx.get_name ().c_str ());
+                    }
+                  else
+                    ::error ("method name mismatch (`%s' != `%s')",
+                             mname.c_str (), meth_name.c_str ());
+                }
+            }
+        }
+      else if (! error_state)
+        ::error ("superclass calls can only occur in methods or constructors");
+
+      return retval;
+    }
+
+private:
+  bool is_constructed_object (const std::string nm)
+    {
+      octave_function *of = octave_call_stack::current ();
+
+      if (of->is_classdef_constructor ())
+        {
+          octave_user_function *uf = of->user_function_value (true);
+
+          if (uf)
+            {
+              tree_parameter_list *ret_list = uf->return_list ();
+
+              if (ret_list && ret_list->length () == 1)
+                return (ret_list->front ()->name () == nm);
+            }
+        }
+
+      return false;
+    }
+
+private:
+  octave_value_list args;
+};
+
+//----------------------------------------------------------------------------
+
+string_vector
+cdef_object_rep::map_keys (void) const
+{
+  cdef_class cls = get_class ();
+
+  if (cls.ok ())
+    return cls.get_names ();
+  
+  return string_vector ();
+}
+
+octave_value_list
+cdef_object_scalar::subsref (const std::string& type,
+                             const std::list<octave_value_list>& idx,
+                             int nargout, size_t& skip,
+                             const cdef_class& context, bool auto_add)
+{
+  skip = 0;
+
+  cdef_class cls = (context.ok () ? context : get_class ());
+
+  octave_value_list retval;
+
+  if (! cls.ok ())
+    return retval;
+
+  switch (type[0])
+    {
+    case '.':
+        {
+          std::string name = (idx.front ())(0).string_value ();
+
+          cdef_method meth = cls.find_method (name);
+
+          if (meth.ok ())
+            {
+              int _nargout = (type.length () > 2 ? 1 : nargout);
+
+              octave_value_list args;
+
+              skip = 1;
+
+              if (type.length () > 1 && type[1] == '(')
+                {
+                  std::list<octave_value_list>::const_iterator it = idx.begin ();
+
+                  args = *++it;
+
+                  skip++;
+                }
+
+              if (meth.is_static ())
+                retval = meth.execute (args, _nargout, true, "subsref");
+              else
+                {
+                  refcount++;
+                  retval = meth.execute (cdef_object (this), args, _nargout,
+                                         true, "subsref");
+                }
+            }
+
+          if (skip == 0 && ! error_state)
+            {
+              cdef_property prop = cls.find_property (name);
+
+              if (prop.ok ())
+                {
+                  if (prop.is_constant ())
+                    retval(0) = prop.get_value (true, "subsref");
+                  else
+                    {
+                      refcount++;
+                      retval(0) = prop.get_value (cdef_object (this),
+                                                  true, "subsref");
+                    }
+
+                  skip = 1;
+                }
+              else
+                error ("subsref: unknown method or property: %s", name.c_str ());
+            }
+          break;
+        }
+
+    case '(':
+        {
+          refcount++;
+
+          cdef_object this_obj (this);
+
+          Array<cdef_object> arr (dim_vector (1, 1), this_obj);
+
+          cdef_object new_obj = cdef_object (new cdef_object_array (arr));
+
+          new_obj.set_class (get_class ());
+
+          retval = new_obj.subsref (type, idx, nargout, skip, cls, auto_add);
+        }
+      break;
+
+    default:
+      error ("object cannot be indexed with `%c'", type[0]);
+      break;
+    }
+
+  return retval;
+}
+
+octave_value
+cdef_object_scalar::subsasgn (const std::string& type,
+                              const std::list<octave_value_list>& idx,
+                              const octave_value& rhs)
+{
+  octave_value retval;
+
+  cdef_class cls = get_class ();
+
+  switch (type[0])
+    {
+    case '.':
+        {
+          std::string name = (idx.front ())(0).string_value ();
+
+          if (! error_state)
+            {
+              cdef_property prop = cls.find_property (name);
+
+              if (prop.ok ())
+                {
+                  if (prop.is_constant ())
+                    error ("subsasgn: cannot assign constant property: %s",
+                           name.c_str ());
+                  else
+                    {
+                      refcount++;
+
+                      cdef_object obj (this);
+
+                      if (type.length () == 1)
+                        {
+                          prop.set_value (obj, rhs, true, "subsasgn");
+
+                          if (! error_state)
+                            retval = to_ov (obj);
+                        }
+                      else
+                        {
+                          octave_value val = 
+                            prop.get_value (obj, true, "subsasgn");
+
+                          if (! error_state)
+                            {
+                              std::list<octave_value_list> args (idx);
+
+                              args.erase (args.begin ());
+
+                              val = val.assign (octave_value::op_asn_eq,
+                                                type.substr (1), args, rhs);
+
+                              if (! error_state)
+                                {
+                                  if (val.class_name () != "object"
+                                      || ! to_cdef (val).is_handle_object ())
+                                    prop.set_value (obj, val, true, "subsasgn");
+
+                                  if (! error_state)
+                                    retval = to_ov (obj);
+                                }
+                            }
+                        }
+                    }
+                }
+              else
+                error ("subsasgn: unknown property: %s", name.c_str ());
+            }
+        }
+      break;
+
+    case '(':
+        {
+          refcount++;
+
+          cdef_object this_obj (this);
+
+          Array<cdef_object> arr (dim_vector (1, 1), this_obj);
+
+          cdef_object new_obj = cdef_object (new cdef_object_array (arr));
+
+          new_obj.set_class (get_class ());
+
+          octave_value tmp = new_obj.subsasgn (type, idx, rhs);
+
+          if (! error_state)
+            retval = tmp;
+        }
+      break;
+
+    default:
+      error ("subsasgn: object cannot be index with `%c'", type[0]);
+      break;
+    }
+
+  return retval;
+}
+
+void
+cdef_object_scalar::mark_for_construction (const cdef_class& cls)
+{
+  std::string cls_name = cls.get_name ();
+
+  Cell supcls = cls.get ("SuperClasses").cell_value ();
+
+  if (! error_state)
+    {
+      std::list<cdef_class> supcls_list = lookup_classes (supcls);
+
+      if (! error_state)
+        ctor_list[cls] = supcls_list;
+    }
+}
+
+octave_value_list
+cdef_object_array::subsref (const std::string& type,
+                            const std::list<octave_value_list>& idx,
+                            int /* nargout */, size_t& skip,
+                            const cdef_class& /* context */, bool auto_add)
+{
+  octave_value_list retval;
+
+  skip = 1;
+
+  switch (type[0])
+    {
+    case '(':
+        {
+          const octave_value_list& ival = idx.front ();
+          bool is_scalar = true;
+          Array<idx_vector> iv (dim_vector (1, ival.length ()));
+
+          for (int i = 0; ! error_state && i < ival.length (); i++)
+            {
+              iv(i) = ival(i).index_vector ();
+              if (! error_state)
+                is_scalar = is_scalar && iv(i).is_scalar ();
+            }
+
+          if (! error_state)
+            {
+              Array<cdef_object> ires = array.index (iv, auto_add);
+
+              if (! error_state)
+                {
+                  // If resizing is enabled (auto_add = true), it's possible
+                  // indexing was out-of-bound and the result array contains
+                  // invalid cdef_objects.
+
+                  if (auto_add)
+                    fill_empty_values (ires);
+
+                  if (is_scalar)
+                    retval(0) = to_ov (ires(0));
+                  else
+                    {
+                      cdef_object array_obj (new cdef_object_array (ires));
+
+                      array_obj.set_class (get_class ());
+
+                      retval(0) = to_ov (array_obj);
+                    }
+                }
+            }
+        }
+      break;
+
+    case '.':
+      if (type.size () == 1 && idx.size () == 1)
+        {
+          Cell c (dims ());
+
+          octave_idx_type n = array.numel ();
+
+          // dummy variables
+          size_t dummy_skip;
+          cdef_class dummy_cls;
+
+          for (octave_idx_type i = 0; i < n; i++)
+            {
+              octave_value_list r = array(i).subsref (type, idx, 1, dummy_skip,
+                                                      dummy_cls);
+
+              if (! error_state)
+                {
+                  if (r.length () > 0)
+                    c(i) = r(0);
+                }
+              else
+                break;
+            }
+
+          if (! error_state)
+            retval(0) = octave_value (c, true);
+
+          break;
+        }
+      // fall through "default"
+
+    default:
+      ::error ("can't perform indexing operation on array of %s objects",
+               class_name ().c_str ());
+      break;
+    }
+
+  return retval;
+}
+
+octave_value
+cdef_object_array::subsasgn (const std::string& type,
+                             const std::list<octave_value_list>& idx,
+                             const octave_value& rhs)
+{
+  octave_value retval;
+
+  switch (type[0])
+    {
+    case '(':
+      if (type.length () == 1)
+        {
+          cdef_object rhs_obj = to_cdef (rhs);
+
+          if (! error_state)
+            {
+              if (rhs_obj.get_class () == get_class ())
+                {
+                  const octave_value_list& ival = idx.front ();
+                  bool is_scalar = true;
+                  Array<idx_vector> iv (dim_vector (1, ival.length ()));
+
+                  for (int i = 0; ! error_state && i < ival.length (); i++)
+                    {
+                      iv(i) = ival(i).index_vector ();
+                      if (! error_state)
+                        is_scalar = is_scalar && iv(i).is_scalar ();
+                    }
+
+                  if (! error_state)
+                    {
+                      Array<cdef_object> rhs_mat;
+
+                      if (! rhs_obj.is_array ())
+                        {
+                          rhs_mat = Array<cdef_object> (dim_vector (1, 1));
+                          rhs_mat(0) = rhs_obj;
+                        }
+                      else
+                        rhs_mat = rhs_obj.array_value ();
+
+                      if (! error_state)
+                        {
+                          octave_idx_type n = array.numel ();
+
+                          array.assign (iv, rhs_mat, cdef_object ());
+
+                          if (! error_state)
+                            {
+                              if (array.numel () > n)
+                                fill_empty_values ();
+
+                              if (! error_state)
+                                {
+                                  refcount++;
+                                  retval = to_ov (cdef_object (this));
+                                }
+                            }
+                        }
+                    }
+                }
+              else
+                ::error ("can't assign %s object into array of %s objects.",
+                         rhs_obj.class_name ().c_str (),
+                         class_name ().c_str ());
+            }
+        }
+      else
+        {
+          const octave_value_list& ival = idx.front ();
+
+          bool is_scalar = true;
+
+          Array<idx_vector> iv (dim_vector (1, ival.length ()));
+
+          for (int i = 0; ! error_state && i < ival.length (); i++)
+            {
+              iv(i) = ival(i).index_vector ();
+
+              if (! error_state)
+                {
+                  is_scalar = is_scalar && iv(i).is_scalar ();
+
+                  if (! is_scalar)
+                    error ("subsasgn: invalid indexing for object array "
+                           "assignment, the index must reference a single "
+                           "object in the array.");
+                }
+            }
+
+          if (! error_state)
+            {
+              Array<cdef_object> a = array.index (iv, true);
+
+              if (a.numel () != 1)
+                error ("subsasgn: invalid indexing for object array "
+                       "assignment");
+
+              if (! error_state)
+                {
+                  cdef_object obj = a(0);
+
+                  int ignore_copies = 0;
+
+                  // If the object in 'a' is not valid, this means the index
+                  // was out-of-bound and we need to create a new object.
+
+                  if (! obj.ok ())
+                    obj = get_class ().construct_object (octave_value_list ());
+                  else
+                    // Optimize the subsasgn call to come. There are 2 copies
+                    // that we can safely ignore:
+                    // - 1 in "array"
+                    // - 1 in "a"
+                    ignore_copies = 2;
+
+                  std::list<octave_value_list> next_idx (idx);
+
+                  next_idx.erase (next_idx.begin ());
+
+                  octave_value tmp = obj.subsasgn (type.substr (1), next_idx,
+                                                   rhs, ignore_copies);
+
+                  if (! error_state)
+                    {
+                      cdef_object robj = to_cdef (tmp);
+
+                      if (robj.ok ()
+                          && ! robj.is_array ()
+                          && robj.get_class () == get_class ())
+                        {
+                          // Small optimization, when dealing with handle
+                          // objects, we don't need to re-assign the result
+                          // of subsasgn back into the array.
+
+                          if (! robj.is (a(0)))
+                            {
+                              Array<cdef_object> rhs_a (dim_vector (1, 1),
+                                                        robj);
+
+                              octave_idx_type n = array.numel ();
+
+                              array.assign (iv, rhs_a);
+
+                              if (array.numel () > n)
+                                fill_empty_values ();
+                            }
+
+                          refcount++;
+
+                          retval = to_ov (cdef_object (this));
+                        }
+                      else
+                        error ("subasgn: invalid assignment into array of %s "
+                               "objects", class_name ().c_str ());
+                    }
+                }
+            }
+        }
+      break;
+
+    default:
+      ::error ("can't perform indexing operation on array of %s objects",
+               class_name ().c_str ());
+      break;
+    }
+
+  return retval;
+}
+
+void
+cdef_object_array::fill_empty_values (Array<cdef_object>& arr)
+{
+  cdef_class cls = get_class ();
+
+  if (! error_state)
+    {
+      cdef_object obj;
+
+      int n = arr.numel ();
+
+      for (int i = 0; ! error_state && i < n; i++)
+        {
+          if (! arr.xelem (i).ok ())
+            {
+              if (! obj.ok ())
+                {
+                  obj = cls.construct_object (octave_value_list ());
+
+                  if (! error_state)
+                    arr.xelem (i) = obj;
+                }
+              else
+                arr.xelem (i) = obj.copy ();
+            }
+        }
+    }
+}
+  
+bool cdef_object_scalar::is_constructed_for (const cdef_class& cls) const
+{
+  return (is_constructed ()
+          || ctor_list.find (cls) == ctor_list.end ());
+}
+
+bool cdef_object_scalar::is_partially_constructed_for (const cdef_class& cls) const
+{
+  std::map< cdef_class, std::list<cdef_class> >::const_iterator it;
+
+  if (is_constructed ())
+    return true;
+  else if ((it = ctor_list.find (cls)) == ctor_list.end ()
+           || it->second.empty ())
+    return true;
+
+  for (std::list<cdef_class>::const_iterator lit = it->second.begin ();
+       lit != it->second.end (); ++lit)
+    if (! is_constructed_for (*lit))
+      return false;
+
+  return true;
+}
+
+handle_cdef_object::~handle_cdef_object (void)
+{
+  gnulib::printf ("deleting %s object (handle)\n",
+                  get_class ().get_name ().c_str ());
+}
+
+value_cdef_object::~value_cdef_object (void)
+{
+  gnulib::printf ("deleting %s object (value)\n",
+                  get_class ().get_name ().c_str ());
+}
+
+cdef_class::cdef_class_rep::cdef_class_rep (const std::list<cdef_class>& superclasses)
+     : cdef_meta_object_rep (), member_count (0), handle_class (false),
+       object_count (0), meta (false)
+{
+  put ("SuperClasses", to_ov (superclasses));
+  implicit_ctor_list = superclasses;
+}
+
+cdef_method
+cdef_class::cdef_class_rep::find_method (const std::string& nm, bool local)
+{
+  method_iterator it = method_map.find (nm);
+
+  if (it == method_map.end ())
+    {
+      // FIXME: look into class directory
+    }
+  else
+    {
+      cdef_method& meth = it->second;
+
+      // FIXME: check if method reload needed
+
+      if (meth.ok ())
+        return meth;
+    }
+
+  if (! local)
+    {
+      // Look into superclasses
+
+      Cell super_classes = get ("SuperClasses").cell_value ();
+
+      for (int i = 0; i < super_classes.numel (); i++)
+        {
+          cdef_class cls = lookup_class (super_classes(i));
+
+          if (! error_state)
+            {
+              cdef_method meth = cls.find_method (nm);
+
+              if (meth.ok ())
+                return meth;
+            }
+        }
+    }
+
+  return cdef_method ();
+}
+
+class ctor_analyzer : public tree_walker
+{
+public:
+  ctor_analyzer (const std::string& ctor, const std::string& obj)
+    : tree_walker (), who (ctor), obj_name (obj) { }
+
+  void visit_statement_list (tree_statement_list& t)
+    {
+      for (tree_statement_list::const_iterator it = t.begin ();
+           ! error_state && it != t.end (); ++it)
+        (*it)->accept (*this);
+    }
+
+  void visit_statement (tree_statement& t)
+    {
+      if (t.is_expression ())
+        t.expression ()->accept (*this);
+    }
+
+  void visit_simple_assignment (tree_simple_assignment& t)
+    {
+      t.right_hand_side ()->accept (*this);
+    }
+
+  void visit_multi_assignment (tree_multi_assignment& t)
+    {
+      t.right_hand_side ()->accept (*this);
+    }
+
+  void visit_index_expression (tree_index_expression& t)
+    {
+      t.expression ()->accept (*this);
+    }
+
+  void visit_funcall (tree_funcall& t)
+    {
+      octave_value fcn = t.function ();
+
+      if (fcn.is_function ())
+        {
+          octave_function *of = fcn.function_value (true);
+
+          if (of)
+            {
+              if (of->name () == "__superclass_reference__")
+                {
+                  octave_value_list args = t.arguments ();
+
+                  if (args(0).string_value () == obj_name)
+                    {
+                      std::string class_name = args(1).string_value ();
+
+                      cdef_class cls = lookup_class (class_name, false);
+
+                      if (cls.ok ())
+                        ctor_list.push_back (cls);
+                    }
+                }
+            }
+        }
+    }
+
+  std::list<cdef_class> get_constructor_list (void) const
+    { return ctor_list; }
+
+  // NO-OP
+  void visit_anon_fcn_handle (tree_anon_fcn_handle&) { }
+  void visit_argument_list (tree_argument_list&) { }
+  void visit_binary_expression (tree_binary_expression&) { }
+  void visit_break_command (tree_break_command&) { }
+  void visit_colon_expression (tree_colon_expression&) { }
+  void visit_continue_command (tree_continue_command&) { }
+  void visit_global_command (tree_global_command&) { }
+  void visit_persistent_command (tree_persistent_command&) { }
+  void visit_decl_elt (tree_decl_elt&) { }
+  void visit_decl_init_list (tree_decl_init_list&) { }
+  void visit_simple_for_command (tree_simple_for_command&) { }
+  void visit_complex_for_command (tree_complex_for_command&) { }
+  void visit_octave_user_script (octave_user_script&) { }
+  void visit_octave_user_function (octave_user_function&) { }
+  void visit_function_def (tree_function_def&) { }
+  void visit_identifier (tree_identifier&) { }
+  void visit_if_clause (tree_if_clause&) { }
+  void visit_if_command (tree_if_command&) { }
+  void visit_if_command_list (tree_if_command_list&) { }
+  void visit_switch_case (tree_switch_case&) { }
+  void visit_switch_case_list (tree_switch_case_list&) { }
+  void visit_switch_command (tree_switch_command&) { }
+  void visit_matrix (tree_matrix&) { }
+  void visit_cell (tree_cell&) { }
+  void visit_no_op_command (tree_no_op_command&) { }
+  void visit_constant (tree_constant&) { }
+  void visit_fcn_handle (tree_fcn_handle&) { }
+  void visit_parameter_list (tree_parameter_list&) { }
+  void visit_postfix_expression (tree_postfix_expression&) { }
+  void visit_prefix_expression (tree_prefix_expression&) { }
+  void visit_return_command (tree_return_command&) { }
+  void visit_return_list (tree_return_list&) { }
+  void visit_try_catch_command (tree_try_catch_command&) { }
+  void visit_unwind_protect_command (tree_unwind_protect_command&) { }
+  void visit_while_command (tree_while_command&) { }
+  void visit_do_until_command (tree_do_until_command&) { }
+
+private:
+  /* The name of the constructor being analyzed */
+  std::string who;
+
+  /* The name of the first output argument of the constructor */
+  std::string obj_name;
+
+  /* The list of superclass constructors that are explicitly called */
+  std::list<cdef_class> ctor_list;
+};
+
+void
+cdef_class::cdef_class_rep::install_method (const cdef_method& meth)
+{
+  method_map[meth.get_name ()] = meth;
+
+  member_count++;
+
+  if (meth.is_constructor ())
+    {
+      // Analyze the constructor code to determine what superclass
+      // constructors are called explicitly.
+
+      octave_function *of = meth.get_function ().function_value (true);
+
+      if (of)
+        {
+          octave_user_function *uf = of->user_function_value (true);
+
+          if (uf)
+            {
+              tree_parameter_list *ret_list = uf->return_list ();
+              tree_statement_list *body = uf->body ();
+
+              if (ret_list && ret_list->size () == 1)
+                {
+                  std::string obj_name = ret_list->front ()->name ();
+                  ctor_analyzer a (meth.get_name (), obj_name);
+
+                  body->accept (a);
+                  if (! error_state)
+                    {
+                      std::list<cdef_class> explicit_ctor_list
+                        = a.get_constructor_list ();
+
+                      for (std::list<cdef_class>::const_iterator it = explicit_ctor_list.begin ();
+                           ! error_state && it != explicit_ctor_list.end (); ++it)
+                        {
+                          gnulib::printf ("explicit superclass constructor: %s\n",
+                                          it->get_name ().c_str ());
+                          implicit_ctor_list.remove (*it);
+                        }
+                    }
+                }
+              else
+                ::error ("%s: invalid constructor output arguments",
+                         meth.get_name ().c_str ());
+            }
+        }
+    }
+}
+
+void
+cdef_class::cdef_class_rep::load_all_methods (void)
+{
+  // FIXME: re-scan class directory
+}
+
+Cell
+cdef_class::cdef_class_rep::get_methods (void)
+{
+  std::map<std::string,cdef_method> meths;
+
+  find_methods (meths, false);
+
+  if (! error_state)
+    {
+      Cell c (meths.size (), 1);
+
+      int idx = 0;
+
+      for (std::map<std::string,cdef_method>::const_iterator it = meths.begin ();
+           it != meths.end (); ++it, ++idx)
+        c (idx, 0) = to_ov (it->second);
+
+      return c;
+    }
+
+  return Cell ();
+}
+
+void
+cdef_class::cdef_class_rep::find_methods (std::map<std::string, cdef_method>& meths,
+                                          bool only_inherited)
+{
+  load_all_methods ();
+
+  method_const_iterator it;
+
+  for (it = method_map.begin (); it != method_map.end (); ++it)
+    {
+      if (! it->second.is_constructor ())
+        {
+          std::string nm = it->second.get_name ();
+
+          if (meths.find (nm) == meths.end ())
+            {
+              if (only_inherited)
+                {
+                  octave_value acc = it->second.get ("Access");
+
+                  if (! acc.is_string ()
+                      || acc.string_value () == "private")
+                    continue;
+                }
+
+              meths[nm] = it->second;
+            }
+        }
+    }
+
+  // Look into superclasses
+
+  Cell super_classes = get ("SuperClasses").cell_value ();
+
+  for (int i = 0; i < super_classes.numel (); i++)
+    {
+      cdef_class cls = lookup_class (super_classes(i));
+
+      if (! error_state)
+        cls.get_rep ()->find_methods (meths, true);
+      else
+        break;
+    }
+}
+
+cdef_property
+cdef_class::cdef_class_rep::find_property (const std::string& nm)
+{
+  property_iterator it = property_map.find (nm);
+
+  if (it != property_map.end ())
+    {
+      cdef_property& prop = it->second;
+
+      if (prop.ok ())
+        return prop;
+    }
+
+  // Look into superclasses
+
+  Cell super_classes = get ("SuperClasses").cell_value ();
+
+  for (int i = 0; i < super_classes.numel (); i++)
+    {
+      cdef_class cls = lookup_class (super_classes(i));
+
+      if (! error_state)
+        {
+          cdef_property prop = cls.find_property (nm);
+
+          if (prop.ok ())
+            return prop;
+        }
+    }
+
+  return cdef_property ();
+}
+
+void
+cdef_class::cdef_class_rep::install_property (const cdef_property& prop)
+{
+  property_map[prop.get_name ()] = prop;
+
+  member_count++;
+}
+
+Cell
+cdef_class::cdef_class_rep::get_properties (void)
+{
+  std::map<std::string,cdef_property> props;
+
+  find_properties (props, false);
+
+  if (! error_state)
+    {
+      Cell c (props.size (), 1);
+
+      int idx = 0;
+
+      for (std::map<std::string,cdef_property>::const_iterator it = props.begin ();
+           it != props.end (); ++it, ++idx)
+        c (idx, 0) = to_ov (it->second);
+
+      return c;
+    }
+
+  return Cell ();
+}
+
+void
+cdef_class::cdef_class_rep::find_properties (std::map<std::string,cdef_property>& props,
+                                             bool only_inherited)
+{
+  property_const_iterator it;
+
+  for (it = property_map.begin (); ! error_state && it != property_map.end ();
+       ++it)
+    {
+      std::string nm = it->second.get_name ();
+
+      if (props.find (nm) == props.end ())
+        {
+          if (only_inherited)
+            {
+              octave_value acc = it->second.get ("GetAccess");
+
+              if (! acc.is_string ()
+                  || acc.string_value () == "private")
+                continue;
+            }
+
+          props[nm] = it->second;
+        }
+    }
+
+  // Look into superclasses
+
+  Cell super_classes = get ("SuperClasses").cell_value ();
+
+  for (int i = 0; ! error_state && i < super_classes.numel (); i++)
+    {
+      cdef_class cls = lookup_class (super_classes(i));
+
+      if (! error_state)
+        cls.get_rep ()->find_properties (props, true);
+      else
+        break;
+    }
+}
+
+void
+cdef_class::cdef_class_rep::find_names (std::set<std::string>& names,
+                                        bool all)
+{
+  load_all_methods ();
+
+  for (method_const_iterator it = method_map.begin ();
+       ! error_state && it != method_map.end(); ++it)
+    {
+      if (! it->second.is_constructor ())
+        {
+          std::string nm = it->second.get_name ();
+
+          if (! all)
+            {
+              octave_value acc = it->second.get ("Access");
+
+              if (! acc.is_string()
+                  || acc.string_value () != "public")
+                continue;
+            }
+
+          names.insert (nm);
+        }
+    }
+
+  for (property_const_iterator it = property_map.begin ();
+       ! error_state && it != property_map.end (); ++it)
+    {
+      std::string nm = it->second.get_name ();
+
+      if (! all)
+        {
+          octave_value acc = it->second.get ("GetAccess");
+
+          if (! acc.is_string()
+              || acc.string_value () != "public")
+            continue;
+        }
+
+      names.insert (nm);
+    }
+
+  // Look into superclasses
+
+  Cell super_classes = get ("SuperClasses").cell_value ();
+
+  for (int i = 0; ! error_state && i < super_classes.numel (); i++)
+    {
+      cdef_class cls = lookup_class (super_classes(i));
+
+      if (! error_state)
+        cls.get_rep ()->find_names (names, all);
+      else
+        break;
+    }
+}
+
+string_vector
+cdef_class::cdef_class_rep::get_names (void)
+{
+  std::set<std::string> names;
+
+  find_names (names, false);
+
+  if (! error_state)
+    {
+      string_vector v (names.size ());
+
+      int idx = 0;
+      for (std::set<std::string>::const_iterator it = names.begin ();
+           it != names.end (); ++it, ++idx)
+        v[idx] = *it;
+
+      return v.sort (true);
+    }
+
+  return string_vector ();
+}
+
+void
+cdef_class::cdef_class_rep::delete_object (cdef_object obj)
+{
+  method_iterator it = method_map.find ("delete");
+
+  if (it != method_map.end ())
+    {
+      cdef_class cls = obj.get_class ();
+
+      obj.set_class (wrap ());
+
+      it->second.execute (obj, octave_value_list (), 0, false);
+
+      obj.set_class (cls);
+    }
+
+  // FIXME: should we destroy corresponding properties here?
+
+  // Call "delete" in super classes
+
+  Cell super_classes = get ("SuperClasses").cell_value ();
+
+  for (int i = 0; i < super_classes.numel (); i++)
+    {
+      cdef_class cls = lookup_class (super_classes(i));
+
+      if (!error_state)
+        cls.delete_object (obj);
+    }
+}
+
+octave_value_list
+cdef_class::cdef_class_rep::meta_subsref (const std::string& type,
+                                          const std::list<octave_value_list>& idx,
+                                          int nargout)
+{
+  size_t skip = 1;
+
+  octave_value_list retval;
+
+  switch (type[0])
+    {
+    case '(':
+      // Constructor call
+      gnulib::printf ("constructor\n");
+      retval(0) = construct (idx.front ());
+      break;
+
+    case '.':
+      // Static method, constant (or property?)
+      gnulib::printf ("static method/property\n");
+      if (idx.front ().length () == 1)
+        {
+          std::string nm = idx.front ()(0).string_value ();
+
+          if (! error_state)
+            {
+              cdef_method meth = find_method (nm);
+
+              if (meth.ok ())
+                {
+                  if (meth.is_static ())
+                    {
+                      octave_value_list args;
+
+                      if (type.length () > 1 && idx.size () > 1
+                          && type[1] == '(')
+                        {
+                          args = *(++(idx.begin ()));
+                          skip++;
+                        }
+
+                      retval = meth.execute (args, (type.length () > skip
+                                                    ? 1 : nargout), true,
+                                             "meta.class");
+                    }
+                  else
+                    ::error ("method `%s' is not static", nm.c_str ());
+                }
+              else
+                {
+                  cdef_property prop = find_property (nm);
+
+                  if (prop.ok ())
+                    {
+                      if (prop.is_constant ())
+                        retval(0) = prop.get_value (true, "meta.class");
+                      else
+                        ::error ("property `%s' is not constant",
+                                 nm.c_str ());
+                    }
+                  else
+                    ::error ("no such method or property `%s'", nm.c_str ());
+                }
+            }
+          else
+            ::error ("invalid meta.class indexing, expected a method or property name");
+        }
+      else
+        ::error ("invalid meta.class indexing");
+      break;
+
+    default:
+      ::error ("invalid meta.class indexing");
+      break;
+    }
+
+  if (! error_state)
+    {
+      if (type.length () > skip && idx.size () > skip && ! retval.empty ())
+        retval = retval(0).next_subsref (nargout, type, idx, skip);
+    }
+
+  return retval;
+}
+
+void
+cdef_class::cdef_class_rep::meta_release (void)
+{
+  cdef_manager::unregister_class (wrap ());
+}
+
+void
+cdef_class::cdef_class_rep::initialize_object (cdef_object& obj)
+{
+  // Populate the object with default property values
+
+  std::list<cdef_class> super_classes = lookup_classes (get ("SuperClasses").cell_value ());
+
+  if (! error_state)
+    {
+      for (std::list<cdef_class>::iterator it = super_classes.begin ();
+           ! error_state && it != super_classes.end (); ++it)
+        it->initialize_object (obj);
+
+      if (! error_state)
+        {
+          for (property_const_iterator it = property_map.begin ();
+               ! error_state && it != property_map.end (); ++it)
+            {
+              if (! it->second.get ("Dependent").bool_value ())
+                {
+                  octave_value pvalue = it->second.get ("DefaultValue");
+
+                  if (pvalue.is_defined ())
+                    obj.put (it->first, pvalue);
+                  else
+                    obj.put (it->first, octave_value (Matrix ()));
+                }
+            }
+
+          if (! error_state)
+            {
+              refcount++;
+              obj.mark_for_construction (cdef_class (this));
+            }
+        }
+    }
+}
+
+void
+cdef_class::cdef_class_rep::run_constructor (cdef_object& obj,
+                                             const octave_value_list& args)
+{
+  octave_value_list empty_args;
+
+  for (std::list<cdef_class>::const_iterator it = implicit_ctor_list.begin ();
+       ! error_state && it != implicit_ctor_list.end (); ++it)
+    {
+      cdef_class supcls = lookup_class (*it);
+
+      if (! error_state)
+        supcls.run_constructor (obj, empty_args);
+    }
+
+  if (error_state)
+    return;
+
+  std::string cls_name = get_name ();
+  std::string ctor_name = get_base_name (cls_name);
+
+  cdef_method ctor = find_method (ctor_name);
+
+  if (ctor.ok ())
+    {
+      octave_value_list ctor_args (args);
+      octave_value_list ctor_retval;
+
+      ctor_args.prepend (to_ov (obj));
+      ctor_retval = ctor.execute (ctor_args, 1, true, "constructor");
+
+      if (! error_state)
+        {
+          if (ctor_retval.length () == 1)
+            obj = to_cdef (ctor_retval(0));
+          else
+            {
+              ::error ("%s: invalid number of output arguments for classdef constructor",
+                       ctor_name.c_str ());
+              return;
+            }
+        }
+    }
+
+  obj.mark_as_constructed (wrap ());
+}
+
+octave_value
+cdef_class::cdef_class_rep::construct (const octave_value_list& args)
+{
+  cdef_object obj = construct_object (args);
+
+  if (! error_state && obj.ok ())
+    return to_ov (obj);
+
+  return octave_value ();
+}
+
+cdef_object
+cdef_class::cdef_class_rep::construct_object (const octave_value_list& args)
+{
+  if (! is_abstract ())
+    {
+      cdef_object obj;
+
+      if (is_meta_class ())
+        {
+          // This code path is only used to create empty meta objects
+          // as filler for the empty values within a meta object array.
+
+          cdef_class this_cls = wrap ();
+
+          static cdef_object empty_class;
+
+          if (this_cls == cdef_class::meta_class ())
+            {
+              if (! empty_class.ok ())
+                empty_class = make_class ("", std::list<cdef_class> ());
+              obj = empty_class;
+            }
+          else if (this_cls == cdef_class::meta_property ())
+            {
+              static cdef_property empty_property;
+
+              if (! empty_class.ok ())
+                empty_class = make_class ("", std::list<cdef_class> ());
+              if (! empty_property.ok ())
+                empty_property = make_property (empty_class, "");
+              obj = empty_property;
+            }
+          else if (this_cls == cdef_class::meta_method ())
+            {
+              static cdef_method empty_method;
+
+              if (! empty_class.ok ())
+                empty_class = make_class ("", std::list<cdef_class> ());
+              if (! empty_method.ok ())
+                empty_method = make_method (empty_class, "", octave_value ());
+              obj = empty_method;
+            }
+          else if (this_cls == cdef_class::meta_package ())
+            {
+              static cdef_package empty_package;
+
+              if (! empty_package.ok ())
+                empty_package = make_package ("");
+              obj = empty_package;
+            }
+          else
+            panic_impossible ();
+
+          return obj;
+        }
+      else
+        {
+          if (is_handle_class ())
+            obj = cdef_object (new handle_cdef_object ());
+          else
+            obj = cdef_object (new value_cdef_object ());
+          obj.set_class (wrap ());
+
+          initialize_object (obj);
+
+          if (! error_state)
+            {
+              run_constructor (obj, args);
+
+              if (! error_state)
+                return obj;
+            }
+        }
+    }
+  else
+    error ("cannot instantiate object for abstract class `%s'",
+           get_name ().c_str ());
+
+  return cdef_object ();
+}
+
+static octave_value
+compute_attribute_value (tree_classdef_attribute* t)
+{
+  if (t->expression ())
+    {
+      if (t->expression ()->is_identifier ())
+        {
+          std::string s = t->expression ()->name ();
+
+          if (s == "public")
+            return std::string ("public");
+          else if (s == "protected")
+            return std::string ("protected");
+          else if (s == "private")
+            return std::string ("private");
+        }
+
+      return t->expression ()->rvalue1 ();
+    }
+  else
+    return octave_value (true);
+}
+
+template<class T>
+static std::string
+attribute_value_to_string (T* t, octave_value v)
+{
+  if (v.is_string ())
+    return v.string_value ();
+  else if (t->expression ())
+    return t->expression ()->original_text ();
+  else
+    return std::string ("true");
+}
+
+cdef_class
+cdef_class::make_meta_class (tree_classdef* t, bool is_at_folder)
+{
+  cdef_class retval;
+  std::string class_name, full_class_name;
+
+  // Class creation
+
+  class_name = full_class_name = t->ident ()->name ();
+  if (! t->package_name ().empty ())
+    full_class_name = t->package_name () + "." + full_class_name;
+  gnulib::printf ("class: %s\n", full_class_name.c_str ());
+
+  std::list<cdef_class> slist;
+
+  if (t->superclass_list ())
+    {
+      for (tree_classdef_superclass_list::iterator it = t->superclass_list ()->begin ();
+           ! error_state && it != t->superclass_list ()->end (); ++it)
+        {
+          std::string sclass_name = (*it)->class_name ();
+
+          gnulib::printf ("superclass: %s\n", sclass_name.c_str ());
+
+          cdef_class sclass = lookup_class (sclass_name);
+
+          if (! error_state)
+            {
+              if (! sclass.get ("Sealed").bool_value ())
+                slist.push_back (sclass);
+              else
+                {
+                  ::error ("`%s' cannot inherit from `%s', because it is sealed",
+                           full_class_name.c_str (), sclass_name.c_str ());
+                  return retval;
+                }
+            }
+          else
+            return retval;
+
+        }
+    }
+
+  retval = ::make_class (full_class_name, slist);
+
+  if (error_state)
+    return cdef_class ();
+
+  // Package owning this class
+
+  if (! t->package_name ().empty ())
+    {
+      cdef_package pack = cdef_manager::find_package (t->package_name ());
+
+      if (! error_state && pack.ok ())
+        retval.put ("ContainingPackage", to_ov (pack));
+    }
+
+  // Class attributes
+
+  if (t->attribute_list ())
+    {
+      for (tree_classdef_attribute_list::iterator it = t->attribute_list ()->begin ();
+           it != t->attribute_list ()->end (); ++it)
+        {
+          std::string aname = (*it)->ident ()->name ();
+          octave_value avalue = compute_attribute_value (*it);
+
+          gnulib::printf ("class attribute: %s = %s\n", aname.c_str (),
+                  attribute_value_to_string (*it, avalue).c_str ());
+          retval.put (aname, avalue);
+        }
+    }
+
+  tree_classdef_body* b = t->body ();
+
+  if (b)
+    {
+      // Keep track of the get/set accessor methods. They will be used
+      // later on when creating properties.
+
+      std::map<std::string, octave_value> get_methods;
+      std::map<std::string, octave_value> set_methods;
+
+      // Method blocks
+
+      std::list<tree_classdef_methods_block *> mb_list = b->methods_list ();
+
+      for (tree_classdef_body::methods_list_iterator it = mb_list.begin ();
+           it != mb_list.end (); ++it)
+        {
+          std::map<std::string, octave_value> amap;
+          gnulib::printf ("method block\n");
+
+          // Method attributes
+
+          if ((*it)->attribute_list ())
+            {
+              for (tree_classdef_attribute_list::iterator ait = (*it)->attribute_list ()->begin ();
+                   ait != (*it)->attribute_list ()->end (); ++ait)
+                {
+                  std::string aname = (*ait)->ident ()->name ();
+                  octave_value avalue = compute_attribute_value (*ait);
+
+                  gnulib::printf ("method attribute: %s = %s\n", aname.c_str (),
+                                  attribute_value_to_string (*ait, avalue).c_str ());
+                  amap[aname] = avalue;
+                }
+            }
+
+          // Methods
+
+          if ((*it)->element_list ())
+            {
+              for (tree_classdef_methods_list::iterator mit = (*it)->element_list ()->begin ();
+                   mit != (*it)->element_list ()->end (); ++mit)
+                {
+                  std::string mname = mit->function_value ()->name ();
+                  std::string mprefix = mname.substr (0, 4);
+
+                  if (mprefix == "get.")
+                    get_methods[mname.substr (4)] =
+                      make_fcn_handle (*mit, full_class_name + ">" + mname);
+                  else if (mprefix == "set.")
+                    set_methods[mname.substr (4)] =
+                      make_fcn_handle (*mit, full_class_name + ">" + mname);
+                  else
+                    {
+                      cdef_method meth = make_method (retval, mname, *mit);
+
+                      gnulib::printf ("%s: %s\n", (mname == class_name ? "constructor" : "method"),
+                                      mname.c_str ());
+                      for (std::map<std::string, octave_value>::iterator ait = amap.begin ();
+                           ait != amap.end (); ++ait)
+                        meth.put (ait->first, ait->second);
+
+                      retval.install_method (meth);
+                    }
+                }
+            }
+        }
+
+      if (is_at_folder)
+        {
+          // Look for all external methods visible on octave path at the
+          // time of loading of the class.
+          //
+          // TODO: This is an "extension" to Matlab behavior, which only
+          // looks in the @-folder containing the original classdef
+          // file. However, this is easier to implement it that way at
+          // the moment.
+
+          std::list<std::string> external_methods =
+            load_path::methods (full_class_name);
+
+          for (std::list<std::string>::const_iterator it = external_methods.begin ();
+               it != external_methods.end (); ++it)
+            {
+              // TODO: should we issue a warning if the method is already
+              // defined in the classdef file?
+
+              if (*it != class_name
+                  && ! retval.find_method (*it, true).ok ())
+                {
+                  // Create a dummy method that is used until the actual
+                  // method is loaded.
+
+                  octave_user_function *fcn = new octave_user_function ();
+
+                  fcn->stash_function_name (*it);
+
+                  cdef_method meth = make_method (retval, *it,
+                                                  octave_value (fcn));
+
+                  retval.install_method (meth);
+                }
+            }
+        }
+
+      // Property blocks
+
+      // FIXME: default property expression should be able to call static
+      //        methods of the class being constructed. A restricted CLASSNAME
+      //        symbol should be added to the scope before evaluating default
+      //        value expressions.
+
+      std::list<tree_classdef_properties_block *> pb_list = b->properties_list ();
+
+      for (tree_classdef_body::properties_list_iterator it = pb_list.begin ();
+           it != pb_list.end (); ++it)
+        {
+          std::map<std::string, octave_value> amap;
+          gnulib::printf ("property block\n");
+
+          // Property attributes
+
+          if ((*it)->attribute_list ())
+            {
+              for (tree_classdef_attribute_list::iterator ait = (*it)->attribute_list ()->begin ();
+                   ait != (*it)->attribute_list ()->end (); ++ait)
+                {
+                  std::string aname = (*ait)->ident ()->name ();
+                  octave_value avalue = compute_attribute_value (*ait);
+
+                  gnulib::printf ("property attribute: %s = %s\n", aname.c_str (),
+                          attribute_value_to_string (*ait, avalue).c_str ());
+                  if (aname == "Access")
+                    {
+                      amap["GetAccess"] = avalue;
+                      amap["SetAccess"] = avalue;
+                    }
+                  else
+                    amap[aname] = avalue;
+                }
+            }
+
+          // Properties
+
+          if ((*it)->element_list ())
+            {
+              for (tree_classdef_property_list::iterator pit = (*it)->element_list ()->begin ();
+                   pit != (*it)->element_list ()->end (); ++pit)
+                {
+                  std::string prop_name = (*pit)->ident ()->name ();
+
+                  cdef_property prop = ::make_property (retval, prop_name);
+
+                  gnulib::printf ("property: %s\n", (*pit)->ident ()->name ().c_str ());
+                  if ((*pit)->expression ())
+                    {
+                      octave_value pvalue = (*pit)->expression ()->rvalue1 ();
+
+                      gnulib::printf ("property default: %s\n",
+                              attribute_value_to_string (*pit, pvalue).c_str ());
+                      prop.put ("DefaultValue", pvalue);
+                    }
+
+                  // Install property attributes. This is done before assigning the
+                  // property accessors so we can do validationby using cdef_property
+                  // methods.
+
+                  for (std::map<std::string, octave_value>::iterator ait = amap.begin ();
+                       ait != amap.end (); ++ait)
+                    prop.put (ait->first, ait->second);
+
+                  // Install property access methods, if any. Remove the accessor
+                  // methods from the temporary storage map, so we can detect which
+                  // ones are invalid and do not correspond to a defined property.
+
+                  std::map<std::string, octave_value>::iterator git =
+                    get_methods.find (prop_name);
+
+                  if (git != get_methods.end ())
+                    {
+                      make_function_of_class (retval, git->second);
+                      prop.put ("GetMethod", git->second);
+                      get_methods.erase (git);
+                    }
+
+                  std::map<std::string, octave_value>::iterator sit =
+                    set_methods.find (prop_name);
+
+                  if (sit != set_methods.end ())
+                    {
+                      make_function_of_class (retval, sit->second);
+                      prop.put ("SetMethod", sit->second);
+                      set_methods.erase (sit);
+                    }
+
+                  retval.install_property (prop);
+                }
+            }
+        }
+    }
+
+  return retval;
+}
+
+octave_function*
+cdef_class::get_method_function (const std::string& /* nm */)
+{
+  octave_classdef_meta* p = new octave_classdef_meta (*this);
+
+  return p;
+}
+
+octave_value
+cdef_property::cdef_property_rep::get_value (const cdef_object& obj,
+                                             bool do_check_access,
+                                             const std::string& who)
+{
+  octave_value retval;
+
+  if (do_check_access && ! check_get_access ())
+    {
+      gripe_property_access (who, wrap (), false);
+
+      return retval;
+    }
+
+  if (! obj.is_constructed ())
+    {
+      cdef_class cls (to_cdef (get ("DefiningClass")));
+
+      if (! obj.is_partially_constructed_for (cls))
+        {
+          ::error ("cannot reference properties of class `%s' for non-constructed object",
+                   cls.get_name ().c_str ());
+          return retval;
+        }
+    }
+ 
+  octave_value get_fcn = get ("GetMethod");
+
+  // FIXME: should check whether we're already in get accessor method
+
+  if (get_fcn.is_empty () || is_method_executing (get_fcn, obj))
+    retval = obj.get (get ("Name").string_value ());
+  else
+    {
+      octave_value_list args;
+
+      args(0) = to_ov (obj);
+      
+      args = execute_ov (get_fcn, args, 1);
+
+      if (! error_state)
+        retval = args(0);
+    }
+
+  return retval;
+}
+
+octave_value
+cdef_property::cdef_property_rep::get_value (bool do_check_access,
+                                             const std::string& who)
+{
+  if (do_check_access && ! check_get_access ())
+    {
+      gripe_property_access (who, wrap (), false);
+
+      return octave_value ();
+    }
+
+  return get ("DefaultValue");
+}
+
+bool
+cdef_property::cdef_property_rep::is_recursive_set (const cdef_object& /* obj */) const
+{
+  // FIXME: implement
+  return false;
+}
+
+void
+cdef_property::cdef_property_rep::set_value (cdef_object& obj,
+                                             const octave_value& val,
+                                             bool do_check_access,
+                                             const std::string& who)
+{
+  if (do_check_access && ! check_set_access ())
+    {
+      gripe_property_access (who, wrap (), true);
+
+      return;
+    }
+
+  if (! obj.is_constructed ())
+    {
+      cdef_class cls (to_cdef (get ("DefiningClass")));
+
+      if (! obj.is_partially_constructed_for (cls))
+        {
+          ::error ("cannot reference properties of class `%s' for non-constructed object",
+                   cls.get_name ().c_str ());
+          return;
+        }
+    }
+ 
+  octave_value set_fcn = get ("SetMethod");
+
+  if (set_fcn.is_empty () || is_method_executing (set_fcn, obj))
+    obj.put (get ("Name").string_value (), val);
+  else
+    {
+      octave_value_list args;
+
+      args(0) = to_ov (obj);
+      args(1) = val;
+
+      args = execute_ov (set_fcn, args, 1);
+
+      if (! error_state)
+        {
+          if (args.length() > 0)
+            {
+              cdef_object new_obj = to_cdef (args(0));
+
+              if (! error_state)
+                obj = new_obj;
+            }
+        }
+    }
+}
+
+bool
+cdef_property::cdef_property_rep::check_get_access (void) const
+{
+  cdef_class cls (to_cdef (get ("DefiningClass")));
+
+  if (! error_state)
+    return ::check_access (cls, get ("GetAccess"), std::string (),
+                           get_name (), false);
+
+  return false;
+}
+
+bool
+cdef_property::cdef_property_rep::check_set_access (void) const
+{
+  cdef_class cls (to_cdef (get ("DefiningClass")));
+
+  if (! error_state)
+    return ::check_access (cls, get ("SetAccess"), std::string (),
+                           get_name (), true);
+
+  return false;
+}
+
+void
+cdef_method::cdef_method_rep::check_method (void)
+{
+  if (is_external ())
+    {
+      if (is_dummy_method (function))
+        {
+          std::string name = get_name ();
+          std::string cls_name = dispatch_type;
+          std::string pack_name;
+
+          size_t pos = cls_name.rfind ('.');
+
+          if (pos != std::string::npos)
+            {
+              pack_name = cls_name.substr (0, pos);
+              cls_name = cls_name.substr (pos + 1);
+            }
+
+          std::string dir_name;
+          std::string file_name = load_path::find_method (cls_name, name,
+                                                          dir_name, pack_name);
+
+          if (! file_name.empty ())
+            {
+              octave_function *fcn = load_fcn_from_file (file_name, dir_name,
+                                                         dispatch_type,
+                                                         pack_name);
+
+              if (fcn)
+                {
+                  function = octave_value (fcn);
+
+                  make_function_of_class (dispatch_type, function);
+                }
+            }
+        }
+      else
+        {
+          // FIXME: check out-of-date status
+        }
+
+      if (is_dummy_method (function))
+        ::error ("no definition found for method `%s' of class `%s'",
+                 get_name ().c_str (), dispatch_type.c_str ());
+    }
+}
+
+octave_value_list
+cdef_method::cdef_method_rep::execute (const octave_value_list& args,
+                                       int nargout, bool do_check_access,
+                                       const std::string& who)
+{
+  octave_value_list retval;
+
+  if (do_check_access && ! check_access ())
+    {
+      gripe_method_access (who, wrap ());
+
+      return retval;
+    }
+
+  if (! get ("Abstract").bool_value ())
+    {
+      check_method ();
+
+      if (! error_state && function.is_defined ())
+        {
+          retval = execute_ov (function, args, nargout);
+        }
+    }
+  else
+    error ("%s: cannot execute abstract method",
+           get ("Name").string_value ().c_str ());
+
+  return retval;
+}
+
+octave_value_list
+cdef_method::cdef_method_rep::execute (const cdef_object& obj,
+                                       const octave_value_list& args,
+                                       int nargout, bool do_check_access,
+                                       const std::string& who)
+{
+  octave_value_list retval;
+
+  if (do_check_access && ! check_access ())
+    {
+      gripe_method_access (who, wrap ());
+
+      return retval;
+    }
+
+  if (! get ("Abstract").bool_value ())
+    {
+      check_method ();
+
+      if (! error_state && function.is_defined ())
+        {
+          octave_value_list new_args;
+
+          new_args.resize (args.length () + 1);
+
+          new_args(0) = to_ov (obj);
+          for (int i = 0; i < args.length (); i++)
+            new_args(i+1) = args(i);
+
+          retval = execute_ov (function, new_args, nargout);
+        }
+    }
+  else
+    error ("%s: cannot execute abstract method",
+           get ("Name").string_value ().c_str ());
+
+  return retval;
+}
+
+bool
+cdef_method::cdef_method_rep::is_constructor (void) const
+{
+  if (function.is_function())
+    return function.function_value ()->is_classdef_constructor ();
+
+  return false;
+}
+
+bool
+cdef_method::cdef_method_rep::check_access (void) const
+{
+  cdef_class cls (to_cdef (get ("DefiningClass")));
+
+  if (! error_state)
+    return ::check_access (cls, get ("Access"), get_name ());
+
+  return false;
+}
+
+octave_value_list
+cdef_method::cdef_method_rep::meta_subsref
+  (const std::string& type, const std::list<octave_value_list>& idx,
+   int nargout)
+{
+  octave_value_list retval;
+
+  switch (type[0])
+    {
+    case '(':
+      retval = execute (idx.front (), type.length () > 1 ? 1 : nargout, true);
+      break;
+
+    default:
+      error ("invalid meta.method indexing");
+      break;
+    }
+
+  if (! error_state)
+    {
+      if (type.length () > 1 && idx.size () > 1 && ! retval.empty ())
+        retval = retval(0).next_subsref (nargout, type, idx, 1);
+    }
+
+  return retval;
+}
+
+static cdef_package
+lookup_package (const std::string& name)
+{
+  return cdef_manager::find_package (name);
+}
+
+static octave_value_list
+package_fromName (const octave_value_list& args, int /* nargout */)
+{
+  octave_value_list retval;
+
+  if (args.length () == 1)
+    {
+      std::string name = args(0).string_value ();
+
+      if (! error_state)
+        retval(0) = to_ov (lookup_package (name));
+      else
+        error ("fromName: invalid package name, expected a string value");
+    }
+  else
+    error ("fromName: invalid number of parameters");
+
+  return retval;
+}
+
+static octave_value_list
+package_get_classes (const octave_value_list& args, int /* nargout */)
+{
+  octave_value_list retval (1, Matrix ());
+
+  if (args.length () == 1 && args(0).type_name () == "object"
+      && args(0).class_name () == "meta.package")
+    {
+      cdef_package pack (to_cdef (args(0)));
+
+      retval(0) = pack.get_classes ();
+    }
+
+  return retval;
+}
+
+static octave_value_list
+package_get_functions (const octave_value_list& args, int /* nargout */)
+{
+  octave_value_list retval (1, Matrix ());
+
+  if (args.length () == 0 && args(0).type_name () == "object"
+      && args(0).class_name () == "meta.package")
+    {
+      cdef_package pack (to_cdef (args(0)));
+
+      retval(0) = pack.get_functions ();
+    }
+
+  return retval;
+}
+
+static octave_value_list
+package_get_packages (const octave_value_list& args, int /* nargout */)
+{
+  octave_value_list retval (1, Matrix ());
+
+  if (args.length () == 0 && args(0).type_name () == "object"
+      && args(0).class_name () == "meta.package")
+    {
+      cdef_package pack (to_cdef (args(0)));
+
+      retval(0) = pack.get_packages ();
+    }
+
+  return retval;
+}
+
+static octave_value_list
+package_getAllPackages (const octave_value_list& /* args */,
+                        int /* nargout */)
+{
+  std::map<std::string, cdef_package> toplevel_packages;
+
+  std::list<std::string> names = load_path::get_all_package_names ();
+
+  toplevel_packages["meta"] = cdef_manager::find_package ("meta", false,
+                                                          false);
+
+  for (std::list<std::string>::const_iterator it = names.begin ();
+       it != names.end (); ++it)
+    toplevel_packages[*it] = cdef_manager::find_package (*it, false, true);
+
+  Cell c (toplevel_packages.size (), 1);
+
+  int i = 0;
+
+  for (std::map<std::string, cdef_package>::const_iterator it = toplevel_packages.begin ();
+       it != toplevel_packages.end (); ++it)
+    c(i++,0) = to_ov (it->second);
+
+  return octave_value_list (octave_value (c));
+}
+
+void
+cdef_package::cdef_package_rep::install_class (const cdef_class& cls,
+                                               const std::string& nm)
+{
+  class_map[nm] = cls;
+
+  member_count++;
+}
+
+void
+cdef_package::cdef_package_rep::install_function (const octave_value& fcn,
+                                                  const std::string& nm)
+{
+  function_map[nm] = fcn;
+}
+
+void
+cdef_package::cdef_package_rep::install_package (const cdef_package& pack,
+                                                 const std::string& nm)
+{
+  package_map[nm] = pack;
+
+  member_count++;
+}
+
+template<class T1, class T2>
+Cell
+map2Cell (const std::map<T1, T2>& m)
+{
+  Cell retval (1, m.size ());
+  int i = 0;
+
+  for (typename std::map<T1, T2>::const_iterator it = m.begin ();
+       it != m.end (); ++it, ++i)
+    {
+      retval(i) = to_ov (it->second);
+    }
+
+  return retval;
+}
+
+Cell
+cdef_package::cdef_package_rep::get_classes (void) const
+{ return map2Cell (class_map); }
+
+Cell
+cdef_package::cdef_package_rep::get_functions (void) const
+{ return map2Cell (function_map); }
+
+Cell
+cdef_package::cdef_package_rep::get_packages (void) const
+{ return map2Cell (package_map); }
+
+octave_value
+cdef_package::cdef_package_rep::find (const std::string& nm)
+{
+  std::string symbol_name = get_name () + "." + nm;
+
+  return symbol_table::find (symbol_name, octave_value_list (), true, false);
+}
+
+octave_value_list
+cdef_package::cdef_package_rep::meta_subsref
+  (const std::string& type, const std::list<octave_value_list>& idx,
+   int nargout)
+{
+  octave_value_list retval;
+
+  switch (type[0])
+    {
+    case '.':
+      if (idx.front ().length () == 1)
+        {
+          std::string nm = idx.front ()(0).string_value ();
+
+          if (! error_state)
+            {
+              gnulib::printf ("meta.package query: %s\n", nm.c_str ());
+
+              octave_value o = find (nm);
+
+              if (o.is_defined ())
+                {
+                  if (o.is_function ())
+                    {
+                      octave_function* fcn = o.function_value ();
+
+                      if (! error_state)
+                        {
+                          // NOTE: the case where the package query is the last
+                          // part of this subsref index is handled in the parse
+                          // tree, because there is some logic to handle magic
+                          // "end" that makes it impossible to execute the
+                          // function call at this stage.
+
+                          if (type.size () > 1 &&
+                              ! fcn->is_postfix_index_handled (type[1]))
+                            {
+                              octave_value_list tmp_args;
+
+                              retval = o.do_multi_index_op (nargout,
+                                                            tmp_args);
+                            }
+                          else
+                            retval(0) = o;
+
+                          if (type.size () > 1 && idx.size () > 1)
+                            retval = retval(0).next_subsref (nargout, type,
+                                                             idx, 1);
+                        }
+                    }
+                  else if (type.size () > 1 && idx.size () > 1)
+                    retval = o.next_subsref (nargout, type, idx, 1);
+                  else
+                    retval(0) = o;
+                }
+              else if (! error_state)
+                error ("member `%s' in package `%s' does not exist",
+                       nm.c_str (), get_name ().c_str ());
+            }
+          else
+            error ("invalid meta.package indexing, expected a symbol name");
+        }
+      else
+        error ("invalid meta.package indexing");
+      break;
+
+    default:
+      error ("invalid meta.package indexing");
+      break;
+    }
+
+  return retval;
+}
+
+void
+cdef_package::cdef_package_rep::meta_release (void)
+{
+  // FIXME: Do we really want to unregister the package, as it
+  //        could still be referenced by classes or sub-packages?
+  //        If the package object is recreated later on, it won't
+  //        match the one already referenced by those classes or
+  //        sub-packages.
+
+  //cdef_manager::unregister_package (wrap ());
+}
+
+cdef_class cdef_class::_meta_class = cdef_class ();
+cdef_class cdef_class::_meta_property = cdef_class ();
+cdef_class cdef_class::_meta_method = cdef_class ();
+cdef_class cdef_class::_meta_package = cdef_class ();
+
+cdef_package cdef_package::_meta = cdef_package ();
+
+void
+install_classdef (void)
+{
+  octave_classdef::register_type ();
+
+  /* bootstrap */
+  cdef_class handle = make_class ("handle");
+  cdef_class meta_class = cdef_class::_meta_class = make_meta_class ("meta.class", handle);
+  handle.set_class (meta_class);
+  meta_class.set_class (meta_class);
+
+  /* meta classes */
+  cdef_class meta_property = cdef_class::_meta_property = make_meta_class ("meta.property", handle);
+  cdef_class meta_method = cdef_class::_meta_method = make_meta_class ("meta.method", handle);
+  cdef_class meta_package = cdef_class::_meta_package = make_meta_class ("meta.package", handle);
+
+  cdef_class meta_event = make_meta_class ("meta.event", handle);
+  cdef_class meta_dynproperty = make_meta_class ("meta.dynamicproperty", handle);
+
+  /* meta.class properties */
+  meta_class.install_property (make_attribute (meta_class, "Abstract"));
+  meta_class.install_property (make_attribute (meta_class, "ConstructOnLoad"));
+  meta_class.install_property (make_property  (meta_class, "ContainingPackage"));
+  meta_class.install_property (make_property  (meta_class, "Description"));
+  meta_class.install_property (make_property  (meta_class, "DetailedDescription"));
+  meta_class.install_property (make_property  (meta_class, "Events"));
+  meta_class.install_property (make_attribute (meta_class, "HandleCompatible"));
+  meta_class.install_property (make_attribute (meta_class, "Hidden"));
+  meta_class.install_property
+      (make_property (meta_class, "InferiorClasses",
+                      make_fcn_handle (class_get_inferiorclasses, "meta.class>get.InferiorClasses"),
+                      "public", Matrix (), "private"));
+  meta_class.install_property
+      (make_property  (meta_class, "Methods",
+                       make_fcn_handle (class_get_methods, "meta.class>get.Methods"),
+                       "public", Matrix (), "private"));
+  meta_class.install_property
+      (make_property  (meta_class, "MethodList",
+                       make_fcn_handle (class_get_methods, "meta.class>get.MethodList"),
+                       "public", Matrix (), "private"));
+  meta_class.install_property (make_attribute (meta_class, "Name"));
+  meta_class.install_property
+      (make_property  (meta_class, "Properties",
+                       make_fcn_handle (class_get_properties, "meta.class>get.Properties"),
+                       "public", Matrix (), "private"));
+  meta_class.install_property
+      (make_property  (meta_class, "PropertyList",
+                       make_fcn_handle (class_get_properties, "meta.class>get.PropertyList"),
+                       "public", Matrix (), "private"));
+  meta_class.install_property (make_attribute (meta_class, "Sealed"));
+  meta_class.install_property
+      (make_property (meta_class, "SuperClasses",
+                      make_fcn_handle (class_get_superclasses, "meta.class>get.SuperClasses"),
+                      "public", Matrix (), "private"));
+  meta_class.install_property
+      (make_property (meta_class, "SuperClassList",
+                      make_fcn_handle (class_get_superclasses, "meta.class>get.SuperClassList"),
+                      "public", Matrix (), "private"));
+  /* meta.class methods */
+  meta_class.install_method (make_method (meta_class, "fromName", class_fromName,
+                                          "public", true));
+  meta_class.install_method (make_method (meta_class, "fevalStatic", class_fevalStatic,
+                                          "public", false));
+  meta_class.install_method (make_method (meta_class, "getConstant", class_getConstant,
+                                          "public", false));
+  meta_class.install_method (make_method (meta_class, "eq", class_eq));
+  meta_class.install_method (make_method (meta_class, "ne", class_ne));
+  meta_class.install_method (make_method (meta_class, "lt", class_lt));
+  meta_class.install_method (make_method (meta_class, "le", class_le));
+  meta_class.install_method (make_method (meta_class, "gt", class_gt));
+  meta_class.install_method (make_method (meta_class, "ge", class_ge));
+
+  /* meta.method properties */
+  meta_method.install_property (make_attribute (meta_method, "Abstract"));
+  meta_method.install_property (make_attribute (meta_method, "Access"));
+  meta_method.install_property (make_attribute (meta_method, "DefiningClass"));
+  meta_method.install_property (make_attribute (meta_method, "Description"));
+  meta_method.install_property (make_attribute (meta_method, "DetailedDescription"));
+  meta_method.install_property (make_attribute (meta_method, "Hidden"));
+  meta_method.install_property (make_attribute (meta_method, "Name"));
+  meta_method.install_property (make_attribute (meta_method, "Sealed"));
+  meta_method.install_property (make_attribute (meta_method, "Static"));
+
+  /* meta.property properties */
+  meta_property.install_property (make_attribute (meta_property, "Name"));
+  meta_property.install_property (make_attribute (meta_property, "Description"));
+  meta_property.install_property (make_attribute (meta_property, "DetailedDescription"));
+  meta_property.install_property (make_attribute (meta_property, "Abstract"));
+  meta_property.install_property (make_attribute (meta_property, "Constant"));
+  meta_property.install_property (make_attribute (meta_property, "GetAccess"));
+  meta_property.install_property (make_attribute (meta_property, "SetAccess"));
+  meta_property.install_property (make_attribute (meta_property, "Dependent"));
+  meta_property.install_property (make_attribute (meta_property, "Transient"));
+  meta_property.install_property (make_attribute (meta_property, "Hidden"));
+  meta_property.install_property (make_attribute (meta_property, "GetObservable"));
+  meta_property.install_property (make_attribute (meta_property, "SetObservable"));
+  meta_property.install_property (make_attribute (meta_property, "GetMethod"));
+  meta_property.install_property (make_attribute (meta_property, "SetMethod"));
+  meta_property.install_property (make_attribute (meta_property, "DefiningClass"));
+  meta_property.install_property
+      (make_property (meta_property, "DefaultValue",
+                      make_fcn_handle (property_get_defaultvalue, "meta.property>get.DefaultValue"),
+                      "public", Matrix (), "private"));
+  meta_property.install_property (make_attribute (meta_property, "HasDefault"));
+  /* meta.property events */
+  // FIXME: add events
+
+  /* handle methods */
+  handle.install_method (make_method (handle, "delete", handle_delete));
+
+  /* meta.package properties */
+  meta_package.install_property (make_attribute (meta_package, "Name"));
+  meta_package.install_property (make_property  (meta_package, "ContainingPackage"));
+  meta_package.install_property
+      (make_property (meta_package, "ClassList",
+                      make_fcn_handle (package_get_classes, "meta.package>get.ClassList"),
+                      "public", Matrix (), "private"));
+  meta_package.install_property
+      (make_property (meta_package, "Classes",
+                      make_fcn_handle (package_get_classes, "meta.package>get.Classes"),
+                      "public", Matrix (), "private"));
+  meta_package.install_property
+      (make_property (meta_package, "FunctionList",
+                      make_fcn_handle (package_get_functions, "meta.package>get.FunctionList"),
+                      "public", Matrix (), "private"));
+  meta_package.install_property
+      (make_property (meta_package, "Functions",
+                      make_fcn_handle (package_get_functions, "meta.package>get.Functions"),
+                      "public", Matrix (), "private"));
+  meta_package.install_property
+      (make_property (meta_package, "PackageList",
+                      make_fcn_handle (package_get_packages, "meta.package>get.PackageList"),
+                      "public", Matrix (), "private"));
+  meta_package.install_property
+      (make_property (meta_package, "Packages",
+                      make_fcn_handle (package_get_packages, "meta.package>get.Packages"),
+                      "public", Matrix (), "private"));
+  meta_package.install_method (make_method (meta_package, "fromName", package_fromName,
+                                            "public", true));
+  meta_package.install_method (make_method (meta_package, "getAllPackages", package_getAllPackages,
+                                            "public", true));
+
+  /* create "meta" package */
+  cdef_package package_meta = cdef_package::_meta = make_package ("meta");
+  package_meta.install_class (meta_class,       "class");
+  package_meta.install_class (meta_property,    "property");
+  package_meta.install_class (meta_method,      "method");
+  package_meta.install_class (meta_package,     "package");
+  package_meta.install_class (meta_event,       "event");
+  package_meta.install_class (meta_dynproperty, "dynproperty");
+
+  /* install built-in classes into the symbol table */
+  symbol_table::install_built_in_function
+    ("meta.class", octave_value (meta_class.get_constructor_function ()));
+  symbol_table::install_built_in_function
+    ("meta.method", octave_value (meta_method.get_constructor_function ()));
+  symbol_table::install_built_in_function
+    ("meta.property", octave_value (meta_property.get_constructor_function ()));
+  symbol_table::install_built_in_function
+    ("meta.package", octave_value (meta_package.get_constructor_function ()));
+  symbol_table::install_built_in_function
+    ("meta.event", octave_value (meta_event.get_constructor_function ()));
+  symbol_table::install_built_in_function
+    ("meta.dynproperty", octave_value (meta_dynproperty.get_constructor_function ()));
+}
+
+//----------------------------------------------------------------------------
+
+cdef_manager* cdef_manager::instance = 0;
+
+void
+cdef_manager::create_instance (void)
+{
+  instance = new cdef_manager ();
+
+  if (instance)
+    singleton_cleanup_list::add (cleanup_instance);
+}
+
+cdef_class
+cdef_manager::do_find_class (const std::string& name,
+                             bool error_if_not_found, bool load_if_not_found)
+{
+  std::map<std::string, cdef_class>::iterator it = all_classes.find (name);
+
+  if (it == all_classes.end ())
+    {
+      if (load_if_not_found)
+        {
+          octave_value ov_cls;
+
+          size_t pos = name.rfind ('.');
+
+          if (pos == std::string::npos)
+            ov_cls = symbol_table::find (name);
+          else
+            {
+              std::string pack_name = name.substr (0, pos);
+
+              cdef_package pack = do_find_package (pack_name, false, true);
+
+              if (pack.ok ())
+                ov_cls = pack.find (name.substr (pos+1));
+            }
+
+          if (ov_cls.is_defined ())
+            it = all_classes.find (name);
+        }
+    }
+
+  if (it == all_classes.end ())
+    {
+      if (error_if_not_found)
+        error ("class not found: %s", name.c_str ());
+    }
+  else
+    {
+      cdef_class cls = it->second;
+
+      if (! cls.is_builtin ())
+        cls = lookup_class (cls);
+
+      if (cls.ok ())
+        return cls;
+      else
+        all_classes.erase (it);
+    }
+
+  return cdef_class ();
+}
+
+octave_function*
+cdef_manager::do_find_method_symbol (const std::string& method_name,
+                                     const std::string& class_name)
+{
+  octave_function *retval = 0;
+
+  cdef_class cls = find_class (class_name, false, false);
+
+  if (cls.ok ())
+    {
+      cdef_method meth = cls.find_method (method_name);
+
+      if (meth.ok ())
+        retval = new octave_classdef_meta (meth);
+    }
+
+  return retval;
+}
+
+cdef_package
+cdef_manager::do_find_package (const std::string& name,
+                               bool error_if_not_found,
+                               bool load_if_not_found)
+{
+  cdef_package retval;
+
+  std::map<std::string, cdef_package>::const_iterator it
+    = all_packages.find (name);
+
+  if (it != all_packages.end ())
+    {
+      retval = it->second;
+
+      if (! retval.ok ())
+        error ("invalid package `%s'", name.c_str ());
+    }
+  else
+    {
+      if (load_if_not_found && load_path::find_package (name))
+        {
+          size_t pos = name.find ('.');
+
+          if (pos == std::string::npos)
+            retval = make_package (name, std::string ());
+          else
+            {
+              std::string parent_name = name.substr (0, pos);
+
+              retval = make_package (name, parent_name);
+            }
+        }
+      else if (error_if_not_found)
+        error ("unknown package `%s'", name.c_str ());
+    }
+
+  return retval;
+}
+
+octave_function*
+cdef_manager::do_find_package_symbol (const std::string& pack_name)
+{
+  octave_function* retval = 0;
+
+  cdef_package pack = find_package (pack_name, false);
+
+  if (pack.ok ())
+    retval = new octave_classdef_meta (pack);
+
+  return retval;
+}
+
+//----------------------------------------------------------------------------
+
+DEFUN (__meta_get_package__, args, , "")
+{
+  octave_value retval;
+
+  if (args.length () == 1)
+    {
+      std::string cname = args(0).string_value ();
+
+      if (! error_state)
+        retval = to_ov (lookup_package (cname));
+      else
+        error ("invalid package name, expected a string value");
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+
+DEFUN (__superclass_reference__, args, /* nargout */,
+  "-*- texinfo -*-\n\
+@deftypefn {Built-in Function} {} __superclass_reference__ ()\n\
+Undocumented internal function.\n\
+@end deftypefn")
+{
+  return octave_value (new octave_classdef_superclass_ref (args));
+}
+
+DEFUN (__meta_class_query__, args, /* nargout */,
+  "-*- texinfo -*-\n\
+@deftypefn {Built-in Function} {} __meta_class_query__ ()\n\
+Undocumented internal function.\n\
+@end deftypefn")
+{
+  octave_value retval;
+
+  std::cerr << "__meta_class_query__ ("
+            << args(0).string_value () << ")"
+            << std::endl;
+
+  if (args.length () == 1)
+    {
+      std::string cls = args(0).string_value ();
+
+      if (! error_state)
+        retval = to_ov (lookup_class (cls));
+      else
+        error ("invalid class name, expected a string value");
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+
+DEFUN (metaclass, args, /* nargout */,
+  "-*- texinfo -*-\n\
+@deftypefn {Built-in Function} {} metaclass (obj)\n\
+Returns the meta.class object corresponding to the class of @var{obj}.\n\
+@end deftypefn")
+{
+  octave_value retval;
+
+  if (args.length () == 1)
+    {
+      cdef_object obj = to_cdef (args(0));
+
+      if (! error_state)
+        retval = to_ov (obj.get_class ());
+      else
+        print_usage ();
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libinterp/octave-value/ov-classdef.h	Fri Aug 01 12:10:05 2014 -0400
@@ -0,0 +1,1666 @@
+/*
+
+Copyright (C) 2012-2013 Michael Goffioul
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_classdef_h)
+#define octave_classdef_h 1
+
+#include <map>
+#include <set>
+#include <string>
+
+#include "oct-map.h"
+#include "oct-refcount.h"
+#include "ov-base.h"
+#include "symtab.h"
+
+class cdef_object;
+class cdef_class;
+class cdef_property;
+class cdef_method;
+class cdef_package;
+
+class tree_classdef;
+
+// This is mainly a boostrap class to declare the expected interface.
+// The actual base class is cdef_class_base, which is declared after
+// cdef_object, such that it can contain cdef_object objects.
+class
+cdef_object_rep
+{
+public:
+  friend class cdef_object;
+
+public:
+  cdef_object_rep (void) : refcount (1) { }
+
+  virtual ~cdef_object_rep (void) { }
+
+  virtual cdef_class get_class (void) const;
+
+  virtual void set_class (const cdef_class&)
+    { gripe_invalid_object ("set_class"); }
+
+  virtual cdef_object_rep* clone (void) const
+    {
+      gripe_invalid_object ("clone");
+      return new cdef_object_rep ();
+    }
+
+  virtual cdef_object_rep* empty_clone (void) const
+    {
+      gripe_invalid_object ("empty_clone");
+      return new cdef_object_rep ();
+    }
+
+  virtual cdef_object_rep* copy (void) const
+    {
+      gripe_invalid_object ("copy");
+      return new cdef_object_rep ();
+    }
+
+  virtual cdef_object_rep* make_array (void) const
+    {
+      gripe_invalid_object ("make_array");
+      return new cdef_object_rep ();
+    }
+
+  virtual bool is_array (void) const { return false; }
+
+  virtual bool is_value_object (void) const { return false; }
+
+  virtual bool is_handle_object (void) const { return false; }
+
+  virtual bool is_meta_object (void) const { return false; }
+
+  virtual Array<cdef_object> array_value (void) const
+    {
+      gripe_invalid_object ("array_value");
+      return Array<cdef_object> ();
+    }
+
+  virtual void put (const std::string&, const octave_value&)
+    { gripe_invalid_object ("put"); }
+
+  virtual octave_value get (const std::string&) const
+    {
+      gripe_invalid_object ("get");
+      return octave_value ();
+    }
+
+  virtual octave_value_list
+  subsref (const std::string&, const std::list<octave_value_list>&,
+           int, size_t&, const cdef_class&, bool)
+    {
+      gripe_invalid_object ("subsref");
+      return octave_value_list ();
+    }
+
+  virtual octave_value
+  subsasgn (const std::string&, const std::list<octave_value_list>&,
+            const octave_value&)
+    {
+      gripe_invalid_object ("subsasgn");
+      return octave_value ();
+    }
+
+  virtual string_vector map_keys(void) const;
+
+  virtual bool is_valid (void) const { return false; }
+
+  std::string class_name (void) const;
+
+  virtual void mark_for_construction (const cdef_class&)
+    { gripe_invalid_object ("mark_for_construction"); }
+
+  virtual bool is_constructed_for (const cdef_class&) const
+    {
+      gripe_invalid_object ("is_constructed_for");
+      return false;
+    }
+
+  virtual bool is_partially_constructed_for (const cdef_class&) const
+    {
+      gripe_invalid_object ("is_partially_constructed_for");
+      return false;
+    }
+
+  virtual void mark_as_constructed (void)
+    { gripe_invalid_object ("mark_as_constructed"); }
+
+  virtual void mark_as_constructed (const cdef_class&)
+    { gripe_invalid_object ("mark_as_constructed"); }
+
+  virtual bool is_constructed (void) const
+    {
+      gripe_invalid_object ("is_constructed");
+      return false;
+    }
+
+  virtual octave_idx_type static_count (void) const { return 0; }
+
+  virtual void destroy (void) { delete this; }
+
+  void release (void)
+    {
+      if (--refcount == static_count ())
+        destroy ();
+    }
+
+  virtual dim_vector dims (void) const { return dim_vector (); }
+
+protected:
+  /* reference count */
+  octave_refcount<octave_idx_type> refcount;
+
+protected:
+  /* Restricted copying */
+  cdef_object_rep (const cdef_object_rep&)
+    : refcount (1) { }
+
+private:
+  /* No assignment */
+  cdef_object_rep& operator = (const cdef_object_rep& );
+
+  void gripe_invalid_object (const char *who) const
+    { error ("%s: invalid object", who); }
+};
+
+class
+cdef_object
+{
+public:
+  /* FIXME: use a null object */
+  cdef_object (void)
+      : rep (new cdef_object_rep ()) { }
+
+  cdef_object (const cdef_object& obj)
+    : rep (obj.rep)
+    {
+      rep->refcount++;
+    }
+
+  cdef_object (cdef_object_rep *r)
+      : rep (r) { }
+
+  virtual ~cdef_object (void)
+    { rep->release (); }
+
+  cdef_object& operator = (const cdef_object& obj)
+    {
+      if (rep != obj.rep)
+        {
+          rep->release ();
+
+          rep = obj.rep;
+          rep->refcount++;
+        }
+
+      return *this;
+    }
+
+  cdef_class get_class (void) const;
+
+  void set_class (const cdef_class& cls) { rep->set_class (cls); }
+
+  std::string class_name (void) const
+    { return rep->class_name (); }
+
+  cdef_object clone (void) const
+    { return cdef_object (rep->clone ()); }
+
+  cdef_object empty_clone (void) const
+    { return cdef_object (rep->empty_clone ()); }
+
+  dim_vector dims (void) const { return rep->dims (); }
+
+  cdef_object make_array (void) const
+    { return cdef_object (rep->make_array ()); }
+
+  cdef_object copy (void) const
+    { return cdef_object (rep->copy ()); }
+
+  bool is_array (void) const { return rep->is_array (); }
+
+  bool is_value_object (void) const { return rep->is_value_object (); }
+
+  bool is_handle_object (void) const { return rep->is_handle_object (); }
+
+  bool is_meta_object (void) const { return rep->is_meta_object (); }
+
+  Array<cdef_object> array_value (void) const { return rep->array_value (); }
+
+  void put (const std::string& pname, const octave_value& val)
+    { rep->put (pname, val); }
+
+  octave_value get (const std::string& pname) const
+    { return rep->get (pname); }
+
+  octave_value_list
+  subsref (const std::string& type, const std::list<octave_value_list>& idx,
+           int nargout, size_t& skip, const cdef_class& context,
+           bool auto_add = false)
+    { return rep->subsref (type, idx, nargout, skip, context, auto_add); }
+
+  octave_value
+  subsasgn (const std::string& type, const std::list<octave_value_list>& idx,
+            const octave_value& rhs, int ignore_copies = 0)
+    {
+      make_unique (ignore_copies);
+      return rep->subsasgn (type, idx, rhs);
+    }
+
+  string_vector map_keys (void) const { return rep->map_keys (); }
+
+  const cdef_object_rep* get_rep (void) const { return rep; }
+
+  bool ok (void) const { return rep->is_valid (); }
+
+  void mark_for_construction (const cdef_class& cls)
+    { rep->mark_for_construction (cls); }
+
+  bool is_constructed (void) const { return rep->is_constructed (); }
+
+  bool is_constructed_for (const cdef_class& cls) const
+    { return rep->is_constructed_for (cls); }
+
+  bool is_partially_constructed_for (const cdef_class& cls) const
+    { return rep->is_partially_constructed_for (cls); }
+
+  void mark_as_constructed (void) { rep->mark_as_constructed (); }
+
+  void mark_as_constructed (const cdef_class& cls)
+    { rep->mark_as_constructed (cls); }
+
+  bool is (const cdef_object& obj) const { return rep == obj.rep; }
+
+protected:
+  cdef_object_rep* get_rep (void) { return rep; }
+
+  void make_unique (int ignore_copies)
+    {
+      if (rep->refcount > ignore_copies + 1)
+        *this = clone ();
+    }
+
+private:
+  cdef_object_rep *rep;
+};
+
+class
+cdef_object_base : public cdef_object_rep
+{
+public:
+  cdef_object_base (void)
+    : cdef_object_rep (), klass ()
+    {
+      register_object ();
+    }
+
+  ~cdef_object_base (void) { unregister_object (); }
+
+  cdef_class get_class (void) const;
+
+  void set_class (const cdef_class& cls);
+
+  cdef_object_rep* empty_clone (void) const
+    { return new cdef_object_base (*this); }
+
+  cdef_object_rep* make_array (void) const;
+
+protected:
+  // Restricted copying!
+  cdef_object_base (const cdef_object_base& obj)
+    : cdef_object_rep (obj), klass (obj.klass)
+    {
+      register_object ();
+    }
+
+private:
+  void register_object (void);
+
+  void unregister_object (void);
+
+private:
+  // The class of the object
+  cdef_object klass;
+
+private:
+  // No assignment!
+  cdef_object_base& operator = (const cdef_object_base&);
+};
+
+class
+cdef_object_array : public cdef_object_base
+{
+public:
+  cdef_object_array (void) : cdef_object_base () { }
+
+  cdef_object_array (const Array<cdef_object>& a)
+    : cdef_object_base (), array (a) { }
+
+  cdef_object_rep* clone (void) const
+    { return new cdef_object_array (*this); }
+
+  dim_vector dims (void) const { return array.dims (); }
+
+  bool is_valid (void) const { return true; }
+
+  bool is_array (void) const { return true; }
+
+  Array<cdef_object> array_value (void) const { return array; }
+
+  octave_value_list
+  subsref (const std::string& type, const std::list<octave_value_list>& idx,
+           int nargout, size_t& skip, const cdef_class& context,
+           bool auto_add);
+
+  octave_value
+  subsasgn (const std::string& type, const std::list<octave_value_list>& idx,
+            const octave_value& rhs);
+
+private:
+  Array<cdef_object> array;
+
+private:
+  void fill_empty_values (void) { fill_empty_values (array); }
+
+  void fill_empty_values (Array<cdef_object>& arr);
+
+  // Private copying!
+  cdef_object_array (const cdef_object_array& obj)
+    : cdef_object_base (obj), array (obj.array) { }
+
+  // No assignment!
+  cdef_object_array& operator = (const cdef_object_array&);
+};
+
+class
+cdef_object_scalar : public cdef_object_base
+{
+public:
+  cdef_object_scalar (void) : cdef_object_base () { }
+
+  ~cdef_object_scalar (void) { }
+
+  dim_vector dims (void) const { return dim_vector (1, 1); }
+
+  void put (const std::string& pname, const octave_value& val)
+    { map.assign (pname, val); }
+
+  octave_value get (const std::string& pname) const
+    {
+      Cell val = map.contents (pname);
+
+      if (val.numel () > 0)
+        return val(0, 0);
+      else
+        {
+          error ("get: unknown slot: %s", pname.c_str ());
+          return octave_value ();
+        }
+    }
+
+  octave_value_list
+  subsref (const std::string& type, const std::list<octave_value_list>& idx,
+           int nargout, size_t& skip, const cdef_class& context,
+           bool auto_add);
+
+  octave_value
+  subsasgn (const std::string& type, const std::list<octave_value_list>& idx,
+            const octave_value& rhs);
+
+  void mark_for_construction (const cdef_class&);
+
+  bool is_constructed_for (const cdef_class& cls) const;
+
+  bool is_partially_constructed_for (const cdef_class& cls) const;
+
+  void mark_as_constructed (void) { ctor_list.clear (); }
+
+  void mark_as_constructed (const cdef_class& cls) { ctor_list.erase (cls); }
+
+  bool is_constructed (void) const { return ctor_list.empty (); }
+
+protected:
+  // Object property values
+  octave_scalar_map map;
+
+  // Internal/temporary structure used during object construction
+  std::map< cdef_class, std::list<cdef_class> > ctor_list;
+
+protected:
+  // Restricted object copying!
+  cdef_object_scalar (const cdef_object_scalar& obj)
+    : cdef_object_base (obj), map (obj.map), ctor_list (obj.ctor_list) { }
+
+private:
+  // No assignment!
+  cdef_object_scalar& operator = (const cdef_object_scalar&);
+};
+
+class
+handle_cdef_object : public cdef_object_scalar
+{
+public:
+  handle_cdef_object (void)
+      : cdef_object_scalar () { }
+
+  ~handle_cdef_object (void);
+
+  cdef_object_rep* clone (void) const
+    {
+      handle_cdef_object *obj = const_cast<handle_cdef_object *> (this);
+      obj->refcount++;
+      return obj;
+    }
+
+  cdef_object_rep* copy (void) const
+    { return new handle_cdef_object (*this); }
+
+  bool is_valid (void) const { return true; }
+
+  bool is_handle_object (void) const { return true; }
+
+protected:
+  // Restricted copying!
+  handle_cdef_object (const handle_cdef_object& obj)
+    : cdef_object_scalar (obj) { }
+
+private:
+  // No assignment
+  handle_cdef_object& operator = (const handle_cdef_object&);
+};
+
+class
+value_cdef_object : public cdef_object_scalar
+{
+public:
+  value_cdef_object (void)
+      : cdef_object_scalar () { }
+
+  ~value_cdef_object (void);
+
+  cdef_object_rep* clone (void) const
+    { return new value_cdef_object (*this); }
+
+  cdef_object_rep* copy (void) const { return clone (); }
+
+  bool is_valid (void) const { return true; }
+
+  bool is_value_object (void) const { return true; }
+
+private:
+  // Private copying!
+  value_cdef_object (const value_cdef_object& obj)
+    : cdef_object_scalar (obj) { }
+
+  // No assignment!
+  value_cdef_object& operator = (const value_cdef_object&);
+};
+
+class
+cdef_meta_object_rep : public handle_cdef_object
+{
+public:
+  cdef_meta_object_rep (void)
+    : handle_cdef_object () { }
+
+  ~cdef_meta_object_rep (void) { }
+
+  cdef_object_rep* copy (void) const
+    { return new cdef_meta_object_rep (*this); }
+
+  bool is_meta_object (void) const { return true; }
+
+  virtual bool is_class (void) const { return false; }
+
+  virtual bool is_property (void) const { return false; }
+
+  virtual bool is_method (void) const { return false; }
+
+  virtual bool is_package (void) const { return false; }
+  
+  virtual octave_value_list
+  meta_subsref (const std::string& /* type */,
+                const std::list<octave_value_list>& /* idx */,
+                int /* nargout */)
+    {
+      ::error ("subsref: invalid meta object");
+      return octave_value_list ();
+    }
+
+  virtual void meta_release (void) { }
+
+  virtual bool meta_is_postfix_index_handled (char /* type */) const
+    { return false; }
+
+protected:
+  // Restricted copying!
+  cdef_meta_object_rep (const cdef_meta_object_rep& obj)
+    : handle_cdef_object (obj) { }
+
+private:
+  // No assignment!
+  cdef_meta_object_rep& operator = (const cdef_meta_object_rep&);
+};
+
+class
+cdef_meta_object : public cdef_object
+{
+public:
+  cdef_meta_object (void)
+    : cdef_object () { }
+
+  cdef_meta_object (const cdef_meta_object& obj)
+    : cdef_object (obj) { }
+
+  cdef_meta_object (cdef_meta_object_rep *r)
+    : cdef_object (r) { }
+
+  // Object consistency is checked in sub-classes.
+  cdef_meta_object (const cdef_object& obj)
+    : cdef_object (obj) { }
+
+  ~cdef_meta_object (void) { }
+
+  bool is_class (void) const { return get_rep ()->is_class (); }
+
+  bool is_property (void) const { return get_rep ()->is_property (); }
+
+  bool is_method (void) const { return get_rep ()->is_method (); }
+
+  bool is_package (void) const { return get_rep ()->is_package (); }
+
+  octave_value_list
+  meta_subsref (const std::string& type,
+                const std::list<octave_value_list>& idx, int nargout)
+    { return get_rep ()->meta_subsref (type, idx, nargout); }
+
+  void meta_release (void) { get_rep ()->meta_release (); }
+
+  bool meta_is_postfix_index_handled (char type) const
+    { return get_rep ()->meta_is_postfix_index_handled (type); }
+
+private:
+  cdef_meta_object_rep* get_rep (void)
+    { return dynamic_cast<cdef_meta_object_rep *> (cdef_object::get_rep ()); }
+  
+  const cdef_meta_object_rep* get_rep (void) const
+    { return dynamic_cast<const cdef_meta_object_rep *> (cdef_object::get_rep ()); }
+};
+
+class
+cdef_class : public cdef_meta_object
+{
+private:
+
+  class
+  cdef_class_rep : public cdef_meta_object_rep
+  {
+  public:
+    cdef_class_rep (void)
+        : cdef_meta_object_rep (), member_count (0), handle_class (false),
+          object_count (0), meta (false) { }
+
+    cdef_class_rep (const std::list<cdef_class>& superclasses);
+
+    cdef_object_rep* copy (void) const { return new cdef_class_rep (*this); }
+
+    bool is_class (void) const { return true; }
+
+    std::string get_name (void) const
+      { return get ("Name").string_value (); }
+
+    void set_name (const std::string& nm) { put ("Name", nm); }
+
+    bool is_abstract (void) const { return get ("Abstract").bool_value (); }
+
+    bool is_sealed (void) const { return get ("Sealed").bool_value (); }
+
+    cdef_method find_method (const std::string& nm, bool local = false);
+
+    void install_method (const cdef_method& meth);
+
+    Cell get_methods (void);
+
+    cdef_property find_property (const std::string& nm);
+
+    void install_property (const cdef_property& prop);
+
+    Cell get_properties (void);
+
+    string_vector get_names (void);
+
+    void set_directory (const std::string& dir) { directory = dir; }
+
+    std::string get_directory (void) const { return directory; }
+
+    void delete_object (cdef_object obj);
+
+    octave_value_list
+    meta_subsref (const std::string& type,
+                  const std::list<octave_value_list>& idx, int nargout);
+
+    void meta_release (void);
+
+    bool meta_is_postfix_index_handled (char type) const
+      { return (type == '(' || type == '.'); }
+
+    octave_value construct (const octave_value_list& args);
+
+    cdef_object construct_object (const octave_value_list& args);
+
+    void initialize_object (cdef_object& obj);
+
+    void run_constructor (cdef_object& obj, const octave_value_list& args);
+
+    void mark_as_handle_class (void) { handle_class = true; }
+
+    bool is_handle_class (void) const { return handle_class; }
+
+    void register_object (void) { object_count++; }
+
+    void unregister_object (void) { object_count--; }
+
+    octave_idx_type static_count (void) const { return member_count; }
+
+    void destroy (void)
+      {
+        if (member_count)
+          {
+            refcount++;
+            cdef_class lock (this);
+
+            member_count = 0;
+            method_map.clear ();
+            property_map.clear ();
+          }
+        else
+          delete this;
+      }
+
+    void mark_as_meta_class (void) { meta = true; }
+
+    bool is_meta_class (void) const { return meta; }
+
+  private:
+    void load_all_methods (void);
+
+    void find_names (std::set<std::string>& names, bool all);
+    
+    void find_properties (std::map<std::string,cdef_property>& props,
+                          bool only_inherited);
+
+    void find_methods (std::map<std::string, cdef_method>& meths,
+                       bool only_inherited);
+
+    cdef_class wrap (void)
+      {
+        refcount++;
+        return cdef_class (this);
+      }
+
+  private:
+    // The @-directory were this class is loaded from.
+    // (not used yet)
+    std::string directory;
+
+    // The methods defined by this class.
+    std::map<std::string,cdef_method> method_map;
+
+    // The properties defined by this class.
+    std::map<std::string,cdef_property> property_map;
+
+    // The number of members in this class (methods, properties...)
+    octave_idx_type member_count;
+
+    // TRUE if this class is a handle class. A class is a handle
+    // class when the abstract "handle" class is one of its superclasses.
+    bool handle_class;
+
+    // The list of super-class constructors that are called implicitly by the
+    // the classdef engine when creating an object. These constructors are not
+    // called explicitly by the class constructor.
+    std::list<cdef_class> implicit_ctor_list;
+
+    // The number of objects of this class.
+    octave_refcount<octave_idx_type> object_count;
+
+    // TRUE if this class is a built-in meta class.
+    bool meta;
+
+    // Utility iterator typedef's.
+    typedef std::map<std::string,cdef_method>::iterator method_iterator;
+    typedef std::map<std::string,cdef_method>::const_iterator method_const_iterator;
+    typedef std::map<std::string,cdef_property>::iterator property_iterator;
+    typedef std::map<std::string,cdef_property>::const_iterator property_const_iterator;
+
+  private:
+    cdef_class_rep (const cdef_class_rep& c)
+      : cdef_meta_object_rep (c), directory (c.directory),
+        method_map (c.method_map), property_map (c.property_map),
+        member_count (c.member_count), handle_class (c.handle_class),
+        implicit_ctor_list (c.implicit_ctor_list),
+        object_count (c.object_count), meta (c.meta) { }
+  };
+
+public:
+  // Create and invalid class object
+  cdef_class (void)
+      : cdef_meta_object () { }
+
+  cdef_class (const std::string& nm,
+              const std::list<cdef_class>& superclasses)
+      : cdef_meta_object (new cdef_class_rep (superclasses))
+    { get_rep ()->set_name (nm); }
+
+  cdef_class (const cdef_class& cls)
+      : cdef_meta_object (cls) { }
+
+  cdef_class (const cdef_object& obj)
+      : cdef_meta_object (obj)
+    {
+      // This should never happen...
+      if (! is_class ())
+        error ("internal error: invalid assignment from %s to meta.class object",
+               class_name ().c_str ());
+    }
+
+  cdef_class& operator = (const cdef_class& cls)
+    {
+      cdef_object::operator= (cls);
+
+      return *this;
+    }
+
+  cdef_method find_method (const std::string& nm, bool local = false);
+
+  void install_method (const cdef_method& meth)
+    { get_rep ()->install_method (meth); }
+
+  Cell get_methods (void) { return get_rep ()->get_methods (); }
+
+  cdef_property find_property (const std::string& nm);
+  
+  void install_property (const cdef_property& prop)
+    { get_rep ()->install_property (prop); }
+
+  Cell get_properties (void) { return get_rep ()->get_properties (); }
+
+  string_vector get_names (void) { return get_rep ()->get_names (); }
+
+  bool is_abstract (void) const { return get_rep ()->is_abstract (); }
+
+  bool is_sealed (void) const { return get_rep ()->is_sealed (); }
+
+  void set_directory (const std::string& dir)
+    { get_rep ()->set_directory (dir); }
+
+  std::string get_directory (void) const
+    { return get_rep ()->get_directory (); }
+
+  std::string get_name (void) const
+    { return get_rep ()->get_name (); }
+
+  bool is_builtin (void) const
+    { return get_directory ().empty (); }
+
+  void delete_object (cdef_object obj)
+    { get_rep ()->delete_object (obj); }
+
+  static cdef_class make_meta_class (tree_classdef* t,
+                                     bool is_at_folder = false);
+
+  octave_function* get_method_function (const std::string& nm);
+
+  octave_function* get_constructor_function (void)
+    { return get_method_function (get_name ()); }
+
+  octave_value construct (const octave_value_list& args)
+    { return get_rep ()->construct (args); }
+
+  cdef_object construct_object (const octave_value_list& args)
+    { return get_rep ()->construct_object (args); }
+
+  void initialize_object (cdef_object& obj)
+    { get_rep ()->initialize_object (obj); }
+
+  void run_constructor (cdef_object& obj, const octave_value_list& args)
+    { get_rep ()->run_constructor (obj, args); }
+
+  void mark_as_handle_class (void)
+    { get_rep ()->mark_as_handle_class (); }
+
+  bool is_handle_class (void) const
+    { return get_rep ()->is_handle_class (); }
+
+  void mark_as_meta_class (void) { get_rep ()->mark_as_meta_class (); }
+
+  bool is_meta_class (void) const { return get_rep ()->is_meta_class (); }
+
+  static const cdef_class& meta_class (void) { return _meta_class; }
+  static const cdef_class& meta_property (void) { return _meta_property; }
+  static const cdef_class& meta_method (void) { return _meta_method; }
+  static const cdef_class& meta_package (void) { return _meta_package; }
+
+  void register_object (void) { get_rep ()->register_object (); }
+
+  void unregister_object (void) { get_rep ()->unregister_object (); }
+
+private:
+  cdef_class_rep* get_rep (void)
+    { return dynamic_cast<cdef_class_rep *> (cdef_object::get_rep ()); }
+  
+  const cdef_class_rep* get_rep (void) const
+    { return dynamic_cast<const cdef_class_rep *> (cdef_object::get_rep ()); }
+
+  friend bool operator == (const cdef_class&, const cdef_class&);
+  friend bool operator != (const cdef_class&, const cdef_class&);
+  friend bool operator < (const cdef_class&, const cdef_class&);
+
+private:
+  static cdef_class _meta_class;
+  static cdef_class _meta_property;
+  static cdef_class _meta_method;
+  static cdef_class _meta_package;
+
+  friend void install_classdef (void);
+};
+
+inline bool
+operator == (const cdef_class& clsa, const cdef_class& clsb)
+// FIXME: is this really the right way to check class equality?
+{ return (clsa.get_rep () == clsb.get_rep ()); }
+
+inline bool
+operator != (const cdef_class& clsa, const cdef_class& clsb)
+{ return ! (clsa == clsb); }
+
+// This is only to be able to use cdef_class as map keys.
+inline bool
+operator < (const cdef_class& clsa, const cdef_class& clsb)
+{ return clsa.get_rep () < clsb.get_rep (); }
+
+class
+cdef_property : public cdef_meta_object
+{
+  friend class cdef_class;
+
+private:
+
+  class
+  cdef_property_rep : public cdef_meta_object_rep
+  {
+  public:
+    cdef_property_rep (void)
+        : cdef_meta_object_rep () { }
+
+    cdef_object_rep* copy (void) const { return new cdef_property_rep (*this); }
+
+    bool is_property (void) const { return true; }
+
+    std::string get_name (void) const { return get("Name").string_value (); }
+
+    void set_name (const std::string& nm) { put ("Name", nm); }
+
+    bool is_constant (void) const { return get("Constant").bool_value (); }
+
+    octave_value get_value (bool do_check_access = true,
+                            const std::string& who = std::string ());
+
+    octave_value get_value (const cdef_object& obj,
+                            bool do_check_access = true,
+                            const std::string& who = std::string ());
+
+    void set_value (cdef_object& obj, const octave_value& val,
+                    bool do_check_access = true,
+                    const std::string& who = std::string ());
+
+    bool check_get_access (void) const;
+
+    bool check_set_access (void) const;
+
+  private:
+    cdef_property_rep (const cdef_property_rep& p)
+      : cdef_meta_object_rep (p) { }
+
+    bool is_recursive_set (const cdef_object& obj) const;
+    
+    cdef_property wrap (void)
+      {
+        refcount++;
+        return cdef_property (this);
+      }
+  };
+
+public:
+  cdef_property (void) : cdef_meta_object () { }
+
+  cdef_property (const std::string& nm)
+      : cdef_meta_object (new cdef_property_rep ())
+    { get_rep ()->set_name (nm); }
+
+  cdef_property (const cdef_property& prop)
+      : cdef_meta_object (prop) { }
+
+  cdef_property (const cdef_object& obj)
+      : cdef_meta_object (obj)
+    {
+      // This should never happen...
+      if (! is_property ())
+        error ("internal error: invalid assignment from %s to meta.property object",
+               class_name ().c_str ());
+    }
+
+  cdef_property& operator = (const cdef_property& prop)
+    {
+      cdef_object::operator= (prop);
+
+      return *this;
+    }
+
+  octave_value get_value (const cdef_object& obj, bool do_check_access = true,
+                          const std::string& who = std::string ())
+    { return get_rep ()->get_value (obj, do_check_access, who); }
+
+  octave_value get_value (bool do_check_access = true,
+                          const std::string& who = std::string ())
+    { return get_rep ()->get_value (do_check_access, who); }
+
+  void set_value (cdef_object& obj, const octave_value& val,
+                  bool do_check_access = true,
+                  const std::string& who = std::string ())
+    { get_rep ()->set_value (obj, val, do_check_access, who); }
+
+  bool check_get_access (void) const
+    { return get_rep ()->check_get_access (); }
+  
+  bool check_set_access (void) const
+    { return get_rep ()->check_set_access (); }
+
+  std::string get_name (void) const { return get_rep ()->get_name (); }
+
+  bool is_constant (void) const { return get_rep ()->is_constant (); }
+
+private:
+  cdef_property_rep* get_rep (void)
+    { return dynamic_cast<cdef_property_rep *> (cdef_object::get_rep ()); }
+  
+  const cdef_property_rep* get_rep (void) const
+    { return dynamic_cast<const cdef_property_rep *> (cdef_object::get_rep ()); }
+};
+
+class
+cdef_method : public cdef_meta_object
+{
+  friend class cdef_class;
+
+private:
+
+  class
+  cdef_method_rep : public cdef_meta_object_rep
+  {
+  public:
+    cdef_method_rep (void)
+      : cdef_meta_object_rep (), function (), dispatch_type ()
+      { }
+
+    cdef_object_rep* copy (void) const { return new cdef_method_rep(*this); }
+
+    bool is_method (void) const { return true; }
+
+    std::string get_name (void) const { return get("Name").string_value (); }
+
+    void set_name (const std::string& nm) { put ("Name", nm); }
+
+    bool is_static (void) const { return get("Static").bool_value (); }
+
+    octave_value get_function (void) const { return function; }
+
+    void set_function (const octave_value& fcn) { function = fcn; }
+
+    bool check_access (void) const;
+
+    bool is_external (void) const { return ! dispatch_type.empty (); }
+
+    void mark_as_external (const std::string& dtype)
+      { dispatch_type = dtype; }
+
+    octave_value_list execute (const octave_value_list& args, int nargout,
+                               bool do_check_access = true,
+                               const std::string& who = std::string ());
+
+    octave_value_list execute (const cdef_object& obj,
+                               const octave_value_list& args, int nargout,
+                               bool do_check_access = true,
+                               const std::string& who = std::string ());
+
+    bool is_constructor (void) const;
+
+    octave_value_list
+    meta_subsref (const std::string& type,
+                  const std::list<octave_value_list>& idx, int nargout);
+
+    bool meta_is_postfix_index_handled (char type) const
+      { return (type == '(' || type == '.'); }
+
+  private:
+    cdef_method_rep (const cdef_method_rep& m)
+      : cdef_meta_object_rep (m), function (m.function),
+        dispatch_type (m.dispatch_type)
+      { }
+
+    void check_method (void);
+
+    cdef_method wrap (void)
+      {
+        refcount++;
+        return cdef_method (this);
+      }
+
+  private:
+    octave_value function;
+
+    // When non-empty, the method is externally defined and this member
+    // is used to cache the dispatch type to look for the method.
+    std::string dispatch_type;
+  };
+
+public:
+  cdef_method (void) : cdef_meta_object () { }
+
+  cdef_method (const std::string& nm)
+      : cdef_meta_object (new cdef_method_rep ())
+    { get_rep ()->set_name (nm); }
+
+  cdef_method (const cdef_method& meth)
+      : cdef_meta_object (meth) { }
+
+  cdef_method (const cdef_object& obj)
+      : cdef_meta_object (obj)
+    {
+      // This should never happen...
+      if (! is_method ())
+        error ("internal error: invalid assignment from %s to meta.method object",
+               class_name ().c_str ());
+    }
+
+  cdef_method& operator = (const cdef_method& meth)
+    {
+      cdef_object::operator= (meth);
+
+      return *this;
+    }
+
+  /* normal invokation */
+  octave_value_list execute (const octave_value_list& args, int nargout,
+                             bool do_check_access = true,
+                             const std::string& who = std::string ())
+    { return get_rep ()->execute (args, nargout, do_check_access, who); }
+
+  /* dot-invokation: object is pushed as 1st argument */
+  octave_value_list execute (const cdef_object& obj,
+                             const octave_value_list& args, int nargout,
+                             bool do_check_access = true,
+                             const std::string& who = std::string ())
+    { return get_rep ()->execute (obj, args, nargout, do_check_access, who); }
+
+  bool check_access (void) const { return get_rep ()->check_access (); }
+  
+  std::string get_name (void) const { return get_rep ()->get_name (); }
+
+  bool is_static (void) const { return get_rep ()->is_static (); }
+
+  void set_function (const octave_value& fcn)
+    { get_rep ()->set_function (fcn); }
+
+  octave_value get_function (void) const
+    { return get_rep ()->get_function (); }
+
+  bool is_constructor (void) const
+    { return get_rep ()->is_constructor (); }
+
+  bool is_external (void) const { return get_rep ()->is_external (); }
+
+  void mark_as_external (const std::string& dtype)
+    { get_rep ()->mark_as_external (dtype); }
+
+private:
+  cdef_method_rep* get_rep (void)
+    { return dynamic_cast<cdef_method_rep *> (cdef_object::get_rep ()); }
+  
+  const cdef_method_rep* get_rep (void) const
+    { return dynamic_cast<const cdef_method_rep *> (cdef_object::get_rep ()); }
+};
+
+inline cdef_class
+cdef_object_rep::get_class (void) const
+{
+  gripe_invalid_object ("get_class");
+  return cdef_class ();
+}
+
+inline std::string
+cdef_object_rep::class_name (void) const
+{ return get_class ().get_name (); }
+
+inline cdef_class
+cdef_object::get_class (void) const
+{ return rep->get_class (); }
+
+inline cdef_class
+cdef_object_base::get_class (void) const
+{ return cdef_class (klass); }
+
+inline void
+cdef_object_base::set_class (const cdef_class& cls)
+{
+  if ((klass.ok () && cls.ok () && cls != get_class ())
+      || (klass.ok () && ! cls.ok ())
+      || (! klass.ok () && cls.ok ()))
+    {
+      unregister_object ();
+      klass = cls;
+      register_object ();
+    }
+}
+
+inline void
+cdef_object_base::register_object (void)
+{
+  if (klass.ok ())
+    {
+      cdef_class cls (get_class ());
+
+      if (! error_state && cls.ok ())
+        cls.register_object ();
+    }
+}
+
+inline void
+cdef_object_base::unregister_object (void)
+{
+  if (klass.ok ())
+    {
+      cdef_class cls (get_class ());
+
+      if (! error_state && cls.ok ())
+        cls.unregister_object ();
+    }
+}
+
+inline cdef_object_rep*
+cdef_object_base::make_array (void) const
+{
+  cdef_object_rep* r = new cdef_object_array ();
+
+  r->set_class (get_class ());
+
+  return r;
+}
+
+inline cdef_method
+cdef_class::find_method (const std::string& nm, bool local)
+{ return get_rep ()->find_method (nm, local); }
+
+inline cdef_property
+cdef_class::find_property (const std::string& nm)
+{ return get_rep ()->find_property (nm); }
+
+class
+cdef_package : public cdef_meta_object
+{
+  friend class cdef_class;
+
+private:
+
+  class
+  cdef_package_rep : public cdef_meta_object_rep
+  {
+  public:
+    cdef_package_rep (void)
+      : cdef_meta_object_rep (), member_count (0) { }
+
+    ~cdef_package_rep (void) { }
+
+    cdef_object_rep* copy (void) const { return new cdef_package_rep (*this); }
+
+    bool is_package (void) const { return true; }
+
+    std::string get_name (void) const { return get("Name").string_value (); }
+
+    void set_name (const std::string& nm) { put ("Name", nm); }
+
+    void install_class (const cdef_class& cls, const std::string& nm);
+
+    void install_function (const octave_value& fcn, const std::string& nm);
+
+    void install_package (const cdef_package& pack, const std::string& nm);
+
+    Cell get_classes (void) const;
+
+    Cell get_functions (void) const;
+
+    Cell get_packages (void) const;
+
+    octave_idx_type static_count (void) const { return member_count; }
+
+    void destroy (void)
+      {
+        if (member_count)
+          {
+            refcount++;
+            cdef_package lock (this);
+
+            member_count = 0;
+            class_map.clear ();
+            package_map.clear ();
+          }
+        else
+          delete this;
+      }
+
+    octave_value_list
+    meta_subsref (const std::string& type,
+                  const std::list<octave_value_list>& idx, int nargout);
+
+    void meta_release (void);
+
+    bool meta_is_postfix_index_handled (char type) const
+      { return (type == '.'); }
+
+    octave_value find (const std::string& nm);
+
+  private:
+    std::string full_name;
+    std::map<std::string, cdef_class> class_map;
+    std::map<std::string, octave_value> function_map;
+    std::map<std::string, cdef_package> package_map;
+
+    // The number of registered members in this package (classes, packages).
+    // This only accounts for the members that back-reference to this package.
+    octave_idx_type member_count;
+
+    typedef std::map<std::string, cdef_class>::iterator class_iterator;
+    typedef std::map<std::string, cdef_class>::const_iterator class_const_iterator;
+    typedef std::map<std::string, octave_value>::iterator function_iterator;
+    typedef std::map<std::string, octave_value>::const_iterator function_const_iterator;
+    typedef std::map<std::string, cdef_package>::iterator package_iterator;
+    typedef std::map<std::string, cdef_package>::const_iterator package_const_iterator;
+
+  private:
+    cdef_package_rep (const cdef_package_rep& p)
+      : cdef_meta_object_rep (p), full_name (p.full_name),
+        class_map (p.class_map), function_map (p.function_map),
+        package_map (p.package_map), member_count (p.member_count)
+      { }
+
+    cdef_package wrap (void)
+      {
+        refcount++;
+        return cdef_package (this);
+      }
+  };
+
+public:
+  cdef_package (void) : cdef_meta_object () { }
+
+  cdef_package (const std::string& nm)
+      : cdef_meta_object (new cdef_package_rep ())
+    { get_rep ()->set_name (nm); }
+
+  cdef_package (const cdef_package& pack)
+    : cdef_meta_object (pack) { }
+
+  cdef_package (const cdef_object& obj)
+      : cdef_meta_object (obj)
+    {
+      // This should never happen...
+      if (! is_package ())
+        error ("internal error: invalid assignment from %s to meta.package object",
+               class_name ().c_str ());
+    }
+
+  cdef_package& operator = (const cdef_package& pack)
+    {
+      cdef_object::operator= (pack);
+
+      return *this;
+    }
+
+  void install_class (const cdef_class& cls, const std::string& nm)
+    { get_rep ()->install_class (cls, nm); }
+
+  void install_function (const octave_value& fcn, const std::string& nm)
+    { get_rep ()->install_function (fcn, nm); }
+
+  void install_package (const cdef_package& pack, const std::string& nm)
+    { get_rep ()->install_package (pack, nm); }
+
+  Cell get_classes (void) const
+    { return get_rep ()->get_classes (); }
+
+  Cell get_functions (void) const
+    { return get_rep ()->get_functions (); }
+
+  Cell get_packages (void) const
+    { return get_rep ()->get_packages (); }
+
+  std::string get_name (void) const { return get_rep ()->get_name (); }
+
+  octave_value find (const std::string& nm) { return get_rep ()->find (nm); }
+
+  static const cdef_package& meta (void) { return _meta; }
+
+private:
+  cdef_package_rep* get_rep (void)
+    { return dynamic_cast<cdef_package_rep *> (cdef_object::get_rep ()); }
+  
+  const cdef_package_rep* get_rep (void) const
+    { return dynamic_cast<const cdef_package_rep *> (cdef_object::get_rep ()); }
+
+private:
+  static cdef_package _meta;
+
+  friend void install_classdef (void);
+};
+
+class
+octave_classdef : public octave_base_value
+{
+public:
+  octave_classdef (void)
+      : octave_base_value (), object () { }
+
+  octave_classdef (const cdef_object& obj)
+      : octave_base_value (), object (obj) { }
+
+  octave_classdef (const octave_classdef& obj)
+      : octave_base_value (obj), object (obj.object) { }
+
+  octave_base_value* clone (void) const
+    { return new octave_classdef (object.clone ()); }
+
+  octave_base_value* empty_clone (void) const
+    { return new octave_classdef (object.empty_clone ()); }
+
+  cdef_object get_object (void) const { return object; }
+
+  cdef_object& get_object_ref (void) { return object; }
+
+  bool is_defined (void) const { return true; }
+
+  bool is_map (void) const { return true; }
+
+  bool is_object (void) const { return true; }
+
+  void print (std::ostream& os, bool pr_as_read_syntax = false);
+
+  void print_raw (std::ostream& os, bool pr_as_read_syntax = false) const;
+
+  bool print_name_tag (std::ostream& os, const std::string& name) const;
+
+  void print_with_name (std::ostream& os, const std::string& name,
+                        bool print_padding = true);
+
+  octave_value_list subsref (const std::string& type,
+                             const std::list<octave_value_list>& idx,
+                             int nargout);
+
+  octave_value subsref (const std::string& type,
+                        const std::list<octave_value_list>& idx)
+    {
+      octave_value_list retval = subsref (type, idx, 1);
+      return (retval.length () > 0 ? retval(0) : octave_value ());
+    }
+
+  octave_value subsref (const std::string& type,
+                        const std::list<octave_value_list>& idx,
+                        bool auto_add);
+
+  octave_value subsasgn (const std::string& type,
+                         const std::list<octave_value_list>& idx,
+                         const octave_value& rhs);
+
+  octave_value
+  undef_subsasgn (const std::string& type,
+                  const std::list<octave_value_list>& idx,
+                  const octave_value& rhs);
+
+  string_vector map_keys (void) const { return object.map_keys (); }
+
+  dim_vector dims (void) const { return object.dims (); }
+
+private:
+  cdef_object object;
+
+private:
+  DECLARE_OCTAVE_ALLOCATOR
+
+public:
+  int type_id (void) const { return t_id; }
+  std::string type_name (void) const { return t_name; }
+  std::string class_name (void) const { return object.class_name (); }
+
+  static int static_type_id (void) { return t_id; }
+  static std::string static_type_name (void) { return t_name; }
+  static std::string static_class_name (void) { return "<unknown>"; }
+  static void register_type (void);
+
+private:
+  static int t_id;
+
+  static const std::string t_name;
+};
+
+inline octave_value
+to_ov (const cdef_object& obj)
+{
+  if (obj.ok ())
+    return octave_value (new octave_classdef (obj));
+  else
+    return octave_value (Matrix ());
+}
+
+inline octave_value
+to_ov (const octave_value& ov)
+{ return ov; }
+
+inline cdef_object
+to_cdef (const octave_value& val)
+{
+  if (val.type_name () == "object")
+    return dynamic_cast<octave_classdef *> (val.internal_rep ())->get_object ();
+  else
+    {
+      error ("cannot convert `%s' into `object'", val.type_name().c_str ());
+      return cdef_object ();
+    }
+}
+
+inline cdef_object&
+to_cdef_ref (const octave_value& val)
+{
+  static cdef_object empty;
+
+  if (val.type_name () == "object")
+    return dynamic_cast<octave_classdef *> (val.internal_rep ())->get_object_ref ();
+  else
+    {
+      error ("cannot convert `%s' into `object'", val.type_name().c_str ());
+      return empty;
+    }
+}
+
+inline cdef_object
+to_cdef (const cdef_object& obj)
+{ return obj; }
+
+OCTINTERP_API void install_classdef (void);
+
+class
+cdef_manager
+{
+public:
+
+  static cdef_class find_class (const std::string& name,
+                                bool error_if_not_found = true,
+                                bool load_if_not_found = true)
+    {
+      if (instance_ok ())
+        return instance->do_find_class (name, error_if_not_found,
+                                        load_if_not_found);
+
+      return cdef_class ();
+    }
+
+  static octave_function* find_method_symbol (const std::string& method_name,
+                                              const std::string& class_name)
+    {
+      if (instance_ok ())
+        return instance->do_find_method_symbol (method_name, class_name);
+
+      return 0;
+    }
+
+  static cdef_package find_package (const std::string& name,
+                                    bool error_if_not_found = true,
+                                    bool load_if_not_found = true)
+    {
+      if (instance_ok ())
+        return instance->do_find_package (name, error_if_not_found,
+                                          load_if_not_found);
+
+      return cdef_package ();
+    }
+
+  static octave_function* find_package_symbol (const std::string& pack_name)
+    {
+      if (instance_ok ())
+        return instance->do_find_package_symbol (pack_name);
+
+      return 0;
+    }
+
+  static void register_class (const cdef_class& cls)
+    {
+      if (instance_ok ())
+        instance->do_register_class (cls);
+    }
+
+  static void unregister_class (const cdef_class& cls)
+    {
+      if (instance_ok ())
+        instance->do_unregister_class (cls);
+    }
+
+  static void register_package (const cdef_package& pkg)
+    {
+      if (instance_ok ())
+        instance->do_register_package (pkg);
+    }
+
+  static void unregister_package (const cdef_package& pkg)
+    {
+      if (instance_ok ())
+        instance->do_unregister_package (pkg);
+    }
+
+private:
+
+  cdef_manager (void) { }
+
+  cdef_manager (const cdef_manager&);
+
+  cdef_manager& operator = (const cdef_manager&);
+
+  ~cdef_manager (void) { }
+
+  static void create_instance (void);
+
+  static bool instance_ok (void)
+    {
+      bool retval = true;
+
+      if (! instance)
+        create_instance ();
+
+      if (! instance)
+        {
+          ::error ("unable to create cdef_manager!");
+
+          retval = false;
+        }
+
+      return retval;
+    }
+
+  static void cleanup_instance (void)
+    {
+      delete instance;
+
+      instance = 0;
+    }
+
+  cdef_class do_find_class (const std::string& name, bool error_if_not_found,
+                            bool load_if_not_found);
+
+  octave_function* do_find_method_symbol (const std::string& method_name,
+                                          const std::string& class_name);
+
+  cdef_package do_find_package (const std::string& name,
+                                bool error_if_not_found,
+                                bool load_if_not_found);
+
+  octave_function* do_find_package_symbol (const std::string& pack_name);
+
+  void do_register_class (const cdef_class& cls)
+    { all_classes[cls.get_name ()] = cls; }
+
+  void do_unregister_class (const cdef_class& cls)
+    { all_classes.erase(cls.get_name ()); }
+
+  void do_register_package (const cdef_package& pkg)
+    { all_packages[pkg.get_name ()] = pkg; }
+
+  void do_unregister_package (const cdef_package& pkg)
+    { all_packages.erase(pkg.get_name ()); }
+
+private:
+
+  // The single cdef_manager instance
+  static cdef_manager *instance;
+
+  // All registered/loaded classes
+  std::map<std::string, cdef_class> all_classes;
+
+  // All registered/loaded packages
+  std::map<std::string, cdef_package> all_packages;
+};
+
+#endif
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
--- a/libinterp/octave-value/ov-colon.cc	Fri Aug 01 09:06:21 2014 -0400
+++ b/libinterp/octave-value/ov-colon.cc	Fri Aug 01 12:10:05 2014 -0400
@@ -35,7 +35,7 @@
                                      "magic-colon", "magic-colon");
 
 void
-octave_magic_colon::print (std::ostream& os, bool) const
+octave_magic_colon::print (std::ostream& os, bool)
 {
   indent (os);
   print_raw (os);
--- a/libinterp/octave-value/ov-colon.h	Fri Aug 01 09:06:21 2014 -0400
+++ b/libinterp/octave-value/ov-colon.h	Fri Aug 01 12:10:05 2014 -0400
@@ -67,7 +67,7 @@
 
   bool is_magic_colon (void) const { return true; }
 
-  void print (std::ostream& os, bool pr_as_read_syntax = false) const;
+  void print (std::ostream& os, bool pr_as_read_syntax = false);
 
   void print_raw (std::ostream& os, bool pr_as_read_syntax = false) const;
 
--- a/libinterp/octave-value/ov-complex.cc	Fri Aug 01 09:06:21 2014 -0400
+++ b/libinterp/octave-value/ov-complex.cc	Fri Aug 01 12:10:05 2014 -0400
@@ -105,7 +105,7 @@
 double
 octave_complex::double_value (bool force_conversion) const
 {
-  double retval = lo_ieee_nan_value ();
+  double retval;
 
   if (! force_conversion)
     gripe_implicit_conversion ("Octave:imag-to-real",
@@ -119,7 +119,7 @@
 float
 octave_complex::float_value (bool force_conversion) const
 {
-  float retval = lo_ieee_float_nan_value ();
+  float retval;
 
   if (! force_conversion)
     gripe_implicit_conversion ("Octave:imag-to-real",
@@ -315,7 +315,8 @@
                            bool /* save_as_floats */)
 {
   hsize_t dimens[3];
-  hid_t space_hid = -1, type_hid = -1, data_hid = -1;
+  hid_t space_hid, type_hid, data_hid;
+  space_hid = type_hid = data_hid = -1;
   bool retval = true;
 
   space_hid = H5Screate_simple (0, dimens, 0);
--- a/libinterp/octave-value/ov-cx-diag.cc	Fri Aug 01 09:06:21 2014 -0400
+++ b/libinterp/octave-value/ov-cx-diag.cc	Fri Aug 01 12:10:05 2014 -0400
@@ -167,7 +167,8 @@
 octave_complex_diag_matrix::save_binary (std::ostream& os, bool& save_as_floats)
 {
 
-  int32_t r = matrix.rows (), c = matrix.cols ();
+  int32_t r = matrix.rows ();
+  int32_t c = matrix.cols ();
   os.write (reinterpret_cast<char *> (&r), 4);
   os.write (reinterpret_cast<char *> (&c), 4);
 
--- a/libinterp/octave-value/ov-cx-mat.cc	Fri Aug 01 09:06:21 2014 -0400
+++ b/libinterp/octave-value/ov-cx-mat.cc	Fri Aug 01 12:10:05 2014 -0400
@@ -561,7 +561,8 @@
     return (empty > 0);
 
   int rank = dv.length ();
-  hid_t space_hid = -1, data_hid = -1, type_hid = -1;
+  hid_t space_hid, data_hid, type_hid;
+  space_hid = data_hid = type_hid = -1;
   bool retval = true;
   ComplexNDArray m = complex_array_value ();
 
--- a/libinterp/octave-value/ov-cx-sparse.cc	Fri Aug 01 09:06:21 2014 -0400
+++ b/libinterp/octave-value/ov-cx-sparse.cc	Fri Aug 01 12:10:05 2014 -0400
@@ -241,16 +241,16 @@
 
   int32_t itmp;
   // Use negative value for ndims to be consistent with other formats
-  itmp= -2;
+  itmp = -2;
   os.write (reinterpret_cast<char *> (&itmp), 4);
 
-  itmp= nr;
+  itmp = nr;
   os.write (reinterpret_cast<char *> (&itmp), 4);
 
-  itmp= nc;
+  itmp = nc;
   os.write (reinterpret_cast<char *> (&itmp), 4);
 
-  itmp= nz;
+  itmp = nz;
   os.write (reinterpret_cast<char *> (&itmp), 4);
 
   save_type st = LS_DOUBLE;
@@ -390,7 +390,8 @@
   if (group_hid < 0)
     return false;
 
-  hid_t space_hid = -1, data_hid = -1;
+  hid_t space_hid, data_hid;
+  space_hid = data_hid = -1;
   bool retval = true;
   SparseComplexMatrix m = sparse_complex_matrix_value ();
   octave_idx_type tmp;
@@ -636,7 +637,7 @@
 #else
   group_hid = H5Gopen (loc_id, name);
 #endif
-  if (group_hid < 0 ) return false;
+  if (group_hid < 0) return false;
 
 #if HAVE_HDF5_18
   data_hid = H5Dopen (group_hid, "nr", H5P_DEFAULT);
--- a/libinterp/octave-value/ov-fcn-handle.cc	Fri Aug 01 09:06:21 2014 -0400
+++ b/libinterp/octave-value/ov-fcn-handle.cc	Fri Aug 01 12:10:05 2014 -0400
@@ -270,7 +270,7 @@
           std::string dir_name = str.substr (0, xpos);
 
           octave_function *xfcn
-            = load_fcn_from_file (str, dir_name, "", nm);
+            = load_fcn_from_file (str, dir_name, "", "", nm);
 
           if (xfcn)
             {
@@ -300,7 +300,7 @@
 
           std::string dir_name = str.substr (0, xpos);
 
-          octave_function *xfcn = load_fcn_from_file (str, dir_name, "", nm);
+          octave_function *xfcn = load_fcn_from_file (str, dir_name, "", "", nm);
 
           if (xfcn)
             {
@@ -323,7 +323,7 @@
 
           std::string dir_name = fpath.substr (0, xpos);
 
-          octave_function *xfcn = load_fcn_from_file (fpath, dir_name, "", nm);
+          octave_function *xfcn = load_fcn_from_file (fpath, dir_name, "", "", nm);
 
           if (xfcn)
             {
@@ -721,7 +721,8 @@
   if (group_hid < 0)
     return false;
 
-  hid_t space_hid = -1, data_hid = -1, type_hid = -1;;
+  hid_t space_hid, data_hid, type_hid;
+  space_hid = data_hid = type_hid = -1;
 
   // attach the type of the variable
   type_hid = H5Tcopy (H5T_C_S1);
@@ -1386,7 +1387,7 @@
 */
 
 void
-octave_fcn_handle::print (std::ostream& os, bool pr_as_read_syntax) const
+octave_fcn_handle::print (std::ostream& os, bool pr_as_read_syntax)
 {
   print_raw (os, pr_as_read_syntax);
   newline (os);
@@ -1572,7 +1573,8 @@
   // for any class.
   if (local_funcs && fptr
       && (fptr->is_subfunction () || fptr->is_private_function ()
-          || fptr->is_class_constructor ()))
+          || fptr->is_class_constructor ()
+          || fptr->is_classdef_constructor ()))
     {
       // Locally visible function.
       retval = octave_value (new octave_fcn_handle (f, tnm));
--- a/libinterp/octave-value/ov-fcn-handle.h	Fri Aug 01 09:06:21 2014 -0400
+++ b/libinterp/octave-value/ov-fcn-handle.h	Fri Aug 01 12:10:05 2014 -0400
@@ -153,7 +153,7 @@
   bool load_hdf5 (hid_t loc_id, const char *name);
 #endif
 
-  void print (std::ostream& os, bool pr_as_read_syntax = false) const;
+  void print (std::ostream& os, bool pr_as_read_syntax = false);
 
   void print_raw (std::ostream& os, bool pr_as_read_syntax = false) const;
 
--- a/libinterp/octave-value/ov-fcn-inline.cc	Fri Aug 01 09:06:21 2014 -0400
+++ b/libinterp/octave-value/ov-fcn-inline.cc	Fri Aug 01 12:10:05 2014 -0400
@@ -284,14 +284,15 @@
 #else
   group_hid = H5Gcreate (loc_id, name, 0);
 #endif
-  if (group_hid < 0 ) return false;
+  if (group_hid < 0) return false;
 
   size_t len = 0;
   for (int i = 0; i < ifargs.length (); i++)
     if (len < ifargs(i).length ())
       len = ifargs(i).length ();
 
-  hid_t space_hid = -1, data_hid = -1, type_hid = -1;;
+  hid_t space_hid, data_hid, type_hid;
+  space_hid = data_hid = type_hid = -1;
   bool retval = true;
 
   // FIXME: Is there a better way of saving string vectors,
@@ -423,7 +424,7 @@
 #else
   group_hid = H5Gopen (loc_id, name);
 #endif
-  if (group_hid < 0 ) return false;
+  if (group_hid < 0) return false;
 
 #if HAVE_HDF5_18
   data_hid = H5Dopen (group_hid, "args", H5P_DEFAULT);
@@ -597,7 +598,7 @@
 #endif
 
 void
-octave_fcn_inline::print (std::ostream& os, bool pr_as_read_syntax) const
+octave_fcn_inline::print (std::ostream& os, bool pr_as_read_syntax)
 {
   print_raw (os, pr_as_read_syntax);
   newline (os);
--- a/libinterp/octave-value/ov-fcn-inline.h	Fri Aug 01 09:06:21 2014 -0400
+++ b/libinterp/octave-value/ov-fcn-inline.h	Fri Aug 01 12:10:05 2014 -0400
@@ -86,7 +86,7 @@
   bool load_hdf5 (hid_t loc_id, const char *name);
 #endif
 
-  void print (std::ostream& os, bool pr_as_read_syntax = false) const;
+  void print (std::ostream& os, bool pr_as_read_syntax = false);
 
   void print_raw (std::ostream& os, bool pr_as_read_syntax = false) const;
 
--- a/libinterp/octave-value/ov-fcn.h	Fri Aug 01 09:06:21 2014 -0400
+++ b/libinterp/octave-value/ov-fcn.h	Fri Aug 01 12:10:05 2014 -0400
@@ -46,7 +46,8 @@
 
   octave_function (void)
     : relative (false), locked (false), private_function (false),
-      xdispatch_class (), my_name (), my_dir_name (), doc () { }
+      xdispatch_class (), xpackage_name (), my_name (), my_dir_name (),
+      doc () { }
 
   ~octave_function (void) { }
 
@@ -85,6 +86,10 @@
   virtual bool is_class_constructor (const std::string& = std::string ()) const
   { return false; }
 
+  virtual bool
+  is_classdef_constructor (const std::string& = std::string ()) const
+    { return false; }
+
   virtual bool is_class_method (const std::string& = std::string ()) const
   { return false; }
 
@@ -96,6 +101,10 @@
 
   std::string dispatch_class (void) const { return xdispatch_class; }
 
+  void stash_package_name (const std::string& pack) { xpackage_name = pack; }
+
+  std::string package_name (void) const { return xpackage_name; }
+
   virtual void
   mark_as_private_function (const std::string& cname = std::string ())
   {
@@ -152,6 +161,14 @@
 
   std::string name (void) const { return my_name; }
 
+  std::string canonical_name (void) const
+    {
+      if (xpackage_name.empty ())
+        return my_name;
+      else
+        return xpackage_name + "." + my_name;
+    }
+
   void document (const std::string& ds) { doc = ds; }
 
   std::string doc_string (void) const { return doc; }
@@ -160,6 +177,9 @@
 
   virtual void accept (tree_walker&) { }
 
+  virtual bool is_postfix_index_handled (char type) const
+    { return (type == '(' || type == '{'); }
+
 protected:
 
   octave_function (const std::string& nm,
@@ -181,6 +201,10 @@
   // to which the method belongs.
   std::string xdispatch_class;
 
+  // If this function is part of a package, this is the full name
+  // of the package to which the function belongs.
+  std::string xpackage_name;
+
   // The name of this function.
   std::string my_name;
 
--- a/libinterp/octave-value/ov-float.cc	Fri Aug 01 09:06:21 2014 -0400
+++ b/libinterp/octave-value/ov-float.cc	Fri Aug 01 12:10:05 2014 -0400
@@ -191,7 +191,8 @@
                                 bool /* save_as_floats */)
 {
   hsize_t dimens[3];
-  hid_t space_hid = -1, data_hid = -1;
+  hid_t space_hid, data_hid;
+  space_hid = data_hid = -1;
   bool retval = true;
 
   space_hid = H5Screate_simple (0, dimens, 0);
@@ -326,8 +327,31 @@
       SCALAR_MAPPER (isnan, xisnan);
       SCALAR_MAPPER (xsignbit, xsignbit);
 
+    // Special cases for Matlab compatibility.
+    case umap_xtolower:
+    case umap_xtoupper:
+      return scalar;
+
+    case umap_xisalnum:
+    case umap_xisalpha:
+    case umap_xisascii:
+    case umap_xiscntrl:
+    case umap_xisdigit:
+    case umap_xisgraph:
+    case umap_xislower:
+    case umap_xisprint:
+    case umap_xispunct:
+    case umap_xisspace:
+    case umap_xisupper:
+    case umap_xisxdigit:
+    case umap_xtoascii:
+      {
+        octave_value str_conv = convert_to_str (true, true);
+        return error_state ? octave_value () : str_conv.map (umap);
+      }
+
     default:
-      return octave_base_value::map (umap);
+        return octave_base_value::map (umap);
     }
 }
 
--- a/libinterp/octave-value/ov-flt-complex.cc	Fri Aug 01 09:06:21 2014 -0400
+++ b/libinterp/octave-value/ov-flt-complex.cc	Fri Aug 01 12:10:05 2014 -0400
@@ -89,7 +89,7 @@
 double
 octave_float_complex::double_value (bool force_conversion) const
 {
-  double retval = lo_ieee_nan_value ();
+  double retval;
 
   if (! force_conversion)
     gripe_implicit_conversion ("Octave:imag-to-real",
@@ -103,7 +103,7 @@
 float
 octave_float_complex::float_value (bool force_conversion) const
 {
-  float retval = lo_ieee_float_nan_value ();
+  float retval;
 
   if (! force_conversion)
     gripe_implicit_conversion ("Octave:imag-to-real",
@@ -300,7 +300,8 @@
                                  bool /* save_as_floats */)
 {
   hsize_t dimens[3];
-  hid_t space_hid = -1, type_hid = -1, data_hid = -1;
+  hid_t space_hid, type_hid, data_hid;
+  space_hid = type_hid = data_hid = -1;
   bool retval = true;
 
   space_hid = H5Screate_simple (0, dimens, 0);
--- a/libinterp/octave-value/ov-flt-cx-diag.cc	Fri Aug 01 09:06:21 2014 -0400
+++ b/libinterp/octave-value/ov-flt-cx-diag.cc	Fri Aug 01 12:10:05 2014 -0400
@@ -150,7 +150,8 @@
                                                bool& /* save_as_floats */)
 {
 
-  int32_t r = matrix.rows (), c = matrix.cols ();
+  int32_t r = matrix.rows ();
+  int32_t c = matrix.cols ();
   os.write (reinterpret_cast<char *> (&r), 4);
   os.write (reinterpret_cast<char *> (&c), 4);
 
--- a/libinterp/octave-value/ov-flt-cx-mat.cc	Fri Aug 01 09:06:21 2014 -0400
+++ b/libinterp/octave-value/ov-flt-cx-mat.cc	Fri Aug 01 12:10:05 2014 -0400
@@ -536,7 +536,8 @@
     return (empty > 0);
 
   int rank = dv.length ();
-  hid_t space_hid = -1, data_hid = -1, type_hid = -1;
+  hid_t space_hid, data_hid, type_hid;
+  space_hid = data_hid = type_hid = -1;
   bool retval = true;
   FloatComplexNDArray m = complex_array_value ();
 
--- a/libinterp/octave-value/ov-flt-re-diag.cc	Fri Aug 01 09:06:21 2014 -0400
+++ b/libinterp/octave-value/ov-flt-re-diag.cc	Fri Aug 01 12:10:05 2014 -0400
@@ -119,7 +119,8 @@
                                        bool& /* save_as_floats*/)
 {
 
-  int32_t r = matrix.rows (), c = matrix.cols ();
+  int32_t r = matrix.rows ();
+  int32_t c = matrix.cols ();
   os.write (reinterpret_cast<char *> (&r), 4);
   os.write (reinterpret_cast<char *> (&c), 4);
 
--- a/libinterp/octave-value/ov-flt-re-mat.cc	Fri Aug 01 09:06:21 2014 -0400
+++ b/libinterp/octave-value/ov-flt-re-mat.cc	Fri Aug 01 12:10:05 2014 -0400
@@ -563,7 +563,8 @@
     return (empty > 0);
 
   int rank = dv.length ();
-  hid_t space_hid = -1, data_hid = -1;
+  hid_t space_hid, data_hid;
+  space_hid = data_hid = -1;
   bool retval = true;
   FloatNDArray m = array_value ();
 
@@ -811,6 +812,29 @@
       ARRAY_MAPPER (isna, bool, octave_is_NA);
       ARRAY_MAPPER (xsignbit, float, xsignbit);
 
+    // Special cases for Matlab compatibility.
+    case umap_xtolower:
+    case umap_xtoupper:
+      return matrix;
+
+    case umap_xisalnum:
+    case umap_xisalpha:
+    case umap_xisascii:
+    case umap_xiscntrl:
+    case umap_xisdigit:
+    case umap_xisgraph:
+    case umap_xislower:
+    case umap_xisprint:
+    case umap_xispunct:
+    case umap_xisspace:
+    case umap_xisupper:
+    case umap_xisxdigit:
+    case umap_xtoascii:
+      {
+        octave_value str_conv = convert_to_str (true, true);
+        return error_state ? octave_value () : str_conv.map (umap);
+      }
+
     default:
       return octave_base_value::map (umap);
     }
--- a/libinterp/octave-value/ov-intx.h	Fri Aug 01 09:06:21 2014 -0400
+++ b/libinterp/octave-value/ov-intx.h	Fri Aug 01 12:10:05 2014 -0400
@@ -358,8 +358,15 @@
       case umap_finite:
         return boolNDArray (matrix.dims (), true);
 
+      // Special cases for Matlab compatibility.
+      case umap_xtolower:
+      case umap_xtoupper:
+        return matrix;
+
       default:
         {
+          // FIXME: we should be able to do better than converting to
+          // double here.
           octave_matrix m (array_value ());
           return m.map (umap);
         }
@@ -658,6 +665,11 @@
       case umap_finite:
         return true;
 
+      // Special cases for Matlab compatibility.
+      case umap_xtolower:
+      case umap_xtoupper:
+        return scalar;
+
       default:
         {
           octave_scalar m (scalar_value ());
--- a/libinterp/octave-value/ov-java.cc	Fri Aug 01 09:06:21 2014 -0400
+++ b/libinterp/octave-value/ov-java.cc	Fri Aug 01 12:10:05 2014 -0400
@@ -1150,7 +1150,8 @@
           if (jni_env->IsInstanceOf (jobj, cls))
             {
               jobjectArray jarr = reinterpret_cast<jobjectArray> (jobj);
-              int rows = jni_env->GetArrayLength (jarr), cols = 0;
+              int rows = jni_env->GetArrayLength (jarr);
+              int cols = 0;
 
               if (rows > 0)
                 {
@@ -1761,7 +1762,7 @@
 }
 
 void
-octave_java::print (std::ostream& os, bool) const
+octave_java::print (std::ostream& os, bool)
 {
   print_raw (os);
   newline (os);
--- a/libinterp/octave-value/ov-java.h	Fri Aug 01 09:06:21 2014 -0400
+++ b/libinterp/octave-value/ov-java.h	Fri Aug 01 12:10:05 2014 -0400
@@ -149,7 +149,7 @@
 
   dim_vector dims (void) const;
 
-  void print (std::ostream& os, bool pr_as_read_syntax = false) const;
+  void print (std::ostream& os, bool pr_as_read_syntax = false);
 
   void print_raw (std::ostream& os, bool pr_as_read_syntax = false) const;
 
--- a/libinterp/octave-value/ov-lazy-idx.h	Fri Aug 01 09:06:21 2014 -0400
+++ b/libinterp/octave-value/ov-lazy-idx.h	Fri Aug 01 12:10:05 2014 -0400
@@ -128,7 +128,7 @@
   bool print_as_scalar (void) const
   { return make_value ().print_as_scalar (); }
 
-  void print (std::ostream& os, bool pr_as_read_syntax = false) const
+  void print (std::ostream& os, bool pr_as_read_syntax = false)
   { make_value ().print (os, pr_as_read_syntax); }
 
   void print_info (std::ostream& os, const std::string& prefix) const
--- a/libinterp/octave-value/ov-oncleanup.cc	Fri Aug 01 09:06:21 2014 -0400
+++ b/libinterp/octave-value/ov-oncleanup.cc	Fri Aug 01 12:10:05 2014 -0400
@@ -170,7 +170,7 @@
 #endif
 
 void
-octave_oncleanup::print (std::ostream& os, bool pr_as_read_syntax) const
+octave_oncleanup::print (std::ostream& os, bool pr_as_read_syntax)
 {
   print_raw (os, pr_as_read_syntax);
   newline (os);
--- a/libinterp/octave-value/ov-oncleanup.h	Fri Aug 01 09:06:21 2014 -0400
+++ b/libinterp/octave-value/ov-oncleanup.h	Fri Aug 01 12:10:05 2014 -0400
@@ -87,7 +87,7 @@
   bool load_hdf5 (hid_t loc_id, const char *name);
 #endif
 
-  void print (std::ostream& os, bool pr_as_read_syntax = false) const;
+  void print (std::ostream& os, bool pr_as_read_syntax = false);
 
   void print_raw (std::ostream& os, bool pr_as_read_syntax = false) const;
 
--- a/libinterp/octave-value/ov-perm.cc	Fri Aug 01 09:06:21 2014 -0400
+++ b/libinterp/octave-value/ov-perm.cc	Fri Aug 01 12:10:05 2014 -0400
@@ -260,12 +260,10 @@
 bool
 octave_perm_matrix::save_ascii (std::ostream& os)
 {
-  typedef octave_int<octave_idx_type> idx_int_type;
+  os << "# size: " << matrix.rows () << "\n";
+  os << "# orient: c\n";
 
-  os << "# size: " << matrix.rows () << "\n";
-  os << "# orient: " << (matrix.is_col_perm () ? 'c' : 'r') << '\n';
-
-  Array<octave_idx_type> pvec = matrix.pvec ();
+  Array<octave_idx_type> pvec = matrix.col_perm_vec ();
   octave_idx_type n = pvec.length ();
   ColumnVector tmp (n);
   for (octave_idx_type i = 0; i < n; i++) tmp(i) = pvec(i) + 1;
@@ -277,7 +275,6 @@
 bool
 octave_perm_matrix::load_ascii (std::istream& is)
 {
-  typedef octave_int<octave_idx_type> idx_int_type;
   octave_idx_type n;
   bool success = true;
   char orient;
@@ -317,18 +314,19 @@
 {
 
   int32_t sz = matrix.rows ();
-  bool colp = matrix.is_col_perm ();
+  bool colp = true;
   os.write (reinterpret_cast<char *> (&sz), 4);
   os.write (reinterpret_cast<char *> (&colp), 1);
-  os.write (reinterpret_cast<const char *> (matrix.data ()),
-                                            matrix.byte_size ());
+  const Array<octave_idx_type>& col_perm = matrix.col_perm_vec ();
+  os.write (reinterpret_cast<const char *> (col_perm.data ()),
+                                            col_perm.byte_size ());
 
   return true;
 }
 
 bool
 octave_perm_matrix::load_binary (std::istream& is, bool swap,
-                                 oct_mach_info::float_format )
+                                 oct_mach_info::float_format)
 {
   int32_t sz;
   bool colp;
@@ -389,7 +387,7 @@
 }
 
 void
-octave_perm_matrix::print (std::ostream& os, bool pr_as_read_syntax) const
+octave_perm_matrix::print (std::ostream& os, bool pr_as_read_syntax)
 {
   print_raw (os, pr_as_read_syntax);
   newline (os);
@@ -451,3 +449,18 @@
   return retval;
 }
 
+octave_value
+octave_perm_matrix::fast_elem_extract (octave_idx_type n) const
+{
+  if (n < matrix.numel ())
+    {
+      octave_idx_type nr = matrix.rows ();
+
+      octave_idx_type r = n % nr;
+      octave_idx_type c = n / nr;
+
+      return octave_value (matrix.elem (r, c));
+    }
+  else
+    return octave_value ();
+}
--- a/libinterp/octave-value/ov-perm.h	Fri Aug 01 09:06:21 2014 -0400
+++ b/libinterp/octave-value/ov-perm.h	Fri Aug 01 12:10:05 2014 -0400
@@ -211,13 +211,15 @@
 
   bool print_as_scalar (void) const;
 
-  void print (std::ostream& os, bool pr_as_read_syntax = false) const;
+  void print (std::ostream& os, bool pr_as_read_syntax = false);
 
   void print_info (std::ostream& os, const std::string& prefix) const;
 
   octave_value map (unary_mapper_t umap) const
   { return to_dense ().map (umap); }
 
+  octave_value fast_elem_extract (octave_idx_type n) const;
+
 protected:
 
   PermMatrix matrix;
--- a/libinterp/octave-value/ov-range.cc	Fri Aug 01 09:06:21 2014 -0400
+++ b/libinterp/octave-value/ov-range.cc	Fri Aug 01 12:10:05 2014 -0400
@@ -352,7 +352,7 @@
 }
 
 void
-octave_range::print (std::ostream& os, bool pr_as_read_syntax) const
+octave_range::print (std::ostream& os, bool pr_as_read_syntax)
 {
   print_raw (os, pr_as_read_syntax);
   newline (os);
@@ -549,7 +549,8 @@
                          bool /* save_as_floats */)
 {
   hsize_t dimens[3];
-  hid_t space_hid = -1, type_hid = -1, data_hid = -1;
+  hid_t space_hid, type_hid, data_hid;
+  space_hid = type_hid = data_hid = -1;
   bool retval = true;
 
   space_hid = H5Screate_simple (0, dimens, 0);
@@ -676,6 +677,13 @@
   return retval;
 }
 
+octave_value
+octave_range::fast_elem_extract (octave_idx_type n) const
+{
+  return (n < range.nelem ())
+    ? octave_value (range.elem (n)) : octave_value ();
+}
+
 DEFUN (allow_noninteger_range_as_index, args, nargout,
        "-*- texinfo -*-\n\
 @deftypefn  {Built-in Function} {@var{val} =} allow_noninteger_range_as_index ()\n\
--- a/libinterp/octave-value/ov-range.h	Fri Aug 01 09:06:21 2014 -0400
+++ b/libinterp/octave-value/ov-range.h	Fri Aug 01 12:10:05 2014 -0400
@@ -249,7 +249,7 @@
 
   octave_value convert_to_str_internal (bool pad, bool force, char type) const;
 
-  void print (std::ostream& os, bool pr_as_read_syntax = false) const;
+  void print (std::ostream& os, bool pr_as_read_syntax = false);
 
   void print_raw (std::ostream& os, bool pr_as_read_syntax = false) const;
 
@@ -290,6 +290,8 @@
     return m.map (umap);
   }
 
+  octave_value fast_elem_extract (octave_idx_type n) const;
+
 private:
 
   Range range;
--- a/libinterp/octave-value/ov-re-diag.cc	Fri Aug 01 09:06:21 2014 -0400
+++ b/libinterp/octave-value/ov-re-diag.cc	Fri Aug 01 12:10:05 2014 -0400
@@ -179,7 +179,8 @@
 octave_diag_matrix::save_binary (std::ostream& os, bool& save_as_floats)
 {
 
-  int32_t r = matrix.rows (), c = matrix.cols ();
+  int32_t r = matrix.rows ();
+  int32_t c = matrix.cols ();
   os.write (reinterpret_cast<char *> (&r), 4);
   os.write (reinterpret_cast<char *> (&c), 4);
 
--- a/libinterp/octave-value/ov-re-mat.cc	Fri Aug 01 09:06:21 2014 -0400
+++ b/libinterp/octave-value/ov-re-mat.cc	Fri Aug 01 12:10:05 2014 -0400
@@ -675,7 +675,8 @@
     return (empty > 0);
 
   int rank = dv.length ();
-  hid_t space_hid = -1, data_hid = -1;
+  hid_t space_hid, data_hid;
+  space_hid = data_hid = -1;
   bool retval = true;
   NDArray m = array_value ();
 
@@ -934,13 +935,30 @@
       ARRAY_MAPPER (isna, bool, octave_is_NA);
       ARRAY_MAPPER (xsignbit, double, xsignbit);
 
+    // Special cases for Matlab compatibility.
+    case umap_xtolower:
+    case umap_xtoupper:
+      return matrix;
+
+    case umap_xisalnum:
+    case umap_xisalpha:
+    case umap_xisascii:
+    case umap_xiscntrl:
+    case umap_xisdigit:
+    case umap_xisgraph:
+    case umap_xislower:
+    case umap_xisprint:
+    case umap_xispunct:
+    case umap_xisspace:
+    case umap_xisupper:
+    case umap_xisxdigit:
+    case umap_xtoascii:
+      {
+        octave_value str_conv = convert_to_str (true, true);
+        return error_state ? octave_value () : str_conv.map (umap);
+      }
+
     default:
-      if (umap >= umap_xisalnum && umap <= umap_xtoupper)
-        {
-          octave_value str_conv = convert_to_str (true, true);
-          return error_state ? octave_value () : str_conv.map (umap);
-        }
-      else
         return octave_base_value::map (umap);
     }
 }
--- a/libinterp/octave-value/ov-re-sparse.cc	Fri Aug 01 09:06:21 2014 -0400
+++ b/libinterp/octave-value/ov-re-sparse.cc	Fri Aug 01 12:10:05 2014 -0400
@@ -274,16 +274,16 @@
 
   int32_t itmp;
   // Use negative value for ndims to be consistent with other formats
-  itmp= -2;
+  itmp = -2;
   os.write (reinterpret_cast<char *> (&itmp), 4);
 
-  itmp= nr;
+  itmp = nr;
   os.write (reinterpret_cast<char *> (&itmp), 4);
 
-  itmp= nc;
+  itmp = nc;
   os.write (reinterpret_cast<char *> (&itmp), 4);
 
-  itmp= nz;
+  itmp = nz;
   os.write (reinterpret_cast<char *> (&itmp), 4);
 
   save_type st = LS_DOUBLE;
@@ -421,7 +421,8 @@
   if (group_hid < 0)
     return false;
 
-  hid_t space_hid = -1, data_hid = -1;
+  hid_t space_hid, data_hid;
+  space_hid = data_hid = -1;
   bool retval = true;
   SparseMatrix m = sparse_matrix_value ();
   octave_idx_type tmp;
--- a/libinterp/octave-value/ov-scalar.cc	Fri Aug 01 09:06:21 2014 -0400
+++ b/libinterp/octave-value/ov-scalar.cc	Fri Aug 01 12:10:05 2014 -0400
@@ -206,7 +206,8 @@
                           bool /* save_as_floats */)
 {
   hsize_t dimens[3];
-  hid_t space_hid = -1, data_hid = -1;
+  hid_t space_hid, data_hid;
+  space_hid = data_hid = -1;
   bool retval = true;
 
   space_hid = H5Screate_simple (0, dimens, 0);
@@ -342,14 +343,31 @@
       SCALAR_MAPPER (isnan, xisnan);
       SCALAR_MAPPER (xsignbit, xsignbit);
 
+    // Special cases for Matlab compatibility.
+    case umap_xtolower:
+    case umap_xtoupper:
+      return scalar;
+
+    case umap_xisalnum:
+    case umap_xisalpha:
+    case umap_xisascii:
+    case umap_xiscntrl:
+    case umap_xisdigit:
+    case umap_xisgraph:
+    case umap_xislower:
+    case umap_xisprint:
+    case umap_xispunct:
+    case umap_xisspace:
+    case umap_xisupper:
+    case umap_xisxdigit:
+    case umap_xtoascii:
+      {
+        octave_value str_conv = convert_to_str (true, true);
+        return error_state ? octave_value () : str_conv.map (umap);
+      }
+
     default:
-      if (umap >= umap_xisalnum && umap <= umap_xtoupper)
-        {
-          octave_value str_conv = convert_to_str (true, true);
-          return error_state ? octave_value () : str_conv.map (umap);
-        }
-      else
-        return octave_base_value::map (umap);
+      return octave_base_value::map (umap);
     }
 }
 
--- a/libinterp/octave-value/ov-str-mat.cc	Fri Aug 01 09:06:21 2014 -0400
+++ b/libinterp/octave-value/ov-str-mat.cc	Fri Aug 01 12:10:05 2014 -0400
@@ -583,7 +583,8 @@
     return (empty > 0);
 
   int rank = dv.length ();
-  hid_t space_hid = -1, data_hid = -1;
+  hid_t space_hid, data_hid;
+  space_hid = data_hid = -1;
   bool retval = true;
   charNDArray m = char_array_value ();
 
--- a/libinterp/octave-value/ov-struct.cc	Fri Aug 01 09:06:21 2014 -0400
+++ b/libinterp/octave-value/ov-struct.cc	Fri Aug 01 12:10:05 2014 -0400
@@ -648,7 +648,7 @@
 }
 
 void
-octave_struct::print (std::ostream& os, bool) const
+octave_struct::print (std::ostream& os, bool)
 {
   print_raw (os);
 }
@@ -844,7 +844,7 @@
               success = false;
             }
         }
-      else if (len == 0 )
+      else if (len == 0)
         map = octave_map (dv);
       else
         panic_impossible ();
@@ -1359,7 +1359,7 @@
 }
 
 void
-octave_scalar_struct::print (std::ostream& os, bool) const
+octave_scalar_struct::print (std::ostream& os, bool)
 {
   print_raw (os);
 }
@@ -2066,9 +2066,9 @@
   return retval;
 }
 
-DEFUN (nfields, args, ,
+DEFUN (numfields, args, ,
        "-*- texinfo -*-\n\
-@deftypefn {Built-in Function} {} nfields (@var{s})\n\
+@deftypefn {Built-in Function} {} numfields (@var{s})\n\
 Return the number of fields of the structure @var{s}.\n\
 @seealso{fieldnames}\n\
 @end deftypefn")
--- a/libinterp/octave-value/ov-struct.h	Fri Aug 01 09:06:21 2014 -0400
+++ b/libinterp/octave-value/ov-struct.h	Fri Aug 01 12:10:05 2014 -0400
@@ -126,7 +126,7 @@
 
   string_vector map_keys (void) const { return map.fieldnames (); }
 
-  void print (std::ostream& os, bool pr_as_read_syntax = false) const;
+  void print (std::ostream& os, bool pr_as_read_syntax = false);
 
   void print_raw (std::ostream& os, bool pr_as_read_syntax = false) const;
 
@@ -249,7 +249,7 @@
 
   string_vector map_keys (void) const { return map.fieldnames (); }
 
-  void print (std::ostream& os, bool pr_as_read_syntax = false) const;
+  void print (std::ostream& os, bool pr_as_read_syntax = false);
 
   void print_raw (std::ostream& os, bool pr_as_read_syntax = false) const;
 
--- a/libinterp/octave-value/ov-usr-fcn.cc	Fri Aug 01 09:06:21 2014 -0400
+++ b/libinterp/octave-value/ov-usr-fcn.cc	Fri Aug 01 12:10:05 2014 -0400
@@ -203,7 +203,7 @@
     num_named_args (param_list ? param_list->length () : 0),
     subfunction (false), inline_function (false),
     anonymous_function (false), nested_function (false),
-    class_constructor (false), class_method (false),
+    class_constructor (none), class_method (false),
     parent_scope (-1), local_scope (sid),
     curr_unwind_protect_frame (0)
 #ifdef HAVE_LLVM
@@ -319,14 +319,18 @@
 {
   std::ostringstream result;
 
-  if (is_inline_function ())
-    result << "inline@" << fcn_file_name ()
-           << ":" << location_line << ":" << location_column;
-  else if (is_anonymous_function ())
+  if (is_anonymous_function ())
     result << "anonymous@" << fcn_file_name ()
            << ":" << location_line << ":" << location_column;
   else if (is_subfunction ())
     result << parent_fcn_name () << ">" << name ();
+  else if (is_class_method ())
+    result << "@" << dispatch_class () << "/" << name ();
+  else if (is_class_constructor () || is_classdef_constructor ())
+    result << "@" << name ();
+  else if (is_inline_function ())
+    result << "inline@" << fcn_file_name ()
+           << ":" << location_line << ":" << location_column;
   else
     result << name ();
 
@@ -470,7 +474,7 @@
 
 octave_value_list
 octave_user_function::do_multi_index_op (int nargout,
-                                         const octave_value_list& args,
+                                         const octave_value_list& _args,
                                          const std::list<octave_lvalue>* lvalue_list)
 {
   octave_value_list retval;
@@ -481,6 +485,23 @@
   if (! cmd_list)
     return retval;
 
+  // If this function is a classdef constructor, extract the first input
+  // argument, which must be the partially constructed object instance.
+
+  octave_value_list args (_args);
+  octave_value_list ret_args;
+
+  if (is_classdef_constructor ())
+    {
+      if (args.length () > 0)
+        {
+          ret_args = args.slice (0, 1, true);
+          args = args.slice (1, args.length () - 1, true);
+        }
+      else
+        panic_impossible ();
+    }
+
 #ifdef HAVE_LLVM
   if (is_special_expr ()
       && tree_jit::execute (*this, args, retval))
@@ -524,6 +545,25 @@
         return retval;
     }
 
+  // For classdef constructor, pre-populate the output arguments
+  // with the pre-initialized object instance, extracted above.
+
+  if (is_classdef_constructor ())
+    {
+      if (ret_list)
+        {
+          ret_list->define_from_arg_vector (ret_args);
+          if (error_state)
+            return retval;
+        }
+      else
+        {
+          ::error ("%s: invalid classdef constructor, no output argument defined",
+                   dispatch_class ().c_str ());
+          return retval;
+        }
+    }
+
   // Force parameter list to be undefined when this function exits.
   // Doing so decrements the reference counts on the values of local
   // variables that are also named function parameters.
@@ -744,7 +784,8 @@
         {
           // Only assign the hidden variable if black holes actually present.
           Matrix bh (1, nbh);
-          octave_idx_type k = 0, l = 0;
+          octave_idx_type k = 0;
+          octave_idx_type l = 0;
           for (std::list<octave_lvalue>::const_iterator
                p = lvalue_list->begin (); p != lvalue_list->end (); p++)
             {
@@ -849,7 +890,7 @@
             {
               // Matlab gives up for histc,
               // so maybe it's ok that that we give up somtimes too?
-              error ("nargin: nargin information not available for builtin functions");
+              error ("nargin: nargin information not available for built-in functions");
             }
         }
       else
@@ -971,7 +1012,7 @@
               // without making intrusive changes to Octave.
               // Matlab gives up for histc,
               // so maybe it's ok that we give up somtimes too?
-              error ("nargout: nargout information not available for builtin functions.");
+              error ("nargout: nargout information not available for built-in functions.");
             }
         }
       else
--- a/libinterp/octave-value/ov-usr-fcn.h	Fri Aug 01 09:06:21 2014 -0400
+++ b/libinterp/octave-value/ov-usr-fcn.h	Fri Aug 01 12:10:05 2014 -0400
@@ -327,12 +327,20 @@
 
   void mark_as_nested_function (void) { nested_function = true; }
 
-  void mark_as_class_constructor (void) { class_constructor = true; }
+  void mark_as_class_constructor (void) { class_constructor = legacy; }
+
+  void mark_as_classdef_constructor (void) { class_constructor = classdef; }
 
   bool is_class_constructor (const std::string& cname = std::string ()) const
   {
-    return class_constructor
-           ? (cname.empty () ? true : cname == dispatch_class ()) : false;
+    return class_constructor == legacy
+      ? (cname.empty () ? true : cname == dispatch_class ()) : false;
+  }
+
+  bool is_classdef_constructor (const std::string& cname = std::string ()) const
+  {
+    return class_constructor == classdef
+      ? (cname.empty () ? true : cname == dispatch_class ()) : false;
   }
 
   void mark_as_class_method (void) { class_method = true; }
@@ -408,6 +416,13 @@
 
 private:
 
+  enum class_ctor_type
+    {
+      none,
+      legacy,
+      classdef
+    };
+
   // List of arguments for this function.  These are local variables.
   tree_parameter_list *param_list;
 
@@ -470,8 +485,8 @@
   // TRUE means this is a nested function. (either a child or parent)
   bool nested_function;
 
-  // TRUE means this function is the constructor for class object.
-  bool class_constructor;
+  // Enum describing whether this function is the constructor for class object.
+  class_ctor_type class_constructor;
 
   // TRUE means this function is a method for a class.
   bool class_method;
--- a/libinterp/octave-value/ov.cc	Fri Aug 01 09:06:21 2014 -0400
+++ b/libinterp/octave-value/ov.cc	Fri Aug 01 12:10:05 2014 -0400
@@ -65,6 +65,7 @@
 #include "ov-range.h"
 #include "ov-struct.h"
 #include "ov-class.h"
+#include "ov-classdef.h"
 #include "ov-oncleanup.h"
 #include "ov-cs-list.h"
 #include "ov-colon.h"
@@ -1193,13 +1194,14 @@
 {
 }
 
-octave_value::octave_value (const Octave_map& m)
-  : rep (new octave_struct (m))
+octave_value::octave_value (const octave_map& m, const std::string& id,
+                            const std::list<std::string>& plist)
+  : rep (new octave_class (m, id, plist))
 {
   maybe_mutate ();
 }
 
-octave_value::octave_value (const Octave_map& m, const std::string& id,
+octave_value::octave_value (const octave_scalar_map& m, const std::string& id,
                             const std::list<std::string>& plist)
   : rep (new octave_class (m, id, plist))
 {
@@ -1951,7 +1953,9 @@
   int t2 = v2.type_id ();
 
   if (t1 == octave_class::static_type_id ()
-      || t2 == octave_class::static_type_id ())
+      || t2 == octave_class::static_type_id ()
+      || t1 == octave_classdef::static_type_id ()
+      || t2 == octave_classdef::static_type_id ())
     {
       octave_value_typeinfo::binary_class_op_fcn f
         = octave_value_typeinfo::lookup_binary_class_op (op);
@@ -2207,7 +2211,9 @@
   int t2 = v2.type_id ();
 
   if (t1 == octave_class::static_type_id ()
-      || t2 == octave_class::static_type_id ())
+      || t2 == octave_class::static_type_id ()
+      || t1 == octave_classdef::static_type_id ()
+      || t2 == octave_classdef::static_type_id ())
     {
       octave_value_typeinfo::binary_class_op_fcn f
         = octave_value_typeinfo::lookup_binary_class_op (op);
@@ -2381,7 +2387,8 @@
 
   int t = v.type_id ();
 
-  if (t == octave_class::static_type_id ())
+  if (t == octave_class::static_type_id ()
+      || t == octave_classdef::static_type_id ())
     {
       octave_value_typeinfo::unary_class_op_fcn f
         = octave_value_typeinfo::lookup_unary_class_op (op);
--- a/libinterp/octave-value/ov.h	Fri Aug 01 09:06:21 2014 -0400
+++ b/libinterp/octave-value/ov.h	Fri Aug 01 12:10:05 2014 -0400
@@ -46,7 +46,6 @@
 class mxArray;
 class octave_map;
 class octave_scalar_map;
-class Octave_map;
 class octave_stream;
 class octave_function;
 class octave_user_function;
@@ -285,8 +284,9 @@
   octave_value (const Range& r);
   octave_value (const octave_map& m);
   octave_value (const octave_scalar_map& m);
-  octave_value (const Octave_map& m);
-  octave_value (const Octave_map& m, const std::string& id,
+  octave_value (const octave_map& m, const std::string& id,
+                const std::list<std::string>& plist);
+  octave_value (const octave_scalar_map& m, const std::string& id,
                 const std::list<std::string>& plist);
   octave_value (const octave_value_list& m, bool = false);
   octave_value (octave_value::magic_colon);
@@ -1017,7 +1017,7 @@
   bool print_as_scalar (void) const
   { return rep->print_as_scalar (); }
 
-  void print (std::ostream& os, bool pr_as_read_syntax = false) const
+  void print (std::ostream& os, bool pr_as_read_syntax = false)
   { rep->print (os, pr_as_read_syntax); }
 
   void print_raw (std::ostream& os, bool pr_as_read_syntax = false) const
--- a/libinterp/octave.cc	Fri Aug 01 09:06:21 2014 -0400
+++ b/libinterp/octave.cc	Fri Aug 01 12:10:05 2014 -0400
@@ -68,6 +68,7 @@
 #include "ops.h"
 #include "options-usage.h"
 #include "ov.h"
+#include "ov-classdef.h"
 #include "ov-range.h"
 #include "toplev.h"
 #include "parse.h"
@@ -754,6 +755,8 @@
 
   install_builtins ();
 
+  install_classdef ();
+
   for (std::list<std::string>::const_iterator it = command_line_path.begin ();
        it != command_line_path.end (); it++)
     load_path::set_command_line_path (*it);
--- a/libinterp/operators/op-b-b.cc	Fri Aug 01 09:06:21 2014 -0400
+++ b/libinterp/operators/op-b-b.cc	Fri Aug 01 12:10:05 2014 -0400
@@ -33,6 +33,7 @@
 #include "ov-float.h"
 #include "ov-re-mat.h"
 #include "ov-typeinfo.h"
+#include "ov-null-mat.h"
 #include "ops.h"
 #include "xdiv.h"
 #include "xpow.h"
@@ -92,4 +93,8 @@
   INSTALL_CATOP (octave_float_scalar, octave_bool, f_b);
 
   INSTALL_ASSIGNCONV (octave_bool, octave_bool, octave_bool_matrix);
+
+  INSTALL_ASSIGNCONV (octave_bool, octave_null_matrix, octave_bool_matrix);
+  INSTALL_ASSIGNCONV (octave_bool, octave_null_str, octave_bool_matrix);
+  INSTALL_ASSIGNCONV (octave_bool, octave_null_sq_str, octave_bool_matrix);
 }
--- a/libinterp/operators/op-cm-sm.cc	Fri Aug 01 09:06:21 2014 -0400
+++ b/libinterp/operators/op-cm-sm.cc	Fri Aug 01 12:10:05 2014 -0400
@@ -106,8 +106,8 @@
                    const octave_sparse_matrix&);
 
   return octave_value
-         (elem_xpow ( SparseComplexMatrix (v1.complex_matrix_value ()),
-                      v2.sparse_matrix_value ()));
+         (elem_xpow (SparseComplexMatrix (v1.complex_matrix_value ()),
+                     v2.sparse_matrix_value ()));
 }
 
 DEFBINOP (el_ldiv, complex_matrix, sparse_matrix)
--- a/libinterp/operators/op-int.h	Fri Aug 01 09:06:21 2014 -0400
+++ b/libinterp/operators/op-int.h	Fri Aug 01 12:10:05 2014 -0400
@@ -1160,7 +1160,10 @@
 #define OCTAVE_INSTALL_INT_NULL_ASSIGN_OPS(TYPE) \
   INSTALL_ASSIGNOP (op_asn_eq, octave_ ## TYPE ## _matrix, octave_null_matrix, TYPE ## null_assign) \
   INSTALL_ASSIGNOP (op_asn_eq, octave_ ## TYPE ## _matrix, octave_null_str, TYPE ## null_assign) \
-  INSTALL_ASSIGNOP (op_asn_eq, octave_ ## TYPE ## _matrix, octave_null_sq_str, TYPE ## null_assign)
+  INSTALL_ASSIGNOP (op_asn_eq, octave_ ## TYPE ## _matrix, octave_null_sq_str, TYPE ## null_assign) \
+  INSTALL_ASSIGNCONV (octave_ ## TYPE ## _scalar, octave_null_matrix, octave_ ## TYPE ## _matrix) \
+  INSTALL_ASSIGNCONV (octave_## TYPE ## _scalar, octave_null_str, octave_ ## TYPE ## _matrix) \
+  INSTALL_ASSIGNCONV (octave_## TYPE ## _scalar, octave_null_sq_str, octave_ ## TYPE ## _matrix)
 
 #define OCTAVE_INSTALL_INT_OPS(TYPE) \
   OCTAVE_INSTALL_SS_INT_OPS (TYPE) \
--- a/libinterp/operators/op-pm-sm.cc	Fri Aug 01 09:06:21 2014 -0400
+++ b/libinterp/operators/op-pm-sm.cc	Fri Aug 01 12:10:05 2014 -0400
@@ -44,12 +44,12 @@
 DEFUNOP (not, perm_matrix)
 {
   // Obviously negation of a permutation matrix destroys sparsity
-  return octave_value ( ! a.bool_array_value ());
+  return octave_value (! a.bool_array_value ());
 }
 
 DEFUNOP (uminus, perm_matrix)
 {
-  return octave_value ( - a.sparse_matrix_value ());
+  return octave_value (- a.sparse_matrix_value ());
 }
 
 // Most other logical operations cast to SparseBoolMatrix
--- a/libinterp/operators/op-sbm-sbm.cc	Fri Aug 01 09:06:21 2014 -0400
+++ b/libinterp/operators/op-sbm-sbm.cc	Fri Aug 01 12:10:05 2014 -0400
@@ -49,7 +49,7 @@
 DEFUNOP (uminus, sparse_bool_matrix)
 {
   CAST_UNOP_ARG (const octave_sparse_bool_matrix&);
-  return octave_value ( - v.sparse_matrix_value ());
+  return octave_value (- v.sparse_matrix_value ());
 }
 
 DEFUNOP (transpose, sparse_bool_matrix)
--- a/libinterp/parse-tree/lex.h	Fri Aug 01 09:06:21 2014 -0400
+++ b/libinterp/parse-tree/lex.h	Fri Aug 01 12:10:05 2014 -0400
@@ -261,7 +261,9 @@
       looking_at_matrix_or_assign_lhs (false),
       looking_for_object_index (false),
       looking_at_indirect_ref (false), parsing_class_method (false),
-      maybe_classdef_get_set_method (false), parsing_classdef (false),
+      parsing_classdef (false), maybe_classdef_get_set_method (false),
+      parsing_classdef_get_method (false),
+      parsing_classdef_set_method (false), 
       quote_is_transpose (false), force_script (false),
       reading_fcn_file (false), reading_script_file (false),
       reading_classdef_file (false),
@@ -341,13 +343,19 @@
   // true means we are parsing a class method in function or classdef file.
   bool parsing_class_method;
 
+  // true means we are parsing a classdef file
+  bool parsing_classdef;
+
   // true means we are parsing a class method declaration line in a
   // classdef file and can accept a property get or set method name.
   // for example, "get.propertyname" is recognized as a function name.
   bool maybe_classdef_get_set_method;
 
-  // true means we are parsing a classdef file
-  bool parsing_classdef;
+  // TRUE means we are parsing a classdef get.method.
+  bool parsing_classdef_get_method;
+
+  // TRUE means we are parsing a classdef set.method.
+  bool parsing_classdef_set_method;
 
   // return transpose or start a string?
   bool quote_is_transpose;
@@ -572,6 +580,8 @@
 
   int is_keyword_token (const std::string& s);
 
+  bool fq_identifier_contains_keyword (const std::string& s);
+
   bool whitespace_is_significant (void);
 
   void handle_number (void);
@@ -590,6 +600,8 @@
 
   int handle_meta_identifier (void);
 
+  int handle_fq_identifier (void);
+
   int handle_identifier (void);
 
   void maybe_warn_separator_insert (char sep);
@@ -675,6 +687,8 @@
 
   int show_token (int tok);
 
+  void enable_fq_identifier (void);
+
 protected:
 
   std::stack<int> start_state_stack;
--- a/libinterp/parse-tree/lex.ll	Fri Aug 01 09:06:21 2014 -0400
+++ b/libinterp/parse-tree/lex.ll	Fri Aug 01 12:10:05 2014 -0400
@@ -54,6 +54,8 @@
 %x DQ_STRING_START
 %x SQ_STRING_START
 
+%x FQ_IDENT_START
+
 %{
 
 #include <cctype>
@@ -265,6 +267,43 @@
     } \
   while (0)
 
+#define HANDLE_IDENTIFIER(pattern, get_set) \
+  do \
+    { \
+      curr_lexer->lexer_debug (pattern); \
+ \
+      int tok = curr_lexer->previous_token_value (); \
+ \
+      if (curr_lexer->whitespace_is_significant () \
+          && curr_lexer->space_follows_previous_token () \
+          && ! (tok == '[' || tok == '{' \
+                || curr_lexer->previous_token_is_binop ())) \
+        { \
+          yyless (0); \
+          unput (','); \
+        } \
+      else \
+        { \
+          if (! curr_lexer->looking_at_decl_list \
+              && curr_lexer->previous_token_may_be_command ()) \
+            { \
+              yyless (0); \
+              curr_lexer->push_start_state (COMMAND_START); \
+            } \
+          else \
+            { \
+              if (get_set) \
+                curr_lexer->maybe_classdef_get_set_method = false; \
+ \
+              int id_tok = curr_lexer->handle_identifier (); \
+ \
+              if (id_tok >= 0) \
+                return curr_lexer->count_token_internal (id_tok); \
+            } \
+        } \
+    } \
+  while (0)
+
 static bool Vdisplay_tokens = false;
 
 static unsigned int Vtoken_count = 0;
@@ -272,11 +311,6 @@
 // Internal variable for lexer debugging state.
 static bool lexer_debug_flag = false;
 
-// Forward declarations for functions defined at the bottom of this
-// file that are needed inside the lexer actions.
-
-static std::string strip_trailing_whitespace (char *s);
-
 %}
 
 D       [0-9]
@@ -285,6 +319,7 @@
 Im      [iIjJ]
 CCHAR   [#%]
 IDENT   ([_$a-zA-Z][_$a-zA-Z0-9]*)
+FQIDENT ({IDENT}(\.{IDENT})*)
 EXPON   ([DdEe][+-]?{D}+)
 NUMBER  (({D}+\.?{D}*{EXPON}?)|(\.{D}+{EXPON}?)|(0[xX][0-9a-fA-F]+))
 
@@ -1017,6 +1052,35 @@
   }
 
 %{
+// Fully-qualified identifiers (used for classdef).
+%}
+
+<FQ_IDENT_START>{FQIDENT} {
+    curr_lexer->lexer_debug ("<FQ_IDENT_START>{FQIDENT}");
+    curr_lexer->pop_start_state ();
+
+    int id_tok = curr_lexer->handle_fq_identifier ();
+
+    if (id_tok >= 0)
+      {
+        curr_lexer->looking_for_object_index = true;
+
+        return curr_lexer->count_token_internal (id_tok);
+      }
+  }
+
+<FQ_IDENT_START>{S}+ {
+    curr_lexer->current_input_column += yyleng;
+
+    curr_lexer->mark_previous_token_trailing_space ();
+  }
+
+<FQ_IDENT_START>. {
+    yyless (0);
+    curr_lexer->pop_start_state ();
+  }
+
+%{
 // Imaginary numbers.
 %}
 
@@ -1137,46 +1201,25 @@
 
 %{
 // Identifiers.
+
+// Don't allow get and set to be recognized as keywords if they are
+// followed by "(".
 %}
 
+(set|get)/{S}*\( {
+    HANDLE_IDENTIFIER ("(set|get)/{S}*\\(", true);
+  }
+
 {IDENT} {
-    curr_lexer->lexer_debug ("{IDENT}");
-
-    int tok = curr_lexer->previous_token_value ();
-
-    if (curr_lexer->whitespace_is_significant ()
-        && curr_lexer->space_follows_previous_token ()
-        && ! (tok == '[' || tok == '{'
-              || curr_lexer->previous_token_is_binop ()))
-      {
-        yyless (0);
-        unput (',');
-      }
-    else
-      {
-        if (! curr_lexer->looking_at_decl_list
-            && curr_lexer->previous_token_may_be_command ())
-          {
-            yyless (0);
-            curr_lexer->push_start_state (COMMAND_START);
-          }
-        else
-          {
-            int id_tok = curr_lexer->handle_identifier ();
-
-            if (id_tok >= 0)
-              return curr_lexer->count_token_internal (id_tok);
-          }
-      }
+    HANDLE_IDENTIFIER ("{IDENT}", false);
   }
 
 %{
 // Superclass method identifiers.
 %}
 
-{IDENT}@{IDENT} |
-{IDENT}@{IDENT}.{IDENT} {
-    curr_lexer->lexer_debug ("{IDENT}@{IDENT}|{IDENT}@{IDENT}.{IDENT}");
+{IDENT}@{FQIDENT} {
+    curr_lexer->lexer_debug ("{IDENT}@{FQIDENT}");
 
     if (curr_lexer->previous_token_may_be_command ())
       {
@@ -1191,7 +1234,7 @@
           {
             curr_lexer->looking_for_object_index = true;
 
-            return curr_lexer->count_token_internal (SUPERCLASSREF);
+            return curr_lexer->count_token_internal (id_tok);
           }
       }
   }
@@ -1200,9 +1243,8 @@
 // Metaclass query
 %}
 
-\?{IDENT} |
-\?{IDENT}\.{IDENT} {
-    curr_lexer->lexer_debug ("\\?{IDENT}|\\?{IDENT}\\.{IDENT}");
+\?{FQIDENT} {
+    curr_lexer->lexer_debug ("\\?{FQIDENT}");
 
     if (curr_lexer->previous_token_may_be_command ()
         &&  curr_lexer->space_follows_previous_token ())
@@ -1218,7 +1260,7 @@
           {
             curr_lexer->looking_for_object_index = true;
 
-            return curr_lexer->count_token_internal (METAQUERY);
+            return curr_lexer->count_token_internal (id_tok);
           }
       }
   }
@@ -1886,21 +1928,6 @@
 
 */
 
-// Used to delete trailing white space from tokens.
-
-static std::string
-strip_trailing_whitespace (char *s)
-{
-  std::string retval = s;
-
-  size_t pos = retval.find_first_of (" \t");
-
-  if (pos != std::string::npos)
-    retval.resize (pos);
-
-  return retval;
-}
-
 DEFUN (__display_tokens__, args, nargout,
   "-*- texinfo -*-\n\
 @deftypefn {Built-in Function} {} __display_tokens__ ()\n\
@@ -1966,8 +1993,10 @@
   looking_for_object_index = false; 
   looking_at_indirect_ref = false;
   parsing_class_method = false;
+  parsing_classdef = false;
   maybe_classdef_get_set_method = false;
-  parsing_classdef = false;
+  parsing_classdef_get_method = false;
+  parsing_classdef_set_method = false;
   force_script = false;
   reading_fcn_file = false;
   reading_script_file = false;
@@ -2369,20 +2398,6 @@
           at_beginning_of_statement = true;
           break;
 
-        case static_kw:
-          if ((reading_fcn_file || reading_script_file
-               || reading_classdef_file)
-              && ! fcn_file_full_name.empty ())
-            warning_with_id ("Octave:deprecated-keyword",
-                             "the 'static' keyword is obsolete and will be removed from a future version of Octave; please use 'persistent' instead; near line %d of file '%s'",
-                             input_line_number,
-                             fcn_file_full_name.c_str ());
-          else
-            warning_with_id ("Octave:deprecated-keyword",
-                             "the 'static' keyword is obsolete and will be removed from a future version of Octave; please use 'persistent' instead; near line %d",
-                             input_line_number);
-          // fall through ...
-
         case persistent_kw:
         case global_kw:
           looking_at_decl_list = true;
@@ -2395,10 +2410,9 @@
 
         case end_kw:
           if (inside_any_object_index ()
-              || (! reading_classdef_file
-                  && (defining_func
-                      && ! (looking_at_return_list
-                            || parsed_function_name.top ()))))
+              || (defining_func
+                  && ! (looking_at_return_list
+                        || parsed_function_name.top ())))
             {
               at_beginning_of_statement = previous_at_bos;
               return 0;
@@ -2584,6 +2598,34 @@
 }
 
 bool
+octave_base_lexer::fq_identifier_contains_keyword (const std::string& s)
+{
+  size_t p1 = 0;
+  size_t p2;
+
+  std::string s_part;
+
+  do
+    {
+      p2 = s.find ('.', p1);
+
+      if (p2 != std::string::npos)
+        {
+          s_part = s.substr (p1, p2 - p1);
+          p1 = p2 + 1;
+        }
+      else
+        s_part = s.substr (p1);
+
+      if (is_keyword_token (s_part))
+        return true;
+    }
+  while (p2 != std::string::npos);
+
+  return false;
+}
+
+bool
 octave_base_lexer::whitespace_is_significant (void)
 {
   return (nesting_level.is_bracket ()
@@ -2755,36 +2797,23 @@
 int
 octave_base_lexer::handle_superclass_identifier (void)
 {
-  std::string pkg;
-  char *yytxt = flex_yytext ();
-  std::string meth = strip_trailing_whitespace (yytxt);
+  std::string meth = flex_yytext ();
+
   size_t pos = meth.find ("@");
-  std::string cls = meth.substr (pos).substr (1);
-  meth = meth.substr (0, pos - 1);
-
-  pos = cls.find (".");
-  if (pos != std::string::npos)
-    {
-      pkg = cls.substr (pos).substr (1);
-      cls = cls.substr (0, pos - 1);
-    }
-
-  int kw_token = (is_keyword_token (meth) || is_keyword_token (cls)
-                  || is_keyword_token (pkg));
+  std::string cls = meth.substr (pos + 1);
+  meth = meth.substr (0, pos);
+
+  bool kw_token = (is_keyword_token (meth)
+                   || fq_identifier_contains_keyword (cls));
+
   if (kw_token)
     {
-      error ("method, class and package names may not be keywords");
+      error ("method, class, and package names may not be keywords");
       return LEXICAL_ERROR;
     }
 
-  symbol_table::scope_id sid = symtab_context.curr_scope ();
-
-  push_token (new token
-              (SUPERCLASSREF,
-               meth.empty () ? 0 : &(symbol_table::insert (meth, sid)),
-               cls.empty () ? 0 : &(symbol_table::insert (cls, sid)),
-               pkg.empty () ? 0 : &(symbol_table::insert (pkg, sid)),
-               input_line_number, current_input_column));
+  push_token (new token (SUPERCLASSREF, meth, cls,
+                         input_line_number, current_input_column));
 
   current_input_column += flex_yyleng ();
 
@@ -2794,37 +2823,41 @@
 int
 octave_base_lexer::handle_meta_identifier (void)
 {
-  std::string pkg;
-  char *yytxt = flex_yytext ();
-  std::string cls = strip_trailing_whitespace (yytxt).substr (1);
-  size_t pos = cls.find (".");
-
-  if (pos != std::string::npos)
+  std::string cls = std::string(flex_yytext ()).substr (1);
+
+  if (fq_identifier_contains_keyword (cls))
     {
-      pkg = cls.substr (pos).substr (1);
-      cls = cls.substr (0, pos - 1);
-    }
-
-  int kw_token = is_keyword_token (cls) || is_keyword_token (pkg);
-  if (kw_token)
-    {
-       error ("class and package names may not be keywords");
+      error ("class and package names may not be keywords");
       return LEXICAL_ERROR;
     }
 
-  symbol_table::scope_id sid = symtab_context.curr_scope ();
-
-  push_token (new token
-              (METAQUERY,
-               cls.empty () ? 0 : &(symbol_table::insert (cls, sid)),
-               pkg.empty () ? 0 : &(symbol_table::insert (pkg, sid)),
-               input_line_number, current_input_column));
+  push_token (new token (METAQUERY, cls, input_line_number,
+                         current_input_column));
 
   current_input_column += flex_yyleng ();
 
   return METAQUERY;
 }
 
+int
+octave_base_lexer::handle_fq_identifier (void)
+{
+  std::string tok = flex_yytext ();
+
+  if (fq_identifier_contains_keyword (tok))
+    {
+      error ("function, method, class, and package names may not be keywords");
+      return LEXICAL_ERROR;
+    }
+
+  push_token (new token (FQ_IDENT, tok, input_line_number,
+                         current_input_column));
+
+  current_input_column += flex_yyleng ();
+
+  return FQ_IDENT;
+}
+
 // Figure out exactly what kind of token to return when we have seen
 // an identifier.  Handles keywords.  Return -1 if the identifier
 // should be ignored.
@@ -3382,6 +3415,12 @@
   return tok;
 }
 
+void
+octave_base_lexer::enable_fq_identifier (void)
+{
+  push_start_state (FQ_IDENT_START);
+}
+
 int
 octave_lexer::fill_flex_buffer (char *buf, unsigned max_size)
 {
--- a/libinterp/parse-tree/module.mk	Fri Aug 01 09:06:21 2014 -0400
+++ b/libinterp/parse-tree/module.mk	Fri Aug 01 12:10:05 2014 -0400
@@ -21,6 +21,7 @@
   parse-tree/pt-cbinop.h \
   parse-tree/pt-cell.h \
   parse-tree/pt-check.h \
+  parse-tree/pt-classdef.h \
   parse-tree/pt-cmd.h \
   parse-tree/pt-colon.h \
   parse-tree/pt-const.h \
@@ -29,6 +30,7 @@
   parse-tree/pt-except.h \
   parse-tree/pt-exp.h \
   parse-tree/pt-fcn-handle.h \
+  parse-tree/pt-funcall.h \
   parse-tree/pt-id.h \
   parse-tree/pt-idx.h \
   parse-tree/pt-jump.h \
@@ -52,6 +54,7 @@
   parse-tree/pt-cbinop.cc \
   parse-tree/pt-cell.cc \
   parse-tree/pt-check.cc \
+  parse-tree/pt-classdef.cc \
   parse-tree/pt-cmd.cc \
   parse-tree/pt-colon.cc \
   parse-tree/pt-const.cc \
@@ -60,6 +63,7 @@
   parse-tree/pt-except.cc \
   parse-tree/pt-exp.cc \
   parse-tree/pt-fcn-handle.cc \
+  parse-tree/pt-funcall.cc \
   parse-tree/pt-id.cc \
   parse-tree/pt-idx.cc \
   parse-tree/pt-jump.cc \
--- a/libinterp/parse-tree/oct-parse.in.yy	Fri Aug 01 09:06:21 2014 -0400
+++ b/libinterp/parse-tree/oct-parse.in.yy	Fri Aug 01 12:10:05 2014 -0400
@@ -62,6 +62,7 @@
 #include "load-path.h"
 #include "oct-hist.h"
 #include "oct-map.h"
+#include "ov-classdef.h"
 #include "ov-fcn-handle.h"
 #include "ov-usr-fcn.h"
 #include "ov-null-mat.h"
@@ -70,6 +71,7 @@
 #include "parse.h"
 #include "pt-all.h"
 #include "pt-eval.h"
+#include "pt-funcall.h"
 #include "symtab.h"
 #include "token.h"
 #include "unwind-prot.h"
@@ -161,6 +163,8 @@
   tree_expression *tree_expression_type;
   tree_constant *tree_constant_type;
   tree_fcn_handle *tree_fcn_handle_type;
+  tree_funcall *tree_funcall_type;
+  tree_function_def *tree_function_def_type;
   tree_anon_fcn_handle *tree_anon_fcn_handle_type;
   tree_identifier *tree_identifier_type;
   tree_index_expression *tree_index_expression_type;
@@ -180,7 +184,24 @@
   tree_statement *tree_statement_type;
   tree_statement_list *tree_statement_list_type;
   octave_user_function *octave_user_function_type;
-  void *dummy_type;
+
+  tree_classdef *tree_classdef_type;
+  tree_classdef_attribute* tree_classdef_attribute_type;
+  tree_classdef_attribute_list* tree_classdef_attribute_list_type;
+  tree_classdef_superclass* tree_classdef_superclass_type;
+  tree_classdef_superclass_list* tree_classdef_superclass_list_type;
+  tree_classdef_body* tree_classdef_body_type;
+  tree_classdef_property* tree_classdef_property_type;
+  tree_classdef_property_list* tree_classdef_property_list_type;
+  tree_classdef_properties_block* tree_classdef_properties_block_type;
+  tree_classdef_methods_list* tree_classdef_methods_list_type;
+  tree_classdef_methods_block* tree_classdef_methods_block_type;
+  tree_classdef_event* tree_classdef_event_type;
+  tree_classdef_events_list* tree_classdef_events_list_type;
+  tree_classdef_events_block* tree_classdef_events_block_type;
+  tree_classdef_enum* tree_classdef_enum_type;
+  tree_classdef_enum_list* tree_classdef_enum_list_type;
+  tree_classdef_enum_block* tree_classdef_enum_block_type;
 }
 
 // Tokens with line and column information.
@@ -207,21 +228,22 @@
 %token <tok_val> TRY CATCH
 %token <tok_val> GLOBAL PERSISTENT
 %token <tok_val> FCN_HANDLE
+%token <tok_val> CLASSDEF
 %token <tok_val> PROPERTIES METHODS EVENTS ENUMERATION
 %token <tok_val> METAQUERY
 %token <tok_val> SUPERCLASSREF
+%token <tok_val> FQ_IDENT
 %token <tok_val> GET SET
 %token <tok_val> FCN
 
 // Other tokens.
 %token END_OF_INPUT LEXICAL_ERROR
-%token INPUT_FILE CLASSDEF
+%token INPUT_FILE
 // %token VARARGIN VARARGOUT
 
 // Nonterminals we construct.
-%type <tok_val> function_beg
-%type <comment_type> stash_comment classdef_beg
-%type <comment_type> properties_beg methods_beg events_beg enum_beg
+%type <comment_type> stash_comment
+%type <tok_val> function_beg classdef_beg
 %type <sep_type> sep_no_nl opt_sep_no_nl nl opt_nl sep opt_sep
 %type <tree_type> input
 %type <tree_constant_type> string constant magic_colon
@@ -233,18 +255,19 @@
 %type <tree_expression_type> primary_expr oper_expr power_expr
 %type <tree_expression_type> simple_expr colon_expr assign_expr expression
 %type <tree_identifier_type> identifier fcn_name magic_tilde
-%type <tree_identifier_type> superclass_identifier meta_identifier
-%type <octave_user_function_type> function1 function2 classdef1
+%type <tree_funcall_type> superclass_identifier meta_identifier
+%type <octave_user_function_type> function1 function2
 %type <tree_index_expression_type> word_list_cmd
 %type <tree_colon_expression_type> colon_expr1
 %type <tree_argument_list_type> arg_list word_list assign_lhs
 %type <tree_argument_list_type> cell_or_matrix_row
 %type <tree_parameter_list_type> param_list param_list1 param_list2
 %type <tree_parameter_list_type> return_list return_list1
-%type <tree_parameter_list_type> superclasses opt_superclasses
 %type <tree_command_type> command select_command loop_command
-%type <tree_command_type> jump_command except_command function
-%type <tree_command_type> file classdef
+%type <tree_command_type> jump_command except_command
+%type <tree_function_def_type> function
+%type <tree_classdef_type> classdef
+%type <tree_command_type> file
 %type <tree_if_command_type> if_command
 %type <tree_if_clause_type> elseif_clause else_clause
 %type <tree_if_command_list_type> if_cmd_list1 if_cmd_list
@@ -254,25 +277,27 @@
 %type <tree_decl_elt_type> decl2 param_list_elt
 %type <tree_decl_init_list_type> decl1
 %type <tree_decl_command_type> declaration
-%type <tree_statement_type> statement function_end classdef_end
+%type <tree_statement_type> statement function_end
 %type <tree_statement_list_type> simple_list simple_list1 list list1
 %type <tree_statement_list_type> opt_list
-// These types need to be specified.
-%type <dummy_type> attr
-%type <dummy_type> class_event
-%type <dummy_type> class_enum
-%type <dummy_type> class_property
-%type <dummy_type> properties_list
-%type <dummy_type> properties_block
-%type <dummy_type> methods_list
-%type <dummy_type> methods_block
-%type <dummy_type> opt_attr_list
-%type <dummy_type> attr_list
-%type <dummy_type> events_list
-%type <dummy_type> events_block
-%type <dummy_type> enum_list
-%type <dummy_type> enum_block
-%type <dummy_type> class_body
+%type <tree_classdef_attribute_type> attr
+%type <tree_classdef_attribute_list_type> attr_list opt_attr_list
+%type <tree_classdef_superclass_type> superclass
+%type <tree_classdef_superclass_list_type> superclass_list opt_superclass_list
+%type <tree_classdef_body_type> class_body
+%type <tree_classdef_property_type> class_property
+%type <tree_classdef_property_list_type> property_list
+%type <tree_classdef_properties_block_type> properties_block
+%type <tree_classdef_methods_list_type> methods_list
+%type <tree_classdef_methods_block_type> methods_block
+%type <tree_classdef_event_type> class_event
+%type <tree_classdef_events_list_type> events_list
+%type <tree_classdef_events_block_type> events_block
+%type <tree_classdef_enum_type> class_enum
+%type <tree_classdef_enum_list_type> enum_list
+%type <tree_classdef_enum_block_type> enum_block
+%type <tree_function_def_type> method_decl method
+%type <octave_user_function_type> method_decl1
 
 // Precedence and associativity.
 %right '=' ADD_EQ SUB_EQ MUL_EQ DIV_EQ LEFTDIV_EQ POW_EQ EMUL_EQ EDIV_EQ ELEFTDIV_EQ EPOW_EQ OR_EQ AND_EQ LSHIFT_EQ RSHIFT_EQ
@@ -309,6 +334,8 @@
 %destructor { delete $$; } <tree_expression_type> 
 %destructor { delete $$; } <tree_constant_type> 
 %destructor { delete $$; } <tree_fcn_handle_type> 
+%destructor { delete $$; } <tree_funcall>
+%destructor { delete $$; } <tree_function_def>
 %destructor { delete $$; } <tree_anon_fcn_handle_type> 
 %destructor { delete $$; } <tree_identifier_type> 
 %destructor { delete $$; } <tree_index_expression_type> 
@@ -329,6 +356,24 @@
 %destructor { delete $$; } <tree_statement_list_type> 
 %destructor { delete $$; } <octave_user_function_type> 
 
+%destructor { delete $$; } <tree_classdef_type>
+%destructor { delete $$; } <tree_classdef_attribute_type>
+%destructor { delete $$; } <tree_classdef_attribute_list_type>
+%destructor { delete $$; } <tree_classdef_superclass_type>
+%destructor { delete $$; } <tree_classdef_superclass_list_type>
+%destructor { delete $$; } <tree_classdef_body_type>
+%destructor { delete $$; } <tree_classdef_property_type>
+%destructor { delete $$; } <tree_classdef_property_list_type>
+%destructor { delete $$; } <tree_classdef_properties_block_type>
+%destructor { delete $$; } <tree_classdef_methods_list_type>
+%destructor { delete $$; } <tree_classdef_methods_block_type>
+%destructor { delete $$; } <tree_classdef_event_type>
+%destructor { delete $$; } <tree_classdef_events_list_type>
+%destructor { delete $$; } <tree_classdef_events_block_type>
+%destructor { delete $$; } <tree_classdef_enum_type>
+%destructor { delete $$; } <tree_classdef_enum_list_type>
+%destructor { delete $$; } <tree_classdef_enum_block_type>
+
 %destructor {
     warning_with_id
       ("Octave:parser-destructor",
@@ -436,11 +481,20 @@
 
 superclass_identifier
                 : SUPERCLASSREF
-                  { $$ = new tree_identifier ($1->line (), $1->column ()); }
+                  {
+                    std::string method_nm = $1->superclass_method_name ();
+                    std::string class_nm = $1->superclass_class_name ();
+
+                    $$ = parser.make_superclass_ref (method_nm, class_nm);
+                  }
                 ;
 
 meta_identifier : METAQUERY
-                  { $$ = new tree_identifier ($1->line (), $1->column ()); }
+                  {
+                    std::string class_nm = $1->text ();
+
+                    $$ = parser.make_meta_class_query (class_nm);
+                  }
                 ;
 
 string          : DQ_STRING
@@ -864,8 +918,6 @@
                   { $$ = $1; }
                 | file
                   { $$ = $1; }
-                | classdef
-                  { $$ = $1; }
                 ;
 
 // =====================
@@ -1291,6 +1343,13 @@
 
                     $$ = 0;
                   }
+                | INPUT_FILE opt_nl classdef opt_sep END_OF_INPUT
+                  {
+                    if (lexer.reading_classdef_file)
+                      parser.classdef_object = $3;
+
+                    $$ = 0;
+                  }
                 ;
 
 // ===================
@@ -1333,12 +1392,14 @@
                   {
                     lexer.parsed_function_name.top () = true;
                     lexer.maybe_classdef_get_set_method = false;
+                    lexer.parsing_classdef_get_method = true;
                     $$ = $3;
                   }
                 | SET '.' identifier
                   {
                     lexer.parsed_function_name.top () = true;
                     lexer.maybe_classdef_get_set_method = false;
+                    lexer.parsing_classdef_set_method = true;
                     $$ = $3;
                   }
                 ;
@@ -1349,6 +1410,14 @@
 
                     delete $1;
 
+                    if (lexer.parsing_classdef_get_method)
+                      fname.insert (0, "get.");
+                    else if (lexer.parsing_classdef_set_method)
+                      fname.insert (0, "set.");
+
+                    lexer.parsing_classdef_get_method = false;
+                    lexer.parsing_classdef_set_method = false;
+
                     $$ = parser.frob_function (fname, $2);
                   }
                 ;
@@ -1408,158 +1477,299 @@
 // Classdef
 // ========
 
-classdef_beg    : CLASSDEF stash_comment
+classdef_beg    : CLASSDEF
                   {
-                    $$ = 0;
+                    if (! lexer.reading_classdef_file)
+                      {
+                        parser.bison_error ("classdef must appear inside a file containing only a class definition");
+                        YYABORT;
+                      }
+
                     lexer.parsing_classdef = true;
+                    $$ = $1;
                   }
                 ;
 
-classdef_end    : END
+classdef        : classdef_beg stash_comment opt_attr_list identifier opt_superclass_list opt_sep class_body opt_sep END
                   {
                     lexer.parsing_classdef = false;
 
-                    if (parser.end_token_ok ($1, token::classdef_end))
-                      $$ = parser.make_end ("endclassdef", false,
-                                            $1->line (), $1->column ());
-                    else
-                      ABORT_PARSE;
+                    if (! ($$ = parser.make_classdef ($1, $3, $4, $5, $7, $9, $2)))
+                      {
+                        // make_classdef deleted $3, $4, $5, and $7.
+                        ABORT_PARSE;
+                      }
                   }
-                ;
-
-classdef1       : classdef_beg opt_attr_list identifier opt_superclasses
-                  { $$ = 0; }
-                ;
-
-classdef        : classdef1 opt_sep class_body opt_sep stash_comment classdef_end
-                  { $$ = 0; }
+                | classdef_beg stash_comment opt_attr_list identifier opt_superclass_list opt_sep END
+                  {
+                    lexer.parsing_classdef = false;
+
+                    if (! ($$ = parser.make_classdef ($1, $3, $4, $5, 0, $7, $2)))
+                      {
+                        // make_classdef deleted $3, $4, and $5.
+                        ABORT_PARSE;
+                      }
+                  }
                 ;
 
 opt_attr_list   : // empty
                   { $$ = 0; }
                 | '(' attr_list ')'
-                  { $$ = 0; }
+                  { $$ = $2; }
                 ;
 
 attr_list       : attr
-                  { $$ = 0; }
+                  { $$ = new tree_classdef_attribute_list ($1); }
                 | attr_list ',' attr
-                  { $$ = 0; }
+                  {
+                    $1->append ($3);
+                    $$ = $1;
+                  }
                 ;
 
 attr            : identifier
-                  { $$ = 0; }
+                  { $$ = new tree_classdef_attribute ($1); }
                 | identifier '=' decl_param_init expression
-                  { $$ = 0; }
+                  {
+                    lexer.looking_at_initializer_expression = false;
+                    $$ = new tree_classdef_attribute ($1, $4);
+                  }
                 | EXPR_NOT identifier
-                  { $$ = 0; }
+                  { $$ = new tree_classdef_attribute ($2, false); }
                 ;
 
-opt_superclasses
+opt_superclass_list
                 : // empty
                   { $$ = 0; }
-                | superclasses
-                  { $$ = 0; }
+                | superclass_list
+                  { $$ = $1; }
                 ;
 
-superclasses    : EXPR_LT identifier '.' identifier
-                  { $$ = 0; }
-                | EXPR_LT identifier
-                  { $$ = 0; }
-                | superclasses EXPR_AND identifier '.' identifier
-                  { $$ = 0; }
-                | superclasses EXPR_AND identifier
-                  { $$ = 0; }
+superclass_list : EXPR_LT
+                  { lexer.enable_fq_identifier (); }
+                  superclass
+                  { $$ = new tree_classdef_superclass_list ($3); }
+                | superclass_list EXPR_AND
+                  { lexer.enable_fq_identifier (); }
+                  superclass
+                  {
+                    $1->append ($4);
+                    $$ = $1;
+                  }
+                ;
+
+superclass      : FQ_IDENT
+                  { $$ = new tree_classdef_superclass ($1->text ()); }
                 ;
 
 class_body      : properties_block
-                  { $$ = 0; }
+                  { $$ = new tree_classdef_body ($1); }
                 | methods_block
-                  { $$ = 0; }
+                  { $$ = new tree_classdef_body ($1); }
                 | events_block
-                  { $$ = 0; }
+                  { $$ = new tree_classdef_body ($1); }
                 | enum_block
-                  { $$ = 0; }
+                  { $$ = new tree_classdef_body ($1); }
                 | class_body opt_sep properties_block
-                  { $$ = 0; }
+                  {
+                    $1->append ($3);
+                    $$ = $1;
+                  }
                 | class_body opt_sep methods_block
-                  { $$ = 0; }
+                  {
+                    $1->append ($3);
+                    $$ = $1;
+                  }
                 | class_body opt_sep events_block
-                  { $$ = 0; }
+                  {
+                    $1->append ($3);
+                    $$ = $1;
+                  }
                 | class_body opt_sep enum_block
-                  { $$ = 0; }
-                ;
-
-properties_beg  : PROPERTIES stash_comment
-                  { $$ = 0; }
+                  {
+                    $1->append ($3);
+                    $$ = $1;
+                  }
                 ;
 
 properties_block
-                : properties_beg opt_attr_list opt_sep properties_list opt_sep END
-                  { $$ = 0; }
+                : PROPERTIES stash_comment opt_attr_list opt_sep property_list opt_sep END
+                  {
+                    if (! ($$ = parser.make_classdef_properties_block
+                           ($1, $3, $5, $7, $2)))
+                      {
+                        // make_classdef_properties_block delete $3 and $5.
+                        ABORT_PARSE;
+                      }
+                  }
+                | PROPERTIES stash_comment opt_attr_list opt_sep END
+                  {
+                    if (! ($$ = parser.make_classdef_properties_block
+                           ($1, $3, 0, $5, $2)))
+                      {
+                        // make_classdef_properties_block delete $3.
+                        ABORT_PARSE;
+                      }
+                  }
                 ;
 
-properties_list
+property_list
                 : class_property
-                  { $$ = 0; }
-                | properties_list opt_sep class_property
-                  { $$ = 0; }
+                  { $$ = new tree_classdef_property_list ($1); }
+                | property_list opt_sep class_property
+                  {
+                    $1->append ($3);
+                    $$ = $1;
+                  }
                 ;
 
 class_property  : identifier
-                  { $$ = 0; }
+                  { $$ = new tree_classdef_property ($1); }
                 | identifier '=' decl_param_init expression ';'
-                  { $$ = 0; }
+                  {
+                    lexer.looking_at_initializer_expression = false;
+                    $$ = new tree_classdef_property ($1, $4);
+                  }
                 ;
 
-methods_beg     : METHODS stash_comment
-                  { $$ = 0; }
+methods_block   : METHODS stash_comment opt_attr_list opt_sep methods_list opt_sep END
+                  {
+                    if (! ($$ = parser.make_classdef_methods_block
+                           ($1, $3, $5, $7, $2)))
+                      {
+                        // make_classdef_methods_block deleted $3 and $5.
+                        ABORT_PARSE;
+                      }
+                  }
+                | METHODS stash_comment opt_attr_list opt_sep END
+                  {
+                    if (! ($$ = parser.make_classdef_methods_block
+                           ($1, $3, 0, $5, $2)))
+                      {
+                        // make_classdef_methods_block deleted $3.
+                        ABORT_PARSE;
+                      }
+                  }
                 ;
-
-methods_block   : methods_beg opt_attr_list opt_sep methods_list opt_sep END
-                  { $$ = 0; }
+                ;
+
+method_decl1    : identifier
+                  {
+                    if (! ($$ = parser.start_classdef_external_method ($1, 0)))
+                      ABORT_PARSE;
+                  }
+                | identifier param_list
+                  {
+                    if (! ($$ = parser.start_classdef_external_method ($1, $2)))
+                      ABORT_PARSE;
+                  }
                 ;
 
-methods_list    : function
-                  { $$ = 0; }
-                | methods_list opt_sep function
-                  { $$ = 0; }
+method_decl     : stash_comment method_decl1
+                  { $$ = parser.finish_classdef_external_method ($2, 0, $1); }
+                | stash_comment return_list '='
+                  {
+                    lexer.defining_func++;
+                    lexer.parsed_function_name.push (false);
+                  }
+                  method_decl1
+                  {
+                    lexer.defining_func--;
+                    lexer.parsed_function_name.pop ();
+                    $$ = parser.finish_classdef_external_method ($5, $2, $1);
+                  }
+                ;
+
+method          : method_decl
+                  { $$ = $1; }
+                | function
+                  { $$ = $1; }
                 ;
 
-events_beg      : EVENTS stash_comment
-                  { $$ = 0; }
+methods_list    : method
+                  {
+                    octave_value fcn;
+                    if ($1)
+                      fcn = $1->function ();
+                    delete $1;
+                    $$ = new tree_classdef_methods_list (fcn);
+                  }
+                | methods_list opt_sep method
+                  {
+                    octave_value fcn;
+                    if ($3)
+                      fcn = $3->function ();
+                    delete $3;
+
+                    $1->append (fcn);
+                    $$ = $1;
+                  }
                 ;
 
-events_block    : events_beg opt_attr_list opt_sep events_list opt_sep END
-                  { $$ = 0; }
+events_block    : EVENTS stash_comment opt_attr_list opt_sep events_list opt_sep END
+                  {
+                    if (! ($$ = parser.make_classdef_events_block
+                           ($1, $3, $5, $7, $2)))
+                      {
+                        // make_classdef_events_block deleted $3 and $5.
+                        ABORT_PARSE;
+                      }
+                  }
+                | EVENTS stash_comment opt_attr_list opt_sep END
+                  {
+                    if (! ($$ = parser.make_classdef_events_block
+                           ($1, $3, 0, $5, $2)))
+                      {
+                        // make_classdef_events_block deleted $3.
+                        ABORT_PARSE;
+                      }
+                  }
                 ;
 
 events_list     : class_event
-                  { $$ = 0; }
+                  { $$ = new tree_classdef_events_list ($1); }
                 | events_list opt_sep class_event
-                  { $$ = 0; }
+                  {
+                    $1->append ($3);
+                    $$ = $1;
+                  }
                 ;
 
 class_event     : identifier
-                  { $$ = 0; }
+                  { $$ = new tree_classdef_event ($1); }
                 ;
 
-enum_beg        : ENUMERATION stash_comment
-                  { $$ = 0; }
-                ;
-
-enum_block      : enum_beg opt_attr_list opt_sep enum_list opt_sep END
-                  { $$ = 0; }
+enum_block      : ENUMERATION stash_comment opt_attr_list opt_sep enum_list opt_sep END
+                  {
+                    if (! ($$ = parser.make_classdef_enum_block
+                           ($1, $3, $5, $7, $2)))
+                      {
+                        // make_classdef_enum_block deleted $3 and $5.
+                        ABORT_PARSE;
+                      }
+                  }
+                | ENUMERATION stash_comment opt_attr_list opt_sep END
+                  {
+                    if (! ($$ = parser.make_classdef_enum_block
+                           ($1, $3, 0, $5, $2)))
+                      {
+                        // make_classdef_enum_block deleted $3.
+                        ABORT_PARSE;
+                      }
+                  }
                 ;
 
 enum_list       : class_enum
-                  { $$ = 0; }
+                  { $$ = new tree_classdef_enum_list ($1); }
                 | enum_list opt_sep class_enum
-                  { $$ = 0; }
+                  {
+                    $1->append ($3);
+                    $$ = $1;
+                  }
                 ;
 
 class_enum      : identifier '(' expression ')'
-                  { $$ = 0; }
+                  { $$ = new tree_classdef_enum ($1, $3); }
                 ;
 
 // =============
@@ -1657,6 +1867,7 @@
   curr_fcn_depth = 0;
   primary_fcn_scope = -1;
   curr_class_name = "";
+  curr_package_name = "";
   function_scopes.clear ();
   primary_fcn_ptr  = 0;
   subfunction_names.clear ();
@@ -1828,95 +2039,6 @@
     }
 }
 
-static tree_expression *
-fold (tree_binary_expression *e)
-{
-  tree_expression *retval = e;
-
-  unwind_protect frame;
-
-  frame.protect_var (error_state);
-  frame.protect_var (warning_state);
-
-  frame.protect_var (discard_error_messages);
-  frame.protect_var (discard_warning_messages);
-
-  discard_error_messages = true;
-  discard_warning_messages = true;
-
-  tree_expression *op1 = e->lhs ();
-  tree_expression *op2 = e->rhs ();
-
-  if (op1->is_constant () && op2->is_constant ())
-    {
-      octave_value tmp = e->rvalue1 ();
-
-      if (! (error_state || warning_state))
-        {
-          tree_constant *tc_retval
-            = new tree_constant (tmp, op1->line (), op1->column ());
-
-          std::ostringstream buf;
-
-          tree_print_code tpc (buf);
-
-          e->accept (tpc);
-
-          tc_retval->stash_original_text (buf.str ());
-
-          delete e;
-
-          retval = tc_retval;
-        }
-    }
-
-  return retval;
-}
-
-static tree_expression *
-fold (tree_unary_expression *e)
-{
-  tree_expression *retval = e;
-
-  unwind_protect frame;
-
-  frame.protect_var (error_state);
-  frame.protect_var (warning_state);
-
-  frame.protect_var (discard_error_messages);
-  frame.protect_var (discard_warning_messages);
-
-  discard_error_messages = true;
-  discard_warning_messages = true;
-
-  tree_expression *op = e->operand ();
-
-  if (op->is_constant ())
-    {
-      octave_value tmp = e->rvalue1 ();
-
-      if (! (error_state || warning_state))
-        {
-          tree_constant *tc_retval
-            = new tree_constant (tmp, op->line (), op->column ());
-
-          std::ostringstream buf;
-
-          tree_print_code tpc (buf);
-
-          e->accept (tpc);
-
-          tc_retval->stash_original_text (buf.str ());
-
-          delete e;
-
-          retval = tc_retval;
-        }
-    }
-
-  return retval;
-}
-
 // Finish building a range.
 
 tree_expression *
@@ -1972,8 +2094,6 @@
           e->preserve_base ();
           delete e;
 
-          // FIXME -- need to attempt constant folding here
-          // too (we need a generic way to do that).
           retval = base;
         }
     }
@@ -2186,10 +2306,7 @@
   int l = tok_val->line ();
   int c = tok_val->column ();
 
-  tree_binary_expression *e
-    = maybe_compound_binary_expression (op1, op2, l, c, t);
-
-  return fold (e);
+  return maybe_compound_binary_expression (op1, op2, l, c, t);
 }
 
 // Build a boolean expression.
@@ -2218,10 +2335,7 @@
   int l = tok_val->line ();
   int c = tok_val->column ();
 
-  tree_boolean_expression *e
-    = new tree_boolean_expression (op1, op2, l, c, t);
-
-  return fold (e);
+  return new tree_boolean_expression (op1, op2, l, c, t);
 }
 
 // Build a prefix expression.
@@ -2262,10 +2376,7 @@
   int l = tok_val->line ();
   int c = tok_val->column ();
 
-  tree_prefix_expression *e
-    = new tree_prefix_expression (op1, l, c, t);
-
-  return fold (e);
+  return new tree_prefix_expression (op1, l, c, t);
 }
 
 // Build a postfix expression.
@@ -2302,10 +2413,7 @@
   int l = tok_val->line ();
   int c = tok_val->column ();
 
-  tree_postfix_expression *e
-    = new tree_postfix_expression (op1, l, c, t);
-
-  return fold (e);
+  return new tree_postfix_expression (op1, l, c, t);
 }
 
 // Build an unwind-protect command.
@@ -2999,6 +3107,272 @@
   lexer.looking_at_parameter_list = false;
 }
 
+tree_funcall *
+octave_base_parser::make_superclass_ref (const std::string& method_nm,
+                                         const std::string& class_nm)
+{
+  octave_value_list args;
+
+  args(1) = class_nm;
+  args(0) = method_nm;
+
+  octave_value fcn
+    = symbol_table::find_built_in_function ("__superclass_reference__");
+
+  return new tree_funcall (fcn, args);
+}
+
+tree_funcall *
+octave_base_parser::make_meta_class_query (const std::string& class_nm)
+{
+  octave_value_list args;
+
+  args(0) = class_nm;
+
+  octave_value fcn
+    = symbol_table::find_built_in_function ("__meta_class_query__");
+
+  return new tree_funcall (fcn, args);
+}
+
+// A CLASSDEF block defines a class that has a constructor and other
+// methods, but it is not an executable command.  Parsing the block
+// makes some changes in the symbol table (inserting the constructor
+// and methods, and adding to the list of known objects) and creates
+// a parse tree containing meta information about the class.
+
+tree_classdef *
+octave_base_parser::make_classdef (token *tok_val,
+                                   tree_classdef_attribute_list *a,
+                                   tree_identifier *id,
+                                   tree_classdef_superclass_list *sc,
+                                   tree_classdef_body *body, token *end_tok,
+                                   octave_comment_list *lc)
+{
+  tree_classdef *retval = 0;
+
+  std::string cls_name = id->name ();
+
+  std::string nm = lexer.fcn_file_name;
+
+  size_t pos = nm.find_last_of (file_ops::dir_sep_chars ());
+
+  if (pos != std::string::npos)
+    nm = lexer.fcn_file_name.substr (pos+1);
+
+  if (nm != cls_name)
+    bison_error ("invalid classdef definition, the class name must match the file name");
+  else if (end_token_ok (end_tok, token::classdef_end))
+    {
+      octave_comment_list *tc = lexer.comment_buf.get_comment ();
+
+      int l = tok_val->line ();
+      int c = tok_val->column ();
+
+      if (! body)
+        body = new tree_classdef_body ();
+
+      retval = new tree_classdef (a, id, sc, body, lc, tc,
+                                  curr_package_name, l, c);
+    }
+
+  if (! retval)
+    {
+      delete a;
+      delete id;
+      delete sc;
+      delete body;
+    }
+
+  return retval;
+}
+
+tree_classdef_properties_block *
+octave_base_parser::make_classdef_properties_block (token *tok_val,
+                                                    tree_classdef_attribute_list *a,
+                                                    tree_classdef_property_list *plist,
+                                                    token *end_tok,
+                                                    octave_comment_list *lc)
+{
+  tree_classdef_properties_block *retval = 0;
+
+  if (end_token_ok (end_tok, token::properties_end))
+    {
+      octave_comment_list *tc = lexer.comment_buf.get_comment ();
+
+      int l = tok_val->line ();
+      int c = tok_val->column ();
+
+      if (! plist)
+        plist = new tree_classdef_property_list ();
+
+      retval = new tree_classdef_properties_block (a, plist, lc, tc, l, c);
+    }
+  else
+    {
+      delete a;
+      delete plist;
+    }
+
+  return retval;
+}
+
+tree_classdef_methods_block *
+octave_base_parser::make_classdef_methods_block (token *tok_val,
+                                                 tree_classdef_attribute_list *a,
+                                                 tree_classdef_methods_list *mlist,
+                                                 token *end_tok,
+                                                 octave_comment_list *lc)
+{
+  tree_classdef_methods_block *retval = 0;
+
+  if (end_token_ok (end_tok, token::methods_end))
+    {
+      octave_comment_list *tc = lexer.comment_buf.get_comment ();
+
+      int l = tok_val->line ();
+      int c = tok_val->column ();
+
+      if (! mlist)
+        mlist = new tree_classdef_methods_list ();
+
+      retval = new tree_classdef_methods_block (a, mlist, lc, tc, l, c);
+    }
+  else
+    {
+      delete a;
+      delete mlist;
+    }
+
+  return retval;
+}
+
+tree_classdef_events_block *
+octave_base_parser::make_classdef_events_block (token *tok_val,
+                                                tree_classdef_attribute_list *a,
+                                                tree_classdef_events_list *elist,
+                                                token *end_tok,
+                                                octave_comment_list *lc)
+{
+  tree_classdef_events_block *retval = 0;
+
+  if (end_token_ok (end_tok, token::events_end))
+    {
+      octave_comment_list *tc = lexer.comment_buf.get_comment ();
+
+      int l = tok_val->line ();
+      int c = tok_val->column ();
+
+      if (! elist)
+        elist = new tree_classdef_events_list ();
+
+      retval = new tree_classdef_events_block (a, elist, lc, tc, l, c);
+    }
+  else
+    {
+      delete a;
+      delete elist;
+    }
+
+  return retval;
+}
+
+tree_classdef_enum_block *
+octave_base_parser::make_classdef_enum_block (token *tok_val,
+                                              tree_classdef_attribute_list *a,
+                                              tree_classdef_enum_list *elist,
+                                              token *end_tok,
+                                              octave_comment_list *lc)
+{
+  tree_classdef_enum_block *retval = 0;
+
+  if (end_token_ok (end_tok, token::enumeration_end))
+    {
+      octave_comment_list *tc = lexer.comment_buf.get_comment ();
+
+      int l = tok_val->line ();
+      int c = tok_val->column ();
+
+      if (! elist)
+        elist = new tree_classdef_enum_list ();
+
+      retval = new tree_classdef_enum_block (a, elist, lc, tc, l, c);
+    }
+  else
+    {
+      delete a;
+      delete elist;
+    }
+
+  return retval;
+}
+
+octave_user_function*
+octave_base_parser::start_classdef_external_method (tree_identifier *id,
+                                                    tree_parameter_list *pl)
+{
+  octave_user_function* retval = 0;
+
+  // External methods are only allowed within @-folders. In this case,
+  // curr_class_name will be non-empty.
+
+  if (! curr_class_name.empty ())
+    {
+
+      std::string mname = id->name ();
+
+      // Methods that cannot be declared outside the classdef file:
+      // - methods with '.' character (e.g. property accessors)
+      // - class constructor
+      // - `delete'
+
+      if (mname.find_first_of (".") == std::string::npos
+          && mname != "delete"
+          && mname != curr_class_name)
+        {
+          // Create a dummy function that is used until the real method
+          // is loaded.
+
+          retval = new octave_user_function (-1, pl);
+
+          retval->stash_function_name (mname);
+
+          int l = id->line ();
+          int c = id->column ();
+
+          retval->stash_fcn_location (l, c);
+        }
+      else
+        bison_error ("invalid external method declaration, an external "
+                     "method cannot be the class constructor, `delete' "
+                     "or have a dot (.) character in its name");
+    }
+  else
+    bison_error ("external methods are only allowed in @-folders");
+
+  if (! retval)
+    delete id;
+
+  return retval;
+}
+
+tree_function_def *
+octave_base_parser::finish_classdef_external_method (octave_user_function *fcn,
+                                                     tree_parameter_list *ret_list,
+                                                     octave_comment_list *cl)
+{
+  if (ret_list)
+    fcn->define_ret_list (ret_list);
+
+  if (cl)
+    fcn->stash_leading_comment (cl);
+
+  int l = fcn->beginning_line ();
+  int c = fcn->beginning_column ();
+
+  return new tree_function_def (fcn, l, c);
+}
+
 // Make an index expression.
 
 tree_index_expression *
@@ -3021,7 +3395,8 @@
   int l = expr->line ();
   int c = expr->column ();
 
-  expr->mark_postfix_indexed ();
+  if (! expr->is_postfix_indexed ()) 
+    expr->set_postfix_index (type);
 
   if (expr->is_index_expression ())
     {
@@ -3048,6 +3423,9 @@
   int l = expr->line ();
   int c = expr->column ();
 
+  if (! expr->is_postfix_indexed ()) 
+    expr->set_postfix_index ('.');
+
   if (expr->is_index_expression ())
     {
       tree_index_expression *tmp = static_cast<tree_index_expression *> (expr);
@@ -3067,13 +3445,17 @@
 // Make an indirect reference expression with dynamic field name.
 
 tree_index_expression *
-octave_base_parser::make_indirect_ref (tree_expression *expr, tree_expression *elt)
+octave_base_parser::make_indirect_ref (tree_expression *expr,
+                                       tree_expression *elt)
 {
   tree_index_expression *retval = 0;
 
   int l = expr->line ();
   int c = expr->column ();
 
+  if (! expr->is_postfix_indexed ()) 
+    expr->set_postfix_index ('.');
+
   if (expr->is_index_expression ())
     {
       tree_index_expression *tmp = static_cast<tree_index_expression *> (expr);
@@ -3461,6 +3843,7 @@
 static octave_function *
 parse_fcn_file (const std::string& full_file, const std::string& file,
                 const std::string& dispatch_type,
+                const std::string& package_name,
                 bool require_file, bool force_script, bool autoload,    
                 bool relative_lookup, const std::string& warn_for)
 {
@@ -3494,6 +3877,7 @@
       octave_parser parser (ffile);
 
       parser.curr_class_name = dispatch_type;
+      parser.curr_package_name = package_name;
       parser.autoloading = autoload;
       parser.fcn_file_from_relative_lookup = relative_lookup;
 
@@ -3508,20 +3892,37 @@
 
       fcn_ptr = parser.primary_fcn_ptr;
 
-      if (fcn_ptr)
+      if (status == 0)
         {
-          fcn_ptr->maybe_relocate_end ();
-
-          if (parser.parsing_subfunctions)
+          if (parser.lexer.reading_classdef_file
+              && parser.classdef_object)
             {
-              if (! parser.endfunction_found)
-                parser.subfunction_names.reverse ();
-
-              fcn_ptr->stash_subfunction_names (parser.subfunction_names);
+              // Convert parse tree for classdef object to
+              // meta.class info (and stash it in the symbol
+              // table?).  Return pointer to constructor?
+
+              if (fcn_ptr)
+                panic_impossible ();
+
+              bool is_at_folder = ! dispatch_type.empty ();
+
+              fcn_ptr =
+                parser.classdef_object->make_meta_class (is_at_folder);
+            }
+          else if (fcn_ptr)
+            {
+              fcn_ptr->maybe_relocate_end ();
+
+              if (parser.parsing_subfunctions)
+                {
+                  if (! parser.endfunction_found)
+                    parser.subfunction_names.reverse ();
+
+                  fcn_ptr->stash_subfunction_names (parser.subfunction_names);
+                }
             }
         }
-
-      if (status != 0)
+      else
         error ("parse error while reading file %s", full_file.c_str ());
     }
   else if (require_file)
@@ -3562,7 +3963,8 @@
       symbol_found = true;
 
       octave_function *fcn
-        = parse_fcn_file (full_file, file, "", true, false, false, false, "");
+        = parse_fcn_file (full_file, file, "", "", true, false, false, false,
+                          "");
 
       if (fcn)
         {
@@ -3626,6 +4028,7 @@
 octave_function *
 load_fcn_from_file (const std::string& file_name, const std::string& dir_name,
                     const std::string& dispatch_type,
+                    const std::string& package_name,
                     const std::string& fcn_name, bool autoload)
 {
   octave_function *retval = 0;
@@ -3673,7 +4076,8 @@
       // to get the help-string to use.
 
       octave_function *tmpfcn = parse_fcn_file (file.substr (0, len - 2),
-                                                nm, dispatch_type, false,
+                                                nm, dispatch_type,
+                                                package_name, false,
                                                 autoload, autoload,
                                                 relative_lookup, "");
 
@@ -3685,13 +4089,14 @@
     }
   else if (len > 2)
     {
-      retval = parse_fcn_file (file, nm, dispatch_type, true, autoload,
-                               autoload, relative_lookup, "");
+      retval = parse_fcn_file (file, nm, dispatch_type, package_name, true,
+                               autoload, autoload, relative_lookup, "");
     }
 
   if (retval)
     {
       retval->stash_dir_name (dir_name);
+      retval->stash_package_name (package_name);
 
       if (retval->is_user_function ())
         {
@@ -3901,7 +4306,7 @@
   if (! error_state)
     {
       octave_function *fcn = parse_fcn_file (file_full_name, file_name,
-                                             "", require_file, true,
+                                             "", "", require_file, true,
                                              false, false, warn_for);
 
       if (! error_state)
@@ -4632,7 +5037,7 @@
           if (nargin == 2)
             octave_stdout << "parsing " << full_file << std::endl;
 
-          octave_function *fcn = parse_fcn_file (full_file, file, "",
+          octave_function *fcn = parse_fcn_file (full_file, file, "", "",
                                                  true, false, false,
                                                  false, "__parse_file__");
 
--- a/libinterp/parse-tree/octave.gperf	Fri Aug 01 09:06:21 2014 -0400
+++ b/libinterp/parse-tree/octave.gperf	Fri Aug 01 12:10:05 2014 -0400
@@ -64,7 +64,6 @@
   properties_kw,
   return_kw,
   set_kw,
-  static_kw,
   switch_kw,
   try_kw,
   until_kw,
@@ -111,7 +110,6 @@
 properties, PROPERTIES, properties_kw
 return, FUNC_RET, return_kw
 set, SET, set_kw
-static, PERSISTENT, static_kw
 switch, SWITCH, switch_kw
 try, TRY, try_kw
 until, UNTIL, until_kw
--- a/libinterp/parse-tree/parse.h	Fri Aug 01 09:06:21 2014 -0400
+++ b/libinterp/parse-tree/parse.h	Fri Aug 01 12:10:05 2014 -0400
@@ -43,6 +43,18 @@
 class tree_argument_list;
 class tree_array_list;
 class tree_cell;
+class tree_classdef;
+class tree_classdef_attribute_list;
+class tree_classdef_body;
+class tree_classdef_enum_block;
+class tree_classdef_enum_list;
+class tree_classdef_events_block;
+class tree_classdef_events_list;
+class tree_classdef_methods_block;
+class tree_classdef_methods_list;
+class tree_classdef_properties_block;
+class tree_classdef_property_list;
+class tree_classdef_superclass_list;
 class tree_colon_expression;
 class tree_command;
 class tree_constant;
@@ -50,6 +62,7 @@
 class tree_decl_init_list;
 class tree_expression;
 class tree_fcn_handle;
+class tree_funcall;
 class tree_function_def;
 class tree_identifier;
 class tree_if_clause;
@@ -92,6 +105,7 @@
 load_fcn_from_file (const std::string& file_name,
                     const std::string& dir_name = std::string (),
                     const std::string& dispatch_type = std::string (),
+                    const std::string& package_name = std::string (),
                     const std::string& fcn_name = std::string (),
                     bool autoload = false);
 
@@ -136,9 +150,9 @@
       autoloading (false), fcn_file_from_relative_lookup (false),
       parsing_subfunctions (false), max_fcn_depth (0),
       curr_fcn_depth (0), primary_fcn_scope (-1),
-      curr_class_name (), function_scopes (), primary_fcn_ptr (0),
-      subfunction_names (), stmt_list (0),
-      lexer (lxr)
+      curr_class_name (), curr_package_name (), function_scopes (),
+      primary_fcn_ptr (0), subfunction_names (), classdef_object (0),
+      stmt_list (0), lexer (lxr)
   { }
 
   ~octave_base_parser (void);
@@ -284,6 +298,52 @@
   void
   recover_from_parsing_function (void);
 
+  tree_funcall *
+  make_superclass_ref (const std::string& method_nm,
+                       const std::string& class_nm);
+
+  tree_funcall *
+  make_meta_class_query (const std::string& class_nm);
+
+  tree_classdef *
+  make_classdef (token *tok_val, tree_classdef_attribute_list *a,
+                 tree_identifier *id, tree_classdef_superclass_list *sc,
+                 tree_classdef_body *body, token *end_tok,
+                 octave_comment_list *lc);
+
+  tree_classdef_properties_block *
+  make_classdef_properties_block (token *tok_val,
+                                  tree_classdef_attribute_list *a,
+                                  tree_classdef_property_list *plist,
+                                  token *end_tok, octave_comment_list *lc);
+
+  tree_classdef_methods_block *
+  make_classdef_methods_block (token *tok_val,
+                               tree_classdef_attribute_list *a,
+                               tree_classdef_methods_list *mlist,
+                               token *end_tok, octave_comment_list *lc);
+
+  tree_classdef_events_block *
+  make_classdef_events_block (token *tok_val,
+                              tree_classdef_attribute_list *a,
+                              tree_classdef_events_list *elist,
+                              token *end_tok, octave_comment_list *lc);
+
+  tree_classdef_enum_block *
+  make_classdef_enum_block (token *tok_val,
+                            tree_classdef_attribute_list *a,
+                            tree_classdef_enum_list *elist,
+                            token *end_tok, octave_comment_list *lc);
+
+  octave_user_function *
+  start_classdef_external_method (tree_identifier *id,
+                                  tree_parameter_list *pl);
+
+  tree_function_def *
+  finish_classdef_external_method (octave_user_function *fcn,
+                                   tree_parameter_list *ret_list,
+                                   octave_comment_list *cl);
+
   // Make an index expression.
   tree_index_expression *
   make_index_expression (tree_expression *expr,
@@ -372,6 +432,10 @@
   // constructors.
   std::string curr_class_name;
 
+  // Name of the current package when we are parsing an element contained
+  // in a package directory (+-directory).
+  std::string curr_package_name;
+
   // A stack holding the nested function scopes being parsed.
   // We don't use std::stack, because we want the clear method. Also, we
   // must access one from the top
@@ -385,6 +449,9 @@
   // file.  Eventually stashed in the primary function object.
   std::list<std::string> subfunction_names;
 
+  // Pointer to the classdef object we just parsed, if any.
+  tree_classdef *classdef_object;
+
   // Result of parsing input.
   tree_statement_list *stmt_list;
 
--- a/libinterp/parse-tree/pt-all.h	Fri Aug 01 09:06:21 2014 -0400
+++ b/libinterp/parse-tree/pt-all.h	Fri Aug 01 12:10:05 2014 -0400
@@ -30,6 +30,7 @@
 #include "pt-binop.h"
 #include "pt-cbinop.h"
 #include "pt-check.h"
+#include "pt-classdef.h"
 #include "pt-cmd.h"
 #include "pt-colon.h"
 #include "pt-const.h"
@@ -37,6 +38,7 @@
 #include "pt-except.h"
 #include "pt-exp.h"
 #include "pt-fcn-handle.h"
+#include "pt-funcall.h"
 #include "pt-id.h"
 #include "pt-idx.h"
 #include "pt-jump.h"
--- a/libinterp/parse-tree/pt-bp.cc	Fri Aug 01 09:06:21 2014 -0400
+++ b/libinterp/parse-tree/pt-bp.cc	Fri Aug 01 12:10:05 2014 -0400
@@ -293,6 +293,12 @@
 }
 
 void
+tree_breakpoint::visit_funcall (tree_funcall&)
+{
+  panic_impossible ();
+}
+
+void
 tree_breakpoint::visit_parameter_list (tree_parameter_list&)
 {
   panic_impossible ();
--- a/libinterp/parse-tree/pt-bp.h	Fri Aug 01 09:06:21 2014 -0400
+++ b/libinterp/parse-tree/pt-bp.h	Fri Aug 01 12:10:05 2014 -0400
@@ -106,6 +106,8 @@
 
   void visit_fcn_handle (tree_fcn_handle&);
 
+  void visit_funcall (tree_funcall&);
+
   void visit_parameter_list (tree_parameter_list&);
 
   void visit_postfix_expression (tree_postfix_expression&);
--- a/libinterp/parse-tree/pt-cbinop.cc	Fri Aug 01 09:06:21 2014 -0400
+++ b/libinterp/parse-tree/pt-cbinop.cc	Fri Aug 01 12:10:05 2014 -0400
@@ -162,7 +162,8 @@
 maybe_compound_binary_expression (tree_expression *a, tree_expression *b,
                                   int l, int c, octave_value::binary_op t)
 {
-  tree_expression *ca = a, *cb = b;
+  tree_expression *ca = a;
+  tree_expression *cb = b;
   octave_value::compound_binary_op ct;
 
   switch (t)
--- a/libinterp/parse-tree/pt-check.cc	Fri Aug 01 09:06:21 2014 -0400
+++ b/libinterp/parse-tree/pt-check.cc	Fri Aug 01 12:10:05 2014 -0400
@@ -357,6 +357,11 @@
 }
 
 void
+tree_checker::visit_funcall (tree_funcall& /* fc */)
+{
+}
+
+void
 tree_checker::visit_parameter_list (tree_parameter_list& lst)
 {
   tree_parameter_list::iterator p = lst.begin ();
--- a/libinterp/parse-tree/pt-check.h	Fri Aug 01 09:06:21 2014 -0400
+++ b/libinterp/parse-tree/pt-check.h	Fri Aug 01 12:10:05 2014 -0400
@@ -91,6 +91,8 @@
 
   void visit_fcn_handle (tree_fcn_handle&);
 
+  void visit_funcall (tree_funcall&);
+
   void visit_parameter_list (tree_parameter_list&);
 
   void visit_postfix_expression (tree_postfix_expression&);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libinterp/parse-tree/pt-classdef.cc	Fri Aug 01 12:10:05 2014 -0400
@@ -0,0 +1,259 @@
+/*
+
+Copyright (C) 2012-2013 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "ov-classdef.h"
+#include "pt-classdef.h"
+
+// Classdef attribute
+
+void
+tree_classdef_attribute::accept (tree_walker& tw)
+{
+  tw.visit_classdef_attribute (*this);
+}
+
+// Classdef attribute_list
+
+tree_classdef_attribute_list::~tree_classdef_attribute_list (void)
+{
+  while (! empty ())
+    {
+      iterator p = begin ();
+      delete *p;
+      erase (p);
+    }
+}
+
+void
+tree_classdef_attribute_list::accept (tree_walker& tw)
+{
+  tw.visit_classdef_attribute_list (*this);
+}
+
+// Classdef superclass
+
+void
+tree_classdef_superclass::accept (tree_walker& tw)
+{
+  tw.visit_classdef_superclass (*this);
+}
+
+// Classdef superclass_list
+
+tree_classdef_superclass_list::~tree_classdef_superclass_list (void)
+{
+  while (! empty ())
+    {
+      iterator p = begin ();
+      delete *p;
+      erase (p);
+    }
+}
+
+void
+tree_classdef_superclass_list::accept (tree_walker& tw)
+{
+  tw.visit_classdef_superclass_list (*this);
+}
+
+// Classdef property
+
+void
+tree_classdef_property::accept (tree_walker& tw)
+{
+  tw.visit_classdef_property (*this);
+}
+
+// Classdef property_list
+
+tree_classdef_property_list::~tree_classdef_property_list (void)
+{
+  while (! empty ())
+    {
+      iterator p = begin ();
+      delete *p;
+      erase (p);
+    }
+}
+
+void
+tree_classdef_property_list::accept (tree_walker& tw)
+{
+  tw.visit_classdef_property_list (*this);
+}
+
+// Classdef properties_block
+
+void
+tree_classdef_properties_block::accept (tree_walker& tw)
+{
+  tw.visit_classdef_properties_block (*this);
+}
+
+// Classdef methods_list
+
+void
+tree_classdef_methods_list::accept (tree_walker& tw)
+{
+  tw.visit_classdef_methods_list (*this);
+}
+
+// Classdef methods_block
+
+void
+tree_classdef_methods_block::accept (tree_walker& tw)
+{
+  tw.visit_classdef_methods_block (*this);
+}
+
+// Classdef event
+
+void
+tree_classdef_event::accept (tree_walker& tw)
+{
+  tw.visit_classdef_event (*this);
+}
+
+// Classdef events_list
+
+tree_classdef_events_list::~tree_classdef_events_list (void)
+{
+  while (! empty ())
+    {
+      iterator p = begin ();
+      delete *p;
+      erase (p);
+    }
+}
+
+void
+tree_classdef_events_list::accept (tree_walker& tw)
+{
+  tw.visit_classdef_events_list (*this);
+}
+
+// Classdef events_block
+
+void
+tree_classdef_events_block::accept (tree_walker& tw)
+{
+  tw.visit_classdef_events_block (*this);
+}
+
+// Classdef enum
+
+void
+tree_classdef_enum::accept (tree_walker& tw)
+{
+  tw.visit_classdef_enum (*this);
+}
+
+// Classdef enum_list
+
+tree_classdef_enum_list::~tree_classdef_enum_list (void)
+{
+  while (! empty ())
+    {
+      iterator p = begin ();
+      delete *p;
+      erase (p);
+    }
+}
+
+void
+tree_classdef_enum_list::accept (tree_walker& tw)
+{
+  tw.visit_classdef_enum_list (*this);
+}
+
+// Classdef enum_block
+
+void
+tree_classdef_enum_block::accept (tree_walker& tw)
+{
+  tw.visit_classdef_enum_block (*this);
+}
+
+// Classdef body
+
+tree_classdef_body::~tree_classdef_body (void)
+{
+  while (! properties_lst.empty ())
+    {
+      properties_list_iterator p = properties_lst.begin ();
+      delete *p;
+      properties_lst.erase (p);
+    }
+
+  while (! methods_lst.empty ())
+    {
+      methods_list_iterator p = methods_lst.begin ();
+      delete *p;
+      methods_lst.erase (p);
+    }
+
+  while (! events_lst.empty ())
+    {
+      events_list_iterator p = events_lst.begin ();
+      delete *p;
+      events_lst.erase (p);
+    }
+
+  while (! enum_lst.empty ())
+    {
+      enum_list_iterator p = enum_lst.begin ();
+      delete *p;
+      enum_lst.erase (p);
+    }
+}
+
+// Classdef
+
+octave_function*
+tree_classdef::make_meta_class (bool is_at_folder)
+{
+  octave_value retval;
+  cdef_class cls = cdef_class::make_meta_class (this, is_at_folder);
+
+  if (cls.ok ())
+    return cls.get_constructor_function ();
+
+  return 0;
+}
+
+tree_classdef *
+tree_classdef::dup (symbol_table::scope_id,
+                    symbol_table::context_id) const
+{
+  // FIXME
+  return 0;
+}
+
+void
+tree_classdef::accept (tree_walker& tw)
+{
+  tw.visit_classdef (*this);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libinterp/parse-tree/pt-classdef.h	Fri Aug 01 12:10:05 2014 -0400
@@ -0,0 +1,653 @@
+/*
+
+Copyright (C) 2012-2013 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_tree_classdef_h)
+#define octave_tree_classdef_h 1
+
+class octave_value;
+
+class tree_walker;
+
+#include "pt-cmd.h"
+#include "pt-exp.h"
+#include "pt-id.h"
+
+#include "base-list.h"
+
+#include <list>
+
+class tree_classdef_attribute
+{
+public:
+
+  tree_classdef_attribute (tree_identifier *i = 0, tree_expression *e = 0)
+    : id (i), expr (e), neg (false) { }
+
+  tree_classdef_attribute (tree_identifier *i, bool b)
+    : id (i), expr (0), neg (b) { }
+
+  ~tree_classdef_attribute (void)
+  {
+    delete id;
+    delete expr;
+  }
+
+  tree_identifier *ident (void) { return id; }
+
+  tree_expression *expression (void) { return expr; }
+
+  bool negate (void) { return neg; }
+
+  void accept (tree_walker&);
+
+private:
+  
+  tree_identifier *id;
+  tree_expression *expr;
+  bool neg;
+
+  // No copying!
+
+  tree_classdef_attribute (const tree_classdef_attribute&);
+
+  tree_classdef_attribute& operator = (const tree_classdef_attribute&);
+};
+
+class tree_classdef_attribute_list : public octave_base_list<tree_classdef_attribute *>
+{
+public:
+
+  tree_classdef_attribute_list (void) { }
+
+  tree_classdef_attribute_list (tree_classdef_attribute *a) { append (a); }
+
+  tree_classdef_attribute_list (const octave_base_list<tree_classdef_attribute *>& a)
+    : octave_base_list<tree_classdef_attribute *> (a) { }
+
+  ~tree_classdef_attribute_list (void);
+
+  void accept (tree_walker&);
+
+private:
+
+  // No copying!
+
+  tree_classdef_attribute_list (const tree_classdef_attribute_list&);
+
+  tree_classdef_attribute_list& operator = (const tree_classdef_attribute_list&);
+};
+
+class tree_classdef_superclass
+{
+public:
+
+  tree_classdef_superclass (const std::string& cname)
+    : cls_name (cname) { }
+
+  ~tree_classdef_superclass (void) { }
+
+  std::string class_name (void) { return cls_name; }
+
+  void accept (tree_walker&);
+
+private:
+
+  std::string cls_name;
+
+  // No copying!
+
+  tree_classdef_superclass (const tree_classdef_superclass&);
+
+  tree_classdef_superclass& operator = (const tree_classdef_superclass&);
+};
+
+class tree_classdef_superclass_list : public octave_base_list<tree_classdef_superclass *>
+{
+public:
+
+  tree_classdef_superclass_list (void) { }
+
+  tree_classdef_superclass_list (tree_classdef_superclass *sc) { append (sc); }
+
+  tree_classdef_superclass_list (const octave_base_list<tree_classdef_superclass *>& a)
+    : octave_base_list<tree_classdef_superclass *> (a) { }
+
+  ~tree_classdef_superclass_list (void);
+
+  void accept (tree_walker&);
+
+private:
+
+  // No copying!
+
+  tree_classdef_superclass_list (const tree_classdef_superclass_list&);
+
+  tree_classdef_superclass_list& operator = (const tree_classdef_superclass_list&);
+};
+
+template <typename T>
+class tree_classdef_element : public tree
+{
+public:
+
+  tree_classdef_element (tree_classdef_attribute_list *a,
+                         octave_base_list<T> *elist,
+                         octave_comment_list *lc, octave_comment_list *tc,
+                         int l = -1, int c = -1)
+    : tree (l, c), attr_list (a), elt_list (elist),
+      lead_comm (lc), trail_comm (tc)
+  { }
+
+  ~tree_classdef_element (void)
+  {
+    delete attr_list;
+    delete elt_list;
+    delete lead_comm;
+    delete trail_comm;
+  }
+
+  tree_classdef_attribute_list *attribute_list (void) { return attr_list; }
+
+  octave_base_list<T> *element_list (void) { return elt_list; }
+
+  octave_comment_list *leading_comment (void) { return lead_comm; }
+
+  octave_comment_list *trailing_comment (void) { return trail_comm; }
+
+  void accept (tree_walker&) { }
+
+private:
+
+  // List of attributes that apply to this class.
+  tree_classdef_attribute_list *attr_list;
+
+  // The list of objects contained in this block.
+  octave_base_list<T> *elt_list;
+  
+  // Comment preceding the token marking the beginning of the block.
+  octave_comment_list *lead_comm;
+
+  // Comment preceding END token.
+  octave_comment_list *trail_comm;
+
+  // No copying!
+
+  tree_classdef_element (const tree_classdef_element&);
+
+  tree_classdef_element& operator = (const tree_classdef_element&);
+};
+
+class tree_classdef_property
+{
+public:
+
+  tree_classdef_property (tree_identifier *i = 0, tree_expression *e = 0)
+    : id (i), expr (e) { }
+
+  ~tree_classdef_property (void)
+  {
+    delete id;
+    delete expr;
+  }
+
+  tree_identifier *ident (void) { return id; }
+
+  tree_expression *expression (void) { return expr; }
+
+  void accept (tree_walker&);
+
+private:
+
+  tree_identifier *id;
+  tree_expression *expr;
+
+  // No copying!
+
+  tree_classdef_property (const tree_classdef_property&);
+
+  tree_classdef_property& operator = (const tree_classdef_property&);
+};
+
+class tree_classdef_property_list : public octave_base_list<tree_classdef_property *>
+{
+public:
+
+  tree_classdef_property_list (void) { }
+
+  tree_classdef_property_list (tree_classdef_property* p) { append (p); }
+
+  tree_classdef_property_list (const octave_base_list<tree_classdef_property *>& a)
+    : octave_base_list<tree_classdef_property *> (a) { }
+
+  ~tree_classdef_property_list (void);
+
+  void accept (tree_walker&);
+
+private:
+
+  // No copying!
+
+  tree_classdef_property_list (const tree_classdef_property_list&);
+
+  tree_classdef_property_list& operator = (const tree_classdef_property_list&);
+};
+
+class tree_classdef_properties_block
+  : public tree_classdef_element<tree_classdef_property *>
+{
+public:
+
+  tree_classdef_properties_block (tree_classdef_attribute_list *a,
+                                  tree_classdef_property_list *plist,
+                                  octave_comment_list *lc,
+                                  octave_comment_list *tc,
+                                  int l = -1, int c = -1)
+    : tree_classdef_element<tree_classdef_property *> (a, plist, lc, tc, l, c) { }
+
+  ~tree_classdef_properties_block (void) { }
+
+  void accept (tree_walker&);
+
+private:
+
+  // No copying!
+
+  tree_classdef_properties_block (const tree_classdef_properties_block&);
+
+  tree_classdef_properties_block& operator = (const tree_classdef_properties_block&);
+};
+
+class tree_classdef_methods_list : public octave_base_list<octave_value>
+{
+public:
+
+  tree_classdef_methods_list (void) { }
+
+  tree_classdef_methods_list (const octave_value& f) { append (f); }
+
+  tree_classdef_methods_list (const octave_base_list<octave_value>& a)
+    : octave_base_list<octave_value> (a) { }
+
+  ~tree_classdef_methods_list (void) { }
+
+  void accept (tree_walker&);
+
+private:
+
+  // No copying!
+
+  tree_classdef_methods_list (const tree_classdef_methods_list&);
+
+  tree_classdef_methods_list& operator = (const tree_classdef_methods_list&);
+};
+
+class tree_classdef_methods_block : public tree_classdef_element<octave_value>
+{
+public:
+
+  tree_classdef_methods_block (tree_classdef_attribute_list *a,
+                               tree_classdef_methods_list *mlist,
+                               octave_comment_list *lc,
+                               octave_comment_list *tc, int l = -1, int c = -1)
+    : tree_classdef_element<octave_value> (a, mlist, lc, tc, l, c) { }
+
+  ~tree_classdef_methods_block (void) { }
+
+  void accept (tree_walker&);
+
+private:
+
+  // No copying!
+
+  tree_classdef_methods_block (const tree_classdef_methods_block&);
+
+  tree_classdef_methods_block& operator = (const tree_classdef_methods_block&);
+};
+
+class tree_classdef_event
+{
+public:
+
+  tree_classdef_event (tree_identifier *i = 0) : id (i) { }
+
+  ~tree_classdef_event (void)
+  {
+    delete id;
+  }
+
+  tree_identifier *ident (void) { return id; }
+
+  void accept (tree_walker&);
+
+private:
+
+  tree_identifier *id;
+
+  // No copying!
+
+  tree_classdef_event (const tree_classdef_event&);
+
+  tree_classdef_event& operator = (const tree_classdef_event&);
+};
+
+class tree_classdef_events_list : public octave_base_list<tree_classdef_event *>
+{
+public:
+
+  tree_classdef_events_list (void) { }
+
+  tree_classdef_events_list (tree_classdef_event *e) { append (e); }
+
+  tree_classdef_events_list (const octave_base_list<tree_classdef_event *>& a)
+    : octave_base_list<tree_classdef_event *> (a) { }
+
+  ~tree_classdef_events_list (void);
+
+  void accept (tree_walker&);
+
+private:
+
+  // No copying!
+
+  tree_classdef_events_list (const tree_classdef_events_list&);
+
+  tree_classdef_events_list& operator = (const tree_classdef_events_list&);
+};
+
+class tree_classdef_events_block
+  : public tree_classdef_element<tree_classdef_event *>
+{
+public:
+
+  tree_classdef_events_block (tree_classdef_attribute_list *a,
+                              tree_classdef_events_list *elist,
+                              octave_comment_list *lc,
+                              octave_comment_list *tc, int l = -1, int c = -1)
+    : tree_classdef_element<tree_classdef_event *> (a, elist, lc, tc, l, c) { }
+
+  ~tree_classdef_events_block (void) { }
+
+  void accept (tree_walker&);
+
+private:
+
+  // No copying!
+
+  tree_classdef_events_block (const tree_classdef_events_block&);
+
+  tree_classdef_events_block& operator = (const tree_classdef_events_block&);
+};
+
+class tree_classdef_enum
+{
+public:
+
+  tree_classdef_enum (void) : id (0), expr (0) { }
+
+  tree_classdef_enum (tree_identifier *i, tree_expression *e)
+    : id (i), expr (e) { }
+
+  ~tree_classdef_enum (void)
+  {
+    delete id;
+    delete expr;
+  }
+
+  tree_identifier *ident (void) { return id; }
+
+  tree_expression *expression (void) { return expr; }
+
+  void accept (tree_walker&);
+
+private:
+
+  tree_identifier *id;
+  tree_expression *expr;
+
+  // No copying!
+
+  tree_classdef_enum (const tree_classdef_enum&);
+
+  tree_classdef_enum& operator = (const tree_classdef_enum&);
+};
+
+class tree_classdef_enum_list : public octave_base_list<tree_classdef_enum *>
+{
+public:
+
+  tree_classdef_enum_list (void) { }
+
+  tree_classdef_enum_list (tree_classdef_enum *e) { append (e); }
+
+  tree_classdef_enum_list (const octave_base_list<tree_classdef_enum *>& a)
+    : octave_base_list<tree_classdef_enum *> (a) { }
+
+  ~tree_classdef_enum_list (void);
+
+  void accept (tree_walker&);
+
+private:
+
+  // No copying!
+
+  tree_classdef_enum_list (const tree_classdef_enum_list&);
+
+  tree_classdef_enum_list& operator = (const tree_classdef_enum_list&);
+};
+
+class tree_classdef_enum_block
+  : public tree_classdef_element<tree_classdef_enum *>
+{
+public:
+
+  tree_classdef_enum_block (tree_classdef_attribute_list *a,
+                            tree_classdef_enum_list *elist,
+                            octave_comment_list *lc,
+                            octave_comment_list *tc, int l = -1, int c = -1)
+    : tree_classdef_element<tree_classdef_enum *> (a, elist, lc, tc, l, c) { }
+
+  ~tree_classdef_enum_block (void) { }
+
+  void accept (tree_walker&);
+
+private:
+
+  // No copying!
+
+  tree_classdef_enum_block (const tree_classdef_enum_block&);
+
+  tree_classdef_enum_block& operator = (const tree_classdef_enum_block&);
+};
+
+class tree_classdef_body
+{
+public:
+
+  typedef std::list<tree_classdef_properties_block *>::iterator properties_list_iterator;
+  typedef std::list<tree_classdef_properties_block *>::const_iterator properties_list_const_iterator;
+
+  typedef std::list<tree_classdef_methods_block *>::iterator methods_list_iterator;
+  typedef std::list<tree_classdef_methods_block *>::const_iterator methods_list_const_iterator;
+
+  typedef std::list<tree_classdef_events_block *>::iterator events_list_iterator;
+  typedef std::list<tree_classdef_events_block *>::const_iterator events_list_const_iterator;
+
+  typedef std::list<tree_classdef_enum_block *>::iterator enum_list_iterator;
+  typedef std::list<tree_classdef_enum_block *>::const_iterator enum_list_const_iterator;
+
+  tree_classdef_body (void)
+    : properties_lst (), methods_lst (), events_lst (), enum_lst () { }
+
+  tree_classdef_body (tree_classdef_properties_block *pb)
+    : properties_lst (), methods_lst (), events_lst (), enum_lst ()
+  {
+    append (pb);
+  }
+
+  tree_classdef_body (tree_classdef_methods_block *mb)
+    : properties_lst (), methods_lst (), events_lst (), enum_lst ()
+  {
+    append (mb);
+  }
+
+  tree_classdef_body (tree_classdef_events_block *evb)
+    : properties_lst (), methods_lst (), events_lst (), enum_lst ()
+  {
+    append (evb);
+  }
+
+  tree_classdef_body (tree_classdef_enum_block *enb)
+    : properties_lst (), methods_lst (), events_lst (), enum_lst ()
+  {
+    append (enb);
+  }
+
+  ~tree_classdef_body (void);
+
+  void append (tree_classdef_properties_block *pb)
+  {
+    properties_lst.push_back (pb);
+  }
+
+  void append (tree_classdef_methods_block *mb)
+  {
+    methods_lst.push_back (mb);
+  }
+
+  void append (tree_classdef_events_block *evb)
+  {
+    events_lst.push_back (evb);
+  }
+
+  void append (tree_classdef_enum_block *enb)
+  {
+    enum_lst.push_back (enb);
+  }
+
+  std::list<tree_classdef_properties_block *> properties_list (void)
+  {
+    return properties_lst;
+  }
+
+  std::list<tree_classdef_methods_block *> methods_list (void)
+  {
+    return methods_lst;
+  }
+
+  std::list<tree_classdef_events_block *> events_list (void)
+  {
+    return events_lst;
+  }
+
+  std::list<tree_classdef_enum_block *> enum_list (void)
+  {
+    return enum_lst;
+  }
+
+  void accept (tree_walker&);
+
+private:
+
+  std::list<tree_classdef_properties_block *> properties_lst;
+
+  std::list<tree_classdef_methods_block *> methods_lst;
+
+  std::list<tree_classdef_events_block *> events_lst;
+
+  std::list<tree_classdef_enum_block *> enum_lst;
+
+  // No copying!
+
+  tree_classdef_body (const tree_classdef_body&);
+
+  tree_classdef_body& operator = (const tree_classdef_body&);
+};
+
+// Classdef definition.
+
+class tree_classdef : public tree_command
+{
+public:
+
+  tree_classdef (tree_classdef_attribute_list *a, tree_identifier *i,
+                 tree_classdef_superclass_list *sc,
+                 tree_classdef_body *b, octave_comment_list *lc,
+                 octave_comment_list *tc,
+                 const std::string& pn = std::string (), int l = -1,
+                 int c = -1)
+    : tree_command (l, c), attr_list (a), id (i),
+      supclass_list (sc), element_list (b), lead_comm (lc), trail_comm (tc),
+      pack_name (pn) { }
+
+  ~tree_classdef (void)
+  {
+    delete attr_list;
+    delete id;
+    delete supclass_list;
+    delete element_list;
+    delete lead_comm;
+    delete trail_comm;
+  }
+
+  tree_classdef_attribute_list *attribute_list (void) { return attr_list; }
+
+  tree_identifier *ident (void) { return id; }
+
+  tree_classdef_superclass_list *superclass_list (void) { return supclass_list; }
+
+  tree_classdef_body *body (void) { return element_list; }
+
+  octave_comment_list *leading_comment (void) { return lead_comm; }
+  octave_comment_list *trailing_comment (void) { return trail_comm; }
+
+  const std::string& package_name (void) const { return pack_name; }
+
+  octave_function* make_meta_class (bool is_at_folder = false);
+
+  tree_classdef *dup (symbol_table::scope_id scope,
+                      symbol_table::context_id context) const;
+
+  void accept (tree_walker& tw);
+
+private:
+
+  tree_classdef_attribute_list *attr_list;
+
+  tree_identifier *id;
+
+  tree_classdef_superclass_list *supclass_list;
+
+  tree_classdef_body *element_list;
+
+  octave_comment_list *lead_comm;
+  octave_comment_list *trail_comm;
+
+  std::string pack_name;
+
+  // No copying!
+
+  tree_classdef (const tree_classdef&);
+
+  tree_classdef& operator = (const tree_classdef&);
+};
+
+#endif
--- a/libinterp/parse-tree/pt-eval.cc	Fri Aug 01 09:06:21 2014 -0400
+++ b/libinterp/parse-tree/pt-eval.cc	Fri Aug 01 12:10:05 2014 -0400
@@ -379,7 +379,8 @@
 
         dim_vector dv = rhs.dims ().redim (2);
 
-        octave_idx_type nrows = dv(0), steps = dv(1);
+        octave_idx_type nrows = dv(0);
+        octave_idx_type steps = dv(1);
 
         if (steps > 0)
           {
@@ -637,6 +638,12 @@
 }
 
 void
+tree_evaluator::visit_funcall (tree_funcall&)
+{
+  panic_impossible ();
+}
+
+void
 tree_evaluator::visit_parameter_list (tree_parameter_list&)
 {
   panic_impossible ();
@@ -1114,6 +1121,11 @@
   if (error_state)
     return;
 
+#if HAVE_LLVM
+  if (tree_jit::execute (cmd))
+    return;
+#endif
+
   unwind_protect frame;
 
   frame.protect_var (in_loop_command);
--- a/libinterp/parse-tree/pt-eval.h	Fri Aug 01 09:06:21 2014 -0400
+++ b/libinterp/parse-tree/pt-eval.h	Fri Aug 01 12:10:05 2014 -0400
@@ -102,6 +102,8 @@
 
   void visit_fcn_handle (tree_fcn_handle&);
 
+  void visit_funcall (tree_funcall&);
+
   void visit_parameter_list (tree_parameter_list&);
 
   void visit_postfix_expression (tree_postfix_expression&);
--- a/libinterp/parse-tree/pt-exp.h	Fri Aug 01 09:06:21 2014 -0400
+++ b/libinterp/parse-tree/pt-exp.h	Fri Aug 01 12:10:05 2014 -0400
@@ -40,7 +40,7 @@
 public:
 
   tree_expression (int l = -1, int c = -1)
-    : tree (l, c), num_parens (0), postfix_indexed (false),
+    : tree (l, c), num_parens (0), postfix_index_type ('\0'),
       print_flag (false) { }
 
   virtual ~tree_expression (void) { }
@@ -87,7 +87,9 @@
 
   int paren_count (void) const { return num_parens; }
 
-  bool is_postfix_indexed (void) const { return postfix_indexed; }
+  bool is_postfix_indexed (void) const { return (postfix_index_type != '\0'); }
+
+  char postfix_index (void) const { return postfix_index_type; }
 
   // Check if the result of the expression should be printed.
   // Should normally be used in conjunction with
@@ -108,9 +110,9 @@
     return this;
   }
 
-  tree_expression *mark_postfix_indexed (void)
+  tree_expression *set_postfix_index (char type)
   {
-    postfix_indexed = true;
+    postfix_index_type = type;
     return this;
   }
 
@@ -123,7 +125,7 @@
   virtual void copy_base (const tree_expression& e)
   {
     num_parens = e.num_parens;
-    postfix_indexed = e.postfix_indexed;
+    postfix_index_type = e.postfix_index_type;
     print_flag = e.print_flag;
   }
 
@@ -137,9 +139,10 @@
   //                  ==> 0 for expression e2
   int num_parens;
 
-  // A flag that says whether this expression has an index associated
-  // with it.  See the code in tree_identifier::rvalue for the rationale.
-  bool postfix_indexed;
+  // The first index type associated with this expression. This field
+  // is 0 (character '\0') if the expression has no associated index.
+  // See the code in tree_identifier::rvalue for the rationale.
+  char postfix_index_type;
 
   // Print result of rvalue for this expression?
   bool print_flag;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libinterp/parse-tree/pt-funcall.cc	Fri Aug 01 12:10:05 2014 -0400
@@ -0,0 +1,110 @@
+/*
+
+Copyright (C) 2012-2013 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "ov-fcn.h"
+#include "pt-funcall.h"
+#include "pt-walk.h"
+
+// Function call objects.
+
+void
+tree_funcall::print (std::ostream& os, bool pr_as_read_syntax,
+                     bool pr_orig_text)
+{
+  print_raw (os, pr_as_read_syntax, pr_orig_text);
+}
+
+void
+tree_funcall::print_raw (std::ostream& os, bool pr_as_read_syntax,
+                         bool pr_orig_text)
+{
+  if (pr_orig_text)
+    {
+      os << original_text ();
+    }
+  else
+    {
+      octave_function *fp = fcn.function_value ();
+      std::string nm = fp ? fp->name () : std::string ("<invalid-function>");
+
+      os << nm << " (";
+
+      octave_idx_type len = args.length ();
+      for (octave_idx_type i = 0; i < len; i++)
+        {
+          args(i).print_raw (os, pr_as_read_syntax);
+
+          if (i < len - 1)
+            os << ", ";
+        }
+
+      os << ")";
+    }
+}
+
+tree_funcall *
+tree_funcall::dup (symbol_table::scope_id, symbol_table::context_id) const
+{
+  tree_funcall *new_fc = new tree_funcall (fcn, args, line (), column ());
+
+  new_fc->copy_base (*new_fc);
+
+  return new_fc;
+}
+
+void
+tree_funcall::accept (tree_walker& tw)
+{
+  tw.visit_funcall (*this);
+}
+
+octave_value_list
+tree_funcall::rvalue (int nargout)
+{
+  octave_value_list retval;
+
+  retval = feval (fcn.function_value (), args, nargout);
+
+  if (retval.length () == 1 && retval(0).is_function ())
+    {
+      // The return object is a function. We may need to re-index it using the
+      // same logic as for identifier. This is primarily used for superclass
+      // references in classdef.
+
+      octave_value val = retval(0);
+      octave_function *f = val.function_value (true);
+
+      if (f && ! (is_postfix_indexed ()
+                  && f->is_postfix_index_handled (postfix_index ())))
+        {
+          octave_value_list tmp_args;
+
+          retval = val.do_multi_index_op (nargout, tmp_args);
+        }
+    }
+
+  return retval;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libinterp/parse-tree/pt-funcall.h	Fri Aug 01 12:10:05 2014 -0400
@@ -0,0 +1,98 @@
+/*
+
+Copyright (C) 2012-2013 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#if !defined (octave_tree_funcall_h)
+#define octave_tree_funcall_h 1
+
+#include "ov.h"
+#include "oct-obj.h"
+#include "parse.h"
+#include "pt-exp.h"
+
+// Function call.  This class only represents function calls that have
+// known functions (most useful for calls to built-in functions that
+// are generated by the parser) and fixed argument lists, known at
+// compile time.
+
+class
+tree_funcall : public tree_expression
+{
+public:
+
+  tree_funcall (const octave_value& f, const octave_value_list& a,
+                int l = -1, int c = -1)
+    : tree_expression (l, c), fcn (f), args (a)
+  {
+    if (! fcn.is_function ())
+      error ("tree_funcall: invalid function");
+  }
+
+  ~tree_funcall (void) { }
+
+  bool has_magic_end (void) const { return false; }
+
+  void print (std::ostream& os, bool pr_as_read_syntax = false,
+              bool pr_orig_txt = true);
+
+  void print_raw (std::ostream& os, bool pr_as_read_syntax = false,
+                  bool pr_orig_txt = true);
+
+  tree_funcall *dup (symbol_table::scope_id,
+                     symbol_table::context_id context) const;
+
+  octave_value rvalue1 (int nargout)
+  {
+    octave_value retval;
+
+    const octave_value_list tmp = rvalue (nargout);
+
+    if (! tmp.empty ())
+      retval = tmp(0);
+
+    return retval;
+  }
+
+  octave_value_list rvalue (int nargout);
+
+  octave_value function (void) const { return fcn; }
+
+  octave_value_list arguments (void) const { return args; }
+
+  void accept (tree_walker& tw);
+
+private:
+
+  // Function to call.  Error if not a valid function at time of
+  // construction.
+  octave_value fcn;
+
+  // Argument list.
+  octave_value_list args;
+
+  // No copying!
+
+  tree_funcall (const tree_funcall&);
+
+  tree_funcall& operator = (const tree_funcall&);
+};
+
+#endif
--- a/libinterp/parse-tree/pt-id.cc	Fri Aug 01 09:06:21 2014 -0400
+++ b/libinterp/parse-tree/pt-id.cc	Fri Aug 01 12:10:05 2014 -0400
@@ -76,13 +76,19 @@
       //
       // If this identifier refers to a function, we need to know
       // whether it is indexed so that we can do the same thing
-      // for 'f' and 'f()'.  If the index is present, return the
-      // function object and let tree_index_expression::rvalue
-      // handle indexing.  Otherwise, arrange to call the function
-      // here, so that we don't return the function definition as
-      // a value.
+      // for 'f' and 'f()'.  If the index is present and the function
+      // object declares it can handle it, return the function object
+      // and let tree_index_expression::rvalue handle indexing.
+      // Otherwise, arrange to call the function here, so that we don't
+      // return the function definition as a value.
 
-      if (val.is_function () && ! is_postfix_indexed ())
+      octave_function *fcn = 0;
+
+      if (val.is_function ())
+        fcn = val.function_value (true);
+
+      if (fcn && ! (is_postfix_indexed ()
+                    && fcn->is_postfix_index_handled (postfix_index ())))
         {
           octave_value_list tmp_args;
 
--- a/libinterp/parse-tree/pt-id.h	Fri Aug 01 09:06:21 2014 -0400
+++ b/libinterp/parse-tree/pt-id.h	Fri Aug 01 12:10:05 2014 -0400
@@ -32,6 +32,7 @@
 
 class tree_walker;
 
+#include "oct-lvalue.h"
 #include "pt-bp.h"
 #include "pt-exp.h"
 #include "symtab.h"
--- a/libinterp/parse-tree/pt-idx.cc	Fri Aug 01 09:06:21 2014 -0400
+++ b/libinterp/parse-tree/pt-idx.cc	Fri Aug 01 12:10:05 2014 -0400
@@ -363,7 +363,7 @@
                   // that argument list so we can pass the appropriate
                   // value to the built-in end function.
 
-                  const octave_value_list tmp_list
+                  octave_value_list tmp_list
                     = tmp.subsref (type.substr (tmpi, i - tmpi), idx, nargout);
 
                   tmp = tmp_list.length () ? tmp_list(0) : octave_value ();
@@ -375,6 +375,26 @@
 
                   if (error_state)
                     break;
+
+                  if (tmp.is_function ())
+                    {
+                      octave_function *fcn = tmp.function_value (true);
+
+                      if (fcn && ! fcn->is_postfix_index_handled (type[i]))
+                        {
+                          octave_value_list empty_args;
+
+                          tmp_list = tmp.do_multi_index_op (1, empty_args);
+                          tmp = (tmp_list.length ()
+                                 ? tmp_list(0) : octave_value ());
+
+                          if (tmp.is_cs_list ())
+                            gripe_indexed_cs_list ();
+
+                          if (error_state)
+                            break;
+                        }
+                    }
                 }
             }
 
@@ -412,8 +432,27 @@
         }
 
       if (! error_state)
-        retval = tmp.subsref (type.substr (tmpi, n - tmpi), idx, nargout,
-                              lvalue_list);
+        {
+          retval = tmp.subsref (type.substr (tmpi, n - tmpi), idx, nargout,
+                                lvalue_list);
+
+          octave_value val = retval.length () ? retval(0) : octave_value ();
+
+          if (! error_state && val.is_function ())
+            {
+              octave_function *fcn = val.function_value (true);
+
+              if (fcn)
+                {
+                  octave_value_list empty_args;
+
+                  retval = (lvalue_list
+                            ? val.do_multi_index_op (nargout, empty_args,
+                                                     lvalue_list)
+                            : val.do_multi_index_op (nargout, empty_args));
+                }
+            }
+        }
     }
 
   return retval;
--- a/libinterp/parse-tree/pt-mat.cc	Fri Aug 01 09:06:21 2014 -0400
+++ b/libinterp/parse-tree/pt-mat.cc	Fri Aug 01 12:10:05 2014 -0400
@@ -683,7 +683,8 @@
 single_type_concat (Array<T>& result,
                     tm_const& tmp)
 {
-  octave_idx_type r = 0, c = 0;
+  octave_idx_type r = 0;
+  octave_idx_type c = 0;
 
   for (tm_const::iterator p = tmp.begin (); p != tmp.end (); p++)
     {
@@ -753,7 +754,8 @@
           return;
         }
 
-      octave_idx_type ncols = row.length (), i = 0;
+      octave_idx_type ncols = row.length ();
+      octave_idx_type i = 0;
       OCTAVE_LOCAL_BUFFER (Array<T>, array_list, ncols);
 
       for (tm_row_const::iterator q = row.begin ();
@@ -791,12 +793,14 @@
   // Sparse matrices require preallocation for efficient indexing; besides,
   // only horizontal concatenation can be efficiently handled by indexing.
   // So we just cat all rows through liboctave, then cat the final column.
-  octave_idx_type nrows = tmp.length (), j = 0;
+  octave_idx_type nrows = tmp.length ();
+  octave_idx_type j = 0;
   OCTAVE_LOCAL_BUFFER (Sparse<T>, sparse_row_list, nrows);
   for (tm_const::iterator p = tmp.begin (); p != tmp.end (); p++)
     {
       tm_row_const row = *p;
-      octave_idx_type ncols = row.length (), i = 0;
+      octave_idx_type ncols = row.length ();
+      octave_idx_type i = 0;
       OCTAVE_LOCAL_BUFFER (Sparse<T>, sparse_list, ncols);
 
       for (tm_row_const::iterator q = row.begin ();
@@ -829,12 +833,14 @@
       return;
     }
 
-  octave_idx_type nrows = tmp.length (), j = 0;
+  octave_idx_type nrows = tmp.length ();
+  octave_idx_type j = 0;
   OCTAVE_LOCAL_BUFFER (octave_map, map_row_list, nrows);
   for (tm_const::iterator p = tmp.begin (); p != tmp.end (); p++)
     {
       tm_row_const row = *p;
-      octave_idx_type ncols = row.length (), i = 0;
+      octave_idx_type ncols = row.length ();
+      octave_idx_type i = 0;
       OCTAVE_LOCAL_BUFFER (MAP, map_list, ncols);
 
       for (tm_row_const::iterator q = row.begin ();
--- a/libinterp/parse-tree/pt-pr-code.cc	Fri Aug 01 09:06:21 2014 -0400
+++ b/libinterp/parse-tree/pt-pr-code.cc	Fri Aug 01 12:10:05 2014 -0400
@@ -749,6 +749,18 @@
 }
 
 void
+tree_print_code::visit_funcall (tree_funcall& fc)
+{
+  indent ();
+
+  print_parens (fc, "(");
+
+  fc.print_raw (os, true, print_original_text);
+
+  print_parens (fc, ")");
+}
+
+void
 tree_print_code::visit_parameter_list (tree_parameter_list& lst)
 {
   tree_parameter_list::iterator p = lst.begin ();
@@ -1144,7 +1156,7 @@
 
   indent ();
 
-  os << "until";
+  os << "until ";
 
   tree_expression *expr = cmd.condition ();
 
@@ -1188,10 +1200,7 @@
     }
 }
 
-// Each print_code() function should call this before printing
-// anything.
-//
-// This doesn't need to be fast, but isn't there a better way?
+// Each print_code() function should call this before printing anything.
 
 void
 tree_print_code::indent (void)
@@ -1202,8 +1211,7 @@
     {
       os << prefix;
 
-      for (int i = 0; i < curr_print_indent_level; i++)
-        os << " ";
+      os << std::string (curr_print_indent_level, ' ');
 
       beginning_of_line = false;
     }
--- a/libinterp/parse-tree/pt-pr-code.h	Fri Aug 01 09:06:21 2014 -0400
+++ b/libinterp/parse-tree/pt-pr-code.h	Fri Aug 01 12:10:05 2014 -0400
@@ -109,6 +109,8 @@
 
   void visit_fcn_handle (tree_fcn_handle&);
 
+  void visit_funcall (tree_funcall&);
+
   void visit_parameter_list (tree_parameter_list&);
 
   void visit_postfix_expression (tree_postfix_expression&);
--- a/libinterp/parse-tree/pt-select.cc	Fri Aug 01 09:06:21 2014 -0400
+++ b/libinterp/parse-tree/pt-select.cc	Fri Aug 01 12:10:05 2014 -0400
@@ -123,7 +123,7 @@
 {
   octave_value label_value = label->rvalue1 ();
 
-  if (! error_state && label_value.is_defined () )
+  if (! error_state && label_value.is_defined ())
     {
       if (label_value.is_cell ())
         {
--- a/libinterp/parse-tree/pt-walk.h	Fri Aug 01 09:06:21 2014 -0400
+++ b/libinterp/parse-tree/pt-walk.h	Fri Aug 01 12:10:05 2014 -0400
@@ -52,6 +52,7 @@
 class tree_no_op_command;
 class tree_constant;
 class tree_fcn_handle;
+class tree_funcall;
 class tree_parameter_list;
 class tree_postfix_expression;
 class tree_prefix_expression;
@@ -65,6 +66,24 @@
 class tree_while_command;
 class tree_do_until_command;
 
+class tree_classdef_attribute;
+class tree_classdef_attribute_list;
+class tree_classdef_superclass;
+class tree_classdef_superclass_list;
+class tree_classdef_property;
+class tree_classdef_property_list;
+class tree_classdef_properties_block;
+class tree_classdef_methods_list;
+class tree_classdef_methods_block;
+class tree_classdef_event;
+class tree_classdef_events_list;
+class tree_classdef_events_block;
+class tree_classdef_enum;
+class tree_classdef_enum_list;
+class tree_classdef_enum_block;
+class tree_classdef_body;
+class tree_classdef;
+
 class
 tree_walker
 {
@@ -158,6 +177,9 @@
   visit_fcn_handle (tree_fcn_handle&) = 0;
 
   virtual void
+  visit_funcall (tree_funcall&) = 0;
+
+  virtual void
   visit_parameter_list (tree_parameter_list&) = 0;
 
   virtual void
@@ -193,6 +215,57 @@
   virtual void
   visit_do_until_command (tree_do_until_command&) = 0;
 
+  virtual void
+  visit_classdef_attribute (tree_classdef_attribute&) { } /* = 0; */
+
+  virtual void
+  visit_classdef_attribute_list (tree_classdef_attribute_list&) { } /* = 0; */
+
+  virtual void
+  visit_classdef_superclass (tree_classdef_superclass&) { } /* = 0; */
+
+  virtual void
+  visit_classdef_superclass_list (tree_classdef_superclass_list&) { } /* = 0; */
+
+  virtual void
+  visit_classdef_property (tree_classdef_property&) { } /* = 0; */
+
+  virtual void
+  visit_classdef_property_list (tree_classdef_property_list&) { } /* = 0; */
+
+  virtual void
+  visit_classdef_properties_block (tree_classdef_properties_block&) { } /* = 0; */
+
+  virtual void
+  visit_classdef_methods_list (tree_classdef_methods_list&) { } /* = 0; */
+
+  virtual void
+  visit_classdef_methods_block (tree_classdef_methods_block&) { } /* = 0; */
+
+  virtual void
+  visit_classdef_event (tree_classdef_event&) { } /* = 0; */
+
+  virtual void
+  visit_classdef_events_list (tree_classdef_events_list&) { } /* = 0; */
+
+  virtual void
+  visit_classdef_events_block (tree_classdef_events_block&) { } /* = 0; */
+
+  virtual void
+  visit_classdef_enum (tree_classdef_enum&) { } /* = 0; */
+
+  virtual void
+  visit_classdef_enum_list (tree_classdef_enum_list&) { } /* = 0; */
+
+  virtual void
+  visit_classdef_enum_block (tree_classdef_enum_block&) { } /* = 0; */
+
+  virtual void
+  visit_classdef_body (tree_classdef_body&) { } /* = 0; */
+
+  virtual void
+  visit_classdef (tree_classdef&) { } /* = 0; */
+
 protected:
 
   tree_walker (void) { }
--- a/libinterp/parse-tree/token.cc	Fri Aug 01 09:06:21 2014 -0400
+++ b/libinterp/parse-tree/token.cc	Fri Aug 01 12:10:05 2014 -0400
@@ -97,38 +97,29 @@
   sr = s;
 }
 
-token::token (int tv, symbol_table::symbol_record *cls,
-              symbol_table::symbol_record *pkg, int l, int c)
+token::token (int tv, const std::string& mth, const std::string& cls,
+              int l, int c)
 {
   maybe_cmd = false;
   tspc = false;
   line_num = l;
   column_num = c;
   tok_val = tv;
-  type_tag = meta_rec_token;
-  mc.cr = cls;
-  mc.pr = pkg;
-}
-
-token::token (int tv, symbol_table::symbol_record *mth,
-              symbol_table::symbol_record *cls,
-              symbol_table::symbol_record *pkg, int l, int c)
-{
-  maybe_cmd = false;
-  tspc = false;
-  line_num = l;
-  column_num = c;
-  tok_val = tv;
-  type_tag = scls_rec_token;
-  sc.mr = mth;
-  sc.cr = cls;
-  sc.pr = pkg;
+  type_tag = scls_name_token;
+  sc.method_nm = new std::string (mth);
+  sc.class_nm = new std::string (cls);
 }
 
 token::~token (void)
 {
   if (type_tag == string_token)
     delete str;
+
+  if (type_tag == scls_name_token)
+    {
+      delete sc.method_nm;
+      delete sc.class_nm;
+    }
 }
 
 std::string
@@ -172,39 +163,18 @@
   return sr;
 }
 
-symbol_table::symbol_record *
-token::method_rec (void)
+std::string
+token::superclass_method_name (void)
 {
-  assert (type_tag == scls_rec_token);
-  return sc.mr;
-}
-
-symbol_table::symbol_record *
-token::class_rec (void)
-{
-  assert (type_tag == scls_rec_token);
-  return sc.cr;
+  assert (type_tag == scls_name_token);
+  return *sc.method_nm;
 }
 
-symbol_table::symbol_record *
-token::package_rec (void)
-{
-  assert (type_tag == scls_rec_token);
-  return sc.pr;
-}
-
-symbol_table::symbol_record *
-token::meta_class_rec (void)
+std::string
+token::superclass_class_name (void)
 {
-  assert (type_tag == meta_rec_token);
-  return mc.cr;
-}
-
-symbol_table::symbol_record *
-token::meta_package_rec (void)
-{
-  assert (type_tag == meta_rec_token);
-  return mc.pr;
+  assert (type_tag == scls_name_token);
+  return *sc.class_nm;
 }
 
 std::string
--- a/libinterp/parse-tree/token.h	Fri Aug 01 09:06:21 2014 -0400
+++ b/libinterp/parse-tree/token.h	Fri Aug 01 12:10:05 2014 -0400
@@ -40,8 +40,7 @@
     double_token,
     ettype_token,
     sym_rec_token,
-    scls_rec_token,
-    meta_rec_token
+    scls_name_token,
   };
 
   enum end_tok_type
@@ -69,11 +68,8 @@
          int l = -1, int c = -1);
   token (int tv, end_tok_type t, int l = -1, int c = -1);
   token (int tv, symbol_table::symbol_record *s, int l = -1, int c = -1);
-  token (int tv, symbol_table::symbol_record *cls,
-         symbol_table::symbol_record *pkg, int l = -1, int c = -1);
-  token (int tv, symbol_table::symbol_record *mth,
-         symbol_table::symbol_record *cls,
-         symbol_table::symbol_record *pkg, int l = -1, int c = -1);
+  token (int tv, const std::string& mth, const std::string& cls,
+         int l = -1, int c = -1);
 
   ~token (void);
 
@@ -106,12 +102,8 @@
   end_tok_type ettype (void) const;
   symbol_table::symbol_record *sym_rec (void);
 
-  symbol_table::symbol_record *method_rec (void);
-  symbol_table::symbol_record *class_rec (void);
-  symbol_table::symbol_record *package_rec (void);
-
-  symbol_table::symbol_record *meta_class_rec (void);
-  symbol_table::symbol_record *meta_package_rec (void);
+  std::string superclass_method_name (void);
+  std::string superclass_class_name (void);
 
   std::string text_rep (void);
 
@@ -137,15 +129,9 @@
     symbol_table::symbol_record *sr;
     struct
     {
-      symbol_table::symbol_record *mr;
-      symbol_table::symbol_record *cr;
-      symbol_table::symbol_record *pr;
+      std::string *method_nm;
+      std::string *class_nm;
     } sc;
-    struct
-    {
-      symbol_table::symbol_record *cr;
-      symbol_table::symbol_record *pr;
-    } mc;
   };
   std::string orig_text;
 };
--- a/liboctave/array/Array.cc	Fri Aug 01 09:06:21 2014 -0400
+++ b/liboctave/array/Array.cc	Fri Aug 01 12:10:05 2014 -0400
@@ -688,9 +688,9 @@
       }
     else
       {
-        octave_idx_type sd = sext[lev-1];
-        octave_idx_type dd = dext[lev-1];
-        octave_idx_type k;
+        octave_idx_type sd, dd, k;
+        sd = sext[lev-1];
+        dd = dext[lev-1];
         for (k = 0; k < cext[lev]; k++)
           do_resize_fill (src + k * sd, dest + k * dd, rfv, lev - 1);
 
@@ -2571,9 +2571,8 @@
                     d.xelem (i) = elem (i, i);
                 }
             }
-          else
-            (*current_liboctave_error_handler)
-              ("diag: requested diagonal out of range");
+          else  // Matlab returns [] 0x1 for out-of-range diagonal
+            d.resize (dim_vector (0, 1));
         }
       else
         {
--- a/liboctave/array/CDiagMatrix.cc	Fri Aug 01 09:06:21 2014 -0400
+++ b/liboctave/array/CDiagMatrix.cc	Fri Aug 01 12:10:05 2014 -0400
@@ -383,7 +383,7 @@
 }
 
 ComplexDiagMatrix
-ComplexDiagMatrix::pseudo_inverse (void) const
+ComplexDiagMatrix::pseudo_inverse (double tol) const
 {
   octave_idx_type r = rows ();
   octave_idx_type c = cols ();
@@ -393,10 +393,11 @@
 
   for (octave_idx_type i = 0; i < len; i++)
     {
-      if (elem (i, i) != 0.0)
+      double val = std::abs (elem (i, i));
+      if (val < tol || val == 0.0)
+        retval.elem (i, i) = 0.0;
+      else
         retval.elem (i, i) = 1.0 / elem (i, i);
-      else
-        retval.elem (i, i) = 0.0;
     }
 
   return retval;
--- a/liboctave/array/CDiagMatrix.h	Fri Aug 01 09:06:21 2014 -0400
+++ b/liboctave/array/CDiagMatrix.h	Fri Aug 01 12:10:05 2014 -0400
@@ -116,7 +116,7 @@
 
   ComplexDiagMatrix inverse (octave_idx_type& info) const;
   ComplexDiagMatrix inverse (void) const;
-  ComplexDiagMatrix pseudo_inverse (void) const;
+  ComplexDiagMatrix pseudo_inverse (double tol = 0.0) const;
 
   bool all_elements_are_real (void) const;
 
--- a/liboctave/array/CMatrix.cc	Fri Aug 01 09:06:21 2014 -0400
+++ b/liboctave/array/CMatrix.cc	Fri Aug 01 12:10:05 2014 -0400
@@ -1722,7 +1722,7 @@
 double
 ComplexMatrix::rcond (MatrixType &mattype) const
 {
-  double rcon;
+  double rcon = octave_NaN;
   octave_idx_type nr = rows ();
   octave_idx_type nc = cols ();
 
--- a/liboctave/array/CSparse.cc	Fri Aug 01 09:06:21 2014 -0400
+++ b/liboctave/array/CSparse.cc	Fri Aug 01 12:10:05 2014 -0400
@@ -1118,7 +1118,6 @@
             {
               // Matrix is either singular or not positive definite
               mattype.mark_as_unsymmetric ();
-              typ = MatrixType::Full;
             }
         }
 
@@ -1918,7 +1917,7 @@
                         }
                     }
 
-                  // Count non-zeros in work vector and adjust space in
+                  // Count nonzeros in work vector and adjust space in
                   // retval if needed
                   octave_idx_type new_nnz = 0;
                   for (octave_idx_type i = 0; i < nc; i++)
@@ -2014,7 +2013,7 @@
                         }
                     }
 
-                  // Count non-zeros in work vector and adjust space in
+                  // Count nonzeros in work vector and adjust space in
                   // retval if needed
                   octave_idx_type new_nnz = 0;
                   for (octave_idx_type i = 0; i < nc; i++)
@@ -2441,7 +2440,7 @@
                         }
                     }
 
-                  // Count non-zeros in work vector and adjust space in
+                  // Count nonzeros in work vector and adjust space in
                   // retval if needed
                   octave_idx_type new_nnz = 0;
                   for (octave_idx_type i = 0; i < nc; i++)
@@ -2537,7 +2536,7 @@
                         }
                     }
 
-                  // Count non-zeros in work vector and adjust space in
+                  // Count nonzeros in work vector and adjust space in
                   // retval if needed
                   octave_idx_type new_nnz = 0;
                   for (octave_idx_type i = 0; i < nc; i++)
@@ -2991,7 +2990,7 @@
                         }
                     }
 
-                  // Count non-zeros in work vector and adjust space in
+                  // Count nonzeros in work vector and adjust space in
                   // retval if needed
                   octave_idx_type new_nnz = 0;
                   for (octave_idx_type i = 0; i < nc; i++)
@@ -3100,7 +3099,7 @@
                         }
                     }
 
-                  // Count non-zeros in work vector and adjust space in
+                  // Count nonzeros in work vector and adjust space in
                   // retval if needed
                   octave_idx_type new_nnz = 0;
                   for (octave_idx_type i = 0; i < nc; i++)
@@ -3558,7 +3557,7 @@
                         }
                     }
 
-                  // Count non-zeros in work vector and adjust space in
+                  // Count nonzeros in work vector and adjust space in
                   // retval if needed
                   octave_idx_type new_nnz = 0;
                   for (octave_idx_type i = 0; i < nc; i++)
@@ -3667,7 +3666,7 @@
                         }
                     }
 
-                  // Count non-zeros in work vector and adjust space in
+                  // Count nonzeros in work vector and adjust space in
                   // retval if needed
                   octave_idx_type new_nnz = 0;
                   for (octave_idx_type i = 0; i < nc; i++)
@@ -4033,7 +4032,7 @@
                              work, b.rows (), err
                              F77_CHAR_ARG_LEN (1)));
 
-                  // Count non-zeros in work vector and adjust
+                  // Count nonzeros in work vector and adjust
                   // space in retval if needed
                   octave_idx_type new_nnz = 0;
                   for (octave_idx_type i = 0; i < nr; i++)
@@ -4315,7 +4314,7 @@
               octave_idx_type b_nc = b.cols ();
               OCTAVE_LOCAL_BUFFER (Complex, Bx, b_nr);
 
-              // Take a first guess that the number of non-zero terms
+              // Take a first guess that the number of nonzero terms
               // will be as many as in b
               volatile octave_idx_type x_nz = b.nnz ();
               volatile octave_idx_type ii = 0;
@@ -4343,7 +4342,7 @@
                       break;
                     }
 
-                  // Count non-zeros in work vector and adjust
+                  // Count nonzeros in work vector and adjust
                   // space in retval if needed
                   octave_idx_type new_nnz = 0;
                   for (octave_idx_type i = 0; i < nr; i++)
@@ -4529,7 +4528,7 @@
               m_band(ridx (i) - j + n_lower + n_upper, j) = data (i);
 
           // Calculate the norm of the matrix, for later use.
-          double anorm;
+          double anorm = 0.0;
           if (calc_cond)
             {
               for (octave_idx_type j = 0; j < nr; j++)
@@ -4735,7 +4734,7 @@
                   octave_idx_type b_nc = b.cols ();
                   OCTAVE_LOCAL_BUFFER (Complex, Bx, b_nr);
 
-                  // Take a first guess that the number of non-zero terms
+                  // Take a first guess that the number of nonzero terms
                   // will be as many as in b
                   volatile octave_idx_type x_nz = b.nnz ();
                   volatile octave_idx_type ii = 0;
@@ -4811,7 +4810,7 @@
               m_band(ridx (i) - j + n_lower + n_upper, j) = data (i);
 
           // Calculate the norm of the matrix, for later use.
-          double anorm;
+          double anorm = 0.0;
           if (calc_cond)
             {
               for (octave_idx_type j = 0; j < nr; j++)
@@ -4909,7 +4908,7 @@
                                  ldm, pipvt, work, b.rows (), err
                                  F77_CHAR_ARG_LEN (1)));
 
-                      // Count non-zeros in work vector and adjust
+                      // Count nonzeros in work vector and adjust
                       // space in retval if needed
                       octave_idx_type new_nnz = 0;
                       for (octave_idx_type i = 0; i < nr; i++)
@@ -5096,7 +5095,7 @@
               m_band(ridx (i) - j + n_lower + n_upper, j) = data (i);
 
           // Calculate the norm of the matrix, for later use.
-          double anorm;
+          double anorm = 0.0;
           if (calc_cond)
             {
               for (octave_idx_type j = 0; j < nr; j++)
@@ -5302,7 +5301,7 @@
                   octave_idx_type b_nc = b.cols ();
                   OCTAVE_LOCAL_BUFFER (Complex, Bx, b_nr);
 
-                  // Take a first guess that the number of non-zero terms
+                  // Take a first guess that the number of nonzero terms
                   // will be as many as in b
                   volatile octave_idx_type x_nz = b.nnz ();
                   volatile octave_idx_type ii = 0;
@@ -5329,7 +5328,7 @@
                           break;
                         }
 
-                      // Count non-zeros in work vector and adjust
+                      // Count nonzeros in work vector and adjust
                       // space in retval if needed
                       octave_idx_type new_nnz = 0;
                       for (octave_idx_type i = 0; i < nr; i++)
@@ -5383,7 +5382,7 @@
               m_band(ridx (i) - j + n_lower + n_upper, j) = data (i);
 
           // Calculate the norm of the matrix, for later use.
-          double anorm;
+          double anorm = 0.0;
           if (calc_cond)
             {
               for (octave_idx_type j = 0; j < nr; j++)
@@ -5482,7 +5481,7 @@
                                  ldm, pipvt, Bx, b.rows (), err
                                  F77_CHAR_ARG_LEN (1)));
 
-                      // Count non-zeros in work vector and adjust
+                      // Count nonzeros in work vector and adjust
                       // space in retval if needed
                       octave_idx_type new_nnz = 0;
                       for (octave_idx_type i = 0; i < nr; i++)
@@ -6077,7 +6076,7 @@
               OCTAVE_LOCAL_BUFFER (Complex, Bz, b_nr);
 #endif
 
-              // Take a first guess that the number of non-zero terms
+              // Take a first guess that the number of nonzero terms
               // will be as many as in b
               octave_idx_type x_nz = b.nnz ();
               octave_idx_type ii = 0;
@@ -6583,7 +6582,7 @@
 
               OCTAVE_LOCAL_BUFFER (Complex, Bx, b_nr);
 
-              // Take a first guess that the number of non-zero terms
+              // Take a first guess that the number of nonzero terms
               // will be as many as in b
               octave_idx_type x_nz = b.nnz ();
               octave_idx_type ii = 0;
@@ -7688,87 +7687,85 @@
 {
   SparseComplexMatrix r;
 
-  if ((a.rows () == b.rows ()) && (a.cols () == b.cols ()))
+  octave_idx_type a_nr = a.rows ();
+  octave_idx_type a_nc = a.cols ();
+  octave_idx_type b_nr = b.rows ();
+  octave_idx_type b_nc = b.cols ();
+
+  if (a_nr == b_nr && a_nc == b_nc)
     {
-      octave_idx_type a_nr = a.rows ();
-      octave_idx_type a_nc = a.cols ();
-
-      octave_idx_type b_nr = b.rows ();
-      octave_idx_type b_nc = b.cols ();
-
-      if (a_nr == 0 || b_nc == 0 || a.nnz () == 0 || b.nnz () == 0)
-        return SparseComplexMatrix (a_nr, a_nc);
-
-      if (a_nr != b_nr || a_nc != b_nc)
-        gripe_nonconformant ("min", a_nr, a_nc, b_nr, b_nc);
-      else
+      r = SparseComplexMatrix (a_nr, a_nc, (a.nnz () + b.nnz ()));
+
+      octave_idx_type jx = 0;
+      r.cidx (0) = 0;
+      for (octave_idx_type i = 0 ; i < a_nc ; i++)
         {
-          r = SparseComplexMatrix (a_nr, a_nc, (a.nnz () + b.nnz ()));
-
-          octave_idx_type jx = 0;
-          r.cidx (0) = 0;
-          for (octave_idx_type i = 0 ; i < a_nc ; i++)
-            {
-              octave_idx_type  ja = a.cidx (i);
-              octave_idx_type  ja_max = a.cidx (i+1);
-              bool ja_lt_max= ja < ja_max;
-
-              octave_idx_type  jb = b.cidx (i);
-              octave_idx_type  jb_max = b.cidx (i+1);
-              bool jb_lt_max = jb < jb_max;
-
-              while (ja_lt_max || jb_lt_max )
-                {
-                  octave_quit ();
-                  if ((! jb_lt_max) ||
-                      (ja_lt_max && (a.ridx (ja) < b.ridx (jb))))
+          octave_idx_type  ja = a.cidx (i);
+          octave_idx_type  ja_max = a.cidx (i+1);
+          bool ja_lt_max= ja < ja_max;
+
+          octave_idx_type  jb = b.cidx (i);
+          octave_idx_type  jb_max = b.cidx (i+1);
+          bool jb_lt_max = jb < jb_max;
+
+          while (ja_lt_max || jb_lt_max)
+            {
+              octave_quit ();
+              if ((! jb_lt_max) ||
+                  (ja_lt_max && (a.ridx (ja) < b.ridx (jb))))
+                {
+                  Complex tmp = xmin (a.data (ja), 0.);
+                  if (tmp != 0.)
                     {
-                      Complex tmp = xmin (a.data (ja), 0.);
-                      if (tmp != 0.)
-                        {
-                          r.ridx (jx) = a.ridx (ja);
-                          r.data (jx) = tmp;
-                          jx++;
-                        }
-                      ja++;
-                      ja_lt_max= ja < ja_max;
+                      r.ridx (jx) = a.ridx (ja);
+                      r.data (jx) = tmp;
+                      jx++;
                     }
-                  else if (( !ja_lt_max ) ||
-                           (jb_lt_max && (b.ridx (jb) < a.ridx (ja)) ) )
+                  ja++;
+                  ja_lt_max= ja < ja_max;
+                }
+              else if ((! ja_lt_max) ||
+                       (jb_lt_max && (b.ridx (jb) < a.ridx (ja))))
+                {
+                  Complex tmp = xmin (0., b.data (jb));
+                  if (tmp != 0.)
                     {
-                      Complex tmp = xmin (0., b.data (jb));
-                      if (tmp != 0.)
-                        {
-                          r.ridx (jx) = b.ridx (jb);
-                          r.data (jx) = tmp;
-                          jx++;
-                        }
-                      jb++;
-                      jb_lt_max= jb < jb_max;
+                      r.ridx (jx) = b.ridx (jb);
+                      r.data (jx) = tmp;
+                      jx++;
                     }
-                  else
+                  jb++;
+                  jb_lt_max= jb < jb_max;
+                }
+              else
+                {
+                  Complex tmp = xmin (a.data (ja), b.data (jb));
+                  if (tmp != 0.)
                     {
-                      Complex tmp = xmin (a.data (ja), b.data (jb));
-                      if (tmp != 0.)
-                        {
-                          r.data (jx) = tmp;
-                          r.ridx (jx) = a.ridx (ja);
-                          jx++;
-                        }
-                      ja++;
-                      ja_lt_max= ja < ja_max;
-                      jb++;
-                      jb_lt_max= jb < jb_max;
+                      r.data (jx) = tmp;
+                      r.ridx (jx) = a.ridx (ja);
+                      jx++;
                     }
-                }
-              r.cidx (i+1) = jx;
-            }
-
-          r.maybe_compress ();
+                  ja++;
+                  ja_lt_max= ja < ja_max;
+                  jb++;
+                  jb_lt_max= jb < jb_max;
+                }
+            }
+          r.cidx (i+1) = jx;
         }
+
+      r.maybe_compress ();
     }
   else
-    (*current_liboctave_error_handler) ("matrix size mismatch");
+    {
+      if (a_nr == 0 || a_nc == 0)
+        r.resize (a_nr, a_nc);
+      else if (b_nr == 0 || b_nc == 0)
+        r.resize (b_nr, b_nc);
+      else
+        gripe_nonconformant ("min", a_nr, a_nc, b_nr, b_nc);
+    }
 
   return r;
 }
@@ -7783,7 +7780,7 @@
 
   EMPTY_RETURN_CHECK (SparseComplexMatrix);
 
-  // Count the number of non-zero elements
+  // Count the number of nonzero elements
   if (xmax (c, 0.) != 0.)
     {
       result = SparseComplexMatrix (nr, nc, c);
@@ -7808,91 +7805,85 @@
 {
   SparseComplexMatrix r;
 
-  if ((a.rows () == b.rows ()) && (a.cols () == b.cols ()))
+  octave_idx_type a_nr = a.rows ();
+  octave_idx_type a_nc = a.cols ();
+  octave_idx_type b_nr = b.rows ();
+  octave_idx_type b_nc = b.cols ();
+
+  if (a_nr == b_nr && a_nc == b_nc)
     {
-      octave_idx_type a_nr = a.rows ();
-      octave_idx_type a_nc = a.cols ();
-
-      octave_idx_type b_nr = b.rows ();
-      octave_idx_type b_nc = b.cols ();
-
-      if (a_nr == 0 || b_nc == 0)
-        return SparseComplexMatrix (a_nr, a_nc);
-      if (a.nnz () == 0)
-        return SparseComplexMatrix (b);
-      if (b.nnz () == 0)
-        return SparseComplexMatrix (a);
-
-      if (a_nr != b_nr || a_nc != b_nc)
-        gripe_nonconformant ("min", a_nr, a_nc, b_nr, b_nc);
-      else
+      r = SparseComplexMatrix (a_nr, a_nc, (a.nnz () + b.nnz ()));
+
+      octave_idx_type jx = 0;
+      r.cidx (0) = 0;
+      for (octave_idx_type i = 0 ; i < a_nc ; i++)
         {
-          r = SparseComplexMatrix (a_nr, a_nc, (a.nnz () + b.nnz ()));
-
-          octave_idx_type jx = 0;
-          r.cidx (0) = 0;
-          for (octave_idx_type i = 0 ; i < a_nc ; i++)
-            {
-              octave_idx_type  ja = a.cidx (i);
-              octave_idx_type  ja_max = a.cidx (i+1);
-              bool ja_lt_max= ja < ja_max;
-
-              octave_idx_type  jb = b.cidx (i);
-              octave_idx_type  jb_max = b.cidx (i+1);
-              bool jb_lt_max = jb < jb_max;
-
-              while (ja_lt_max || jb_lt_max )
-                {
-                  octave_quit ();
-                  if ((! jb_lt_max) ||
-                      (ja_lt_max && (a.ridx (ja) < b.ridx (jb))))
+          octave_idx_type  ja = a.cidx (i);
+          octave_idx_type  ja_max = a.cidx (i+1);
+          bool ja_lt_max= ja < ja_max;
+
+          octave_idx_type  jb = b.cidx (i);
+          octave_idx_type  jb_max = b.cidx (i+1);
+          bool jb_lt_max = jb < jb_max;
+
+          while (ja_lt_max || jb_lt_max)
+            {
+              octave_quit ();
+              if ((! jb_lt_max) ||
+                  (ja_lt_max && (a.ridx (ja) < b.ridx (jb))))
+                {
+                  Complex tmp = xmax (a.data (ja), 0.);
+                  if (tmp != 0.)
                     {
-                      Complex tmp = xmax (a.data (ja), 0.);
-                      if (tmp != 0.)
-                        {
-                          r.ridx (jx) = a.ridx (ja);
-                          r.data (jx) = tmp;
-                          jx++;
-                        }
-                      ja++;
-                      ja_lt_max= ja < ja_max;
+                      r.ridx (jx) = a.ridx (ja);
+                      r.data (jx) = tmp;
+                      jx++;
                     }
-                  else if (( !ja_lt_max ) ||
-                           (jb_lt_max && (b.ridx (jb) < a.ridx (ja)) ) )
+                  ja++;
+                  ja_lt_max= ja < ja_max;
+                }
+              else if ((! ja_lt_max) ||
+                       (jb_lt_max && (b.ridx (jb) < a.ridx (ja))))
+                {
+                  Complex tmp = xmax (0., b.data (jb));
+                  if (tmp != 0.)
                     {
-                      Complex tmp = xmax (0., b.data (jb));
-                      if (tmp != 0.)
-                        {
-                          r.ridx (jx) = b.ridx (jb);
-                          r.data (jx) = tmp;
-                          jx++;
-                        }
-                      jb++;
-                      jb_lt_max= jb < jb_max;
+                      r.ridx (jx) = b.ridx (jb);
+                      r.data (jx) = tmp;
+                      jx++;
                     }
-                  else
+                  jb++;
+                  jb_lt_max= jb < jb_max;
+                }
+              else
+                {
+                  Complex tmp = xmax (a.data (ja), b.data (jb));
+                  if (tmp != 0.)
                     {
-                      Complex tmp = xmax (a.data (ja), b.data (jb));
-                      if (tmp != 0.)
-                        {
-                          r.data (jx) = tmp;
-                          r.ridx (jx) = a.ridx (ja);
-                          jx++;
-                        }
-                      ja++;
-                      ja_lt_max= ja < ja_max;
-                      jb++;
-                      jb_lt_max= jb < jb_max;
+                      r.data (jx) = tmp;
+                      r.ridx (jx) = a.ridx (ja);
+                      jx++;
                     }
-                }
-              r.cidx (i+1) = jx;
-            }
-
-          r.maybe_compress ();
+                  ja++;
+                  ja_lt_max= ja < ja_max;
+                  jb++;
+                  jb_lt_max= jb < jb_max;
+                }
+            }
+          r.cidx (i+1) = jx;
         }
+
+      r.maybe_compress ();
     }
   else
-    (*current_liboctave_error_handler) ("matrix size mismatch");
+    {
+      if (a_nr == 0 || a_nc == 0)
+        r.resize (a_nr, a_nc);
+      else if (b_nr == 0 || b_nc == 0)
+        r.resize (b_nr, b_nc);
+      else
+        gripe_nonconformant ("max", a_nr, a_nc, b_nr, b_nc);
+    }
 
   return r;
 }
--- a/liboctave/array/DiagArray2.cc	Fri Aug 01 09:06:21 2014 -0400
+++ b/liboctave/array/DiagArray2.cc	Fri Aug 01 12:10:05 2014 -0400
@@ -66,9 +66,8 @@
     d = Array<T> (dim_vector (std::min (cols () - k, rows ()), 1), T ());
   else if (k < 0 && -k < rows ())
     d = Array<T> (dim_vector (std::min (rows () + k, cols ()), 1), T ());
-  else
-    (*current_liboctave_error_handler)
-      ("diag: requested diagonal out of range");
+  else  // Matlab returns [] 0x1 for out-of-range diagonal
+    d.resize (dim_vector (0, 1));
 
   return d;
 }
--- a/liboctave/array/MSparse.cc	Fri Aug 01 09:06:21 2014 -0400
+++ b/liboctave/array/MSparse.cc	Fri Aug 01 12:10:05 2014 -0400
@@ -68,7 +68,7 @@
           octave_idx_type  jb_max = b.cidx (i+1);
           bool jb_lt_max = jb < jb_max;
 
-          while (ja_lt_max || jb_lt_max )
+          while (ja_lt_max || jb_lt_max)
             {
               octave_quit ();
               if ((! jb_lt_max) ||
@@ -80,8 +80,8 @@
                   ja++;
                   ja_lt_max= ja < ja_max;
                 }
-              else if (( !ja_lt_max ) ||
-                       (jb_lt_max && (b.ridx (jb) < a.ridx (ja)) ) )
+              else if ((! ja_lt_max) ||
+                       (jb_lt_max && (b.ridx (jb) < a.ridx (ja))))
                 {
                   r.ridx (jx) = b.ridx (jb);
                   r.data (jx) = op (0., b.data (jb));
@@ -340,7 +340,7 @@
           octave_idx_type  jb_max = b.cidx (i+1);
           bool jb_lt_max = jb < jb_max;
 
-          while (ja_lt_max || jb_lt_max )
+          while (ja_lt_max || jb_lt_max)
             {
               octave_quit ();
               if ((! jb_lt_max) ||
@@ -352,8 +352,8 @@
                   ja++;
                   ja_lt_max= ja < ja_max;
                 }
-              else if (( !ja_lt_max ) ||
-                       (jb_lt_max && (b.ridx (jb) < a.ridx (ja)) ) )
+              else if ((! ja_lt_max) ||
+                       (jb_lt_max && (b.ridx (jb) < a.ridx (ja))))
                 {
                   r.ridx (jx) = b.ridx (jb);
                   r.data (jx) = op (0.,  b.data (jb));
@@ -462,7 +462,7 @@
           octave_idx_type  jb_max = b.cidx (i+1);
           bool jb_lt_max = jb < jb_max;
 
-          while (ja_lt_max || jb_lt_max )
+          while (ja_lt_max || jb_lt_max)
             {
               octave_quit ();
               if ((! jb_lt_max) ||
@@ -470,8 +470,8 @@
                 {
                   ja++; ja_lt_max= ja < ja_max;
                 }
-              else if (( !ja_lt_max ) ||
-                       (jb_lt_max && (b.ridx (jb) < a.ridx (ja)) ) )
+              else if ((! ja_lt_max) ||
+                       (jb_lt_max && (b.ridx (jb) < a.ridx (ja))))
                 {
                   jb++; jb_lt_max= jb < jb_max;
                 }
@@ -569,7 +569,7 @@
     gripe_nonconformant ("quotient", a_nr, a_nc, b_nr, b_nc);
   else
     {
-      r = MSparse<T>( a_nr, a_nc, (Zero / Zero));
+      r = MSparse<T> (a_nr, a_nc, (Zero / Zero));
 
       for (octave_idx_type i = 0 ; i < a_nc ; i++)
         {
@@ -581,7 +581,7 @@
           octave_idx_type  jb_max = b.cidx (i+1);
           bool jb_lt_max = jb < jb_max;
 
-          while (ja_lt_max || jb_lt_max )
+          while (ja_lt_max || jb_lt_max)
             {
               octave_quit ();
               if ((! jb_lt_max) ||
@@ -590,8 +590,8 @@
                   r.elem (a.ridx (ja),i) = a.data (ja) / Zero;
                   ja++; ja_lt_max= ja < ja_max;
                 }
-              else if (( !ja_lt_max ) ||
-                       (jb_lt_max && (b.ridx (jb) < a.ridx (ja)) ) )
+              else if ((! ja_lt_max) ||
+                       (jb_lt_max && (b.ridx (jb) < a.ridx (ja))))
                 {
                   r.elem (b.ridx (jb),i) = Zero / b.data (jb);
                   jb++; jb_lt_max= jb < jb_max;
--- a/liboctave/array/MatrixType.cc	Fri Aug 01 09:06:21 2014 -0400
+++ b/liboctave/array/MatrixType.cc	Fri Aug 01 12:10:05 2014 -0400
@@ -119,7 +119,7 @@
 MatrixType::matrix_type
 matrix_complex_probe (const MArray<std::complex<T> >& a)
 {
-  MatrixType::matrix_type typ;
+  MatrixType::matrix_type typ = MatrixType::Unknown;
   octave_idx_type nrows = a.rows ();
   octave_idx_type ncols = a.cols ();
 
--- a/liboctave/array/PermMatrix.cc	Fri Aug 01 09:06:21 2014 -0400
+++ b/liboctave/array/PermMatrix.cc	Fri Aug 01 12:10:05 2014 -0400
@@ -36,8 +36,8 @@
     ("PermMatrix: invalid permutation vector");
 }
 
-PermMatrix::PermMatrix (const Array<octave_idx_type>& p, bool colp, bool check)
-  : Array<octave_idx_type> (p), _colp(colp)
+void
+PermMatrix::setup (const Array<octave_idx_type>& p, bool colp, bool check)
 {
   if (check)
     {
@@ -47,12 +47,28 @@
           Array<octave_idx_type>::operator = (Array<octave_idx_type> ());
         }
     }
+
+  if (!colp)
+    *this = this->transpose ();
+}
+
+PermMatrix::PermMatrix (const Array<octave_idx_type>& p)
+  : Array<octave_idx_type> (p)
+{
+  setup (p, false, true);
 }
 
-PermMatrix::PermMatrix (const idx_vector& idx, bool colp, octave_idx_type n)
-  : Array<octave_idx_type> (), _colp(colp)
+PermMatrix::PermMatrix (const Array<octave_idx_type>& p, bool colp, bool check)
+  : Array<octave_idx_type> (p)
+{
+  setup (p, colp, check);
+}
+
+void
+PermMatrix::setup (const idx_vector& idx, bool colp, octave_idx_type n)
 {
   octave_idx_type len = idx.length (n);
+
   if (! idx.is_permutation (len))
     gripe_invalid_permutation ();
   else
@@ -61,12 +77,28 @@
       for (octave_idx_type i = 0; i < len; i++) idxa(i) = idx(i);
       Array<octave_idx_type>::operator = (idxa);
     }
+
+  if (!colp)
+    *this = this->transpose ();
+}
+
+PermMatrix::PermMatrix (const idx_vector& idx)
+  : Array<octave_idx_type> ()
+{
+    setup (idx, false, 0);
+}
+
+PermMatrix::PermMatrix (const idx_vector& idx, bool colp, octave_idx_type n)
+  : Array<octave_idx_type> ()
+{
+    setup (idx, colp, n);
 }
 
 PermMatrix::PermMatrix (octave_idx_type n)
-  : Array<octave_idx_type> (dim_vector (n, 1)), _colp (false)
+  : Array<octave_idx_type> (dim_vector (n, 1))
 {
-  for (octave_idx_type i = 0; i < n; i++) xelem (i) = i;
+  for (octave_idx_type i = 0; i < n; i++)
+    xelem (i) = i;
 }
 
 octave_idx_type
@@ -86,8 +118,13 @@
 PermMatrix
 PermMatrix::transpose (void) const
 {
-  PermMatrix retval (*this);
-  retval._colp = ! retval._colp;
+  octave_idx_type len = Array<octave_idx_type>::length ();
+
+  PermMatrix retval (len);
+
+  for (octave_idx_type i = 0; i < len; ++i)
+    retval.xelem (xelem (i)) = i;
+
   return retval;
 }
 
@@ -133,17 +170,20 @@
 }
 
 PermMatrix
-PermMatrix::power (octave_idx_type m) const
+PermMatrix::power(octave_idx_type m) const
+{
+  if (m < 0)
+    return inverse ().pos_power (-m);
+  else if (m > 0)
+    return pos_power (m);
+  else
+    return PermMatrix (rows ());
+}
+
+PermMatrix
+PermMatrix::pos_power (octave_idx_type m) const
 {
   octave_idx_type n = rows ();
-  bool res_colp = _colp;
-  if (m < 0)
-    {
-      res_colp = ! res_colp;
-      m = -m;
-    }
-  else if (m == 0)
-    return PermMatrix (n);
 
   const octave_idx_type *p = data ();
   Array<octave_idx_type> res_pvec (dim_vector (n, 1), -1);
@@ -176,43 +216,29 @@
 
     }
 
-  return PermMatrix (res_pvec, res_colp, false);
+  return PermMatrix (res_pvec, true, false);
 }
 
 PermMatrix
 PermMatrix::eye (octave_idx_type n)
 {
-  Array<octave_idx_type> p (dim_vector (n, 1));
-  for (octave_idx_type i = 0; i < n; i++)
-    p(i) = i;
-
-  return PermMatrix (p, false, false);
+  return PermMatrix (n);
 }
 
 PermMatrix
 operator *(const PermMatrix& a, const PermMatrix& b)
 {
-  const Array<octave_idx_type> ia = a.pvec ();
-  const Array<octave_idx_type> ib = b.pvec ();
   PermMatrix r;
+
+  const Array<octave_idx_type> ia = a.col_perm_vec ();
+  const Array<octave_idx_type> ib = b.col_perm_vec ();
+
   octave_idx_type n = a.columns ();
+
   if (n != b.rows ())
     gripe_nonconformant ("operator *", n, n, b.rows (), b.rows ());
-  else if (a._colp == b._colp)
-    {
-      r = PermMatrix ((a._colp
-                       ? ia.index (idx_vector (ib))
-                       : ib.index (idx_vector (ia))), a._colp, false);
-    }
   else
-    {
-      Array<octave_idx_type> ra (dim_vector (n, 1));
-      if (a._colp)
-        ra.assign (idx_vector (ia), ib);
-      else
-        ra.assign (idx_vector (ib), ia);
-      r = PermMatrix (ra, a._colp, false);
-    }
+    r = PermMatrix (ia.index (idx_vector (ib)), true, false);
 
   return r;
 }
--- a/liboctave/array/PermMatrix.h	Fri Aug 01 09:06:21 2014 -0400
+++ b/liboctave/array/PermMatrix.h	Fri Aug 01 12:10:05 2014 -0400
@@ -31,20 +31,21 @@
 
 class OCTAVE_API PermMatrix : protected Array<octave_idx_type>
 {
-
 public:
 
-  PermMatrix (void) : Array<octave_idx_type> (), _colp (false) { }
+  PermMatrix (void) : Array<octave_idx_type> () { }
 
   PermMatrix (octave_idx_type n);
 
-  PermMatrix (const Array<octave_idx_type>& p, bool colp = false,
-              bool check = true);
+  PermMatrix (const Array<octave_idx_type>& p) GCC_ATTR_DEPRECATED;
+
+  PermMatrix (const Array<octave_idx_type>& p, bool colp, bool check = true);
 
-  PermMatrix (const PermMatrix& m)
-    : Array<octave_idx_type> (m), _colp(m._colp) { }
+  PermMatrix (const PermMatrix& m) : Array<octave_idx_type> (m) { }
 
-  PermMatrix (const idx_vector& idx, bool colp = false, octave_idx_type n = 0);
+  PermMatrix (const idx_vector& idx) GCC_ATTR_DEPRECATED;
+
+  PermMatrix (const idx_vector& idx, bool colp, octave_idx_type n = 0);
 
   octave_idx_type dim1 (void) const
   { return Array<octave_idx_type>::length (); }
@@ -68,15 +69,13 @@
 
   dim_vector dims (void) const { return dim_vector (dim1 (), dim2 ()); }
 
-  Array<octave_idx_type> pvec (void) const
+  const Array<octave_idx_type>& col_perm_vec (void) const
   { return *this; }
 
   octave_idx_type
   elem (octave_idx_type i, octave_idx_type j) const
   {
-    return (_colp
-            ? ((Array<octave_idx_type>::elem (j) == i) ? 1 : 0)
-              : ((Array<octave_idx_type>::elem (i) == j) ? 1 : 0));
+    return (Array<octave_idx_type>::elem (j) == i) ? 1 : 0;
   }
 
   octave_idx_type
@@ -102,20 +101,8 @@
   // Efficient integer power of a permutation.
   PermMatrix power (octave_idx_type n) const;
 
-  bool is_col_perm (void) const { return _colp; }
-  bool is_row_perm (void) const { return !_colp; }
-
-  friend OCTAVE_API PermMatrix operator *(const PermMatrix& a,
-                                          const PermMatrix& b);
-
-  const octave_idx_type *data (void) const
-  { return Array<octave_idx_type>::data (); }
-
-  const octave_idx_type *fortran_vec (void) const
-  { return Array<octave_idx_type>::fortran_vec (); }
-
-  octave_idx_type *fortran_vec (void)
-  { return Array<octave_idx_type>::fortran_vec (); }
+  bool is_col_perm (void) const { return true; }
+  bool is_row_perm (void) const { return false; }
 
   void print_info (std::ostream& os, const std::string& prefix) const
   { Array<octave_idx_type>::print_info (os, prefix); }
@@ -123,12 +110,17 @@
   static PermMatrix eye (octave_idx_type n);
 
 private:
-  bool _colp;
+
+  PermMatrix pos_power (octave_idx_type m) const;
+
+  void setup (const Array<octave_idx_type>& p, bool colp, bool check);
+
+  void setup (const idx_vector& idx, bool colp, octave_idx_type n);
 };
 
 // Multiplying permutations together.
 PermMatrix
 OCTAVE_API
-operator *(const PermMatrix& a, const PermMatrix& b);
+operator * (const PermMatrix& a, const PermMatrix& b);
 
 #endif
--- a/liboctave/array/Sparse.cc	Fri Aug 01 09:06:21 2014 -0400
+++ b/liboctave/array/Sparse.cc	Fri Aug 01 12:10:05 2014 -0400
@@ -61,18 +61,10 @@
   for (octave_idx_type i = 0; i <= n; i++)
     cidx (i) = i;
 
-  const Array<octave_idx_type> pv = a.pvec ();
-
-  if (a.is_row_perm ())
-    {
-      for (octave_idx_type i = 0; i < n; i++)
-        ridx (pv(i)) = i;
-    }
-  else
-    {
-      for (octave_idx_type i = 0; i < n; i++)
-        ridx (i) = pv(i);
-    }
+  const Array<octave_idx_type> pv = a.col_perm_vec ();
+
+  for (octave_idx_type i = 0; i < n; i++)
+    ridx (i) = pv(i);
 
   for (octave_idx_type i = 0; i < n; i++)
     data (i) = 1.0;
@@ -657,7 +649,7 @@
       octave_idx_type len = a.length ();
       octave_idx_type new_nzmx = 0;
 
-      // First count the number of non-zero terms
+      // First count the number of nonzero terms
       for (octave_idx_type i = 0; i < len; i++)
         if (a(i) != T ())
           new_nzmx++;
@@ -2427,7 +2419,7 @@
         {
           octave_idx_type ndiag = (nnr < nnc) ? nnr : nnc;
 
-          // Count the number of non-zero elements
+          // Count the number of nonzero elements
           octave_idx_type nel = 0;
           if (k > 0)
             {
@@ -2435,7 +2427,7 @@
                 if (elem (i, i+k) != 0.)
                   nel++;
             }
-          else if ( k < 0)
+          else if (k < 0)
             {
               for (octave_idx_type i = 0; i < ndiag; i++)
                 if (elem (i-k, i) != 0.)
@@ -2465,7 +2457,7 @@
                     }
                 }
             }
-          else if ( k < 0)
+          else if (k < 0)
             {
               for (octave_idx_type i = 0; i < ndiag; i++)
                 {
@@ -2491,8 +2483,15 @@
             }
         }
       else
-        (*current_liboctave_error_handler)
-          ("diag: requested diagonal out of range");
+        {
+          // Matlab returns [] 0x1 for out-of-range diagonal
+
+          octave_idx_type nr = 0;
+          octave_idx_type nc = 1;
+          octave_idx_type nz = 0;
+
+          d = Sparse<T> (nr, nc, nz);
+        }
     }
   else if (nnr != 0 && nnc != 0)
     {
--- a/liboctave/array/Sparse.h	Fri Aug 01 09:06:21 2014 -0400
+++ b/liboctave/array/Sparse.h	Fri Aug 01 12:10:05 2014 -0400
@@ -242,7 +242,7 @@
   Sparse<T>& operator = (const Sparse<T>& a);
 
   // Note that nzmax and capacity are the amount of storage for
-  // non-zero elements, while nnz is the actual number of non-zero
+  // nonzero elements, while nnz is the actual number of nonzero
   // terms.
   octave_idx_type nzmax (void) const { return rep->length (); }
   octave_idx_type capacity (void) const { return nzmax (); }
--- a/liboctave/array/dDiagMatrix.cc	Fri Aug 01 09:06:21 2014 -0400
+++ b/liboctave/array/dDiagMatrix.cc	Fri Aug 01 12:10:05 2014 -0400
@@ -292,7 +292,7 @@
 }
 
 DiagMatrix
-DiagMatrix::pseudo_inverse (void) const
+DiagMatrix::pseudo_inverse (double tol) const
 {
   octave_idx_type r = rows ();
   octave_idx_type c = cols ();
@@ -302,10 +302,11 @@
 
   for (octave_idx_type i = 0; i < len; i++)
     {
-      if (elem (i, i) != 0.0)
+      double val = std::abs (elem (i, i));
+      if (val < tol || val == 0.0)
+        retval.elem (i, i) = 0.0;
+      else
         retval.elem (i, i) = 1.0 / elem (i, i);
-      else
-        retval.elem (i, i) = 0.0;
     }
 
   return retval;
--- a/liboctave/array/dDiagMatrix.h	Fri Aug 01 09:06:21 2014 -0400
+++ b/liboctave/array/dDiagMatrix.h	Fri Aug 01 12:10:05 2014 -0400
@@ -98,7 +98,7 @@
 
   DiagMatrix inverse (void) const;
   DiagMatrix inverse (octave_idx_type& info) const;
-  DiagMatrix pseudo_inverse (void) const;
+  DiagMatrix pseudo_inverse (double tol = 0.0) const;
 
   // other operations
 
--- a/liboctave/array/dMatrix.cc	Fri Aug 01 09:06:21 2014 -0400
+++ b/liboctave/array/dMatrix.cc	Fri Aug 01 12:10:05 2014 -0400
@@ -259,14 +259,10 @@
 Matrix::Matrix (const PermMatrix& a)
   : MArray<double> (a.dims (), 0.0)
 {
-  const Array<octave_idx_type> ia (a.pvec ());
+  const Array<octave_idx_type> ia (a.col_perm_vec ());
   octave_idx_type len = a.rows ();
-  if (a.is_col_perm ())
-    for (octave_idx_type i = 0; i < len; i++)
-      elem (ia(i), i) = 1.0;
-  else
-    for (octave_idx_type i = 0; i < len; i++)
-      elem (i, ia(i)) = 1.0;
+  for (octave_idx_type i = 0; i < len; i++)
+    elem (ia(i), i) = 1.0;
 }
 
 // FIXME: could we use a templated mixed-type copy function here?
@@ -1382,7 +1378,7 @@
 double
 Matrix::rcond (MatrixType &mattype) const
 {
-  double rcon;
+  double rcon = octave_NaN;
   octave_idx_type nr = rows ();
   octave_idx_type nc = cols ();
 
--- a/liboctave/array/dSparse.cc	Fri Aug 01 09:06:21 2014 -0400
+++ b/liboctave/array/dSparse.cc	Fri Aug 01 12:10:05 2014 -0400
@@ -777,7 +777,7 @@
               octave_idx_type  jb_max = y.cidx (i+1);
               bool jb_lt_max = jb < jb_max;
 
-              while (ja_lt_max || jb_lt_max )
+              while (ja_lt_max || jb_lt_max)
                 {
                   octave_quit ();
                   if ((! jb_lt_max) ||
@@ -789,8 +789,8 @@
                       ja++;
                       ja_lt_max= ja < ja_max;
                     }
-                  else if (( !ja_lt_max ) ||
-                           (jb_lt_max && (y.ridx (jb) < x.ridx (ja)) ) )
+                  else if ((! ja_lt_max) ||
+                           (jb_lt_max && (y.ridx (jb) < x.ridx (ja))))
                     {
                       jb++;
                       jb_lt_max= jb < jb_max;
@@ -1216,7 +1216,6 @@
             {
               // Matrix is either singular or not positive definite
               mattype.mark_as_unsymmetric ();
-              typ = MatrixType::Full;
             }
         }
 
@@ -2005,7 +2004,7 @@
                         }
                     }
 
-                  // Count non-zeros in work vector and adjust space in
+                  // Count nonzeros in work vector and adjust space in
                   // retval if needed
                   octave_idx_type new_nnz = 0;
                   for (octave_idx_type i = 0; i < nc; i++)
@@ -2101,7 +2100,7 @@
                         }
                     }
 
-                  // Count non-zeros in work vector and adjust space in
+                  // Count nonzeros in work vector and adjust space in
                   // retval if needed
                   octave_idx_type new_nnz = 0;
                   for (octave_idx_type i = 0; i < nc; i++)
@@ -2530,7 +2529,7 @@
                         }
                     }
 
-                  // Count non-zeros in work vector and adjust space in
+                  // Count nonzeros in work vector and adjust space in
                   // retval if needed
                   octave_idx_type new_nnz = 0;
                   for (octave_idx_type i = 0; i < nc; i++)
@@ -2627,7 +2626,7 @@
                         }
                     }
 
-                  // Count non-zeros in work vector and adjust space in
+                  // Count nonzeros in work vector and adjust space in
                   // retval if needed
                   octave_idx_type new_nnz = 0;
                   for (octave_idx_type i = 0; i < nc; i++)
@@ -3085,7 +3084,7 @@
                         }
                     }
 
-                  // Count non-zeros in work vector and adjust space in
+                  // Count nonzeros in work vector and adjust space in
                   // retval if needed
                   octave_idx_type new_nnz = 0;
                   for (octave_idx_type i = 0; i < nc; i++)
@@ -3194,7 +3193,7 @@
                         }
                     }
 
-                  // Count non-zeros in work vector and adjust space in
+                  // Count nonzeros in work vector and adjust space in
                   // retval if needed
                   octave_idx_type new_nnz = 0;
                   for (octave_idx_type i = 0; i < nc; i++)
@@ -3653,7 +3652,7 @@
                         }
                     }
 
-                  // Count non-zeros in work vector and adjust space in
+                  // Count nonzeros in work vector and adjust space in
                   // retval if needed
                   octave_idx_type new_nnz = 0;
                   for (octave_idx_type i = 0; i < nc; i++)
@@ -3763,7 +3762,7 @@
                         }
                     }
 
-                  // Count non-zeros in work vector and adjust space in
+                  // Count nonzeros in work vector and adjust space in
                   // retval if needed
                   octave_idx_type new_nnz = 0;
                   for (octave_idx_type i = 0; i < nc; i++)
@@ -4130,7 +4129,7 @@
                              work, b.rows (), err
                              F77_CHAR_ARG_LEN (1)));
 
-                  // Count non-zeros in work vector and adjust
+                  // Count nonzeros in work vector and adjust
                   // space in retval if needed
                   octave_idx_type new_nnz = 0;
                   for (octave_idx_type i = 0; i < nr; i++)
@@ -4412,7 +4411,7 @@
               OCTAVE_LOCAL_BUFFER (double, Bx, b_nr);
               OCTAVE_LOCAL_BUFFER (double, Bz, b_nr);
 
-              // Take a first guess that the number of non-zero terms
+              // Take a first guess that the number of nonzero terms
               // will be as many as in b
               volatile octave_idx_type x_nz = b.nnz ();
               volatile octave_idx_type ii = 0;
@@ -4459,7 +4458,7 @@
                       break;
                     }
 
-                  // Count non-zeros in work vector and adjust
+                  // Count nonzeros in work vector and adjust
                   // space in retval if needed
                   octave_idx_type new_nnz = 0;
                   for (octave_idx_type i = 0; i < nr; i++)
@@ -4646,7 +4645,7 @@
               m_band(ridx (i) - j + n_lower + n_upper, j) = data (i);
 
           // Calculate the norm of the matrix, for later use.
-          double anorm;
+          double anorm = 0.0;
           if (calc_cond)
             {
               for (octave_idx_type j = 0; j < nr; j++)
@@ -4853,7 +4852,7 @@
                   octave_idx_type b_nc = b.cols ();
                   OCTAVE_LOCAL_BUFFER (double, Bx, b_nr);
 
-                  // Take a first guess that the number of non-zero terms
+                  // Take a first guess that the number of nonzero terms
                   // will be as many as in b
                   volatile octave_idx_type x_nz = b.nnz ();
                   volatile octave_idx_type ii = 0;
@@ -5027,7 +5026,7 @@
                                  ldm, pipvt, work, b.rows (), err
                                  F77_CHAR_ARG_LEN (1)));
 
-                      // Count non-zeros in work vector and adjust
+                      // Count nonzeros in work vector and adjust
                       // space in retval if needed
                       octave_idx_type new_nnz = 0;
                       for (octave_idx_type i = 0; i < nr; i++)
@@ -5474,7 +5473,7 @@
                   OCTAVE_LOCAL_BUFFER (double, Bx, b_nr);
                   OCTAVE_LOCAL_BUFFER (double, Bz, b_nr);
 
-                  // Take a first guess that the number of non-zero terms
+                  // Take a first guess that the number of nonzero terms
                   // will be as many as in b
                   volatile octave_idx_type x_nz = b.nnz ();
                   volatile octave_idx_type ii = 0;
@@ -5520,7 +5519,7 @@
                           break;
                         }
 
-                      // Count non-zeros in work vector and adjust
+                      // Count nonzeros in work vector and adjust
                       // space in retval if needed
                       octave_idx_type new_nnz = 0;
                       for (octave_idx_type i = 0; i < nr; i++)
@@ -5687,7 +5686,7 @@
                                  ldm, pipvt, Bz, b.rows (), err
                                  F77_CHAR_ARG_LEN (1)));
 
-                      // Count non-zeros in work vector and adjust
+                      // Count nonzeros in work vector and adjust
                       // space in retval if needed
                       octave_idx_type new_nnz = 0;
                       for (octave_idx_type i = 0; i < nr; i++)
@@ -6246,7 +6245,7 @@
               OCTAVE_LOCAL_BUFFER (double, Bx, b_nr);
               OCTAVE_LOCAL_BUFFER (double, Xx, b_nr);
 
-              // Take a first guess that the number of non-zero terms
+              // Take a first guess that the number of nonzero terms
               // will be as many as in b
               octave_idx_type x_nz = b.nnz ();
               octave_idx_type ii = 0;
@@ -6743,7 +6742,7 @@
               OCTAVE_LOCAL_BUFFER (double, Bx, b_nr);
               OCTAVE_LOCAL_BUFFER (double, Bz, b_nr);
 
-              // Take a first guess that the number of non-zero terms
+              // Take a first guess that the number of nonzero terms
               // will be as many as in b
               octave_idx_type x_nz = b.nnz ();
               octave_idx_type ii = 0;
@@ -7743,7 +7742,7 @@
 
   EMPTY_RETURN_CHECK (SparseMatrix);
 
-  // Count the number of non-zero elements
+  // Count the number of nonzero elements
   if (d < 0.)
     {
       result = SparseMatrix (nr, nc, d);
@@ -7801,84 +7800,85 @@
 {
   SparseMatrix r;
 
-  if ((a.rows () == b.rows ()) && (a.cols () == b.cols ()))
+  octave_idx_type a_nr = a.rows ();
+  octave_idx_type a_nc = a.cols ();
+  octave_idx_type b_nr = b.rows ();
+  octave_idx_type b_nc = b.cols ();
+
+  if (a_nr == b_nr && a_nc == b_nc)
     {
-      octave_idx_type a_nr = a.rows ();
-      octave_idx_type a_nc = a.cols ();
-
-      octave_idx_type b_nr = b.rows ();
-      octave_idx_type b_nc = b.cols ();
-
-      if (a_nr != b_nr || a_nc != b_nc)
-        gripe_nonconformant ("min", a_nr, a_nc, b_nr, b_nc);
-      else
+      r = SparseMatrix (a_nr, a_nc, (a.nnz () + b.nnz ()));
+
+      octave_idx_type jx = 0;
+      r.cidx (0) = 0;
+      for (octave_idx_type i = 0 ; i < a_nc ; i++)
         {
-          r = SparseMatrix (a_nr, a_nc, (a.nnz () + b.nnz ()));
-
-          octave_idx_type jx = 0;
-          r.cidx (0) = 0;
-          for (octave_idx_type i = 0 ; i < a_nc ; i++)
-            {
-              octave_idx_type  ja = a.cidx (i);
-              octave_idx_type  ja_max = a.cidx (i+1);
-              bool ja_lt_max= ja < ja_max;
-
-              octave_idx_type  jb = b.cidx (i);
-              octave_idx_type  jb_max = b.cidx (i+1);
-              bool jb_lt_max = jb < jb_max;
-
-              while (ja_lt_max || jb_lt_max )
-                {
-                  octave_quit ();
-                  if ((! jb_lt_max) ||
-                      (ja_lt_max && (a.ridx (ja) < b.ridx (jb))))
+          octave_idx_type  ja = a.cidx (i);
+          octave_idx_type  ja_max = a.cidx (i+1);
+          bool ja_lt_max= ja < ja_max;
+
+          octave_idx_type  jb = b.cidx (i);
+          octave_idx_type  jb_max = b.cidx (i+1);
+          bool jb_lt_max = jb < jb_max;
+
+          while (ja_lt_max || jb_lt_max)
+            {
+              octave_quit ();
+              if ((! jb_lt_max) ||
+                  (ja_lt_max && (a.ridx (ja) < b.ridx (jb))))
+                {
+                  double tmp = xmin (a.data (ja), 0.);
+                  if (tmp != 0.)
                     {
-                      double tmp = xmin (a.data (ja), 0.);
-                      if (tmp != 0.)
-                        {
-                          r.ridx (jx) = a.ridx (ja);
-                          r.data (jx) = tmp;
-                          jx++;
-                        }
-                      ja++;
-                      ja_lt_max= ja < ja_max;
+                      r.ridx (jx) = a.ridx (ja);
+                      r.data (jx) = tmp;
+                      jx++;
                     }
-                  else if (( !ja_lt_max ) ||
-                           (jb_lt_max && (b.ridx (jb) < a.ridx (ja)) ) )
+                  ja++;
+                  ja_lt_max= ja < ja_max;
+                }
+              else if ((! ja_lt_max) ||
+                       (jb_lt_max && (b.ridx (jb) < a.ridx (ja))))
+                {
+                  double tmp = xmin (0., b.data (jb));
+                  if (tmp != 0.)
                     {
-                      double tmp = xmin (0., b.data (jb));
-                      if (tmp != 0.)
-                        {
-                          r.ridx (jx) = b.ridx (jb);
-                          r.data (jx) = tmp;
-                          jx++;
-                        }
-                      jb++;
-                      jb_lt_max= jb < jb_max;
+                      r.ridx (jx) = b.ridx (jb);
+                      r.data (jx) = tmp;
+                      jx++;
                     }
-                  else
+                  jb++;
+                  jb_lt_max= jb < jb_max;
+                }
+              else
+                {
+                  double tmp = xmin (a.data (ja), b.data (jb));
+                  if (tmp != 0.)
                     {
-                      double tmp = xmin (a.data (ja), b.data (jb));
-                      if (tmp != 0.)
-                        {
-                          r.data (jx) = tmp;
-                          r.ridx (jx) = a.ridx (ja);
-                          jx++;
-                        }
-                      ja++;
-                      ja_lt_max= ja < ja_max;
-                      jb++;
-                      jb_lt_max= jb < jb_max;
+                      r.data (jx) = tmp;
+                      r.ridx (jx) = a.ridx (ja);
+                      jx++;
                     }
-                }
-              r.cidx (i+1) = jx;
-            }
-
-          r.maybe_compress ();
+                  ja++;
+                  ja_lt_max= ja < ja_max;
+                  jb++;
+                  jb_lt_max= jb < jb_max;
+                }
+            }
+          r.cidx (i+1) = jx;
         }
+
+      r.maybe_compress ();
     }
   else
-    (*current_liboctave_error_handler) ("matrix size mismatch");
+    {
+      if (a_nr == 0 || a_nc == 0)
+        r.resize (a_nr, a_nc);
+      else if (b_nr == 0 || b_nc == 0)
+        r.resize (b_nr, b_nc);
+      else
+        gripe_nonconformant ("min", a_nr, a_nc, b_nr, b_nc);
+    }
 
   return r;
 }
@@ -7893,7 +7893,7 @@
 
   EMPTY_RETURN_CHECK (SparseMatrix);
 
-  // Count the number of non-zero elements
+  // Count the number of nonzero elements
   if (d > 0.)
     {
       result = SparseMatrix (nr, nc, d);
@@ -7951,84 +7951,85 @@
 {
   SparseMatrix r;
 
-  if ((a.rows () == b.rows ()) && (a.cols () == b.cols ()))
+  octave_idx_type a_nr = a.rows ();
+  octave_idx_type a_nc = a.cols ();
+  octave_idx_type b_nr = b.rows ();
+  octave_idx_type b_nc = b.cols ();
+
+  if (a_nr == b_nr && a_nc == b_nc)
     {
-      octave_idx_type a_nr = a.rows ();
-      octave_idx_type a_nc = a.cols ();
-
-      octave_idx_type b_nr = b.rows ();
-      octave_idx_type b_nc = b.cols ();
-
-      if (a_nr != b_nr || a_nc != b_nc)
-        gripe_nonconformant ("min", a_nr, a_nc, b_nr, b_nc);
-      else
+      r = SparseMatrix (a_nr, a_nc, (a.nnz () + b.nnz ()));
+
+      octave_idx_type jx = 0;
+      r.cidx (0) = 0;
+      for (octave_idx_type i = 0 ; i < a_nc ; i++)
         {
-          r = SparseMatrix (a_nr, a_nc, (a.nnz () + b.nnz ()));
-
-          octave_idx_type jx = 0;
-          r.cidx (0) = 0;
-          for (octave_idx_type i = 0 ; i < a_nc ; i++)
-            {
-              octave_idx_type  ja = a.cidx (i);
-              octave_idx_type  ja_max = a.cidx (i+1);
-              bool ja_lt_max= ja < ja_max;
-
-              octave_idx_type  jb = b.cidx (i);
-              octave_idx_type  jb_max = b.cidx (i+1);
-              bool jb_lt_max = jb < jb_max;
-
-              while (ja_lt_max || jb_lt_max )
-                {
-                  octave_quit ();
-                  if ((! jb_lt_max) ||
-                      (ja_lt_max && (a.ridx (ja) < b.ridx (jb))))
+          octave_idx_type  ja = a.cidx (i);
+          octave_idx_type  ja_max = a.cidx (i+1);
+          bool ja_lt_max= ja < ja_max;
+
+          octave_idx_type  jb = b.cidx (i);
+          octave_idx_type  jb_max = b.cidx (i+1);
+          bool jb_lt_max = jb < jb_max;
+
+          while (ja_lt_max || jb_lt_max)
+            {
+              octave_quit ();
+              if ((! jb_lt_max) ||
+                  (ja_lt_max && (a.ridx (ja) < b.ridx (jb))))
+                {
+                  double tmp = xmax (a.data (ja), 0.);
+                  if (tmp != 0.)
                     {
-                      double tmp = xmax (a.data (ja), 0.);
-                      if (tmp != 0.)
-                        {
-                          r.ridx (jx) = a.ridx (ja);
-                          r.data (jx) = tmp;
-                          jx++;
-                        }
-                      ja++;
-                      ja_lt_max= ja < ja_max;
+                      r.ridx (jx) = a.ridx (ja);
+                      r.data (jx) = tmp;
+                      jx++;
                     }
-                  else if (( !ja_lt_max ) ||
-                           (jb_lt_max && (b.ridx (jb) < a.ridx (ja)) ) )
+                  ja++;
+                  ja_lt_max= ja < ja_max;
+                }
+              else if ((! ja_lt_max) ||
+                       (jb_lt_max && (b.ridx (jb) < a.ridx (ja))))
+                {
+                  double tmp = xmax (0., b.data (jb));
+                  if (tmp != 0.)
                     {
-                      double tmp = xmax (0., b.data (jb));
-                      if (tmp != 0.)
-                        {
-                          r.ridx (jx) = b.ridx (jb);
-                          r.data (jx) = tmp;
-                          jx++;
-                        }
-                      jb++;
-                      jb_lt_max= jb < jb_max;
+                      r.ridx (jx) = b.ridx (jb);
+                      r.data (jx) = tmp;
+                      jx++;
                     }
-                  else
+                  jb++;
+                  jb_lt_max= jb < jb_max;
+                }
+              else
+                {
+                  double tmp = xmax (a.data (ja), b.data (jb));
+                  if (tmp != 0.)
                     {
-                      double tmp = xmax (a.data (ja), b.data (jb));
-                      if (tmp != 0.)
-                        {
-                          r.data (jx) = tmp;
-                          r.ridx (jx) = a.ridx (ja);
-                          jx++;
-                        }
-                      ja++;
-                      ja_lt_max= ja < ja_max;
-                      jb++;
-                      jb_lt_max= jb < jb_max;
+                      r.data (jx) = tmp;
+                      r.ridx (jx) = a.ridx (ja);
+                      jx++;
                     }
-                }
-              r.cidx (i+1) = jx;
-            }
-
-          r.maybe_compress ();
+                  ja++;
+                  ja_lt_max= ja < ja_max;
+                  jb++;
+                  jb_lt_max= jb < jb_max;
+                }
+            }
+          r.cidx (i+1) = jx;
         }
+
+      r.maybe_compress ();
     }
   else
-    (*current_liboctave_error_handler) ("matrix size mismatch");
+    {
+      if (a_nr == 0 || a_nc == 0)
+        r.resize (a_nr, a_nc);
+      else if (b_nr == 0 || b_nc == 0)
+        r.resize (b_nr, b_nc);
+      else
+        gripe_nonconformant ("max", a_nr, a_nc, b_nr, b_nc);
+    }
 
   return r;
 }
--- a/liboctave/array/fCDiagMatrix.cc	Fri Aug 01 09:06:21 2014 -0400
+++ b/liboctave/array/fCDiagMatrix.cc	Fri Aug 01 12:10:05 2014 -0400
@@ -387,7 +387,7 @@
 }
 
 FloatComplexDiagMatrix
-FloatComplexDiagMatrix::pseudo_inverse (void) const
+FloatComplexDiagMatrix::pseudo_inverse (float tol) const
 {
   octave_idx_type r = rows ();
   octave_idx_type c = cols ();
@@ -397,10 +397,11 @@
 
   for (octave_idx_type i = 0; i < len; i++)
     {
-      if (elem (i, i) != 0.0f)
+      float val = std::abs (elem (i, i));
+      if (val < tol || val == 0.0f)
+        retval.elem (i, i) = 0.0f;
+      else
         retval.elem (i, i) = 1.0f / elem (i, i);
-      else
-        retval.elem (i, i) = 0.0f;
     }
 
   return retval;
--- a/liboctave/array/fCDiagMatrix.h	Fri Aug 01 09:06:21 2014 -0400
+++ b/liboctave/array/fCDiagMatrix.h	Fri Aug 01 12:10:05 2014 -0400
@@ -122,7 +122,7 @@
 
   FloatComplexDiagMatrix inverse (octave_idx_type& info) const;
   FloatComplexDiagMatrix inverse (void) const;
-  FloatComplexDiagMatrix pseudo_inverse (void) const;
+  FloatComplexDiagMatrix pseudo_inverse (float tol = 0.0f) const;
 
   bool all_elements_are_real (void) const;
 
--- a/liboctave/array/fCMatrix.cc	Fri Aug 01 09:06:21 2014 -0400
+++ b/liboctave/array/fCMatrix.cc	Fri Aug 01 12:10:05 2014 -0400
@@ -1727,7 +1727,7 @@
 float
 FloatComplexMatrix::rcond (MatrixType &mattype) const
 {
-  float rcon;
+  float rcon = octave_NaN;
   octave_idx_type nr = rows ();
   octave_idx_type nc = cols ();
 
--- a/liboctave/array/fCNDArray.cc	Fri Aug 01 09:06:21 2014 -0400
+++ b/liboctave/array/fCNDArray.cc	Fri Aug 01 12:10:05 2014 -0400
@@ -616,6 +616,12 @@
   return do_mx_red_op<FloatComplex, FloatComplex> (*this, dim, mx_inline_prod);
 }
 
+ComplexNDArray
+FloatComplexNDArray::dprod (int dim) const
+{
+  return do_mx_red_op<Complex, FloatComplex> (*this, dim, mx_inline_dprod);
+}
+
 FloatComplexNDArray
 FloatComplexNDArray::sum (int dim) const
 {
--- a/liboctave/array/fCNDArray.h	Fri Aug 01 09:06:21 2014 -0400
+++ b/liboctave/array/fCNDArray.h	Fri Aug 01 12:10:05 2014 -0400
@@ -83,6 +83,7 @@
   FloatComplexNDArray cumprod (int dim = -1) const;
   FloatComplexNDArray cumsum (int dim = -1) const;
   FloatComplexNDArray prod (int dim = -1) const;
+  ComplexNDArray dprod (int dim = -1) const;
   FloatComplexNDArray sum (int dim = -1) const;
   ComplexNDArray dsum (int dim = -1) const;
   FloatComplexNDArray sumsq (int dim = -1) const;
--- a/liboctave/array/fDiagMatrix.cc	Fri Aug 01 09:06:21 2014 -0400
+++ b/liboctave/array/fDiagMatrix.cc	Fri Aug 01 12:10:05 2014 -0400
@@ -292,7 +292,7 @@
 }
 
 FloatDiagMatrix
-FloatDiagMatrix::pseudo_inverse (void) const
+FloatDiagMatrix::pseudo_inverse (float tol) const
 {
   octave_idx_type r = rows ();
   octave_idx_type c = cols ();
@@ -302,10 +302,11 @@
 
   for (octave_idx_type i = 0; i < len; i++)
     {
-      if (elem (i, i) != 0.0f)
+      float val = std::abs (elem (i, i));
+      if (val < tol || val == 0.0f)
+        retval.elem (i, i) = 0.0f;
+      else
         retval.elem (i, i) = 1.0f / elem (i, i);
-      else
-        retval.elem (i, i) = 0.0f;
     }
 
   return retval;
--- a/liboctave/array/fDiagMatrix.h	Fri Aug 01 09:06:21 2014 -0400
+++ b/liboctave/array/fDiagMatrix.h	Fri Aug 01 12:10:05 2014 -0400
@@ -99,7 +99,7 @@
 
   FloatDiagMatrix inverse (void) const;
   FloatDiagMatrix inverse (octave_idx_type& info) const;
-  FloatDiagMatrix pseudo_inverse (void) const;
+  FloatDiagMatrix pseudo_inverse (float tol = 0.0f) const;
 
   // other operations
 
--- a/liboctave/array/fMatrix.cc	Fri Aug 01 09:06:21 2014 -0400
+++ b/liboctave/array/fMatrix.cc	Fri Aug 01 12:10:05 2014 -0400
@@ -259,14 +259,10 @@
 FloatMatrix::FloatMatrix (const PermMatrix& a)
   : MArray<float> (a.dims (), 0.0)
 {
-  const Array<octave_idx_type> ia (a.pvec ());
+  const Array<octave_idx_type> ia (a.col_perm_vec ());
   octave_idx_type len = a.rows ();
-  if (a.is_col_perm ())
-    for (octave_idx_type i = 0; i < len; i++)
-      elem (ia(i), i) = 1.0;
-  else
-    for (octave_idx_type i = 0; i < len; i++)
-      elem (i, ia(i)) = 1.0;
+  for (octave_idx_type i = 0; i < len; i++)
+    elem (ia(i), i) = 1.0;
 }
 
 // FIXME: could we use a templated mixed-type copy function here?
@@ -1390,7 +1386,7 @@
 float
 FloatMatrix::rcond (MatrixType &mattype) const
 {
-  float rcon;
+  float rcon = octave_NaN;
   octave_idx_type nr = rows ();
   octave_idx_type nc = cols ();
 
--- a/liboctave/array/fNDArray.cc	Fri Aug 01 09:06:21 2014 -0400
+++ b/liboctave/array/fNDArray.cc	Fri Aug 01 12:10:05 2014 -0400
@@ -627,6 +627,12 @@
   return do_mx_red_op<float, float> (*this, dim, mx_inline_prod);
 }
 
+NDArray
+FloatNDArray::dprod (int dim) const
+{
+  return do_mx_red_op<double, float> (*this, dim, mx_inline_dprod);
+}
+
 FloatNDArray
 FloatNDArray::sum (int dim) const
 {
--- a/liboctave/array/fNDArray.h	Fri Aug 01 09:06:21 2014 -0400
+++ b/liboctave/array/fNDArray.h	Fri Aug 01 12:10:05 2014 -0400
@@ -90,6 +90,7 @@
   FloatNDArray cumprod (int dim = -1) const;
   FloatNDArray cumsum (int dim = -1) const;
   FloatNDArray prod (int dim = -1) const;
+  NDArray dprod (int dim = -1) const;
   FloatNDArray sum (int dim = -1) const;
   NDArray dsum (int dim = -1) const;
   FloatNDArray sumsq (int dim = -1) const;
--- a/liboctave/array/intNDArray.cc	Fri Aug 01 09:06:21 2014 -0400
+++ b/liboctave/array/intNDArray.cc	Fri Aug 01 12:10:05 2014 -0400
@@ -213,6 +213,13 @@
 
 template <class T>
 intNDArray<T>
+intNDArray<T>::prod (int dim) const
+{
+  return do_mx_red_op<T, T> (*this, dim, mx_inline_prod);
+}
+
+template <class T>
+intNDArray<T>
 intNDArray<T>::sum (int dim) const
 {
   return do_mx_red_op<T, T> (*this, dim, mx_inline_sum);
--- a/liboctave/array/intNDArray.h	Fri Aug 01 09:06:21 2014 -0400
+++ b/liboctave/array/intNDArray.h	Fri Aug 01 12:10:05 2014 -0400
@@ -89,6 +89,7 @@
   intNDArray cummin (int dim = -1) const;
   intNDArray cummin (Array<octave_idx_type>& index, int dim = -1) const;
 
+  intNDArray prod (int dim) const;
   intNDArray sum (int dim) const;
   NDArray dsum (int dim) const;
   intNDArray cumsum (int dim) const;
--- a/liboctave/cruft/Faddeeva/Faddeeva.cc	Fri Aug 01 09:06:21 2014 -0400
+++ b/liboctave/cruft/Faddeeva/Faddeeva.cc	Fri Aug 01 12:10:05 2014 -0400
@@ -694,7 +694,7 @@
   else {
     const double pi = 3.14159265358979323846264338327950288419716939937510582;
     if (relerr > 0.1) relerr = 0.1; // not sensible to compute < 1 digit
-    a = pi / sqrt(-log(relerr*0.5));
+    a = pi / sqrt(-gnulib::log(relerr*0.5));
     c = (2/pi)*a;
     a2 = a*a;
   }
--- a/liboctave/numeric/CmplxQRP.cc	Fri Aug 01 09:06:21 2014 -0400
+++ b/liboctave/numeric/CmplxQRP.cc	Fri Aug 01 12:10:05 2014 -0400
@@ -103,7 +103,7 @@
 RowVector
 ComplexQRP::Pvec (void) const
 {
-  Array<double> pa (p.pvec ());
+  Array<double> pa (p.col_perm_vec ());
   RowVector pv (MArray<double> (pa) + 1.0);
   return pv;
 }
--- a/liboctave/numeric/DASPK-opts.in	Fri Aug 01 09:06:21 2014 -0400
+++ b/liboctave/numeric/DASPK-opts.in	Fri Aug 01 12:10:05 2014 -0400
@@ -209,7 +209,7 @@
 A vector of the same length as the state vector.  A nonzero element
 indicates that the corresponding element of the state vector is an
 algebraic variable (i.e., its derivative does not appear explicitly
-in the equation set.
+in the equation set).
 
 This option is required by the
 @qcode{\"compute consistent initial condition\"} and
--- a/liboctave/numeric/base-lu.cc	Fri Aug 01 09:06:21 2014 -0400
+++ b/liboctave/numeric/base-lu.cc	Fri Aug 01 12:10:05 2014 -0400
@@ -30,7 +30,7 @@
 template <class lu_type>
 base_lu<lu_type>::base_lu (const lu_type& l, const lu_type& u,
                            const PermMatrix& p)
-  : a_fact (u), l_fact (l), ipvt (p.pvec ())
+  : a_fact (u), l_fact (l), ipvt (p.transpose ().col_perm_vec ())
 {
   if (l.columns () != u.rows ())
     (*current_liboctave_error_handler) ("lu: dimension mismatch");
--- a/liboctave/numeric/bsxfun.h	Fri Aug 01 09:06:21 2014 -0400
+++ b/liboctave/numeric/bsxfun.h	Fri Aug 01 12:10:05 2014 -0400
@@ -41,7 +41,7 @@
       octave_idx_type xk = dx(i);
       octave_idx_type yk = dy(i);
       // Check the three conditions for valid bsxfun dims
-      if (! ( (xk == yk) || (xk == 1 && yk > 1) || (xk > 1 && yk == 1)))
+      if (! ((xk == yk) || (xk == 1 && yk > 1) || (xk > 1 && yk == 1)))
         return false;
     }
 
@@ -71,7 +71,7 @@
       octave_idx_type xk = dx(i);
 
       // Only two valid canditions to check; can't stretch rk
-      if (! ( (rk == xk) || (rk > 1 && xk == 1)))
+      if (! ((rk == xk) || (rk > 1 && xk == 1)))
         return false;
     }
 
--- a/liboctave/numeric/dbleQRP.cc	Fri Aug 01 09:06:21 2014 -0400
+++ b/liboctave/numeric/dbleQRP.cc	Fri Aug 01 12:10:05 2014 -0400
@@ -100,7 +100,7 @@
 RowVector
 QRP::Pvec (void) const
 {
-  Array<double> pa (p.pvec ());
+  Array<double> pa (p.col_perm_vec ());
   RowVector pv (MArray<double> (pa) + 1.0);
   return pv;
 }
--- a/liboctave/numeric/fCmplxQRP.cc	Fri Aug 01 09:06:21 2014 -0400
+++ b/liboctave/numeric/fCmplxQRP.cc	Fri Aug 01 12:10:05 2014 -0400
@@ -103,7 +103,7 @@
 FloatRowVector
 FloatComplexQRP::Pvec (void) const
 {
-  Array<float> pa (p.pvec ());
+  Array<float> pa (p.col_perm_vec ());
   FloatRowVector pv (MArray<float> (pa) + 1.0f);
   return pv;
 }
--- a/liboctave/numeric/floatQRP.cc	Fri Aug 01 09:06:21 2014 -0400
+++ b/liboctave/numeric/floatQRP.cc	Fri Aug 01 12:10:05 2014 -0400
@@ -100,7 +100,7 @@
 FloatRowVector
 FloatQRP::Pvec (void) const
 {
-  Array<float> pa (p.pvec ());
+  Array<float> pa (p.col_perm_vec ());
   FloatRowVector pv (MArray<float> (pa) + 1.0f);
   return pv;
 }
--- a/liboctave/numeric/lo-mappers.cc	Fri Aug 01 09:06:21 2014 -0400
+++ b/liboctave/numeric/lo-mappers.cc	Fri Aug 01 12:10:05 2014 -0400
@@ -101,7 +101,7 @@
 #if defined (M_LN2)
   static double ln2 = M_LN2;
 #else
-  static double ln2 = log (2);
+  static double ln2 = gnulib::log (2);
 #endif
 
   return std::log (x) / ln2;
@@ -116,7 +116,7 @@
 #if defined (M_LN2)
   static double ln2 = M_LN2;
 #else
-  static double ln2 = log (2);
+  static double ln2 = gnulib::log (2);
 #endif
 
   return exp (x * ln2);
@@ -522,14 +522,16 @@
 rc_log (double x)
 {
   const double pi = 3.14159265358979323846;
-  return x < 0.0 ? Complex (log (-x), pi) : Complex (log (x));
+  return x < 0.0 ? Complex (gnulib::log (-x), pi) : Complex (gnulib::log (x));
 }
 
 FloatComplex
 rc_log (float x)
 {
   const float pi = 3.14159265358979323846f;
-  return x < 0.0f ? FloatComplex (logf (-x), pi) : FloatComplex (logf (x));
+  return (x < 0.0f
+          ? FloatComplex (gnulib::logf (-x), pi)
+          : FloatComplex (gnulib::logf (x)));
 }
 
 Complex
--- a/liboctave/numeric/lo-specfun.cc	Fri Aug 01 09:06:21 2014 -0400
+++ b/liboctave/numeric/lo-specfun.cc	Fri Aug 01 12:10:05 2014 -0400
@@ -631,7 +631,7 @@
       retval = 2 * (s + 1) * u;
     }
   else
-    retval = log (1 + x);
+    retval = gnulib::log (1 + x);
 
   return retval;
 }
@@ -690,7 +690,7 @@
       retval = 2 * (s + 1) * u;
     }
   else
-    retval = log (1 + x);
+    retval = gnulib::logf (1 + x);
 
   return retval;
 }
@@ -2578,12 +2578,8 @@
   err = false;
 
   if (a < 0.0 || x < 0.0)
-    {
-      (*current_liboctave_error_handler)
-        ("gammainc: A and X must be non-negative");
-
-      err = true;
-    }
+    (*current_liboctave_error_handler)
+      ("gammainc: A and X must be non-negative");
   else
     F77_XFCN (xgammainc, XGAMMAINC, (a, x, retval));
 
@@ -2783,12 +2779,8 @@
   err = false;
 
   if (a < 0.0 || x < 0.0)
-    {
-      (*current_liboctave_error_handler)
-        ("gammainc: A and X must be non-negative");
-
-      err = true;
-    }
+    (*current_liboctave_error_handler)
+      ("gammainc: A and X must be non-negative");
   else
     F77_XFCN (xsgammainc, XSGAMMAINC, (a, x, retval));
 
@@ -2984,13 +2976,15 @@
 Complex rc_log1p (double x)
 {
   const double pi = 3.14159265358979323846;
-  return x < -1.0 ? Complex (log (-(1.0 + x)), pi) : Complex (log1p (x));
+  return (x < -1.0
+          ? Complex (gnulib::log (-(1.0 + x)), pi)
+          : Complex (log1p (x)));
 }
 
 FloatComplex rc_log1p (float x)
 {
   const float pi = 3.14159265358979323846f;
-  return x < -1.0f ? FloatComplex (logf (-(1.0f + x)), pi)
+  return x < -1.0f ? FloatComplex (gnulib::logf (-(1.0f + x)), pi)
                    : FloatComplex (log1pf (x));
 }
 
@@ -3044,7 +3038,7 @@
   else if (ax < 1.0)
     {
       // Tail region.
-      const double q = sqrt (-2*log (0.5*(1-ax)));
+      const double q = sqrt (-2*gnulib::log (0.5*(1-ax)));
       const double yn = ((((c[0]*q + c[1])*q + c[2])*q + c[3])*q + c[4])*q + c[5];
       const double yd = (((d[0]*q + d[1])*q + d[2])*q + d[3])*q + 1.0;
       y = yn / yd * signum (-x);
@@ -3122,7 +3116,7 @@
   else if (x > 0.0 && x < 2.0)
     {
       // Tail region.
-      const double q = x < 1 ? sqrt (-2*log (0.5*x)) : sqrt (-2*log (0.5*(2-x)));
+      const double q = x < 1 ? sqrt (-2*gnulib::log (0.5*x)) : sqrt (-2*gnulib::log (0.5*(2-x)));
       const double yn = ((((c[0]*q + c[1])*q + c[2])*q + c[3])*q + c[4])*q + c[5];
       const double yd = (((d[0]*q + d[1])*q + d[2])*q + d[3])*q + 1.0;
       y = yn / yd;
@@ -3241,8 +3235,8 @@
 
       if (temp <= acu && temp <= acu * value)
         {
-          value = value * exp (pp * log (xx)
-                               + (qq - 1.0) * log (cx) - beta) / pp;
+          value = value * exp (pp * gnulib::log (xx)
+                               + (qq - 1.0) * gnulib::log (cx) - beta) / pp;
 
           if (indx)
             {
@@ -3340,7 +3334,7 @@
 
   //  Calculate the initial approximation.
 
-  r = sqrt (- log (a * a));
+  r = sqrt (- gnulib::log (a * a));
 
   ycur = r - (2.30753 + 0.27061 * r) / (1.0 + (0.99229 + 0.04481 * r) * r);
 
@@ -3361,7 +3355,7 @@
 
       if (t <= 0.0)
         {
-          value = 1.0 - exp ((log ((1.0 - a) * qq) + beta) / qq);
+          value = 1.0 - exp ((gnulib::log ((1.0 - a) * qq) + beta) / qq);
         }
       else
         {
@@ -3369,7 +3363,7 @@
 
           if (t <= 1.0)
             {
-              value = exp ((log (a * pp) + beta) / pp);
+              value = exp ((gnulib::log (a * pp) + beta) / pp);
             }
           else
             {
@@ -3411,7 +3405,8 @@
         }
 
       xin = value;
-      ycur = (ycur - a) * exp (beta + r * log (xin) + t * log (1.0 - xin));
+      ycur = (ycur - a) * exp (beta + r * gnulib::log (xin)
+                               + t * gnulib::log (1.0 - xin));
 
       if (ycur * yprev <= 0.0)
         {
@@ -3641,7 +3636,7 @@
   double sqrt_eps = sqrt (std::numeric_limits<double>::epsilon ());
   if (m < sqrt_eps)
     {
-      // For small m, ( Abramowitz and Stegun, Section 16.13 )
+      // For small m, (Abramowitz and Stegun, Section 16.13)
       si_u = sin (u);
       co_u = cos (u);
       t = 0.25*m*(u - si_u*co_u);
@@ -3651,7 +3646,7 @@
     }
   else if ((1 - m) < sqrt_eps)
     {
-      // For m1 = (1-m) small ( Abramowitz and Stegun, Section 16.15 )
+      // For m1 = (1-m) small (Abramowitz and Stegun, Section 16.15)
       m1 = 1 - m;
       si_u = sinh (u);
       co_u = cosh (u);
@@ -3663,8 +3658,8 @@
     }
   else
     {
-      //  Arithmetic-Geometric Mean (AGM) algorithm
-      //    ( Abramowitz and Stegun, Section 16.4 )
+      // Arithmetic-Geometric Mean (AGM) algorithm
+      //   (Abramowitz and Stegun, Section 16.4)
       a[0] = 1;
       b    = sqrt (1 - m);
       c[0] = sqrt (m);
--- a/liboctave/numeric/randmtzig.c	Fri Aug 01 09:06:21 2014 -0400
+++ b/liboctave/numeric/randmtzig.c	Fri Aug 01 12:10:05 2014 -0400
@@ -249,7 +249,7 @@
         }
     }
 
-  state[0] = 0x80000000UL; /* MSB is 1; assuring non-zero initial array */
+  state[0] = 0x80000000UL; /* MSB is 1; assuring nonzero initial array */
   left = 1;
   initf = 1;
 }
--- a/liboctave/operators/Sparse-op-defs.h	Fri Aug 01 09:06:21 2014 -0400
+++ b/liboctave/operators/Sparse-op-defs.h	Fri Aug 01 12:10:05 2014 -0400
@@ -456,7 +456,7 @@
             octave_idx_type  jb_max = m2.cidx (i+1); \
             bool jb_lt_max = jb < jb_max; \
             \
-            while (ja_lt_max || jb_lt_max ) \
+            while (ja_lt_max || jb_lt_max) \
               { \
                 octave_quit (); \
                 if ((! jb_lt_max) || \
@@ -468,8 +468,8 @@
                     ja++; \
                     ja_lt_max= ja < ja_max; \
                   } \
-                else if (( !ja_lt_max ) || \
-                     (jb_lt_max && (m2.ridx (jb) < m1.ridx (ja)) ) ) \
+                else if ((! ja_lt_max) || \
+                     (jb_lt_max && (m2.ridx (jb) < m1.ridx (ja)))) \
                   { \
                     r.ridx (jx) = m2.ridx (jb); \
                     r.data (jx) = 0. OP m2.data (jb); \
@@ -564,7 +564,7 @@
             octave_idx_type  jb_max = m2.cidx (i+1); \
             bool jb_lt_max = jb < jb_max; \
             \
-            while (ja_lt_max || jb_lt_max ) \
+            while (ja_lt_max || jb_lt_max) \
               { \
                 octave_quit (); \
                 if ((! jb_lt_max) || \
@@ -572,8 +572,8 @@
                   { \
                      ja++; ja_lt_max= ja < ja_max; \
                   } \
-                else if (( !ja_lt_max ) || \
-                     (jb_lt_max && (m2.ridx (jb) < m1.ridx (ja)) ) ) \
+                else if ((! ja_lt_max) || \
+                     (jb_lt_max && (m2.ridx (jb) < m1.ridx (ja)))) \
                   { \
                      jb++; jb_lt_max= jb < jb_max; \
                   } \
@@ -680,7 +680,7 @@
             octave_idx_type  jb_max = m2.cidx (i+1); \
             bool jb_lt_max = jb < jb_max; \
             \
-            while (ja_lt_max || jb_lt_max ) \
+            while (ja_lt_max || jb_lt_max) \
               { \
                 octave_quit (); \
                 if ((! jb_lt_max) || \
@@ -691,8 +691,8 @@
                     ja++; \
                     ja_lt_max= ja < ja_max; \
                   } \
-                else if (( !ja_lt_max ) || \
-                     (jb_lt_max && (m2.ridx (jb) < m1.ridx (ja)) ) ) \
+                else if ((! ja_lt_max) || \
+                     (jb_lt_max && (m2.ridx (jb) < m1.ridx (ja)))) \
                   { \
                     /* keep those kludges coming */ \
                     r.elem (m2.ridx (jb),i) = Complex () OP m2.data (jb);  \
@@ -1184,7 +1184,7 @@
       { \
         if (m1_nr != 0 || m1_nc != 0) \
           { \
-            /* Count num of non-zero elements */ \
+            /* Count num of nonzero elements */ \
             octave_idx_type nel = 0; \
             for (octave_idx_type j = 0; j < m1_nc; j++) \
               for (octave_idx_type i = 0; i < m1_nr; i++) \
@@ -1252,7 +1252,7 @@
       { \
         if (m1_nr != 0 || m1_nc != 0) \
           { \
-            /* Count num of non-zero elements */ \
+            /* Count num of nonzero elements */ \
             octave_idx_type nel = 0; \
             for (octave_idx_type j = 0; j < m1_nc; j++) \
               for (octave_idx_type i = 0; i < m1_nr; i++) \
@@ -1424,7 +1424,7 @@
       { \
         if (m1_nr != 0 || m1_nc != 0) \
           { \
-            /* Count num of non-zero elements */ \
+            /* Count num of nonzero elements */ \
             octave_idx_type nel = 0; \
             for (octave_idx_type j = 0; j < m1_nc; j++) \
               for (octave_idx_type i = 0; i < m1_nr; i++) \
@@ -1492,7 +1492,7 @@
       { \
         if (m1_nr != 0 || m1_nc != 0) \
           { \
-            /* Count num of non-zero elements */ \
+            /* Count num of nonzero elements */ \
             octave_idx_type nel = 0; \
             for (octave_idx_type j = 0; j < m1_nc; j++) \
               for (octave_idx_type i = 0; i < m1_nr; i++) \
@@ -1836,7 +1836,7 @@
 
 #define SPARSE_ANY_OP(DIM) SPARSE_ANY_ALL_OP (DIM, false, false, !=, true)
 
-#define SPARSE_SPARSE_MUL( RET_TYPE, RET_EL_TYPE, EL_TYPE ) \
+#define SPARSE_SPARSE_MUL(RET_TYPE, RET_EL_TYPE, EL_TYPE) \
   octave_idx_type nr = m.rows (); \
   octave_idx_type nc = m.cols (); \
   \
@@ -1930,10 +1930,10 @@
           retval.change_capacity (nel); \
           /* The optimal break-point as estimated from simulations */ \
           /* Note that Mergesort is O(nz log(nz)) while searching all */ \
-          /* values is O(nr), where nz here is non-zero per row of */ \
+          /* values is O(nr), where nz here is nonzero per row of */ \
           /* length nr. The test itself was then derived from the */ \
           /* simulation with random square matrices and the observation */ \
-          /* of the number of non-zero elements in the output matrix */ \
+          /* of the number of nonzero elements in the output matrix */ \
           /* it was found that the breakpoints were */ \
           /*   nr: 500  1000  2000  5000 10000 */ \
           /*   nz:   6    25    97   585  2202 */ \
@@ -2005,7 +2005,7 @@
         } \
     }
 
-#define SPARSE_FULL_MUL( RET_TYPE, EL_TYPE, ZERO ) \
+#define SPARSE_FULL_MUL(RET_TYPE, EL_TYPE, ZERO) \
   octave_idx_type nr = m.rows (); \
   octave_idx_type nc = m.cols (); \
   \
@@ -2040,7 +2040,7 @@
       return retval; \
     }
 
-#define SPARSE_FULL_TRANS_MUL( RET_TYPE, EL_TYPE, ZERO, CONJ_OP ) \
+#define SPARSE_FULL_TRANS_MUL(RET_TYPE, EL_TYPE, ZERO, CONJ_OP) \
   octave_idx_type nr = m.rows (); \
   octave_idx_type nc = m.cols (); \
   \
@@ -2076,7 +2076,7 @@
       return retval; \
     }
 
-#define FULL_SPARSE_MUL( RET_TYPE, EL_TYPE, ZERO ) \
+#define FULL_SPARSE_MUL(RET_TYPE, EL_TYPE, ZERO) \
   octave_idx_type nr = m.rows (); \
   octave_idx_type nc = m.cols (); \
   \
@@ -2112,7 +2112,7 @@
       return retval; \
     }
 
-#define FULL_SPARSE_MUL_TRANS( RET_TYPE, EL_TYPE, ZERO, CONJ_OP ) \
+#define FULL_SPARSE_MUL_TRANS(RET_TYPE, EL_TYPE, ZERO, CONJ_OP) \
   octave_idx_type nr = m.rows (); \
   octave_idx_type nc = m.cols (); \
   \
--- a/liboctave/operators/Sparse-perm-op-defs.h	Fri Aug 01 09:06:21 2014 -0400
+++ b/liboctave/operators/Sparse-perm-op-defs.h	Fri Aug 01 12:10:05 2014 -0400
@@ -67,17 +67,7 @@
       return SM ();
     }
 
-  if (p.is_row_perm ())
-    {
-      // Form the column permutation and then call the colpm_sm routine.
-      const octave_idx_type *prow = p.pvec ().data ();
-      OCTAVE_LOCAL_BUFFER (octave_idx_type, pcol, nr);
-      for (octave_idx_type i = 0; i < nr; ++i)
-        pcol[prow[i]] = i;
-      return octinternal_do_mul_colpm_sm (pcol, a);
-    }
-  else
-    return octinternal_do_mul_colpm_sm (p.pvec ().data (), a);
+  return octinternal_do_mul_colpm_sm (p.col_perm_vec ().data (), a);
 }
 
 template <typename SM>
@@ -163,10 +153,7 @@
       return SM ();
     }
 
-  if (p.is_row_perm ())
-    return octinternal_do_mul_sm_rowpm (a, p.pvec ().data ());
-  else
-    return octinternal_do_mul_sm_colpm (a, p.pvec ().data ());
+  return octinternal_do_mul_sm_colpm (a, p.col_perm_vec ().data ());
 }
 
 #endif // octave_Sparse_perm_op_defs_h
--- a/liboctave/operators/mx-inlines.cc	Fri Aug 01 09:06:21 2014 -0400
+++ b/liboctave/operators/mx-inlines.cc	Fri Aug 01 12:10:05 2014 -0400
@@ -485,6 +485,14 @@
 #define OP_RED_SUMSQ(ac, el) ac += el*el
 #define OP_RED_SUMSQC(ac, el) ac += cabsq (el)
 
+inline void op_dble_prod (double& ac, float el)
+{ ac *= el; }
+inline void op_dble_prod (Complex& ac, const FloatComplex& el)
+{ ac *= el; } // FIXME: guaranteed?
+template <class T>
+inline void op_dble_prod (double& ac, const octave_int<T>& el)
+{ ac *= el.double_value (); }
+
 inline void op_dble_sum (double& ac, float el)
 { ac += el; }
 inline void op_dble_sum (Complex& ac, const FloatComplex& el)
@@ -514,6 +522,7 @@
 OP_RED_FCN (mx_inline_dsum, T, PROMOTE_DOUBLE(T), op_dble_sum, 0.0)
 OP_RED_FCN (mx_inline_count, bool, T, OP_RED_SUM, 0)
 OP_RED_FCN (mx_inline_prod, T, T, OP_RED_PROD, 1)
+OP_RED_FCN (mx_inline_dprod, T, PROMOTE_DOUBLE(T), op_dble_prod, 1)
 OP_RED_FCN (mx_inline_sumsq, T, T, OP_RED_SUMSQ, 0)
 OP_RED_FCN (mx_inline_sumsq, std::complex<T>, T, OP_RED_SUMSQC, 0)
 OP_RED_FCN (mx_inline_any, T, bool, OP_RED_ANYC, false)
@@ -539,6 +548,7 @@
 OP_RED_FCN2 (mx_inline_dsum, T, PROMOTE_DOUBLE(T), op_dble_sum, 0.0)
 OP_RED_FCN2 (mx_inline_count, bool, T, OP_RED_SUM, 0)
 OP_RED_FCN2 (mx_inline_prod, T, T, OP_RED_PROD, 1)
+OP_RED_FCN2 (mx_inline_dprod, T, PROMOTE_DOUBLE(T), op_dble_prod, 0.0)
 OP_RED_FCN2 (mx_inline_sumsq, T, T, OP_RED_SUMSQ, 0)
 OP_RED_FCN2 (mx_inline_sumsq, std::complex<T>, T, OP_RED_SUMSQC, 0)
 
@@ -612,6 +622,7 @@
 OP_RED_FCNN (mx_inline_dsum, T, PROMOTE_DOUBLE(T))
 OP_RED_FCNN (mx_inline_count, bool, T)
 OP_RED_FCNN (mx_inline_prod, T, T)
+OP_RED_FCNN (mx_inline_dprod, T, PROMOTE_DOUBLE(T))
 OP_RED_FCNN (mx_inline_sumsq, T, T)
 OP_RED_FCNN (mx_inline_sumsq, std::complex<T>, T)
 OP_RED_FCNN (mx_inline_any, T, bool)
@@ -1345,8 +1356,8 @@
 inline T
 mx_inline_xsum (const T *v, octave_idx_type n)
 {
-  T s = 0;
-  T e = 0;
+  T s, e;
+  s = e = 0;
   for (octave_idx_type i = 0; i < n; i++)
     twosum_accum (s, e, v[i]);
 
--- a/liboctave/operators/mx-op-defs.h	Fri Aug 01 09:06:21 2014 -0400
+++ b/liboctave/operators/mx-op-defs.h	Fri Aug 01 12:10:05 2014 -0400
@@ -606,13 +606,8 @@
     gripe_nonconformant ("operator *", p.rows (), p.columns (), nr, nc); \
   else \
     { \
-      if (p.is_col_perm ()) \
-        { \
-          result = M (nr, nc); \
-          result.assign (p.pvec (), idx_vector::colon, x); \
-        } \
-      else \
-        result = x.index (p.pvec (), idx_vector::colon); \
+      result = M (nr, nc); \
+      result.assign (p.col_perm_vec (), idx_vector::colon, x); \
     } \
   \
   return result; \
@@ -627,15 +622,7 @@
   if (p.rows () != nc) \
     gripe_nonconformant ("operator *", nr, nc, p.rows (), p.columns ()); \
   else \
-    { \
-      if (p.is_col_perm ()) \
-        result = x.index (idx_vector::colon, p.pvec ()); \
-      else \
-        { \
-          result = M (nr, nc); \
-          result.assign (idx_vector::colon, p.pvec (), x); \
-        } \
-    } \
+    result = x.index (idx_vector::colon, p.col_perm_vec ()); \
   \
   return result; \
 }
--- a/liboctave/system/module.mk	Fri Aug 01 09:06:21 2014 -0400
+++ b/liboctave/system/module.mk	Fri Aug 01 12:10:05 2014 -0400
@@ -18,10 +18,6 @@
   system/sysdir.h \
   system/syswait.h
 
-SYSTEM_C_SRC = \
-  system/tempnam.c \
-  system/tempname.c
-
 SYSTEM_SRC = \
   system/dir-ops.cc \
   system/file-ops.cc \
@@ -33,8 +29,7 @@
   system/oct-passwd.cc \
   system/oct-syscalls.cc \
   system/oct-time.cc \
-  system/oct-uname.cc \
-  $(SYSTEM_C_SRC)
+  system/oct-uname.cc
 
 noinst_LTLIBRARIES += system/libsystem.la
 
--- a/liboctave/system/tempnam.c	Fri Aug 01 09:06:21 2014 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,59 +0,0 @@
-/* Copyright (C) 1991, 1993 Free Software Foundation, Inc.
-This file is part of the GNU C Library.
-
-The GNU C Library is free software; you can redistribute it and/or
-modify it under the terms of the GNU Library General Public License as
-published by the Free Software Foundation; either version 2 of the
-License, or (at your option) any later version.
-
-The GNU C Library is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-Library General Public License for more details.
-
-You should have received a copy of the GNU Library General Public
-License along with the GNU C Library; see the file COPYING.LIB.  If
-not, write to the Free Software Foundation, Inc., 51 Franklin Street,
-Fifth Floor, Boston, MA  02110-1301, USA.  */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#ifndef HAVE_TEMPNAM
-
-#include <stddef.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-extern char *__stdio_gen_tempname (const char *dir, const char *pfx,
-                                   int dir_search, size_t *lenptr,
-                                   FILE **streamptr);
-
-/* Generate a unique temporary filename using up to five characters of PFX
-   if it is not NULL.  The directory to put this file in is searched for
-   as follows: First the environment variable "TMPDIR" is checked.
-   If it contains the name of a writable directory, that directory is used.
-   If not and if DIR is not NULL, that value is checked.  If that fails,
-   P_tmpdir is tried and finally "/tmp".  The storage for the filename
-   is allocated by `malloc'.  */
-char *
-tempnam (const char *dir, const char *pfx)
-{
-  size_t len;
-  register char *s;
-  register char *t = __stdio_gen_tempname (dir, pfx, 1, &len, (FILE **) NULL);
-
-  if (t == NULL)
-    return NULL;
-
-  s = (char *) malloc (len);
-  if (s == NULL)
-    return NULL;
-
-  (void) memcpy (s, t, len);
-  return s;
-}
-
-#endif
--- a/liboctave/system/tempname.c	Fri Aug 01 09:06:21 2014 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,207 +0,0 @@
-/* Copyright (C) 1991, 1992, 1993 Free Software Foundation, Inc.
-This file is part of the GNU C Library.
-
-The GNU C Library is free software; you can redistribute it and/or
-modify it under the terms of the GNU General Public License as
-published by the Free Software Foundation; either version 2 of the
-License, or (at your option) any later version.
-
-The GNU C Library is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-General Public License for more details.
-
-You should have received a copy of the GNU General Public
-License along with the GNU C Library; see the file COPYING.  If
-not, write to the Free Software Foundation, Inc., 51 Franklin Street,
-Fifth Floor, Boston, MA  02110-1301, USA.  */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#ifndef HAVE_TEMPNAM
-
-#include <errno.h>
-#include <stddef.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <sys/types.h>
-#include <unistd.h>
-
-#include <fcntl.h>
-
-#include "statdefs.h"
-
-#ifndef FILENAME_MAX
-#ifdef MAXPATHLEN
-#define FILENAME_MAX MAXPATHLEN
-#else
-#define FILENAME_MAX 1024
-#endif
-#endif
-
-#ifndef P_tmpdir
-#define P_tmpdir "/usr/tmp/"
-#endif
-
-/* Return nonzero if DIR is an existent directory.  */
-static int
-diraccess (const char *dir)
-{
-  struct stat buf;
-  return stat (dir, &buf) == 0 && S_ISDIR (buf.st_mode);
-}
-
-/* Return nonzero if FILE exists.  */
-static int
-exists (const char *file)
-{
-  /* We can stat the file even if we can't read its data.  */
-  struct stat st;
-  int save = errno;
-  if (stat (file, &st) == 0)
-    return 1;
-  else
-    {
-      /* We report that the file exists if stat failed for a reason other
-         than nonexistence.  In this case, it may or may not exist, and we
-         don't know; but reporting that it does exist will never cause any
-         trouble, while reporting that it doesn't exist when it does would
-         violate the interface of __stdio_gen_tempname.  */
-      int exists = errno != ENOENT;
-      errno = save;
-      return exists;
-    }
-}
-
-
-/* These are the characters used in temporary filenames.  */
-static const char letters[] =
-  "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
-
-/* Generate a temporary filename and return it (in a static buffer).  If
-   STREAMPTR is not NULL, open a stream "w+b" on the file and set
-   *STREAMPTR to it.  If DIR_SEARCH is nonzero, DIR and PFX are used as
-   described for tempnam.  If not, a temporary filename in P_tmpdir with no
-   special prefix is generated.  If LENPTR is not NULL, *LENPTR is set the
-   to length (including the terminating '\0') of the resultant filename,
-   which is returned.  This goes through a cyclic pattern of all possible
-   filenames consisting of five decimal digits of the current pid and three
-   of the characters in `letters'.  Data for tempnam and tmpnam is kept
-   separate, but when tempnam is using P_tmpdir and no prefix (i.e, it is
-   identical to tmpnam), the same data is used.  Each potential filename is
-   tested for an already-existing file of the same name, and no name of an
-   existing file will be returned.  When the cycle reaches its end
-   (12345ZZZ), NULL is returned.  */
-char *
-__stdio_gen_tempname (const char *dir, const char *pfx,
-                      int dir_search, size_t *lenptr,
-                      FILE **streamptr)
-{
-  int saverrno = errno;
-  static const char tmpdir[] = P_tmpdir;
-  static size_t indices[2];
-  size_t *idx;
-  static char buf[FILENAME_MAX];
-  static pid_t oldpid = (pid_t) 0;
-  pid_t pid = getpid ();
-  register size_t len, plen, dlen;
-
-  if (dir_search)
-    {
-      register const char *d = getenv ("TMPDIR");
-      if (d != NULL && !diraccess (d))
-        d = NULL;
-      if (d == NULL && dir != NULL && diraccess (dir))
-        d = dir;
-      if (d == NULL && diraccess (tmpdir))
-        d = tmpdir;
-      if (d == NULL && diraccess ("/tmp"))
-        d = "/tmp";
-      if (d == NULL)
-        {
-          errno = ENOENT;
-          return NULL;
-        }
-      dir = d;
-    }
-  else
-    dir = tmpdir;
-
-  dlen = strlen (dir);
-
-  /* Remove trailing slashes from the directory name.  */
-  while (dlen > 1 && dir[dlen - 1] == '/')
-    --dlen;
-
-  if (pfx != NULL && *pfx != '\0')
-    {
-      plen = strlen (pfx);
-      if (plen > 5)
-        plen = 5;
-    }
-  else
-    plen = 0;
-
-  if (dir != tmpdir && !strcmp (dir, tmpdir))
-    dir = tmpdir;
-  idx = &indices[(plen == 0 && dir == tmpdir) ? 1 : 0];
-
-  if (pid != oldpid)
-    {
-      oldpid = pid;
-      indices[0] = indices[1] = 0;
-    }
-
-  len = dlen + 1 + plen + 5 + 3;
-  for (; *idx < ((sizeof (letters) - 1) * (sizeof (letters) - 1) *
-                 (sizeof (letters) - 1));
-       ++*idx)
-    {
-      /* Construct a file name and see if it already exists.
-
-         We use a single counter in *IDX to cycle each of three
-         character positions through each of 62 possible letters.  */
-
-      if (sizeof (buf) < len)
-        return NULL;
-
-      sprintf (buf, "%.*s/%.*s%.5d%c%c%c",
-               (int) dlen, dir, (int) plen,
-               pfx, pid % 100000,
-               letters[*idx
-                       % (sizeof (letters) - 1)],
-               letters[(*idx / (sizeof (letters) - 1))
-                       % (sizeof (letters) - 1)],
-               letters[(*idx / ((sizeof (letters) - 1) *
-                                (sizeof (letters) - 1)))
-                       % (sizeof (letters) - 1)]
-              );
-
-      if (! buf || strlen (buf) != (int) len)
-        return NULL;
-
-      if (streamptr != NULL)
-        abort ();
-      else if (exists (buf))
-        continue;
-
-      /* If the file already existed we have continued the loop above,
-         so we only get here when we have a winning name to return.  */
-
-      errno = saverrno;
-
-      if (lenptr != NULL)
-        *lenptr = len + 1;
-      return buf;
-    }
-
-  /* We got out of the loop because we ran out of combinations to try.  */
-  errno = EEXIST;               /* ? */
-  return NULL;
-}
-
-#endif
--- a/liboctave/util/base-list.h	Fri Aug 01 09:06:21 2014 -0400
+++ b/liboctave/util/base-list.h	Fri Aug 01 12:10:05 2014 -0400
@@ -104,8 +104,6 @@
   // For backward compatibility.
   void append (const elt_type& s) { lst.push_back (s); }
 
-protected:
-
   octave_base_list (void) : lst () { }
 
   octave_base_list (const std::list<elt_type>& l) : lst (l) { }
--- a/liboctave/util/caseless-str.h	Fri Aug 01 09:06:21 2014 -0400
+++ b/liboctave/util/caseless-str.h	Fri Aug 01 12:10:05 2014 -0400
@@ -57,16 +57,16 @@
         char lp1 = std::tolower (*p1);
         char lp2 = std::tolower (*p2);
 
-        if ( lp1 > lp2 )
+        if (lp1 > lp2)
           return false;
-        if ( lp1 < lp2)
+        if (lp1 < lp2)
           return true;
 
         p1++;
         p2++;
       }
 
-    if ( length () >= s.length ())
+    if (length () >= s.length ())
       return false;
     else
       return true;
--- a/liboctave/util/data-conv.cc	Fri Aug 01 09:06:21 2014 -0400
+++ b/liboctave/util/data-conv.cc	Fri Aug 01 12:10:05 2014 -0400
@@ -409,8 +409,6 @@
 
           if (input_is_output)
             {
-              input_is_output = false;
-
               s1 = s.substr (1, pos-1);
 
               (*current_liboctave_warning_handler)
@@ -587,7 +585,7 @@
       if (len > 0) \
         { \
           OCTAVE_LOCAL_BUFFER (TYPE, ptr, len); \
-          std::streamsize n_bytes = size * len; \
+          std::streamsize n_bytes = size * static_cast<std::streamsize> (len); \
           stream.read (reinterpret_cast<char *> (ptr), n_bytes); \
           if (swap) \
             swap_bytes< size > (ptr, len); \
@@ -610,7 +608,7 @@
           OCTAVE_LOCAL_BUFFER (TYPE, ptr, len); \
           for (octave_idx_type i = 0; i < len; i++) \
             ptr[i] = static_cast <TYPE> (data[i]);         \
-          std::streamsize n_bytes = size * len; \
+          std::streamsize n_bytes = size * static_cast<std::streamsize> (len); \
           stream.write (reinterpret_cast<char *> (ptr), n_bytes); \
         } \
     } \
@@ -809,7 +807,7 @@
     case LS_FLOAT:
       {
         OCTAVE_LOCAL_BUFFER (float, ptr, len);
-        std::streamsize n_bytes = 4 * len;
+        std::streamsize n_bytes = 4 * static_cast<std::streamsize> (len);
         is.read (reinterpret_cast<char *> (ptr), n_bytes);
         do_float_format_conversion (ptr, len, fmt);
         for (octave_idx_type i = 0; i < len; i++)
@@ -867,7 +865,7 @@
 
     case LS_FLOAT: // No conversion necessary.
       {
-        std::streamsize n_bytes = 4 * len;
+        std::streamsize n_bytes = 4 * static_cast<std::streamsize> (len);
         is.read (reinterpret_cast<char *> (data), n_bytes);
         do_float_format_conversion (data, len, fmt);
       }
@@ -876,7 +874,7 @@
     case LS_DOUBLE:
       {
         OCTAVE_LOCAL_BUFFER (double, ptr, len);
-        std::streamsize n_bytes = 8 * len;
+        std::streamsize n_bytes = 8 * static_cast<std::streamsize> (len);
         is.read (reinterpret_cast<char *> (ptr), n_bytes);
         do_double_format_conversion (ptr, len, fmt);
         for (octave_idx_type i = 0; i < len; i++)
@@ -974,7 +972,7 @@
       {
         char tmp_type = static_cast<char> (type);
         os.write (&tmp_type, 1);
-        std::streamsize n_bytes = 4 * len;
+        std::streamsize n_bytes = 4 * static_cast<std::streamsize> (len);
         os.write (reinterpret_cast <const char *> (data), n_bytes);
       }
       break;
--- a/liboctave/util/str-vec.cc	Fri Aug 01 09:06:21 2014 -0400
+++ b/liboctave/util/str-vec.cc	Fri Aug 01 12:10:05 2014 -0400
@@ -250,14 +250,10 @@
     nc = 1;
 
   // Calculate the number of rows that will be in each column except
-  // possibly  for a short column on the right.
+  // possibly for a short column on the right.
 
   octave_idx_type nr = total_names / nc + (total_names % nc != 0);
 
-  // Recalculate columns based on rows.
-
-  nc = total_names / nr + (total_names % nr != 0);
-
   octave_idx_type count;
   for (octave_idx_type row = 0; row < nr; row++)
     {
--- a/m4/acinclude.m4	Fri Aug 01 09:06:21 2014 -0400
+++ b/m4/acinclude.m4	Fri Aug 01 12:10:05 2014 -0400
@@ -1810,6 +1810,58 @@
   fi
 ])
 dnl
+dnl Check for raw_fd_ostream API
+dnl
+AC_DEFUN([OCTAVE_LLVM_RAW_FD_OSTREAM_API], [
+  AC_CACHE_CHECK([check LLVM::raw_fd_ostream arg type is llvm::sys:fs],
+    [octave_cv_raw_fd_ostream_arg_is_llvm_sys_fs],
+    [AC_LANG_PUSH(C++)
+      AC_COMPILE_IFELSE(
+        [AC_LANG_PROGRAM([[
+          #include <llvm/Support/raw_os_ostream.h>
+          ]], [[
+          std::string str;
+          llvm::raw_fd_ostream fout ("", str, llvm::sys::fs::F_Binary);
+        ]])],
+        octave_cv_raw_fd_ostream_arg_is_llvm_sys_fs=yes,
+        octave_cv_raw_fd_ostream_arg_is_llvm_sys_fs=no)
+    AC_LANG_POP(C++)
+  ])
+  if test $octave_cv_raw_fd_ostream_arg_is_llvm_sys_fs = yes; then
+    AC_DEFINE(RAW_FD_OSTREAM_ARG_IS_LLVM_SYS_FS, 1,
+      [Define to 1 if LLVM::raw_fd_ostream arg type is llvm::sys:fs.])
+  fi
+])
+dnl
+dnl Check for legacy::PassManager API
+dnl
+AC_DEFUN([OCTAVE_LLVM_LEGACY_PASSMANAGER_API], [
+  AC_CACHE_CHECK([check for LLVM::legacy::PassManager],
+    [octave_cv_legacy_passmanager],
+    [AC_LANG_PUSH(C++)
+      save_LIBS="$LIBS"
+      LIBS="$LLVM_LIBS $LIBS"
+      AC_LINK_IFELSE(
+        [AC_LANG_PROGRAM([[
+          #include <llvm/IR/LegacyPassManager.h>
+          ]], [[
+          llvm::Module *module;
+          llvm::legacy::PassManager *module_pass_manager;
+          llvm::legacy::FunctionPassManager *pass_manager;      
+          module_pass_manager = new llvm::legacy::PassManager ();
+          pass_manager = new llvm::legacy::FunctionPassManager (module);
+        ]])],
+        octave_cv_legacy_passmanager=yes,
+        octave_cv_legacy_passmanager=no)
+      LIBS="$save_LIBS"
+    AC_LANG_POP(C++)
+  ])
+  if test $octave_cv_legacy_passmanager = yes; then
+    AC_DEFINE(LEGACY_PASSMANAGER, 1,
+      [Define to 1 if LLVM::legacy::PassManager exists.])
+  fi
+])
+dnl
 dnl Check for ar.
 dnl
 AC_DEFUN([OCTAVE_PROG_AR], [
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/deprecated/bicubic.m	Fri Aug 01 12:10:05 2014 -0400
@@ -0,0 +1,260 @@
+## Copyright (C) 2005-2013 Hoxide Ma
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {@var{zi} =} bicubic (@var{x}, @var{y}, @var{z}, @var{xi}, @var{yi}, @var{extrapval})
+##
+## @code{bicubic} is deprecated and will be removed in Octave version 4.6.
+## Use @code{interp2 (@dots{}, "spline")} for the equivalent functionality.
+##
+## Return a matrix @var{zi} corresponding to the bicubic
+## interpolations at @var{xi} and @var{yi} of the data supplied
+## as @var{x}, @var{y} and @var{z}.  Points outside the grid are set
+## to @var{extrapval}.
+##
+## See @url{http://wiki.woodpecker.org.cn/moin/Octave/Bicubic}
+## for further information.
+## @seealso{interp2}
+## @end deftypefn
+
+## Bicubic interpolation method.
+## Author: Hoxide Ma <hoxide_dirac@yahoo.com.cn>
+
+## Deprecated in version 4.2
+
+function zi = bicubic (x, y, z, xi, yi, extrapval, spline_alpha)
+
+  persistent warned = false;
+  if (! warned)
+    warned = true;
+    warning ("Octave:deprecated-function",
+             "bicubic is obsolete and will be removed from a future version of Octave, please use interp2 instead");
+  endif
+
+  if (nargin < 1 || nargin > 7)
+    print_usage ();
+  endif
+
+  if (nargin == 7 && isscalar (spline_alpha))
+    a = spline_alpha;
+  else
+    a = 0.5;
+  endif
+
+  if (nargin < 6)
+    extrapval = NaN;
+  endif
+
+  if (isa (x, "single") || isa (y, "single") || isa (z, "single")
+      || isa (xi, "single") || isa (yi, "single"))
+    myeps = eps ("single");
+  else
+    myeps = eps ();
+  endif
+
+  if (nargin <= 2)
+    ## bicubic (z) or bicubic (z, 2)
+    if (nargin == 1)
+      n = 1;
+    else
+      n = y;
+    endif
+    z = x;
+    x = [];
+    [rz, cz] = size (z);
+    s = linspace (1, cz, (cz-1) * pow2 (n) + 1);
+    t = linspace (1, rz, (rz-1) * pow2 (n) + 1);
+  elseif (nargin == 3)
+    if (! isvector (x) || ! isvector (y))
+      error ("bicubic: XI and YI must be vector");
+    endif
+    s = y;
+    t = z;
+    z = x;
+    [rz, cz] = size (z);
+  elseif (nargin == 5 || nargin == 6)
+    [rz, cz] = size (z) ;
+    if (isvector (x) && isvector (y))
+      if (rz != length (y) || cz != length (x))
+        error ("bicubic: length of X and Y must match the size of Z");
+      endif
+    elseif (size_equal (x, y) && size_equal (x, z))
+      x = x(1,:);
+      y = y(:,1);
+    else
+      error ("bicubic: X, Y and Z must be equal size matrices of same size");
+    endif
+
+    if (all (diff (x) < 0))
+      flipx = true;
+      x = fliplr (x);
+    elseif (all (diff (x) > 0))
+      flipx = false;
+    else
+      error ("bicubic:nonmonotonic", "bicubic: X values must be monotonic");
+    endif
+    if (all (diff (y) < 0))
+      flipy = true;
+      y = flipud (y);
+    elseif (all (diff (y) > 0))
+      flipy = false;
+    else
+      error ("bicubic:nonmonotonic", "bicubic: Y values must be monotonic");
+    endif
+
+    ## Mark values outside the lookup table.
+    xfirst_ind = find (xi < x(1));
+    xlast_ind  = find (xi > x(cz));
+    yfirst_ind = find (yi < y(1));
+    ylast_ind  = find (yi > y(rz));
+    ## Set value outside the table preliminary to min max index.
+    xi(xfirst_ind) = x(1);
+    xi(xlast_ind) = x(cz);
+    yi(yfirst_ind) = y(1);
+    yi(ylast_ind) = y(rz);
+
+    x = reshape (x, 1, cz);
+    x(cz) *= 1 + sign (x(cz)) * myeps;
+    if (x(cz) == 0)
+      x(cz) = myeps;
+    endif;
+    xi = reshape (xi, 1, length (xi));
+    [m, i] = sort ([x, xi]);
+    o = cumsum (i <= cz);
+    xidx = o(find (i > cz));
+
+    y = reshape (y, rz, 1);
+    y(rz) *= 1 + sign (y(rz)) * myeps;
+    if (y(rz) == 0)
+      y(rz) = myeps;
+    endif;
+    yi = reshape (yi, length (yi), 1);
+    [m, i] = sort ([y; yi]);
+    o = cumsum (i <= rz);
+    yidx = o([find(i > rz)]);
+
+    ## Set s and t used follow codes.
+    s = xidx + ((xi .- x(xidx)) ./ (x(xidx+1) .- x(xidx)));
+    t = yidx + ((yi  - y(yidx)) ./ (y(yidx+1)  - y(yidx)));
+
+    if (flipx)
+      s = fliplr (s);
+    endif
+    if (flipy)
+      t = flipud (t);
+    endif
+  else
+    print_usage ();
+  endif
+
+  if (rz < 3 || cz < 3)
+    error ("bicubic: Z at least a 3 by 3 matrices");
+  endif
+
+  inds = floor (s);
+  d = find (s == cz);
+  s = s - floor (s);
+  inds(d) = cz-1;
+  s(d) = 1.0;
+
+  d = [];
+  indt = floor (t);
+  d = find (t == rz);
+  t = t - floor (t);
+  indt(d) = rz-1;
+  t(d) = 1.0;
+  d = [];
+
+  p = zeros (size (z) + 2);
+  p(2:rz+1,2:cz+1) = z;
+  p(1,:) =    (6*(1-a))*p(2,:)    - 3*p(3,:)  + (6*a-2)*p(4,:);
+  p(rz+2,:) = (6*(1-a))*p(rz+1,:) - 3*p(rz,:) + (6*a-2)*p(rz-1,:);
+  p(:,1) =    (6*(1-a))*p(:,2)    - 3*p(:,3)  + (6*a-2)*p(:,4);
+  p(:,cz+2) = (6*(1-a))*p(:,cz+1) - 3*p(:,cz) + (6*a-2)*p(:,cz-1);
+
+  ## Calculte the C1(t) C2(t) C3(t) C4(t) and C1(s) C2(s) C3(s) C4(s).
+  t2 = t.*t;
+  t3 = t2.*t;
+
+  ct0 =    -a .* t3 +     (2 * a) .* t2 - a .* t ;      # -a G0
+  ct1 = (2-a) .* t3 +      (-3+a) .* t2          + 1 ;  # F0 - a G1
+  ct2 = (a-2) .* t3 + (-2 *a + 3) .* t2 + a .* t ;      # F1 + a G0
+  ct3 =     a .* t3 -           a .* t2;                # a G1
+  t = []; t2 = []; t3 = [];
+
+  s2 = s.*s;
+  s3 = s2.*s;
+
+  cs0 =    -a .* s3 +     (2 * a) .* s2 - a .*s ;      # -a G0
+  cs1 = (2-a) .* s3 +    (-3 + a) .* s2         + 1 ;  # F0 - a G1
+  cs2 = (a-2) .* s3 + (-2 *a + 3) .* s2 + a .*s ;      # F1 + a G0
+  cs3 =     a .* s3 -           a .* s2;               # a G1
+  s = []; s2 = []; s3 = [];
+
+  cs0 = cs0([1,1,1,1],:);
+  cs1 = cs1([1,1,1,1],:);
+  cs2 = cs2([1,1,1,1],:);
+  cs3 = cs3([1,1,1,1],:);
+
+  lent = length (ct0);
+  lens = columns (cs0);
+  zi = zeros (lent, lens);
+
+  for i = 1:lent
+    it = indt(i);
+    int = [it, it+1, it+2, it+3];
+    zi(i,:) = ([ct0(i),ct1(i),ct2(i),ct3(i)]
+              * (p(int,inds) .* cs0 + p(int,inds+1) .* cs1
+                 + p(int,inds+2) .* cs2 + p(int,inds+3) .* cs3));
+  endfor
+
+  ## Set points outside the table to extrapval.
+  if (! (isempty (xfirst_ind) && isempty (xlast_ind)))
+    zi(:, [xfirst_ind, xlast_ind]) = extrapval;
+  endif
+  if (! (isempty (yfirst_ind) && isempty (ylast_ind)))
+    zi([yfirst_ind; ylast_ind], :) = extrapval;
+  endif
+
+endfunction
+
+
+%!demo
+%! clf;
+%! colormap ("default");
+%! A = [13,-1,12;5,4,3;1,6,2];
+%! x = [0,1,4]+10;
+%! y = [-10,-9,-8];
+%! xi = linspace (min (x), max (x), 17);
+%! yi = linspace (min (y), max (y), 26)';
+%! mesh (xi, yi, bicubic (x,y,A,xi,yi));
+%! [x,y] = meshgrid (x,y);
+%! hold on; plot3 (x(:),y(:),A(:),"b*"); hold off;
+
+%!test
+%! x = linspace (1, -1, 10);
+%! [xx, yy] = meshgrid (x);
+%! z = cos (6 * xx) + sin (6 * yy);
+%! x = linspace (1, -1, 30);
+%! [xx2, yy2] = meshgrid (x);
+%! z1 = interp2 (xx, yy, z, xx2, yy2, "spline");
+%! z2 = interp2 (fliplr (xx), flipud (yy), fliplr (flipud(z)),
+%!               fliplr (xx2), flipud (yy2), "spline");
+%! z2 = fliplr (flipud (z2));
+%! assert (z1, z2, 100 * eps ())
+
--- a/scripts/deprecated/default_save_options.m	Fri Aug 01 09:06:21 2014 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,42 +0,0 @@
-## Copyright (C) 2013 Rik Wehbring
-##
-## This file is part of Octave.
-##
-## Octave is free software; you can redistribute it and/or modify it
-## under the terms of the GNU General Public License as published by
-## the Free Software Foundation; either version 3 of the License, or (at
-## your option) any later version.
-##
-## Octave is distributed in the hope that it will be useful, but
-## WITHOUT ANY WARRANTY; without even the implied warranty of
-## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-## General Public License for more details.
-##
-## You should have received a copy of the GNU General Public License
-## along with Octave; see the file COPYING.  If not, see
-## <http://www.gnu.org/licenses/>.
-
-## -*- texinfo -*-
-## @deftypefn  {Built-in Function} {@var{val} =} default_save_options ()
-## @deftypefnx {Built-in Function} {@var{old_val} =} default_save_options (@var{new_val})
-## @deftypefnx {Built-in Function} {} default_save_options (@var{new_val}, "local")
-## This function has been deprecated.  Use @code{@file{save_default_options}}
-## instead.
-## @seealso{save_default_options}
-## @end deftypefn
-
-## Deprecated in 3.8
-
-function retval = default_save_options (varargin)
-
-  persistent warned = false;
-  if (! warned)
-    warned = true;
-    warning ("Octave:deprecated-function",
-             "default_save_options is obsolete and will be removed from a future version of Octave, please use save_default_options instead");
-  endif
-
-  retval = save_default_options (varargin{:});
-
-endfunction
-
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/deprecated/find_dir_in_path.m	Fri Aug 01 12:10:05 2014 -0400
@@ -0,0 +1,40 @@
+## Copyright (C) 2013 John W. Eaton
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn  {Built-in Function} {} find_dir_in_path (@var{dir})
+## @deftypefnx {Built-in Function} {} find_dir_in_path (@var{dir}, "all")
+## This function has been deprecated.  Use @code{dir_in_loadpath} instead.
+## @seealso{dir_in_loadpath}
+## @end deftypefn
+
+## Deprecated in version 4.2
+
+function retval = find_dir_in_path (varargin)
+
+  persistent warned = false;
+  if (! warned)
+    warned = true;
+    warning ("Octave:deprecated-function",
+             "find_dir_in_path is obsolete and will be removed from a future version of Octave, please use dir_in_loadpath instead");
+  endif
+
+  retval = dir_in_loadpath (varargin{:});
+
+endfunction
+
--- a/scripts/deprecated/gen_doc_cache.m	Fri Aug 01 09:06:21 2014 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,39 +0,0 @@
-## Copyright (C) 2013 Rik Wehbring
-##
-## This file is part of Octave.
-##
-## Octave is free software; you can redistribute it and/or modify it
-## under the terms of the GNU General Public License as published by
-## the Free Software Foundation; either version 3 of the License, or (at
-## your option) any later version.
-##
-## Octave is distributed in the hope that it will be useful, but
-## WITHOUT ANY WARRANTY; without even the implied warranty of
-## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-## General Public License for more details.
-##
-## You should have received a copy of the GNU General Public License
-## along with Octave; see the file COPYING.  If not, see
-## <http://www.gnu.org/licenses/>.
-
-## -*- texinfo -*-
-## @deftypefn {Function File} {} gen_doc_cache (@var{out_file}, @var{directory})
-## This function has been deprecated.  Use @code{doc_cache_create} instead.
-## @seealso{doc_cache_create}
-## @end deftypefn
-
-## Deprecated in 3.8
-
-function gen_doc_cache (varargin)
-
-  persistent warned = false;
-  if (! warned)
-    warned = true;
-    warning ("Octave:deprecated-function",
-             "gen_doc_cache is obsolete and will be removed from a future version of Octave, please use doc_cache_create instead");
-  endif
-
-  doc_cache_create (varargin{:});
-
-endfunction
-
--- a/scripts/deprecated/interp1q.m	Fri Aug 01 09:06:21 2014 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,81 +0,0 @@
-## Copyright (C) 2008-2013 David Bateman
-##
-## This file is part of Octave.
-##
-## Octave is free software; you can redistribute it and/or modify it
-## under the terms of the GNU General Public License as published by
-## the Free Software Foundation; either version 3 of the License, or (at
-## your option) any later version.
-##
-## Octave is distributed in the hope that it will be useful, but
-## WITHOUT ANY WARRANTY; without even the implied warranty of
-## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-## General Public License for more details.
-##
-## You should have received a copy of the GNU General Public License
-## along with Octave; see the file COPYING.  If not, see
-## <http://www.gnu.org/licenses/>.
-
-## -*- texinfo -*-
-## @deftypefn {Function File} {@var{yi} =} interp1q (@var{x}, @var{y}, @var{xi})
-## One-dimensional linear interpolation without error checking.
-## Interpolates @var{y}, defined at the points @var{x}, at the points
-## @var{xi}.  The sample points @var{x} must be a strictly monotonically
-## increasing column vector.  If @var{y} is a matrix or an N-dimensional
-## array, the interpolation is performed on each column of @var{y}.  If
-## @var{y} is a vector, it must be a column vector of the same length as
-## @var{x}.
-##
-## Values of @var{xi} beyond the endpoints of the interpolation result
-## in NA being returned.
-##
-## Note that the error checking is only a significant portion of the
-## execution time of this @code{interp1} if the size of the input arguments
-## is relatively small.  Therefore, the benefit of using @code{interp1q}
-## is relatively small.
-## @seealso{interp1}
-## @end deftypefn
-
-function yi = interp1q (x, y, xi)
-
-  persistent warned = false;
-  if (! warned)
-    warned = true;
-    warning ("Octave:deprecated-function",
-             "interp1q is obsolete and will be removed from a future version of Octave; use interp1 instead");
-  endif
-
-  x = x(:);
-  nx = rows (x);
-  szy = size (y);
-  y = y(:,:);
-  [ny, nc] = size (y);
-  szx = size (xi);
-  xi = xi (:);
-  dy = diff (y);
-  dx = diff (x);
-  idx = lookup (x, xi, "lr");
-  s = (xi - x (idx)) ./ dx (idx);
-  yi = bsxfun (@times, s, dy(idx,:)) + y(idx,:);
-  range = xi < x(1) | !(xi <= x(nx));
-  yi(range,:) = NA;
-  if (length (szx) == 2 && any (szx == 1))
-    yi = reshape (yi, [max(szx), szy(2:end)]);
-  else
-    yi = reshape (yi, [szx, szy(2:end)]);
-  endif
-endfunction
-
-
-%!shared xp, yp, xi, yi
-%! xp = [0:2:10].';   yp = sin (2*pi*xp/5);
-%! xi = [-1; 0; 2.2; 4; 6.6; 10; 11];
-%! yi = interp1 (xp,yp,xi);
-%!assert (interp1q (xp,yp, [min(xp)-1; max(xp)+1]), [NA; NA]);
-%!assert (interp1q (xp,yp,xp), yp, 100*eps);
-%!assert (isempty (interp1q (xp,yp,[])));
-%!assert (interp1q (xp,yp,xi), yi);
-%!assert (interp1q (xp,[yp,yp],xi), [yi, yi]);
-%!assert (interp1q (xp,yp,[xi,xi]), [yi, yi]);
-%!assert (interp1q (xp,[yp,yp],[xi,xi]), cat (3, [yi, yi], [yi, yi]));
-
--- a/scripts/deprecated/isequalwithequalnans.m	Fri Aug 01 09:06:21 2014 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,50 +0,0 @@
-## Copyright (C) 2005-2013 William Poetra Yoga Hadisoeseno
-##
-## This file is part of Octave.
-##
-## Octave is free software; you can redistribute it and/or modify it
-## under the terms of the GNU General Public License as published by
-## the Free Software Foundation; either version 3 of the License, or (at
-## your option) any later version.
-##
-## Octave is distributed in the hope that it will be useful, but
-## WITHOUT ANY WARRANTY; without even the implied warranty of
-## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-## General Public License for more details.
-##
-## You should have received a copy of the GNU General Public License
-## along with Octave; see the file COPYING.  If not, see
-## <http://www.gnu.org/licenses/>.
-
-## -*- texinfo -*-
-## @deftypefn {Function File} {} isequalwithequalnans (@var{x1}, @var{x2}, @dots{})
-## This function has been deprecated.  Use @code{@file{isequaln}} instead.
-## @seealso{isequaln}
-## @end deftypefn
-
-## Deprecated in 3.8
-
-function retval = isequalwithequalnans (varargin)
-
-  persistent warned = false;
-  if (! warned)
-    warned = true;
-    warning ("Octave:deprecated-function",
-             "isequalwithequalnans is obsolete and will be removed from a future version of Octave, please use isequaln instead");
-  endif
-
-  retval = isequaln (varargin{:});
-
-endfunction
-
-
-## test for equality
-%!assert (isequalwithequalnans ({1,2,NaN,4},{1,2,NaN,4}), true)
-%!assert (isequalwithequalnans ([1,2,NaN,4],[1,2,NaN,4]), true)
-## test for inequality
-%!assert (isequalwithequalnans ([1,2,NaN,4],[1,NaN,3,4]), false)
-%!assert (isequalwithequalnans ([1,2,NaN,4],[1,2,3,4]), false)
-## test for equality (struct)
-%!assert (isequalwithequalnans (struct ('a',NaN,'b',2),struct ('a',NaN,'b',2),struct ('a',NaN,'b',2)), true)
-%!assert (isequalwithequalnans (1,2,1), false)
-
--- a/scripts/deprecated/java_convert_matrix.m	Fri Aug 01 09:06:21 2014 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,48 +0,0 @@
-## Copyright (C) 2012-2013 Rik Wehbring
-##
-## This file is part of Octave.
-##
-## Octave is free software; you can redistribute it and/or modify it
-## under the terms of the GNU General Public License as published by
-## the Free Software Foundation; either version 3 of the License, or (at
-## your option) any later version.
-##
-## Octave is distributed in the hope that it will be useful, but
-## WITHOUT ANY WARRANTY; without even the implied warranty of
-## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-## General Public License for more details.
-##
-## You should have received a copy of the GNU General Public License
-## along with Octave; see the file COPYING.  If not, see
-## <http://www.gnu.org/licenses/>.
-
-## -*- texinfo -*-
-## @deftypefn  {Built-in Function} {@var{val} =} java_convert_matrix ()
-## @deftypefnx {Built-in Function} {@var{old_val} =} java_convert_matrix (@var{new_val})
-## @deftypefnx {Built-in Function} {} java_convert_matrix (@var{new_val}, "local")
-## Query or set the internal variable that controls whether Java arrays are
-## automatically converted to Octave matrices.  The default value is false.
-## 
-## When called from inside a function with the @qcode{"local"} option, the
-## variable is changed locally for the function and any subroutines it calls.
-##  The original variable value is restored when exiting the function.
-## @seealso{java_matrix_autoconversion, java_unsigned_conversion, java_debug}
-## @end deftypefn
-
-function old_val = java_convert_matrix (varargin)
-
-  persistent warned = false;
-  if (! warned)
-    warned = true;
-    warning ("Octave:deprecated-function",
-             "java_convert_matrix is obsolete and will be removed from a future version of Octave; use java_matrix_autoconversion instead");
-  endif
-
-  if (nargin > 2)
-    print_usage ();
-  endif
-
-  old_val = java_matrix_autoconversion (varargin{:});
-
-endfunction
-
--- a/scripts/deprecated/java_debug.m	Fri Aug 01 09:06:21 2014 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,49 +0,0 @@
-## Copyright (C) 2012-2013 Rik Wehbring
-##
-## This file is part of Octave.
-##
-## Octave is free software; you can redistribute it and/or modify it
-## under the terms of the GNU General Public License as published by
-## the Free Software Foundation; either version 3 of the License, or (at
-## your option) any later version.
-##
-## Octave is distributed in the hope that it will be useful, but
-## WITHOUT ANY WARRANTY; without even the implied warranty of
-## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-## General Public License for more details.
-##
-## You should have received a copy of the GNU General Public License
-## along with Octave; see the file COPYING.  If not, see
-## <http://www.gnu.org/licenses/>.
-
-## -*- texinfo -*-
-## @deftypefn  {Built-in Function} {@var{val} =} java_debug ()
-## @deftypefnx {Built-in Function} {@var{old_val} =} java_debug (@var{new_val})
-## @deftypefnx {Built-in Function} {} java_debug (@var{new_val}, "local")
-## Query or set the internal variable that determines whether extra debugging
-## information regarding the initialization of the JVM and any Java exceptions
-## is printed.
-## 
-## When called from inside a function with the @qcode{"local"} option, the
-## variable is changed locally for the function and any subroutines it calls.
-##  The original variable value is restored when exiting the function.
-## @seealso{debug_java, java_convert_matrix, java_unsigned_conversion}
-## @end deftypefn
-
-function old_val = java_debug (varargin)
-
-  persistent warned = false;
-  if (! warned)
-    warned = true;
-    warning ("Octave:deprecated-function",
-             "java_debug is obsolete and will be removed from a future version of Octave; use debug_java instead");
-  endif
-
-  if (nargin > 2)
-    print_usage ();
-  endif
-
-  old_val = debug_java (varargin{:});
-
-endfunction
-
--- a/scripts/deprecated/java_invoke.m	Fri Aug 01 09:06:21 2014 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,57 +0,0 @@
-## Copyright (C) 2007, 2013 Michael Goffioul
-##
-## This file is part of Octave.
-##
-## Octave is free software; you can redistribute it and/or modify it
-## under the terms of the GNU General Public License as published by
-## the Free Software Foundation; either version 3 of the License, or (at
-## your option) any later version.
-##
-## Octave is distributed in the hope that it will be useful, but
-## WITHOUT ANY WARRANTY; without even the implied warranty of
-## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-## General Public License for more details.
-##
-## You should have received a copy of the GNU General Public License
-## along with Octave; see the file COPYING.  If not, see
-## <http://www.gnu.org/licenses/>.
-
-## -*- texinfo -*-
-## @deftypefn  {Built-in Function} {@var{ret} =} java_invoke (@var{obj}, @var{methodname})
-## @deftypefnx {Built-in Function} {@var{ret} =} java_invoke (@var{obj}, @var{methodname}, @var{arg1}, @dots{})
-## Invoke the method @var{methodname} on the Java object @var{obj} with the
-## arguments @var{arg1}, @dots{}  For static methods, @var{obj} can be a
-## string representing the fully qualified name of the corresponding class. 
-## The function returns the result of the method invocation.
-## 
-## When @var{obj} is a regular Java object, structure-like indexing can be
-## used as a shortcut syntax.  For instance, the two following statements are
-## equivalent
-## 
-## @example
-## @group
-##   ret = java_invoke (x, "method1", 1.0, "a string")
-##   ret = x.method1 (1.0, "a string")
-## @end group
-## @end example
-## 
-## @seealso{javaMethod, javaObject}
-## @end deftypefn
-
-function retval = java_invoke (obj, methodname, varargin)
-
-  persistent warned = false;
-  if (! warned)
-    warned = true;
-    warning ("Octave:deprecated-function",
-             "java_invoke is obsolete and will be removed from a future version of Octave, please use javaMethod instead");
-  endif
-  
-  if (nargin < 2)
-    print_usage ();
-  endif
-
-  retval = javaMethod (methodname, obj, varargin{:});
-
-endfunction
-
--- a/scripts/deprecated/java_new.m	Fri Aug 01 09:06:21 2014 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,51 +0,0 @@
-## Copyright (C) 2012-2013 Rik Wehbring
-##
-## This file is part of Octave.
-##
-## Octave is free software; you can redistribute it and/or modify it
-## under the terms of the GNU General Public License as published by
-## the Free Software Foundation; either version 3 of the License, or (at
-## your option) any later version.
-##
-## Octave is distributed in the hope that it will be useful, but
-## WITHOUT ANY WARRANTY; without even the implied warranty of
-## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-## General Public License for more details.
-##
-## You should have received a copy of the GNU General Public License
-## along with Octave; see the file COPYING.  If not, see
-## <http://www.gnu.org/licenses/>.
-
-## -*- texinfo -*-
-## @deftypefn  {Loadable Function} {@var{obj} =} java_new (@var{name})
-## @deftypefnx {Loadable Function} {@var{obj} =} java_new (@var{name}, @var{arg1}, @dots{})
-## Create a Java object of class @var{name}, by calling the class constructor
-## with the arguments @var{arg1}, @dots{}
-## 
-## @example
-## @group
-##   x = java_new ("java.lang.StringBuffer")
-##   x = java_new ("java.lang.StringBuffer", "Initial string")
-## @end group
-## @end example
-## 
-## @seealso{javaObject, javaMethod}
-## @end deftypefn
-
-function retval = java_new (varargin)
-
-  persistent warned = false;
-  if (! warned)
-    warned = true;
-    warning ("Octave:deprecated-function",
-             "java_new is obsolete and will be removed from a future version of Octave; please use javaObject instead");
-  endif
-
-  if (nargin < 1)
-    print_usage ();
-  endif
-
-  retval = javaObject (varargin{:});
-
-endfunction
-
--- a/scripts/deprecated/java_unsigned_conversion.m	Fri Aug 01 09:06:21 2014 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,50 +0,0 @@
-## Copyright (C) 2012-2013 Rik Wehbring
-##
-## This file is part of Octave.
-##
-## Octave is free software; you can redistribute it and/or modify it
-## under the terms of the GNU General Public License as published by
-## the Free Software Foundation; either version 3 of the License, or (at
-## your option) any later version.
-##
-## Octave is distributed in the hope that it will be useful, but
-## WITHOUT ANY WARRANTY; without even the implied warranty of
-## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-## General Public License for more details.
-##
-## You should have received a copy of the GNU General Public License
-## along with Octave; see the file COPYING.  If not, see
-## <http://www.gnu.org/licenses/>.
-
-## -*- texinfo -*-
-## @deftypefn  {Built-in Function} {@var{val} =} java_unsigned_conversion ()
-## @deftypefnx {Built-in Function} {@var{old_val} =} java_unsigned_conversion (@var{new_val})
-## @deftypefnx {Built-in Function} {} java_unsigned_conversion (@var{new_val}, "local")
-## Query or set the internal variable that controls how integer classes are
-## converted when Java matrix autoconversion is enabled.  When enabled, Java
-## arrays of class Byte or Integer are converted to matrices of class uint8 or
-## uint32 respectively.
-## 
-## When called from inside a function with the @qcode{"local"} option, the
-## variable is changed locally for the function and any subroutines it calls.
-##  The original variable value is restored when exiting the function.
-## @seealso{java_unsigned_autoconversion, java_convert_matrix, debug_java}
-## @end deftypefn
-
-function old_val = java_unsigned_conversion (varargin)
-
-  persistent warned = false;
-  if (! warned)
-    warned = true;
-    warning ("Octave:deprecated-function",
-             "java_unsigned_conversion is obsolete and will be removed from a future version of Octave; use java_unsigned_autoconversion instead");
-  endif
-
-  if (nargin > 2)
-    print_usage ();
-  endif
-
-  old_val = java_unsigned_autoconversion (varargin{:});
-
-endfunction
-
--- a/scripts/deprecated/javafields.m	Fri Aug 01 09:06:21 2014 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,54 +0,0 @@
-## Copyright (C) 2007, 2013 Michael Goffioul
-##
-## This file is part of Octave.
-##
-## Octave is free software; you can redistribute it and/or modify it
-## under the terms of the GNU General Public License as published by
-## the Free Software Foundation; either version 3 of the License, or (at
-## your option) any later version.
-##
-## Octave is distributed in the hope that it will be useful, but
-## WITHOUT ANY WARRANTY; without even the implied warranty of
-## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-## General Public License for more details.
-##
-## You should have received a copy of the GNU General Public License
-## along with Octave; see the file COPYING.  If not, see
-## <http://www.gnu.org/licenses/>.
-
-## -*- texinfo -*-
-## @deftypefn  {Function File} {} javafields (@var{javaobj})
-## @deftypefnx {Function File} {} javafields ("@var{classname}")
-## @deftypefnx {Function File} {@var{fld_names} =} javafields (@dots{})
-## Return the fields of a Java object or Java class in the form of a cell 
-## array of strings.  If no output is requested, print the result
-## to the standard output.
-## @seealso{fieldnames, methods, javaObject}
-## @end deftypefn
-
-function fld_names = javafields (javaobj)
-
-  persistent warned = false;
-  if (! warned)
-    warned = true;
-    warning ("Octave:deprecated-function",
-             "javafields is obsolete and will be removed from a future version of Octave, please use fieldnames instead");
-  endif
-  
-  if (nargin != 1)
-    print_usage ();
-  endif
-  
-  c_methods = javaMethod ("getFields", "org.octave.ClassHelper", javaobj);
-  method_list = ostrsplit (c_methods, ';');
-
-  if (nargout == 0)
-    if (! isempty (method_list))
-      disp (method_list);
-    endif
-  else
-    fld_names = cellstr (method_list);
-  endif
-
-endfunction
-
--- a/scripts/deprecated/javamethods.m	Fri Aug 01 09:06:21 2014 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,54 +0,0 @@
-## Copyright (C) 2007, 2013 Michael Goffioul
-##
-## This file is part of Octave.
-##
-## Octave is free software; you can redistribute it and/or modify it
-## under the terms of the GNU General Public License as published by
-## the Free Software Foundation; either version 3 of the License, or (at
-## your option) any later version.
-##
-## Octave is distributed in the hope that it will be useful, but
-## WITHOUT ANY WARRANTY; without even the implied warranty of
-## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-## General Public License for more details.
-##
-## You should have received a copy of the GNU General Public License
-## along with Octave; see the file COPYING.  If not, see
-## <http://www.gnu.org/licenses/>.
-
-## -*- texinfo -*-
-## @deftypefn  {Function File} {} javamethods (@var{javaobj})
-## @deftypefnx {Function File} {} javamethods ("@var{classname}")
-## @deftypefnx {Function File} {@var{mtd_names} =} javamethods (@dots{})
-## Return the methods of a Java object or Java class in the form of a cell 
-## array of strings.  If no output is requested, print the result to the
-## standard output.
-## @seealso{methods, fieldnames, javaMethod, javaObject}
-## @end deftypefn
-
-function mtd_names = javamethods (classname)
-
-  persistent warned = false;
-  if (! warned)
-    warned = true;
-    warning ("Octave:deprecated-function",
-             "javamethods is obsolete and will be removed from a future version of Octave, please use methods instead");
-  endif
-  
-  if (nargin != 1)
-    print_usage ();
-  endif
-
-  cls_methods = javaMethod ("getMethods", "org.octave.ClassHelper", classname);
-  method_list = ostrsplit (cls_methods, ';');
-
-  if (nargout == 0)
-    if (! isempty (method_list))
-      disp (method_list);
-    endif
-  else
-    mtd_names = cellstr (method_list);
-  endif
-
-endfunction
-
--- a/scripts/deprecated/module.mk	Fri Aug 01 09:06:21 2014 -0400
+++ b/scripts/deprecated/module.mk	Fri Aug 01 12:10:05 2014 -0400
@@ -1,21 +1,10 @@
 FCN_FILE_DIRS += deprecated
 
 deprecated_FCN_FILES = \
-  deprecated/default_save_options.m \
-  deprecated/gen_doc_cache.m \
-  deprecated/interp1q.m \
-  deprecated/isequalwithequalnans.m \
+  deprecated/bicubic.m \
+  deprecated/find_dir_in_path.m \
   deprecated/isstr.m \
-  deprecated/java_convert_matrix.m \
-  deprecated/java_debug.m \
-  deprecated/java_invoke.m \
-  deprecated/java_new.m \
-  deprecated/java_unsigned_conversion.m \
-  deprecated/javafields.m \
-  deprecated/javamethods.m \
-  deprecated/re_read_readline_init_file.m \
-  deprecated/read_readline_init_file.m \
-  deprecated/saving_history.m
+  deprecated/nfields.m
 
 FCN_FILES += $(deprecated_FCN_FILES)
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/deprecated/nfields.m	Fri Aug 01 12:10:05 2014 -0400
@@ -0,0 +1,44 @@
+## Copyright (C) 2014 Rik Wehbring
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} nfields (@var{s})
+## Return the number of fields of the structure @var{s}.
+##
+## @strong{Warning:} @code{nfields} is scheduled for removal in version 4.6.
+## Use @code{numfields} instead.
+## @seealso{numfields, fieldnames}
+## @end deftypefn
+
+function retval = nfields (varargin)
+
+  persistent warned = false;
+  if (! warned)
+    warned = true;
+    warning ("Octave:deprecated-function",
+             "nfields is obsolete and will be removed from a future version of Octave; please use numfields instead");
+  endif
+
+  if (nargin < 1)
+    print_usage ();
+  endif
+
+  retval = numfields (varargin{:});
+
+endfunction
+
--- a/scripts/deprecated/re_read_readline_init_file.m	Fri Aug 01 09:06:21 2014 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,40 +0,0 @@
-## Copyright (C) 2013 Rik Wehbring
-##
-## This file is part of Octave.
-##
-## Octave is free software; you can redistribute it and/or modify it
-## under the terms of the GNU General Public License as published by
-## the Free Software Foundation; either version 3 of the License, or (at
-## your option) any later version.
-##
-## Octave is distributed in the hope that it will be useful, but
-## WITHOUT ANY WARRANTY; without even the implied warranty of
-## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-## General Public License for more details.
-##
-## You should have received a copy of the GNU General Public License
-## along with Octave; see the file COPYING.  If not, see
-## <http://www.gnu.org/licenses/>.
-
-## -*- texinfo -*-
-## @deftypefn {Built-in Function} {} re_read_readline_init_file (@var{file})
-## This function has been deprecated.  Use
-## @code{@file{readline_re_read_init_file}} instead.
-## @seealso{readline_read_init_file}
-## @end deftypefn
-
-## Deprecated in 3.8
-
-function re_read_readline_init_file (varargin)
-
-  persistent warned = false;
-  if (! warned)
-    warned = true;
-    warning ("Octave:deprecated-function",
-             "re_read_readline_init_file is obsolete and will be removed from a future version of Octave, please use readline_re_read_init_file instead");
-  endif
-
-  readline_re_read_init_file (varargin{:});
-
-endfunction
-
--- a/scripts/deprecated/read_readline_init_file.m	Fri Aug 01 09:06:21 2014 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,40 +0,0 @@
-## Copyright (C) 2013 Rik Wehbring
-##
-## This file is part of Octave.
-##
-## Octave is free software; you can redistribute it and/or modify it
-## under the terms of the GNU General Public License as published by
-## the Free Software Foundation; either version 3 of the License, or (at
-## your option) any later version.
-##
-## Octave is distributed in the hope that it will be useful, but
-## WITHOUT ANY WARRANTY; without even the implied warranty of
-## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-## General Public License for more details.
-##
-## You should have received a copy of the GNU General Public License
-## along with Octave; see the file COPYING.  If not, see
-## <http://www.gnu.org/licenses/>.
-
-## -*- texinfo -*-
-## @deftypefn {Built-in Function} {} read_readline_init_file (@var{file})
-## This function has been deprecated.  Use
-## @code{@file{readline_read_init_file}} instead.
-## @seealso{readline_read_init_file}
-## @end deftypefn
-
-## Deprecated in 3.8
-
-function read_readline_init_file (varargin)
-
-  persistent warned = false;
-  if (! warned)
-    warned = true;
-    warning ("Octave:deprecated-function",
-             "read_readline_init_file is obsolete and will be removed from a future version of Octave, please use readline_read_init_file instead");
-  endif
-
-  readline_read_init_file (varargin{:});
-
-endfunction
-
--- a/scripts/deprecated/saving_history.m	Fri Aug 01 09:06:21 2014 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,41 +0,0 @@
-## Copyright (C) 2013 Rik Wehbring
-##
-## This file is part of Octave.
-##
-## Octave is free software; you can redistribute it and/or modify it
-## under the terms of the GNU General Public License as published by
-## the Free Software Foundation; either version 3 of the License, or (at
-## your option) any later version.
-##
-## Octave is distributed in the hope that it will be useful, but
-## WITHOUT ANY WARRANTY; without even the implied warranty of
-## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-## General Public License for more details.
-##
-## You should have received a copy of the GNU General Public License
-## along with Octave; see the file COPYING.  If not, see
-## <http://www.gnu.org/licenses/>.
-
-## -*- texinfo -*-
-## @deftypefn  {Built-in Function} {@var{val} =} saving_history ()
-## @deftypefnx {Built-in Function} {@var{old_val} =} saving_history (@var{new_val})
-## @deftypefnx {Built-in Function} {} saving_history (@var{new_val}, "local")
-## This function has been deprecated.  Use @code{@file{history_save}} instead.
-## @seealso{history_save}
-## @end deftypefn
-
-## Deprecated in 3.8
-
-function retval = saving_history (varargin)
-
-  persistent warned = false;
-  if (! warned)
-    warned = true;
-    warning ("Octave:deprecated-function",
-             "saving_history is obsolete and will be removed from a future version of Octave, please use history_save instead");
-  endif
-
-  retval = save_default_options (varargin{:});
-
-endfunction
-
--- a/scripts/general/bicubic.m	Fri Aug 01 09:06:21 2014 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,248 +0,0 @@
-## Copyright (C) 2005-2013 Hoxide Ma
-##
-## This file is part of Octave.
-##
-## Octave is free software; you can redistribute it and/or modify it
-## under the terms of the GNU General Public License as published by
-## the Free Software Foundation; either version 3 of the License, or (at
-## your option) any later version.
-##
-## Octave is distributed in the hope that it will be useful, but
-## WITHOUT ANY WARRANTY; without even the implied warranty of
-## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-## General Public License for more details.
-##
-## You should have received a copy of the GNU General Public License
-## along with Octave; see the file COPYING.  If not, see
-## <http://www.gnu.org/licenses/>.
-
-## -*- texinfo -*-
-## @deftypefn {Function File} {@var{zi} =} bicubic (@var{x}, @var{y}, @var{z}, @var{xi}, @var{yi}, @var{extrapval})
-##
-## Return a matrix @var{zi} corresponding to the bicubic
-## interpolations at @var{xi} and @var{yi} of the data supplied
-## as @var{x}, @var{y} and @var{z}.  Points outside the grid are set
-## to @var{extrapval}.
-##
-## See @url{http://wiki.woodpecker.org.cn/moin/Octave/Bicubic}
-## for further information.
-## @seealso{interp2}
-## @end deftypefn
-
-## Bicubic interpolation method.
-## Author: Hoxide Ma <hoxide_dirac@yahoo.com.cn>
-
-function zi = bicubic (x, y, z, xi, yi, extrapval, spline_alpha)
-
-  if (nargin < 1 || nargin > 7)
-    print_usage ();
-  endif
-
-  if (nargin == 7 && isscalar (spline_alpha))
-    a = spline_alpha;
-  else
-    a = 0.5;
-  endif
-
-  if (nargin < 6)
-    extrapval = NaN;
-  endif
-
-  if (isa (x, "single") || isa (y, "single") || isa (z, "single")
-      || isa (xi, "single") || isa (yi, "single"))
-    myeps = eps ("single");
-  else
-    myeps = eps ();
-  endif
-
-  if (nargin <= 2)
-    ## bicubic (z) or bicubic (z, 2)
-    if (nargin == 1)
-      n = 1;
-    else
-      n = y;
-    endif
-    z = x;
-    x = [];
-    [rz, cz] = size (z);
-    s = linspace (1, cz, (cz-1) * pow2 (n) + 1);
-    t = linspace (1, rz, (rz-1) * pow2 (n) + 1);
-  elseif (nargin == 3)
-    if (! isvector (x) || ! isvector (y))
-      error ("bicubic: XI and YI must be vector");
-    endif
-    s = y;
-    t = z;
-    z = x;
-    [rz, cz] = size (z);
-  elseif (nargin == 5 || nargin == 6)
-    [rz, cz] = size (z) ;
-    if (isvector (x) && isvector (y))
-      if (rz != length (y) || cz != length (x))
-        error ("bicubic: length of X and Y must match the size of Z");
-      endif
-    elseif (size_equal (x, y) && size_equal (x, z))
-      x = x(1,:);
-      y = y(:,1);
-    else
-      error ("bicubic: X, Y and Z must be equal size matrices of same size");
-    endif
-
-    if (all (diff (x) < 0))
-      flipx = true;
-      x = fliplr (x);
-    elseif (all (diff (x) > 0))
-      flipx = false;
-    else
-      error ("bicubic:nonmonotonic", "bicubic: X values must be monotonic");
-    endif
-    if (all (diff (y) < 0))
-      flipy = true;
-      y = flipud (y);
-    elseif (all (diff (y) > 0))
-      flipy = false;
-    else
-      error ("bicubic:nonmonotonic", "bicubic: Y values must be monotonic");
-    endif
-
-    ## Mark values outside the lookup table.
-    xfirst_ind = find (xi < x(1));
-    xlast_ind  = find (xi > x(cz));
-    yfirst_ind = find (yi < y(1));
-    ylast_ind  = find (yi > y(rz));
-    ## Set value outside the table preliminary to min max index.
-    xi(xfirst_ind) = x(1);
-    xi(xlast_ind) = x(cz);
-    yi(yfirst_ind) = y(1);
-    yi(ylast_ind) = y(rz);
-
-    x = reshape (x, 1, cz);
-    x(cz) *= 1 + sign (x(cz)) * myeps;
-    if (x(cz) == 0)
-      x(cz) = myeps;
-    endif;
-    xi = reshape (xi, 1, length (xi));
-    [m, i] = sort ([x, xi]);
-    o = cumsum (i <= cz);
-    xidx = o(find (i > cz));
-
-    y = reshape (y, rz, 1);
-    y(rz) *= 1 + sign (y(rz)) * myeps;
-    if (y(rz) == 0)
-      y(rz) = myeps;
-    endif;
-    yi = reshape (yi, length (yi), 1);
-    [m, i] = sort ([y; yi]);
-    o = cumsum (i <= rz);
-    yidx = o([find(i > rz)]);
-
-    ## Set s and t used follow codes.
-    s = xidx + ((xi .- x(xidx)) ./ (x(xidx+1) .- x(xidx)));
-    t = yidx + ((yi  - y(yidx)) ./ (y(yidx+1)  - y(yidx)));
-
-    if (flipx)
-      s = fliplr (s);
-    endif
-    if (flipy)
-      t = flipud (t);
-    endif
-  else
-    print_usage ();
-  endif
-
-  if (rz < 3 || cz < 3)
-    error ("bicubic: Z at least a 3 by 3 matrices");
-  endif
-
-  inds = floor (s);
-  d = find (s == cz);
-  s = s - floor (s);
-  inds(d) = cz-1;
-  s(d) = 1.0;
-
-  d = [];
-  indt = floor (t);
-  d = find (t == rz);
-  t = t - floor (t);
-  indt(d) = rz-1;
-  t(d) = 1.0;
-  d = [];
-
-  p = zeros (size (z) + 2);
-  p(2:rz+1,2:cz+1) = z;
-  p(1,:) =    (6*(1-a))*p(2,:)    - 3*p(3,:)  + (6*a-2)*p(4,:);
-  p(rz+2,:) = (6*(1-a))*p(rz+1,:) - 3*p(rz,:) + (6*a-2)*p(rz-1,:);
-  p(:,1) =    (6*(1-a))*p(:,2)    - 3*p(:,3)  + (6*a-2)*p(:,4);
-  p(:,cz+2) = (6*(1-a))*p(:,cz+1) - 3*p(:,cz) + (6*a-2)*p(:,cz-1);
-
-  ## Calculte the C1(t) C2(t) C3(t) C4(t) and C1(s) C2(s) C3(s) C4(s).
-  t2 = t.*t;
-  t3 = t2.*t;
-
-  ct0 =    -a .* t3 +     (2 * a) .* t2 - a .* t ;      # -a G0
-  ct1 = (2-a) .* t3 +      (-3+a) .* t2          + 1 ;  # F0 - a G1
-  ct2 = (a-2) .* t3 + (-2 *a + 3) .* t2 + a .* t ;      # F1 + a G0
-  ct3 =     a .* t3 -           a .* t2;                # a G1
-  t = []; t2 = []; t3 = [];
-
-  s2 = s.*s;
-  s3 = s2.*s;
-
-  cs0 =    -a .* s3 +     (2 * a) .* s2 - a .*s ;      # -a G0
-  cs1 = (2-a) .* s3 +    (-3 + a) .* s2         + 1 ;  # F0 - a G1
-  cs2 = (a-2) .* s3 + (-2 *a + 3) .* s2 + a .*s ;      # F1 + a G0
-  cs3 =     a .* s3 -           a .* s2;               # a G1
-  s = []; s2 = []; s3 = [];
-
-  cs0 = cs0([1,1,1,1],:);
-  cs1 = cs1([1,1,1,1],:);
-  cs2 = cs2([1,1,1,1],:);
-  cs3 = cs3([1,1,1,1],:);
-
-  lent = length (ct0);
-  lens = columns (cs0);
-  zi = zeros (lent, lens);
-
-  for i = 1:lent
-    it = indt(i);
-    int = [it, it+1, it+2, it+3];
-    zi(i,:) = ([ct0(i),ct1(i),ct2(i),ct3(i)]
-              * (p(int,inds) .* cs0 + p(int,inds+1) .* cs1
-                 + p(int,inds+2) .* cs2 + p(int,inds+3) .* cs3));
-  endfor
-
-  ## Set points outside the table to extrapval.
-  if (! (isempty (xfirst_ind) && isempty (xlast_ind)))
-    zi(:, [xfirst_ind, xlast_ind]) = extrapval;
-  endif
-  if (! (isempty (yfirst_ind) && isempty (ylast_ind)))
-    zi([yfirst_ind; ylast_ind], :) = extrapval;
-  endif
-
-endfunction
-
-
-%!demo
-%! clf;
-%! colormap ("default");
-%! A = [13,-1,12;5,4,3;1,6,2];
-%! x = [0,1,4]+10;
-%! y = [-10,-9,-8];
-%! xi = linspace (min (x), max (x), 17);
-%! yi = linspace (min (y), max (y), 26)';
-%! mesh (xi, yi, bicubic (x,y,A,xi,yi));
-%! [x,y] = meshgrid (x,y);
-%! hold on; plot3 (x(:),y(:),A(:),"b*"); hold off;
-
-%!test
-%! x = linspace (1, -1, 10);
-%! [xx, yy] = meshgrid (x);
-%! z = cos (6 * xx) + sin (6 * yy);
-%! x = linspace (1, -1, 30);
-%! [xx2, yy2] = meshgrid (x);
-%! z1 = interp2 (xx, yy, z, xx2, yy2, "cubic");
-%! z2 = interp2 (fliplr (xx), flipud (yy), fliplr (flipud(z)),
-%!               fliplr (xx2), flipud (yy2), "cubic");
-%! z2 = fliplr (flipud (z2));
-%! assert (z1, z2, 100 * eps ())
-
--- a/scripts/general/cell2mat.m	Fri Aug 01 09:06:21 2014 -0400
+++ b/scripts/general/cell2mat.m	Fri Aug 01 12:10:05 2014 -0400
@@ -32,15 +32,14 @@
     print_usage ();
   endif
 
-  if (! iscell (c))
-    error ("cell2mat: C is not a cell array");
-  endif
-
   nb = numel (c);
 
   if (nb == 0)
     m = [];
   else
+    if (! iscell (c))
+      error ("cell2mat: C must be a cell array");
+    endif
 
     ## Check first for valid matrix types
     valid = cellfun ("isnumeric", c);
@@ -94,6 +93,7 @@
 %! cell2mat (C)
 
 %!assert (cell2mat ({}), []);
+%!assert (cell2mat ([]), []);
 %!test
 %! C = {[1], [2 3 4]; [5; 9], [6 7 8; 10 11 12]};
 %! D = C; D(:,:,2) = C;
@@ -115,7 +115,7 @@
 
 %!error cell2mat ()
 %!error cell2mat (1,2)
-%!error <C is not a cell array> cell2mat ([1,2])
+%!error <C must be a cell array> cell2mat ([1,2])
 %!error <mixed cells, structs, and matrices> cell2mat ({[1], struct()})
 %!error <mixed cells, structs, and matrices> cell2mat ({[1], {1}})
 %!error <mixed cells, structs, and matrices> cell2mat ({struct(), {1}})
--- a/scripts/general/cplxpair.m	Fri Aug 01 09:06:21 2014 -0400
+++ b/scripts/general/cplxpair.m	Fri Aug 01 12:10:05 2014 -0400
@@ -23,7 +23,7 @@
 ## Sort the numbers @var{z} into complex conjugate pairs ordered by
 ## increasing real part.  Place the negative imaginary complex number
 ## first within each pair.  Place all the real numbers (those with
-## @code{abs (imag (@var{z}) / @var{z}) < @var{tol})}) after the
+## @code{abs (imag (@var{z}) / @var{z}) < @var{tol}}) after the
 ## complex pairs.
 ##
 ## If @var{tol} is unspecified the default value is 100*@code{eps}.
--- a/scripts/general/del2.m	Fri Aug 01 09:06:21 2014 -0400
+++ b/scripts/general/del2.m	Fri Aug 01 12:10:05 2014 -0400
@@ -158,3 +158,164 @@
   D = D ./ nd;
 endfunction
 
+
+## 3x3 constant test
+%!test
+%! a = ones (3,3);
+%! b = del2 (a);
+%! assert (b(:,1), [0.00;0.00;0.00]);
+%! assert (b(:,2), [0.00;0.00;0.00]);
+%! assert (b(:,3), [0.00;0.00;0.00]);
+
+## 3x3 planar test
+%!test
+%! a = [1,2,3;2,3,4;3,4,5];
+%! b = del2 (a);
+%! assert (b(:,1), [0.00;0.00;0.00]);
+%! assert (b(:,2), [0.00;0.00;0.00]);
+%! assert (b(:,3), [0.00;0.00;0.00]);
+
+## 3x3 corner test
+%!test
+%! a = zeros (3,3);
+%! a(1,1) = 1.0;
+%! b = 2*del2 (a);
+%! assert (b(:,1), [1.00;0.50;0.50]);
+%! assert (b(:,2), [0.50;0.00;0.00]);
+%! assert (b(:,3), [0.50;0.00;0.00]);
+%! assert (b, flipud (2*del2 (flipud (a))));
+%! assert (b, fliplr (2*del2 (fliplr (a))));
+%! assert (b, flipud (fliplr (2*del2 (fliplr (flipud (a))))));
+
+## 3x3 boundary test
+%!test
+%! a = zeros (3,3);
+%! a(2,1)=1.0;
+%! b = 2*del2 (a);
+%! assert (b(:,1), [-1.00;-0.50;-1.00]);
+%! assert (b(:,2), [0.00;0.50;0.00]);
+%! assert (b(:,3), [0.00;0.50;0.00]);
+%! assert (b, flipud (2*del2 (flipud (a))));
+%! assert (b, fliplr (2*del2 (fliplr (a))));
+%! assert (b, flipud (fliplr (2*del2 (fliplr (flipud (a))))));
+
+## 3x3 center test
+%!test
+%! a = zeros (3,3);
+%! a(2,2) = 1.0;
+%! b = del2 (a);
+%! assert (b(:,1), [0.00;-0.50;0.00]);
+%! assert (b(:,2), [-0.50;-1.00;-0.50]);
+%! assert (b(:,3), [0.00;-0.50;0.00]);
+
+## 4x4 constant test
+%!test
+%! a = ones (4,4);
+%! b = del2 (a);
+%! assert (b(:,1), [0.00;0.00;0.00;0.00]);
+%! assert (b(:,2), [0.00;0.00;0.00;0.00]);
+%! assert (b(:,3), [0.00;0.00;0.00;0.00]);
+%! assert (b(:,4), [0.00;0.00;0.00;0.00]);
+
+## 4x4 planar test
+%!test
+%! a = [1,2,3,4;2,3,4,5;3,4,5,6;4,5,6,7];
+%! b = del2 (a);
+%! assert (b(:,1), [0.00;0.00;0.00;0.00]);
+%! assert (b(:,2), [0.00;0.00;0.00;0.00]);
+%! assert (b(:,3), [0.00;0.00;0.00;0.00]);
+%! assert (b(:,4), [0.00;0.00;0.00;0.00]);
+
+## 4x4 corner test
+%!test
+%! a = zeros (4,4);
+%! a(1,1) = 1.0;
+%! b = 2*del2 (a);
+%! assert (b(:,1), [2.00;0.50;0.00;-0.50]);
+%! assert (b(:,2), [0.50;0.00;0.00;0.00]);
+%! assert (b(:,3), [0.00;0.00;0.00;0.00]);
+%! assert (b(:,4), [-0.50;0.00;0.00;0.00]);
+%! assert (b, flipud (2*del2 (flipud (a))));
+%! assert (b, fliplr (2*del2 (fliplr (a))));
+%! assert (b, flipud (fliplr (2*del2 (fliplr (flipud (a))))));
+
+## 9x9 center test
+%!test
+%! a = zeros (9,9);
+%! a(5,5) = 1.0;
+%! b = 2*del2 (a);
+%! assert (b(:,1), [0.00;0.00;0.00;0.00;0.00;0.00;0.00;0.00;0.00]);
+%! assert (b(:,2), [0.00;0.00;0.00;0.00;0.00;0.00;0.00;0.00;0.00]);
+%! assert (b(:,3), [0.00;0.00;0.00;0.00;0.00;0.00;0.00;0.00;0.00]);
+%! assert (b(:,4), [0.00;0.00;0.00;0.00;0.50;0.00;0.00;0.00;0.00]);
+%! assert (b(:,5), [0.00;0.00;0.00;0.50;-2.00;0.50;0.00;0.00;0.00]);
+%! assert (b(:,6), b(:,4));
+%! assert (b(:,7), b(:,3));
+%! assert (b(:,8), b(:,2));
+%! assert (b(:,9), b(:,1));
+
+## 9x9 boundary test
+%!test
+%! a = zeros (9,9);
+%! a(1,5) = 1.0;
+%! b = 2*del2 (a);
+%! assert (b(1,:), [0.00,0.00,0.00,0.50,0.00,0.50,0.00,0.00,0.00]);
+%! assert (b(2,:), [0.00,0.00,0.00,0.00,0.50,0.00,0.00,0.00,0.00]);
+%! assert (b(3:9,:), zeros (7,9));
+%! a(1,5) = 0.0;
+%! a(5,1) = 1.0;
+%! b = 2*del2 (a);
+%! assert (b(:,1), [0.00;0.00;0.00;0.50;0.00;0.50;0.00;0.00;0.00]);
+%! assert (b(:,2), [0.00;0.00;0.00;0.00;0.50;0.00;0.00;0.00;0.00]);
+%! assert (b(:,3:9), zeros (9,7));
+
+## 9x9 dh center test
+%!test
+%! a = zeros (9,9);
+%! a(5,5) = 1.0;
+%! b = 8*del2 (a,2);
+%! assert (b(:,1:3), zeros (9,3));
+%! assert (b(:,4), [0.00;0.00;0.00;0.00;0.50;0.00;0.00;0.00;0.00]);
+%! assert (b(:,5), [0.00;0.00;0.00;0.50;-2.00;0.50;0.00;0.00;0.00]);
+%! assert (b(:,6), b(:,4));
+%! assert (b(:,7:9), zeros (9,3));
+
+## 9x9 dx test
+%!test
+%! a = zeros (9,9);
+%! a(5,5) = 1.0;
+%! b = 4*del2 (a,2,1);
+%! assert (b(1:3,:), zeros (3,9));
+%! assert (b(4,:), [0.00;0.00;0.00;0.00;1.00;0.00;0.00;0.00;0.00]');
+%! assert (b(5,:), [0.00;0.00;0.00;0.25;-2.5;0.25;0.00;0.00;0.00]');
+%! assert (b(6,:), b(4,:));
+%! assert (b(7:9,:), zeros (3,9));
+
+## 9x9 dy test
+%!test
+%! a = zeros (9,9);
+%! a(5,5) = 1.0;
+%! b = 4*del2 (a,1,2);
+%! assert (b(:,1:3), zeros (9,3));
+%! assert (b(:,4), [0.00;0.00;0.00;0.00;1.00;0.00;0.00;0.00;0.00]);
+%! assert (b(:,5), [0.00;0.00;0.00;0.25;-2.5;0.25;0.00;0.00;0.00]);
+%! assert (b(:,6), b(:,4));
+%! assert (b(:,7:9), zeros (9,3));
+
+## 3D test
+%!test
+%! a = zeros (9,9,9);
+%! a(5,5,5) = 1.0;
+%! b = 8*3*del2 (a,2);
+%! assert (b(:,:,1:3), zeros (9,9,3));
+%! assert (b(:,1:3,:), zeros (9,3,9));
+%! assert (b(1:3,:,:), zeros (3,9,9));
+%! assert (b(4:5,4,4), [0.0,0.0]');
+%! assert (b(5,5,4), 1.00);
+%! assert (b(4,4,5), 0.00);
+%! assert (b(5,4,5), 1.00);
+%! assert (b(5,5,5),-6.00);
+%! assert (b, flipdim (b,1));
+%! assert (b, flipdim (b,2));
+%! assert (b, flipdim (b,3));
+
--- a/scripts/general/fieldnames.m	Fri Aug 01 09:06:21 2014 -0400
+++ b/scripts/general/fieldnames.m	Fri Aug 01 12:10:05 2014 -0400
@@ -33,7 +33,7 @@
 ## When the input is a Java object @var{javaobj} or Java classname
 ## @var{jclassname} the name are the public data elements of the object or
 ## class.
-## @seealso{nfields, isfield, orderfields, struct, methods}
+## @seealso{numfields, isfield, orderfields, struct, methods}
 ## @end deftypefn
 
 function names = fieldnames (obj)
@@ -70,9 +70,13 @@
 %! s = struct ();
 %! assert (fieldnames (s), cell (0, 1));
 
-## test Java classname
-%!testif HAVE_JAVA 
+## test Java classname by passing classname
+%!testif HAVE_JAVA
 %! names = fieldnames ("java.lang.Double");
-%! search = strfind (names, "java.lang.Double.MAX_VALUE");
-%! assert (! isempty ([search{:}]));
+%! assert (any (strcmp (names, "MAX_VALUE")));
 
+## test Java classname by passing java object
+%!testif HAVE_JAVA
+%! names = fieldnames (javaObject ("java.lang.Double", 10));
+%! assert (any (strcmp (names, "MAX_VALUE")));
+
--- a/scripts/general/flipdim.m	Fri Aug 01 09:06:21 2014 -0400
+++ b/scripts/general/flipdim.m	Fri Aug 01 12:10:05 2014 -0400
@@ -62,7 +62,7 @@
 %!assert (flipdim ([1,2;3,4], 2), [2,1;4,3])
 %!assert (flipdim ([1,2;3,4], 3), [1,2;3,4])
 
-## FIXME -- we need tests for multidimensional arrays.
+## FIXME: We need tests for multidimensional arrays.
 
 %!error flipdim ()
 %!error flipdim (1, 2, 3)
--- a/scripts/general/interp1.m	Fri Aug 01 09:06:21 2014 -0400
+++ b/scripts/general/interp1.m	Fri Aug 01 12:10:05 2014 -0400
@@ -29,28 +29,29 @@
 ## One-dimensional interpolation.
 ##
 ## Interpolate input data to determine the value of @var{yi} at the points
-## @var{xi}.  If not specified, @var{x} is taken to be the indices of @var{y}.
-## If @var{y} is a matrix or an N-dimensional array, the interpolation is
-## performed on each column of @var{y}.
+## @var{xi}.  If not specified, @var{x} is taken to be the indices of @var{y}
+## (@code{1:length (@var{y})}).  If @var{y} is a matrix or an N-dimensional
+## array, the interpolation is performed on each column of @var{y}.
 ##
-## Method is one of:
+## The interpolation @var{method} is one of:
 ##
 ## @table @asis
 ## @item @qcode{"nearest"}
-## Return the nearest neighbor
+## Return the nearest neighbor.
 ##
-## @item @qcode{"linear"}
-## Linear interpolation from nearest neighbors
+## @item @qcode{"linear"} (default)
+## Linear interpolation from nearest neighbors.
 ##
 ## @item @qcode{"pchip"}
-## Piecewise cubic Hermite interpolating polynomial
+## Piecewise cubic Hermite interpolating polynomial---shape-preserving
+## interpolation with smooth first derivative.
 ##
 ## @item @qcode{"cubic"}
-## Cubic interpolation (same as @code{pchip})
+## Cubic interpolation (same as @qcode{"pchip"}).
 ##
 ## @item @qcode{"spline"}
 ## Cubic spline interpolation---smooth first and second derivatives
-## throughout the curve
+## throughout the curve.
 ## @end table
 ##
 ## Adding '*' to the start of any method above forces @code{interp1}
@@ -61,7 +62,7 @@
 ## If @var{extrap} is the string @qcode{"extrap"}, then extrapolate values
 ## beyond the endpoints using the current @var{method}.  If @var{extrap} is a
 ## number, then replace values beyond the endpoints with that number.  When
-## unspecified, @var{extrap} defaults to NA.
+## unspecified, @var{extrap} defaults to @code{NA}.
 ##
 ## If the string argument @qcode{"pp"} is specified, then @var{xi} should not
 ## be supplied and @code{interp1} returns a piecewise polynomial object.  This 
@@ -91,16 +92,16 @@
 ## xp = [0:10];
 ## yp = sin (2*pi*xp/5);
 ## lin = interp1 (xp, yp, xf);
+## near = interp1 (xp, yp, xf, "nearest");
+## pch = interp1 (xp, yp, xf, "pchip");
 ## spl = interp1 (xp, yp, xf, "spline");
-## cub = interp1 (xp, yp, xf, "cubic");
-## near = interp1 (xp, yp, xf, "nearest");
-## plot (xf, yf, "r", xf, lin, "g", xf, spl, "b",
-##       xf, cub, "c", xf, near, "m", xp, yp, "r*");
-## legend ("original", "linear", "spline", "cubic", "nearest");
+## plot (xf,yf,"r", xf,near,"g", xf,lin,"b", xf,pch,"c", xf,spl,"m", 
+##       xp,yp,"r*");
+## legend ("original", "nearest", "linear", "pchip", "spline");
 ## @end group
 ## @end example
 ##
-## @seealso{interpft, interp2, interp3, interpn}
+## @seealso{pchip, spline, interpft, interp2, interp3, interpn}
 ## @end deftypefn
 
 ## Author: Paul Kienzle
@@ -130,17 +131,18 @@
       arg = varargin{i};
       if (ischar (arg))
         arg = tolower (arg);
-        if (strcmp ("extrap", arg))
-          extrap = "extrap";
-        elseif (strcmp ("pp", arg))
-          ispp = true;
-        elseif (strcmp (arg, "right") || strcmp (arg, "-right"))
-          rightcontinuous = true;
-        elseif (strcmp (arg, "left") || strcmp (arg, "-left"))
-          rightcontinuous = false;
-        else
-          method = arg;
-        endif
+        switch (arg)
+          case "extrap"
+            extrap = "extrap";
+          case "pp"
+            ispp = true;
+          case {"right", "-right"}
+            rightcontinuous = true;
+          case {"left", "-left"}
+            rightcontinuous = false;
+          otherwise
+            method = arg;
+        endswitch
       else
         if (firstnumeric)
           xi = arg;
@@ -177,7 +179,7 @@
 
   ## determine sizes
   if (nx < 2 || ny < 2)
-    error ("interp1: table too short");
+    error ("interp1: minimum of 2 points required in each dimension");
   endif
 
   ## check whether x is sorted; sort if not.
@@ -193,10 +195,8 @@
     else
       rightcontinuous = true;
     endif
-  endif
-
-  if ((rightcontinuous && (x(end) < x(1)))
-      || (! rightcontinuous && (x(end) > x(1))))
+  elseif ((rightcontinuous && (x(end) < x(1)))
+          || (! rightcontinuous && (x(end) > x(1))))
     ## Switch between left-continuous and right-continuous
     x = flipud (x);
     y = flipud (y);
@@ -215,7 +215,8 @@
           warning ("interp1: multiple discontinuities at the same X value");
         endif
       else
-        error ("interp1: discontinuities not supported for method '%s'", method);
+        error ("interp1: discontinuities not supported for method '%s'",
+                                                                   method);
       endif
     endif
   endif
@@ -238,6 +239,7 @@
       pp = mkpp ([x(1), x(1)+[0.5:(nx-1)]*dx, x(nx)],
                  shiftdim (y, 1), szy(2:end));
       pp.orient = "first";
+
       if (ispp)
         yi = pp;
       else
@@ -245,7 +247,6 @@
       endif
 
     case "linear"
-
       xx = x;
       nxx = nx;
       yy = y;
@@ -323,13 +324,13 @@
 
   endswitch
 
-  if (! ispp && ! ischar (extrap))
+  if (! ispp && isnumeric (extrap))
     ## determine which values are out of range and set them to extrap,
     ## unless extrap == "extrap".
     minx = min (x(1), x(nx));
     maxx = max (x(1), x(nx));
 
-    outliers = xi < minx | ! (xi <= maxx); # this even catches NaNs
+    outliers = xi < minx | ! (xi <= maxx);  # this even catches NaNs
     if (size_equal (outliers, yi))
       yi(outliers) = extrap;
       yi = reshape (yi, szx);
@@ -347,12 +348,13 @@
 %! clf;
 %! xf = 0:0.05:10;  yf = sin (2*pi*xf/5);
 %! xp = 0:10;       yp = sin (2*pi*xp/5);
-%! lin = interp1 (xp,yp,xf, "linear");
-%! spl = interp1 (xp,yp,xf, "spline");
-%! cub = interp1 (xp,yp,xf, "pchip");
-%! near= interp1 (xp,yp,xf, "nearest");
-%! plot (xf,yf,"r",xf,near,"g",xf,lin,"b",xf,cub,"c",xf,spl,"m",xp,yp,"r*");
-%! legend ("original", "nearest", "linear", "pchip", "spline");
+%! lin = interp1 (xp,yp,xf, 'linear');
+%! spl = interp1 (xp,yp,xf, 'spline');
+%! pch = interp1 (xp,yp,xf, 'pchip');
+%! near= interp1 (xp,yp,xf, 'nearest');
+%! plot (xf,yf,'r',xf,near,'g',xf,lin,'b',xf,pch,'c',xf,spl,'m',xp,yp,'r*');
+%! legend ('original', 'nearest', 'linear', 'pchip', 'spline');
+%! title ('Interpolation of continuous function sin (x) w/various methods');
 %! %--------------------------------------------------------
 %! % confirm that interpolated function matches the original
 
@@ -360,36 +362,50 @@
 %! clf;
 %! xf = 0:0.05:10;  yf = sin (2*pi*xf/5);
 %! xp = 0:10;       yp = sin (2*pi*xp/5);
-%! lin = interp1 (xp,yp,xf, "*linear");
-%! spl = interp1 (xp,yp,xf, "*spline");
-%! cub = interp1 (xp,yp,xf, "*cubic");
-%! near= interp1 (xp,yp,xf, "*nearest");
-%! plot (xf,yf,"r",xf,near,"g",xf,lin,"b",xf,cub,"c",xf,spl,"m",xp,yp,"r*");
-%! legend ("*original", "*nearest", "*linear", "*cubic", "*spline");
+%! lin = interp1 (xp,yp,xf, '*linear');
+%! spl = interp1 (xp,yp,xf, '*spline');
+%! pch = interp1 (xp,yp,xf, '*pchip');
+%! near= interp1 (xp,yp,xf, '*nearest');
+%! plot (xf,yf,'r',xf,near,'g',xf,lin,'b',xf,pch,'c',xf,spl,'m',xp,yp,'r*');
+%! legend ('*original', '*nearest', '*linear', '*pchip', '*spline');
+%! title ('Interpolation of continuous function sin (x) w/various *methods');
 %! %--------------------------------------------------------
 %! % confirm that interpolated function matches the original
 
 %!demo
 %! clf;
+%! fstep = @(x) x > 1;
+%! xf = 0:0.05:2;  yf = fstep (xf);
+%! xp = linspace (0,2,10);  yp = fstep (xp);
+%! pch = interp1 (xp,yp,xf, 'pchip');
+%! spl = interp1 (xp,yp,xf, 'spline');
+%! plot (xf,yf,'r',xf,pch,'b',xf,spl,'m',xp,yp,'r*');
+%! title ({'Interpolation of step function with discontinuity at x==1', ...
+%!         'Note: "pchip" is shape-preserving, "spline" (continuous 1st, 2nd derivatives) is not'});
+%! legend ('original', 'pchip', 'spline');
+
+%!demo
+%! clf;
 %! t = 0 : 0.3 : pi; dt = t(2)-t(1);
 %! n = length (t); k = 100; dti = dt*n/k;
 %! ti = t(1) + [0 : k-1]*dti;
 %! y = sin (4*t + 0.3) .* cos (3*t - 0.1);
-%! ddyc = diff (diff (interp1 (t,y,ti, "cubic")) ./dti)./dti;
-%! ddys = diff (diff (interp1 (t,y,ti, "spline"))./dti)./dti;
-%! ddyp = diff (diff (interp1 (t,y,ti, "pchip")) ./dti)./dti;
-%! plot (ti(2:end-1),ddyc,'g+', ti(2:end-1),ddys,'b*', ti(2:end-1),ddyp,'c^');
-%! legend ("cubic", "spline", "pchip");
-%! title ("Second derivative of interpolated 'sin (4*t + 0.3) .* cos (3*t - 0.1)'");
+%! ddys = diff (diff (interp1 (t,y,ti, 'spline'))./dti)./dti;
+%! ddyp = diff (diff (interp1 (t,y,ti, 'pchip')) ./dti)./dti;
+%! ddyc = diff (diff (interp1 (t,y,ti, 'cubic')) ./dti)./dti;
+%! plot (ti(2:end-1),ddys,'b*', ti(2:end-1),ddyp,'c^', ti(2:end-1),ddyc,'g+');
+%! title ({'Second derivative of interpolated "sin (4*t + 0.3) .* cos (3*t - 0.1)"', ...
+%!         'Note: "spline" has continous 2nd derivative, others do not'});
+%! legend ('spline', 'pchip', 'cubic');
 
 %!demo
 %! clf;
 %! xf = 0:0.05:10;                yf = sin (2*pi*xf/5) - (xf >= 5);
 %! xp = [0:.5:4.5,4.99,5:.5:10];  yp = sin (2*pi*xp/5) - (xp >= 5);
-%! lin = interp1 (xp,yp,xf, "linear");
-%! near= interp1 (xp,yp,xf, "nearest");
-%! plot (xf,yf,"r", xf,near,"g", xf,lin,"b", xp,yp,"r*");
-%! legend ("original", "nearest", "linear");
+%! lin = interp1 (xp,yp,xf, 'linear');
+%! near= interp1 (xp,yp,xf, 'nearest');
+%! plot (xf,yf,'r', xf,near,'g', xf,lin,'b', xp,yp,'r*');
+%! legend ('original', 'nearest', 'linear');
 %! %--------------------------------------------------------
 %! % confirm that interpolated function matches the original
 
@@ -410,7 +426,7 @@
 %! %--------------------------------------------------------
 %! % red curve is left-continuous and blue is right-continuous at x = 2
 
-##FIXME: add test for n-d arguments here
+##FIXME: add test for N-d arguments here
 
 ## For each type of interpolated test, confirm that the interpolated
 ## value at the knots match the values at the knots.  Points away
@@ -638,12 +654,12 @@
 %% Test input validation
 %!error interp1 ()
 %!error interp1 (1,2,3,4,5,6,7)
-%!error <table too short> interp1 (1,1,1, "linear")
-%!error <table too short> interp1 (1,1,1, "*nearest")
-%!error <table too short> interp1 (1,1,1, "*linear")
+%!error <minimum of 2 points required> interp1 (1,1,1, "linear")
+%!error <minimum of 2 points required> interp1 (1,1,1, "*nearest")
+%!error <minimum of 2 points required> interp1 (1,1,1, "*linear")
 %!warning <multiple discontinuities> interp1 ([1 1 1 2], [1 2 3 4], 1);
 %!error <discontinuities not supported> interp1 ([1 1],[1 2],1, "pchip")
 %!error <discontinuities not supported> interp1 ([1 1],[1 2],1, "cubic")
 %!error <discontinuities not supported> interp1 ([1 1],[1 2],1, "spline")
-%!error <invalid method> interp1 (1:2,1:2,1, "bogus")
+%!error <invalid method 'bogus'> interp1 (1:2,1:2,1, "bogus")
 
--- a/scripts/general/interp2.m	Fri Aug 01 09:06:21 2014 -0400
+++ b/scripts/general/interp2.m	Fri Aug 01 12:10:05 2014 -0400
@@ -19,63 +19,63 @@
 
 ## -*- texinfo -*-
 ## @deftypefn  {Function File} {@var{zi} =} interp2 (@var{x}, @var{y}, @var{z}, @var{xi}, @var{yi})
-## @deftypefnx {Function File} {@var{zi} =} interp2 (@var{Z}, @var{xi}, @var{yi})
-## @deftypefnx {Function File} {@var{zi} =} interp2 (@var{Z}, @var{n})
+## @deftypefnx {Function File} {@var{zi} =} interp2 (@var{z}, @var{xi}, @var{yi})
+## @deftypefnx {Function File} {@var{zi} =} interp2 (@var{z}, @var{n})
+## @deftypefnx {Function File} {@var{zi} =} interp2 (@var{z})
 ## @deftypefnx {Function File} {@var{zi} =} interp2 (@dots{}, @var{method})
-## @deftypefnx {Function File} {@var{zi} =} interp2 (@dots{}, @var{method}, @var{extrapval})
+## @deftypefnx {Function File} {@var{zi} =} interp2 (@dots{}, @var{method}, @var{extrap})
+##
+## Two-dimensional interpolation.
 ##
-## Two-dimensional interpolation.  @var{x}, @var{y} and @var{z} describe a
-## surface function.  If @var{x} and @var{y} are vectors their length
-## must correspondent to the size of @var{z}.  @var{x} and @var{y} must be
-## monotonic.  If they are matrices they must have the @code{meshgrid}
-## format.
-##
-## @table @code
-## @item interp2 (@var{x}, @var{y}, @var{Z}, @var{xi}, @var{yi}, @dots{})
-## Returns a matrix corresponding to the points described by the
-## matrices @var{xi}, @var{yi}.
+## Interpolate reference data @var{x}, @var{y}, @var{z} to determine @var{zi}
+## at the coordinates @var{xi}, @var{yi}.  The reference data @var{x}, @var{y}
+## can be matrices, as returned by @code{meshgrid}, in which case the sizes of
+## @var{x}, @var{y}, and @var{z} must be equal.  If @var{x}, @var{y} are
+## vectors describing a grid then @code{length (@var{x}) == columns (@var{z})}
+## and @code{length (@var{y}) == rows (@var{z})}.  In either case the input
+## data must be strictly monotonic.
 ##
-## If the last argument is a string, the interpolation method can
-## be specified.  The method can be @qcode{"linear"}, @qcode{"nearest"} or
-## @qcode{"cubic"}.  If it is omitted @qcode{"linear"} interpolation is
-## assumed.
+## If called without @var{x}, @var{y}, and just a single reference data matrix
+## @var{z}, the 2-D region
+## @code{@var{x} = 1:columns (@var{z}), @var{y} = 1:rows (@var{z})} is assumed.
+## This saves memory if the grid is regular and the distance between points is
+## not important.
 ##
-## @item interp2 (@var{z}, @var{xi}, @var{yi})
-## Assumes @code{@var{x} = 1:rows (@var{z})} and @code{@var{y} =
-## 1:columns (@var{z})}
+## If called with a single reference data matrix @var{z} and a refinement
+## value @var{n}, then perform interpolation over a grid where each original
+## interval has been recursively subdivided @var{n} times.  This results in
+## @code{2^@var{n}-1} additional points for every interval in the original
+## grid.  If @var{n} is omitted a value of 1 is used.  As an example, the
+## interval [0,1] with @code{@var{n}==2} results in a refined interval with
+## points at [0, 1/4, 1/2, 3/4, 1].
 ##
-## @item interp2 (@var{z}, @var{n})
-## Interleaves the matrix @var{z} n-times.  If @var{n} is omitted a value
-## of @code{@var{n} = 1} is assumed.
-## @end table
-##
-## The variable @var{method} defines the method to use for the
-## interpolation.  It can take one of the following values
+## The interpolation @var{method} is one of:
 ##
 ## @table @asis
 ## @item @qcode{"nearest"}
 ## Return the nearest neighbor.
 ##
-## @item @qcode{"linear"}
+## @item @qcode{"linear"} (default)
 ## Linear interpolation from nearest neighbors.
 ##
 ## @item @qcode{"pchip"}
-## Piecewise cubic Hermite interpolating polynomial.
+## Piecewise cubic Hermite interpolating polynomial---shape-preserving
+## interpolation with smooth first derivative.
 ##
 ## @item @qcode{"cubic"}
-## Cubic interpolation from four nearest neighbors.
+## Cubic interpolation (same as @qcode{"pchip"}).
 ##
 ## @item @qcode{"spline"}
 ## Cubic spline interpolation---smooth first and second derivatives
 ## throughout the curve.
 ## @end table
 ##
-## If a scalar value @var{extrapval} is defined as the final value, then
-## values outside the mesh as set to this value.  Note that in this case
-## @var{method} must be defined as well.  If @var{extrapval} is not
-## defined then NA is assumed.
-##
-## @seealso{interp1}
+## If @var{extrap} is the string @qcode{"extrap"}, then extrapolate values
+## beyond the endpoints using the current @var{method}.  If @var{extrap} is a
+## number, then replace values beyond the endpoints with that number.  When
+## unspecified, @var{extrap} defaults to @code{NA}.  Note that if @var{extrap}
+## is used, @var{method} must be specified as well.
+## @seealso{interp1, interp3, interpn, meshgrid}
 ## @end deftypefn
 
 ## Author:      Kai Habel <kai.habel@gmx.de>
@@ -94,10 +94,14 @@
 ##       "meshgridded") to be consistent with the help message
 ##       above and for compatibility.
 
+## FIXME: Need better input validation.
+##        E.g, interp2 (1,1,1) => A(I): index out of bounds
+
 function ZI = interp2 (varargin)
+
   Z = X = Y = XI = YI = n = [];
   method = "linear";
-  extrapval = NA;
+  extrap = NA;
 
   switch (nargin)
     case 1
@@ -120,36 +124,41 @@
       if (ischar (varargin{4}))
         [Z, XI, YI, method] = deal (varargin{:});
       else
-        [Z, n, method, extrapval] = deal (varargin{:});
+        [Z, n, method, extrap] = deal (varargin{:});
       endif
     case 5
       if (ischar (varargin{4}))
-        [Z, XI, YI, method, extrapval] = deal (varargin{:});
+        [Z, XI, YI, method, extrap] = deal (varargin{:});
       else
         [X, Y, Z, XI, YI] = deal (varargin{:});
       endif
     case 6
         [X, Y, Z, XI, YI, method] = deal (varargin{:});
     case 7
-        [X, Y, Z, XI, YI, method, extrapval] = deal (varargin{:});
+        [X, Y, Z, XI, YI, method, extrap] = deal (varargin{:});
     otherwise
       print_usage ();
   endswitch
 
-  ## Type checking.
-  if (!ismatrix (Z))
-    error ("interp2: Z must be a matrix");
+  ## Type checking
+  if (! (ismatrix (Z) && ndims (Z) == 2))
+    error ("interp2: Z must be a 2-D matrix");
   endif
-  if (!isempty (n) && !isscalar (n))
-    error ("interp2: N must be a scalar");
+  if (! isempty (n) && ! (isscalar (n) && n >= 0 && n == fix (n)))
+    error ("interp2: N must be an integer >= 0");
   endif
-  if (!ischar (method))
+  if (! ischar (method))
     error ("interp2: METHOD must be a string");
+  elseif (method(1) == "*")
+    warning ("interp2: ignoring unsupported '*' flag to METHOD");
+    method(1) = [];
   endif
-  if (ischar (extrapval) || strcmp (extrapval, "extrap"))
-    extrapval = [];
-  elseif (!isscalar (extrapval))
-    error ("interp2: EXTRAPVAL must be a scalar");
+  if (isnumeric (extrap) && isscalar (extrap))
+    ## Typical case
+  elseif (strcmp (extrap, "extrap"))
+    extrap = [];
+  else
+    error ('interp2: EXTRAP must be a numeric scalar or "extrap"');
   endif
 
   ## Define X, Y, XI, YI if needed
@@ -171,21 +180,32 @@
     error ("interp2: XI, YI must be numeric");
   endif
 
-
-  if (strcmp (method, "linear") || strcmp (method, "nearest") ...
-      || strcmp (method, "pchip"))
+  if (isvector (X) && isvector (Y))
+    X = X(:);  Y = Y(:);
+  elseif (size_equal (X, Y))
+    X = X(1,:).';  Y = Y(:,1);
+  else
+    error ("interp2: X and Y must be matrices of equal size");
+  endif
+  if (columns (Z) != length (X) || rows (Z) != length (Y))
+    error ("interp2: X and Y size must match the dimensions of Z");
+  endif
+  dx = diff (X);
+  if (all (dx < 0))
+    X = flipud (X);
+    Z = fliplr (Z); 
+  elseif (any (dx <= 0))
+    error ("interp2: X must be strictly monotonic");
+  endif
+  dy = diff (Y);
+  if (all (dy < 0))
+    Y = flipud (Y);
+    Z = flipud (Z); 
+  elseif (any (dy <= 0))
+    error ("interp2: Y must be strictly monotonic");
+  endif
 
-    ## If X and Y vectors produce a grid from them
-    if (isvector (X) && isvector (Y))
-      X = X(:); Y = Y(:);
-    elseif (size_equal (X, Y))
-      X = X(1,:)'; Y = Y(:,1);
-    else
-      error ("interp2: X and Y must be matrices of same size");
-    endif
-    if (columns (Z) != length (X) || rows (Z) != length (Y))
-      error ("interp2: X and Y size must match the dimensions of Z");
-    endif
+  if (any (strcmp (method, {"nearest", "linear", "pchip", "cubic"})))
 
     ## If Xi and Yi are vectors of different orientation build a grid
     if ((rows (XI) == 1 && columns (YI) == 1)
@@ -244,10 +264,11 @@
       idx = sub2ind (size (Z), yidx+jj, xidx+ii);
       ZI = Z(idx);
 
-    elseif (strcmp (method, "pchip"))
+    elseif (strcmp (method, "pchip") || strcmp (method, "cubic"))
 
       if (length (X) < 2 || length (Y) < 2)
-        error ("interp2: pchip2 requires at least 2 points in each dimension");
+        error ("interp2: %s requires at least 2 points in each dimension",
+               method);
       endif
 
       ## first order derivatives
@@ -303,121 +324,114 @@
 
     endif
 
-    if (! isempty (extrapval))
-      ## set points outside the table to 'extrapval'
-      if (X (1) < X (end))
-        if (Y (1) < Y (end))
-          ZI (XI < X(1,1) | XI > X(end) | YI < Y(1,1) | YI > Y(end)) = ...
-                  extrapval;
+    if (! isempty (extrap))
+      ## set points outside the table to 'extrap'
+      if (X(1) < X(end))
+        if (Y(1) < Y(end))
+          ZI(XI < X(1,1) | XI > X(end) | YI < Y(1,1) | YI > Y(end)) = ...
+                  extrap;
         else
-          ZI (XI < X(1) | XI > X(end) | YI < Y(end) | YI > Y(1)) = ...
-                  extrapval;
+          ZI(XI < X(1) | XI > X(end) | YI < Y(end) | YI > Y(1)) = ...
+                  extrap;
         endif
       else
-        if (Y (1) < Y (end))
-          ZI (XI < X(end) | XI > X(1) | YI < Y(1) | YI > Y(end)) = ...
-                  extrapval;
+        if (Y(1) < Y(end))
+          ZI(XI < X(end) | XI > X(1) | YI < Y(1) | YI > Y(end)) = ...
+                  extrap;
         else
-          ZI (XI < X(1,end) | XI > X(1) | YI < Y(end) | YI > Y(1)) = ...
-                  extrapval;
+          ZI(XI < X(1,end) | XI > X(1) | YI < Y(end) | YI > Y(1)) = ...
+                  extrap;
         endif
       endif
     endif
 
   else
 
-    ## Check dimensions of X and Y
-    if (isvector (X) && isvector (Y))
-      X = X(:).';
-      Y = Y(:);
-      if (!isequal ([length(Y), length(X)], size(Z)))
-        error ("interp2: X and Y size must match the dimensions of Z");
-      endif
-    elseif (!size_equal (X, Y))
-      error ("interp2: X and Y must be matrices of equal size");
-      if (! size_equal (X, Z))
-        error ("interp2: X and Y size must match the dimensions of Z");
-      endif
-    endif
-
     ## Check dimensions of XI and YI
     if (isvector (XI) && isvector (YI) && ! size_equal (XI, YI))
-      XI = XI(:).';
-      YI = YI(:);
-      [XI, YI] = meshgrid (XI, YI);
+      XI = XI(:).';  YI = YI(:);
     elseif (! size_equal (XI, YI))
       error ("interp2: XI and YI must be matrices of equal size");
     endif
 
+    ## FIXME: Previously used algorithm for cubic.
+    ##        This produced results within a few eps of "spline".
+    ##        Matlab compatibility requires "cubic" to be a C1 algorithm
+    ##        equivalent to "pchip" so this was commented out 2014/03/30.
+    ##        This can be removed completely in the future if no problems are
+    ##        encountered.
+    #{
     if (strcmp (method, "cubic"))
       if (isgriddata (XI) && isgriddata (YI'))
-        ZI = bicubic (X, Y, Z, XI (1, :), YI (:, 1), extrapval);
+        ZI = bicubic (X, Y, Z, XI (1, :), YI (:, 1), extrap);
       elseif (isgriddata (X) && isgriddata (Y'))
         ## Allocate output
         ZI = zeros (size (X));
 
         ## Find inliers
-        inside = !(XI < X (1) | XI > X (end) | YI < Y (1) | YI > Y (end));
+        inside = !(XI < X(1) | XI > X(end) | YI < Y(1) | YI > Y(end));
 
         ## Scale XI and YI to match indices of Z
-        XI = (columns (Z) - 1) * (XI - X (1)) / (X (end) - X (1)) + 1;
-        YI = (rows (Z) - 1) * (YI - Y (1)) / (Y (end) - Y (1)) + 1;
+        XI = (columns (Z) - 1) * (XI - X(1)) / (X(end) - X(1)) + 1;
+        YI = (rows (Z) - 1) * (YI - Y(1)) / (Y(end) - Y(1)) + 1;
 
         ## Start the real work
         K = floor (XI);
         L = floor (YI);
 
         ## Coefficients
-        AY1  = bc ((YI - L + 1));
-        AX1  = bc ((XI - K + 1));
-        AY0  = bc ((YI - L + 0));
-        AX0  = bc ((XI - K + 0));
-        AY_1 = bc ((YI - L - 1));
-        AX_1 = bc ((XI - K - 1));
-        AY_2 = bc ((YI - L - 2));
-        AX_2 = bc ((XI - K - 2));
+        AY1  = bc (YI - L + 1);
+        AX1  = bc (XI - K + 1);
+        AY0  = bc (YI - L + 0);
+        AX0  = bc (XI - K + 0);
+        AY_1 = bc (YI - L - 1);
+        AX_1 = bc (XI - K - 1);
+        AY_2 = bc (YI - L - 2);
+        AX_2 = bc (XI - K - 2);
 
         ## Perform interpolation
         sz = size (Z);
-        ZI = AY_2 .* AX_2 .* Z (sym_sub2ind (sz, L+2, K+2)) ...
-           + AY_2 .* AX_1 .* Z (sym_sub2ind (sz, L+2, K+1)) ...
-           + AY_2 .* AX0  .* Z (sym_sub2ind (sz, L+2, K))   ...
-           + AY_2 .* AX1  .* Z (sym_sub2ind (sz, L+2, K-1)) ...
-           + AY_1 .* AX_2 .* Z (sym_sub2ind (sz, L+1, K+2)) ...
-           + AY_1 .* AX_1 .* Z (sym_sub2ind (sz, L+1, K+1)) ...
-           + AY_1 .* AX0  .* Z (sym_sub2ind (sz, L+1, K))   ...
-           + AY_1 .* AX1  .* Z (sym_sub2ind (sz, L+1, K-1)) ...
-           + AY0  .* AX_2 .* Z (sym_sub2ind (sz, L,   K+2)) ...
-           + AY0  .* AX_1 .* Z (sym_sub2ind (sz, L,   K+1)) ...
-           + AY0  .* AX0  .* Z (sym_sub2ind (sz, L,   K))   ...
-           + AY0  .* AX1  .* Z (sym_sub2ind (sz, L,   K-1)) ...
-           + AY1  .* AX_2 .* Z (sym_sub2ind (sz, L-1, K+2)) ...
-           + AY1  .* AX_1 .* Z (sym_sub2ind (sz, L-1, K+1)) ...
-           + AY1  .* AX0  .* Z (sym_sub2ind (sz, L-1, K))   ...
-           + AY1  .* AX1  .* Z (sym_sub2ind (sz, L-1, K-1));
-        ZI (!inside) = extrapval;
+        ZI = AY_2 .* AX_2 .* Z(sym_sub2ind (sz, L+2, K+2)) ...
+           + AY_2 .* AX_1 .* Z(sym_sub2ind (sz, L+2, K+1)) ...
+           + AY_2 .* AX0  .* Z(sym_sub2ind (sz, L+2, K))   ...
+           + AY_2 .* AX1  .* Z(sym_sub2ind (sz, L+2, K-1)) ...
+           + AY_1 .* AX_2 .* Z(sym_sub2ind (sz, L+1, K+2)) ...
+           + AY_1 .* AX_1 .* Z(sym_sub2ind (sz, L+1, K+1)) ...
+           + AY_1 .* AX0  .* Z(sym_sub2ind (sz, L+1, K))   ...
+           + AY_1 .* AX1  .* Z(sym_sub2ind (sz, L+1, K-1)) ...
+           + AY0  .* AX_2 .* Z(sym_sub2ind (sz, L,   K+2)) ...
+           + AY0  .* AX_1 .* Z(sym_sub2ind (sz, L,   K+1)) ...
+           + AY0  .* AX0  .* Z(sym_sub2ind (sz, L,   K))   ...
+           + AY0  .* AX1  .* Z(sym_sub2ind (sz, L,   K-1)) ...
+           + AY1  .* AX_2 .* Z(sym_sub2ind (sz, L-1, K+2)) ...
+           + AY1  .* AX_1 .* Z(sym_sub2ind (sz, L-1, K+1)) ...
+           + AY1  .* AX0  .* Z(sym_sub2ind (sz, L-1, K))   ...
+           + AY1  .* AX1  .* Z(sym_sub2ind (sz, L-1, K-1));
+        ZI (!inside) = extrap;
 
       else
         error ("interp2: input data must have 'meshgrid' format");
       endif
+    #}
 
-    elseif (strcmp (method, "spline"))
+    if (strcmp (method, "spline"))
       if (isgriddata (XI) && isgriddata (YI'))
-        ZI = __splinen__ ({Y(:,1).', X(1,:)}, Z, {YI(:,1), XI(1,:)}, extrapval,
-                        "spline");
+        ZI = __splinen__ ({Y, X}, Z, {YI(:,1), XI(1,:)}, extrap,
+                          "spline");
       else
-        error ("interp2: input data must have 'meshgrid' format");
+        error ("interp2: XI, YI must have uniform spacing ('meshgrid' format)");
       endif
     else
-      error ("interp2: interpolation METHOD not recognized");
+      error ("interp2: unrecognized interpolation method '%s'", method);
     endif
 
   endif
+
 endfunction
 
 function b = isgriddata (X)
   d1 = diff (X, 1, 1);
-  b = all (d1 (:) == 0);
+  b = all (d1(:) == 0);
 endfunction
 
 ## Compute the bicubic interpolation coefficients
@@ -432,16 +446,16 @@
 
 ## This version of sub2ind behaves as if the data was symmetrically padded
 function ind = sym_sub2ind (sz, Y, X)
-  Y (Y < 1) = 1 - Y (Y < 1);
-  while (any (Y (:) > 2 * sz (1)))
-    Y (Y > 2 * sz (1)) = round (Y (Y > 2 * sz (1)) / 2);
+  Y(Y < 1) = 1 - Y(Y < 1);
+  while (any (Y(:) > 2*sz(1)))
+    Y(Y > 2*sz(1)) = round (Y(Y > 2*sz(1)) / 2);
   endwhile
-  Y (Y > sz (1)) = 1 + 2 * sz (1) - Y (Y > sz (1));
-  X (X < 1) = 1 - X (X < 1);
-  while (any (X (:) > 2 * sz (2)))
-    X (X > 2 * sz (2)) = round (X (X > 2 * sz (2)) / 2);
+  Y(Y > sz(1)) = 1 + 2*sz(1) - Y(Y > sz(1));
+  X(X < 1) = 1 - X(X < 1);
+  while (any (X(:) > 2*sz(2)))
+    X(X > 2 * sz(2)) = round (X(X > 2*sz(2)) / 2);
   endwhile
-  X (X > sz (2)) = 1 + 2 * sz (2) - X (X > sz (2));
+  X(X > sz(2)) = 1 + 2*sz(2) - X(X > sz(2));
   ind = sub2ind (sz, Y, X);
 endfunction
 
@@ -455,7 +469,7 @@
 %! yi = linspace (min (y), max (y), 26)';
 %! mesh (xi,yi,interp2 (x,y,A,xi,yi, "linear"));
 %! [x,y] = meshgrid (x,y);
-%! hold on; plot3 (x(:),y(:),A(:),"b*"); hold off;
+%! hold on; plot3 (x,y,A,"b*"); hold off;
 
 %!demo
 %! clf;
@@ -466,7 +480,7 @@
 %! yi = linspace (min (y), max (y), 41)';
 %! mesh (xi,yi,interp2 (x,y,A,xi,yi, "linear"));
 %! [x,y] = meshgrid (x,y);
-%! hold on; plot3 (x(:),y(:),A(:),"b*"); hold off;
+%! hold on; plot3 (x,y,A,"b*"); hold off;
 
 %!demo
 %! clf;
@@ -477,7 +491,7 @@
 %! yi = linspace (min (y), max (y), 26)';
 %! mesh (xi,yi,interp2 (x,y,A,xi,yi, "nearest"));
 %! [x,y] = meshgrid (x,y);
-%! hold on; plot3 (x(:),y(:),A(:),"b*"); hold off;
+%! hold on; plot3 (x,y,A,"b*"); hold off;
 
 %!demo
 %! clf;
@@ -488,9 +502,10 @@
 %! yi = linspace (min (y), max (y), 41)';
 %! mesh (xi,yi,interp2 (x,y,A,xi,yi, "nearest"));
 %! [x,y] = meshgrid (x,y);
-%! hold on; plot3 (x(:),y(:),A(:),"b*"); hold off;
+%! hold on; plot3 (x,y,A,"b*"); hold off;
 
-%!demo
+## 'pchip' commented out since it is the same as 'cubic'
+%!#demo
 %! clf;
 %! colormap ("default");
 %! A = [13,-1,12;5,4,3;1,6,2];
@@ -499,9 +514,10 @@
 %! yi = linspace (min (y), max (y), 26)';
 %! mesh (xi,yi,interp2 (x,y,A,xi,yi, "pchip"));
 %! [x,y] = meshgrid (x,y);
-%! hold on; plot3 (x(:),y(:),A(:),"b*"); hold off;
+%! hold on; plot3 (x,y,A,"b*"); hold off;
 
-%!demo
+## 'pchip' commented out since it is the same as 'cubic'
+%!#demo
 %! clf;
 %! colormap ("default");
 %! [x,y,A] = peaks (10);
@@ -510,7 +526,7 @@
 %! yi = linspace (min (y), max (y), 41)';
 %! mesh (xi,yi,interp2 (x,y,A,xi,yi, "pchip"));
 %! [x,y] = meshgrid (x,y);
-%! hold on; plot3 (x(:),y(:),A(:),"b*"); hold off;
+%! hold on; plot3 (x,y,A,"b*"); hold off;
 
 %!demo
 %! clf;
@@ -521,7 +537,7 @@
 %! yi = linspace (min (y), max (y), 26)';
 %! mesh (xi,yi,interp2 (x,y,A,xi,yi, "cubic"));
 %! [x,y] = meshgrid (x,y);
-%! hold on; plot3 (x(:),y(:),A(:),"b*"); hold off;
+%! hold on; plot3 (x,y,A,"b*"); hold off;
 
 %!demo
 %! clf;
@@ -532,7 +548,7 @@
 %! yi = linspace (min (y), max (y), 41)';
 %! mesh (xi,yi,interp2 (x,y,A,xi,yi, "cubic"));
 %! [x,y] = meshgrid (x,y);
-%! hold on; plot3 (x(:),y(:),A(:),"b*"); hold off;
+%! hold on; plot3 (x,y,A,"b*"); hold off;
 
 %!demo
 %! clf;
@@ -543,7 +559,7 @@
 %! yi = linspace (min (y), max (y), 26)';
 %! mesh (xi,yi,interp2 (x,y,A,xi,yi, "spline"));
 %! [x,y] = meshgrid (x,y);
-%! hold on; plot3 (x(:),y(:),A(:),"b*"); hold off;
+%! hold on; plot3 (x,y,A,"b*"); hold off;
 
 %!demo
 %! clf;
@@ -554,68 +570,75 @@
 %! yi = linspace (min (y), max (y), 41)';
 %! mesh (xi,yi,interp2 (x,y,A,xi,yi, "spline"));
 %! [x,y] = meshgrid (x,y);
-%! hold on; plot3 (x(:),y(:),A(:),"b*"); hold off;
+%! hold on; plot3 (x,y,A,"b*"); hold off;
 
-%!test % simple test
+%!test  # simple test
 %! x = [1,2,3];
 %! y = [4,5,6,7];
 %! [X, Y] = meshgrid (x, y);
-%! Orig = X.^2 + Y.^3;
+%! orig = X.^2 + Y.^3;
 %! xi = [1.2,2, 1.5];
 %! yi = [6.2, 4.0, 5.0]';
 %!
-%! Expected = ...
+%! expected = ...
 %!   [243,   245.4,  243.9;
 %!     65.6,  68,     66.5;
 %!    126.6, 129,    127.5];
-%! Result = interp2 (x,y,Orig, xi, yi);
+%! result = interp2 (x,y,orig, xi, yi);
 %!
-%! assert (Result, Expected, 1000*eps);
+%! assert (result, expected, 1000*eps);
 
-%!test % 2^n form
+%!test  # 2^n refinement form
 %! x = [1,2,3];
 %! y = [4,5,6,7];
 %! [X, Y] = meshgrid (x, y);
-%! Orig = X.^2 + Y.^3;
+%! orig = X.^2 + Y.^3;
 %! xi = [1:0.25:3];  yi = [4:0.25:7]';
-%! Expected = interp2 (x,y,Orig, xi, yi);
-%! Result = interp2 (Orig, 2);
+%! expected = interp2 (x,y,orig, xi, yi);
+%! result = interp2 (orig, 2);
 %!
-%! assert (Result, Expected, 10*eps);
+%! assert (result, expected, 10*eps);
 
-%!test % matrix slice
+%!test  # matrix slice
 %! A = eye (4);
 %! assert (interp2 (A,[1:4],[1:4]), [1,1,1,1]);
 
-%!test % non-gridded XI,YI
+%!test  # non-gridded XI,YI
 %! A = eye (4);
 %! assert (interp2 (A,[1,2;3,4],[1,3;2,4]), [1,0;0,1]);
 
-%!test % for values outside of boundaries
+%!test  # for values outside of boundaries
 %! x = [1,2,3];
 %! y = [4,5,6,7];
 %! [X, Y] = meshgrid (x,y);
-%! Orig = X.^2 + Y.^3;
+%! orig = X.^2 + Y.^3;
 %! xi = [0,4];
 %! yi = [3,8]';
-%! assert (interp2 (x,y,Orig, xi, yi), [NA,NA;NA,NA]);
-%! assert (interp2 (x,y,Orig, xi, yi,"linear", 0), [0,0;0,0]);
+%! assert (interp2 (x,y,orig, xi, yi), [NA,NA;NA,NA]);
+%! assert (interp2 (x,y,orig, xi, yi,"linear", 0), [0,0;0,0]);
+%! assert (interp2 (x,y,orig, xi, yi,"linear", "extrap"), [1,17;468,484]);
+%! assert (interp2 (x,y,orig, xi, yi,"nearest", "extrap"), orig([1,end],[1,end]));
 
-%!test % for values at boundaries
-%! A=[1,2;3,4];
-%! x=[0,1];
-%! y=[2,3]';
+%!test  # for values at boundaries
+%! A = [1,2;3,4];
+%! x = [0,1];
+%! y = [2,3]';
 %! assert (interp2 (x,y,A,x,y,"linear"), A);
 %! assert (interp2 (x,y,A,x,y,"nearest"), A);
 
-%!test % for Matlab-compatible rounding for 'nearest'
+%!test  # for Matlab-compatible rounding for 'nearest'
 %! X = meshgrid (1:4);
 %! assert (interp2 (X, 2.5, 2.5, "nearest"), 3);
 
+## re-order monotonically decreasing (bug #41838).
+%!assert (interp2 ([1 2 3], [3 2 1], magic (3), 2.5, 3), 3.5);
+%!assert (interp2 ([3 2 1], [1 2 3], magic (3), 1.5, 1), 3.5);
+
 %!shared z, zout, tol
 %! z = [1 3 5; 3 5 7; 5 7 9];
 %! zout = [1 2 3 4 5; 2 3 4 5 6; 3 4 5 6 7; 4 5 6 7 8; 5 6 7 8 9];
 %! tol = 2 * eps;
+%!
 %!assert (interp2 (z), zout, tol)
 %!assert (interp2 (z, "linear"), zout, tol)
 %!assert (interp2 (z, "pchip"), zout, tol)
@@ -630,3 +653,32 @@
 %!assert (interp2 (z, [2 3 1], [2 2 2], "cubic"), [5 7 3], 10 * tol)
 %!assert (interp2 (z, [2 3 1], [2 2 2], "spline"), [5 7 3], tol)
 
+%% Test input validation
+%!error <Z must be a 2-D matrix> interp2 ({1})
+%!error <Z must be a 2-D matrix> interp2 (ones (2,2,2))
+%!error <N must be an integer .= 0> interp2 (1, ones (2))
+%!error <N must be an integer .= 0> interp2 (1, -1)
+%!error <N must be an integer .= 0> interp2 (1, 1.5)
+%!error <METHOD must be a string> interp2 (1, 1, 1, 1, 1, 2)
+%!warning <ignoring unsupported '\*' flag> interp2 (rand (3,3), 1, "*linear");
+%!error <EXTRAP must be a numeric scalar or "extrap"> interp2 (1, 1, 1, 1, 1, 'linear', {1})
+%!error <EXTRAP must be a numeric scalar or "extrap"> interp2 (1, 1, 1, 1, 1, 'linear', ones (2,2))
+%!error <EXTRAP must be a numeric scalar or "extrap"> interp2 (1, 1, 1, 1, 1, 'linear', "abc")
+%!error <X, Y must be numeric matrices> interp2 ({1}, 1, 1, 1, 1)
+%!error <X, Y must be numeric matrices> interp2 (1, {1}, 1, 1, 1)
+%!error <XI, YI must be numeric> interp2 (1, 1, 1, {1}, 1)
+%!error <XI, YI must be numeric> interp2 (1, 1, 1, 1, {1})
+%!error <X and Y must be matrices of equal size> interp2 (ones(2,2), 1, 1, 1, 1)
+%!error <X and Y must be matrices of equal size> interp2 (ones(2,2), ones(2,3), 1, 1, 1)
+%!error <X and Y size must match the dimensions of Z> interp2 (1:3, 1:3, ones (3,2), 1, 1)
+%!error <X and Y size must match the dimensions of Z> interp2 (1:2, 1:2, ones (3,2), 1, 1)
+%!error <X must be strictly monotonic> interp2 ([1 0 2], 1:3, ones (3,3), 1, 1)
+%!error <Y must be strictly monotonic> interp2 (1:3, [1 0 2], ones (3,3), 1, 1)
+%!error <XI and YI must be matrices of equal size> interp2 (1, 1, 1, ones(2,2), 1)
+%!error <XI and YI must be matrices of equal size> interp2 (1, 1, 1, 1, ones(2,2))
+%!error <pchip requires at least 2 points> interp2 (1, 1, 1, 1, 1, "pchip")
+%!error <cubic requires at least 2 points> interp2 (1, 1, 1, 1, 1, "cubic")
+%!error <XI, YI must have uniform spacing> interp2 (1, 1, 1, [1 2 4], [1 2 3], "spline")
+%!error <XI, YI must have uniform spacing> interp2 (1, 1, 1, [1 2 3], [1 2 4], "spline")
+%!error <unrecognized interpolation method 'foobar'> interp2 (1, 1, 1, 1, 1, "foobar")
+
--- a/scripts/general/interp3.m	Fri Aug 01 09:06:21 2014 -0400
+++ b/scripts/general/interp3.m	Fri Aug 01 12:10:05 2014 -0400
@@ -19,52 +19,72 @@
 ## -*- texinfo -*-
 ## @deftypefn  {Function File} {@var{vi} =} interp3 (@var{x}, @var{y}, @var{z}, @var{v}, @var{xi}, @var{yi}, @var{zi})
 ## @deftypefnx {Function File} {@var{vi} =} interp3 (@var{v}, @var{xi}, @var{yi}, @var{zi})
-## @deftypefnx {Function File} {@var{vi} =} interp3 (@var{v}, @var{m})
+## @deftypefnx {Function File} {@var{vi} =} interp3 (@var{v}, @var{n})
 ## @deftypefnx {Function File} {@var{vi} =} interp3 (@var{v})
 ## @deftypefnx {Function File} {@var{vi} =} interp3 (@dots{}, @var{method})
 ## @deftypefnx {Function File} {@var{vi} =} interp3 (@dots{}, @var{method}, @var{extrapval})
 ##
-## Perform 3-dimensional interpolation.  Each element of the 3-dimensional
-## array @var{v} represents a value at a location given by the parameters
-## @var{x}, @var{y}, and @var{z}.  The parameters @var{x}, @var{x}, and
-## @var{z} are either 3-dimensional arrays of the same size as the array
-## @var{v} in the @qcode{"meshgrid"} format or vectors.  The parameters
-## @var{xi}, etc. respect a similar format to @var{x}, etc., and they
-## represent the points at which the array @var{vi} is interpolated.
+## Three-dimensional interpolation.
+##
+## Interpolate reference data @var{x}, @var{y}, @var{z}, @var{v} to determine
+## @var{vi} at the coordinates @var{xi}, @var{yi}, @var{zi}.  The reference
+## data @var{x}, @var{y}, @var{z} can be matrices, as returned by
+## @code{meshgrid}, in which case the sizes of
+## @var{x}, @var{y}, @var{z}, and @var{v} must be equal.  If @var{x}, @var{y},
+## @var{z} are vectors describing a cubic grid then
+## @code{length (@var{x}) == columns (@var{v})},
+## @code{length (@var{y}) == rows (@var{v})},
+## and @code{length (@var{z}) == size (@var{v}, 3)}.  In either case the input
+## data must be strictly monotonic.
 ##
-## If @var{x}, @var{y}, @var{z} are omitted, they are assumed to be
-## @code{x = 1 : size (@var{v}, 2)}, @code{y = 1 : size (@var{v}, 1)} and
-## @code{z = 1 : size (@var{v}, 3)}.  If @var{m} is specified, then
-## the interpolation adds a point half way between each of the interpolation
-## points.  This process is performed @var{m} times.  If only @var{v} is
-## specified, then @var{m} is assumed to be @code{1}.
+## If called without @var{x}, @var{y}, @var{z}, and just a single reference
+## data matrix @var{v}, the 3-D region
+## @code{@var{x} = 1:columns (@var{v}), @var{y} = 1:rows (@var{v}),
+## @var{z} = 1:size (@var{v}, 3)} is assumed.
+## This saves memory if the grid is regular and the distance between points is
+## not important.
 ##
-## Method is one of:
+## If called with a single reference data matrix @var{v} and a refinement
+## value @var{n}, then perform interpolation over a 3-D grid where each original
+## interval has been recursively subdivided @var{n} times.  This results in
+## @code{2^@var{n}-1} additional points for every interval in the original
+## grid.  If @var{n} is omitted a value of 1 is used.  As an example, the
+## interval [0,1] with @code{@var{n}==2} results in a refined interval with
+## points at [0, 1/4, 1/2, 3/4, 1].
+##
+## The interpolation @var{method} is one of:
 ##
 ## @table @asis
 ## @item @qcode{"nearest"}
 ## Return the nearest neighbor.
 ##
-## @item @qcode{"linear"}
+## @item @qcode{"linear"} (default)
 ## Linear interpolation from nearest neighbors.
 ##
+## @item @qcode{"pchip"}
+## Piecewise cubic Hermite interpolating polynomial---shape-preserving
+## interpolation with smooth first derivative (not implemented yet).
+##
 ## @item @qcode{"cubic"}
-## Cubic interpolation from four nearest neighbors (not implemented yet).
+## Cubic interpolation (same as @qcode{"pchip"} [not implemented yet]).
 ##
 ## @item @qcode{"spline"}
 ## Cubic spline interpolation---smooth first and second derivatives
 ## throughout the curve.
 ## @end table
 ##
-## The default method is @qcode{"linear"}.
-##
-## If @var{extrap} is the string @qcode{"extrap"}, then extrapolate values
-## beyond the endpoints.  If @var{extrap} is a number, replace values beyond
-## the endpoints with that number.  If @var{extrap} is missing, assume NA.
-## @seealso{interp1, interp2, spline, meshgrid}
+## If @var{extrapval} is a number, then replace values beyond the endpoints
+## with that number.  When unspecified, @var{extrapval} defaults to @code{NA}.
+## Note that if @var{extrapval} is used, @var{method} must be specified as well.
+## @seealso{interp1, interp2, interpn, meshgrid}
 ## @end deftypefn
 
+## FIXME: Need to validate N argument (maybe change interpn).
+## FIXME: Need to add support for 'pchip' method (maybe change interpn).
+## FIXME: Need to add support for "extrap" string value (maybe change interpn).
+
 function vi = interp3 (varargin)
+
   method = "linear";
   extrapval = NA;
   nargs = nargin;
@@ -75,112 +95,143 @@
 
   if (ischar (varargin{end}))
     method = varargin{end};
-    nargs = nargs - 1;
-  elseif (nargs > 1 && ischar (varargin{end - 1}))
+    nargs--;
+  elseif (nargs > 1 && ischar (varargin{end-1}))
+    ## FIXME: No support for "extrap" string
     if (! isnumeric (varargin{end}) || ! isscalar (varargin{end}))
-      error ("interp3: extrapal is expected to be a numeric scalar");
+      error ("interp3: EXTRAPVAL must be a numeric scalar");
     endif
     extrapval = varargin{end};
     method = varargin{end-1};
-    nargs = nargs - 2;
+    nargs -= 2;
   endif
 
-  if (nargs < 3 || (nargs == 4 && ! isvector (varargin{1})
-                    && nargs == (ndims (varargin{1}) + 1)))
+  if (method(1) == "*")
+    warning ("interp3: ignoring unsupported '*' flag to METHOD");
+    method(1) = [];
+  endif
+
+  if (nargs < 3)
+    ## Calling form interp3 (v) OR interp3 (v, n)
     v = varargin{1};
     if (ndims (v) != 3)
-      error ("interp3: expect 3-dimensional array of values");
+      error ("interp3: V must be a 3-D array of values");
     endif
-    x = varargin (2:nargs);
-    if (any (! cellfun (@isvector, x)))
-      for i = 2 : 3
-        if (! size_equal (x{1}, x{i}))
-          error ("interp3: dimensional mismatch");
-        endif
-        x{i} = permute (x{i}, [2, 1, 3]);
+    n = varargin(2:nargs);
+    v = permute (v, [2, 1, 3]);
+    vi = ipermute (interpn (v, n{:}, method, extrapval), [2, 1, 3]);
+
+  elseif (nargs == 4 && ! isvector (varargin{1}))
+    ## Calling form interp3 (v, xi, yi, zi)
+    v = varargin{1};
+    if (ndims (v) != 3)
+      error ("interp3: V must be a 3-D array of values");
+    endif
+    xi = varargin(2:4);
+    if (any (! cellfun (@isvector, xi)))
+      ## Meshgridded values rather than vectors
+      if (! size_equal (xi{:}))
+        error ("interp3: XI, YI, and ZI dimensions must be equal");
+      endif
+      for i = 1 : 3
+        xi{i} = permute (xi{i}, [2, 1, 3]);
       endfor
-      x{1} = permute (x{1}, [2, 1, 3]);
     endif
     v = permute (v, [2, 1, 3]);
-    vi = ipermute (interpn (v, x{:}, method, extrapval), [2, 1, 3]);
-  elseif (nargs == 7 && nargs == (2 * ndims (varargin{ceil (nargs / 2)})) + 1)
+    vi = ipermute (interpn (v, xi{:}, method, extrapval), [2, 1, 3]);
+
+  elseif (nargs == 7)
+    ## Calling form interp3 (x, y, z, v, xi, yi, zi)
     v = varargin{4};
     if (ndims (v) != 3)
-      error ("interp3: expect 3-dimensional array of values");
+      error ("interp3: V must be a 3-D array of values");
     endif
-    x = varargin (1:3);
+    x = varargin(1:3);
     if (any (! cellfun (@isvector, x)))
-      for i = 2 : 3
-        if (! size_equal (x{1}, x{i}) || ! size_equal (x{i}, v))
-          error ("interp3: dimensional mismatch");
-        endif
+      ## Meshgridded values rather than vectors
+      if (! size_equal (x{:}, v))
+        error ("interp3: X, Y, Z, and V dimensions must be equal");
+      endif
+      for i = 1 : 3
         x{i} = permute (x{i}, [2, 1, 3]);
       endfor
-      x{1} = permute (x{1}, [2, 1, 3]);
     endif
-    y = varargin (5:7);
-    if (any (! cellfun (@isvector, y)))
-      for i = 2 : 3
-        if (! size_equal (y{1}, y{i}))
-          error ("interp3: dimensional mismatch");
-        endif
-        y{i} = permute (y{i}, [2, 1, 3]);
+    xi = varargin(5:7);
+    if (any (! cellfun (@isvector, xi)))
+      ## Meshgridded values rather than vectors
+      if (! size_equal (xi{:}))
+        error ("interp3: XI, YI, and ZI dimensions must be equal");
+      endif
+      for i = 1 : 3
+        xi{i} = permute (xi{i}, [2, 1, 3]);
       endfor
-      y{1} = permute (y{1}, [2, 1, 3]);
     endif
     v = permute (v, [2, 1, 3]);
-    vi = ipermute (interpn (x{:}, v, y{:}, method, extrapval), [2, 1, 3]);
+    vi = ipermute (interpn (x{:}, v, xi{:}, method, extrapval), [2, 1, 3]);
+
   else
     error ("interp3: wrong number or incorrectly formatted input arguments");
   endif
+
 endfunction
 
 
-%!test
-%! x = y = z = -1:1; y = y + 2;
+%% FIXME: Need some demo blocks here to show off the function like interp2.m.
+
+%!test  # basic test
+%! x = y = z = -1:1;  y = y + 2;
 %! f = @(x,y,z) x.^2 - y - z.^2;
 %! [xx, yy, zz] = meshgrid (x, y, z);
 %! v = f (xx,yy,zz);
-%! xi = yi = zi = -1:0.5:1; yi = yi + 2.1;
+%! xi = yi = zi = -1:0.5:1;  yi = yi + 2.1;
 %! [xxi, yyi, zzi] = meshgrid (xi, yi, zi);
 %! vi = interp3 (x, y, z, v, xxi, yyi, zzi);
 %! [xxi, yyi, zzi] = ndgrid (yi, xi, zi);
 %! vi2 = interpn (y, x, z, v, xxi, yyi, zzi);
-%! tol = 10 * eps;
-%! assert (vi, vi2, tol);
+%! assert (vi, vi2, 10*eps);
 
-%!test
-%! x=z=1:2; y=1:3;xi=zi=.6:1.6; yi=1; v=ones([3,2,2]);  v(:,2,1)=[7 ;5;4];  v(:,1,2)=[2 ;3;5];
+%!test  # meshgridded xi, yi, zi
+%! x = z = 1:2;  y = 1:3;
+%! v = ones ([3,2,2]);  v(:,2,1) = [7;5;4];  v(:,1,2) = [2;3;5];
+%! xi = zi = .6:1.6;  yi = 1; 
 %! [xxi3, yyi3, zzi3] = meshgrid (xi, yi, zi);
 %! [xxi, yyi, zzi] = ndgrid (yi, xi, zi);
 %! vi = interp3 (x, y, z, v, xxi3, yyi3, zzi3, "nearest");
-%! vi2 = interpn (y, x, z, v, xxi, yyi, zzi,"nearest");
+%! vi2 = interpn (y, x, z, v, xxi, yyi, zzi, "nearest");
 %! assert (vi, vi2);
 
-%!test
-%! x=z=1:2; y=1:3;xi=zi=.6:1.6; yi=1; v=ones([3,2,2]);  v(:,2,1)=[7 ;5;4];  v(:,1,2)=[2 ;3;5];
-%! vi = interp3 (x, y, z, v, xi+1, yi, zi, "nearest",3);
-%! vi2 = interpn (y, x, z, v, yi, xi+1, zi,"nearest", 3);
-%! assert (vi, vi2);
-
-%!test
-%! x=z=1:2; y=1:3;xi=zi=.6:1.6; yi=1; v=ones([3,2,2]);  v(:,2,1)=[7 ;5;4];  v(:,1,2)=[2 ;3;5];
+%!test  # vector xi, yi, zi
+%! x = z = 1:2;  y = 1:3;
+%! v = ones ([3,2,2]);  v(:,2,1) = [7;5;4];  v(:,1,2) = [2;3;5];
+%! xi = zi = .6:1.6;  yi = 1; 
 %! vi = interp3 (x, y, z, v, xi, yi, zi, "nearest");
 %! vi2 = interpn (y, x, z, v, yi, xi, zi,"nearest");
 %! assert (vi, vi2);
 
-%!test
-%! x=z=1:2; y=1:3;xi=zi=.6:1.6; yi=1; v=ones([3,2,2]);  v(:,2,1)=[7 ;5;4];  v(:,1,2)=[2 ;3;5];
-%! vi = interp3 (v, xi, yi, zi, "nearest",3);
-%! vi2 = interpn (v, yi, xi, zi,"nearest", 3);
+%!test  # vector xi+1 with extrap value
+%! x = z = 1:2;  y = 1:3;
+%! v = ones ([3,2,2]);  v(:,2,1) = [7;5;4];  v(:,1,2) = [2;3;5];
+%! xi = zi = .6:1.6;  yi = 1; 
+%! vi = interp3 (x, y, z, v, xi+1, yi, zi, "nearest", 3);
+%! vi2 = interpn (y, x, z, v, yi, xi+1, zi, "nearest", 3);
 %! assert (vi, vi2);
 
-%!test
-%! xi=zi=.6:1.6; yi=1; v=ones([3,2,2]);  v(:,2,1)=[7 ;5;4];  v(:,1,2)=[2 ;3;5];
+%!test  # input value matrix--no x,y,z
+%! x = z = 1:2;  y = 1:3;
+%! v = ones ([3,2,2]);  v(:,2,1) = [7;5;4];  v(:,1,2) = [2;3;5];
+%! xi = zi = .6:1.6;  yi = 1; 
 %! vi = interp3 (v, xi, yi, zi, "nearest");
 %! vi2 = interpn (v, yi, xi, zi,"nearest");
 %! assert (vi, vi2);
 
+%!test  # input value matrix--no x,y,z, with extrap value
+%! x = z = 1:2;  y = 1:3;
+%! v = ones ([3,2,2]);  v(:,2,1) = [7;5;4];  v(:,1,2) = [2;3;5];
+%! xi = zi = .6:1.6;  yi = 1; 
+%! vi = interp3 (v, xi, yi, zi, "nearest", 3);
+%! vi2 = interpn (v, yi, xi, zi, "nearest", 3);
+%! assert (vi, vi2);
+
 %!shared z, zout, tol
 %! z = zeros (3, 3, 3);
 %! zout = zeros (5, 5, 5);
@@ -195,7 +246,21 @@
 %!                  5 6 7 8 9] + (n-1);
 %! end
 %! tol = 10 * eps;
+%!
 %!assert (interp3 (z), zout, tol)
 %!assert (interp3 (z, "linear"), zout, tol)
 %!assert (interp3 (z, "spline"), zout, tol)
 
+%% Test input validation
+%!error interp3 ()
+%!error interp3 ({1})
+%!error <EXTRAPVAL must be a numeric scalar> interp3 (1,2,3,4,1,2,3,"linear", {1})
+%!error <EXTRAPVAL must be a numeric scalar> interp3 (1,2,3,4,1,2,3,"linear", ones (2,2))
+%!warning <ignoring unsupported '\*' flag> interp3 (rand (3,3,3), 1, "*linear");
+%!error <V must be a 3-D array> interp3 (rand (2,2))
+%!error <V must be a 3-D array> interp3 (rand (2,2), 1,1,1)
+%!error <XI, YI, and ZI dimensions must be equal> interp3 (rand (2,2,2), 1,1, ones (2,2))
+%!error <V must be a 3-D array> interp3 (1:2, 1:2, 1:2, rand (2,2), 1,1,1)
+%!error <X, Y, Z, and V dimensions must be equal> interp3 (ones(1,2,2), ones(2,2,2), ones(2,2,2), rand (2,2,2), 1,1,1)
+%!error <XI, YI, and ZI dimensions must be equal> interp3 (1:2, 1:2, 1:2, rand (2,2,2), 1,1, ones (2,2))
+
--- a/scripts/general/interpn.m	Fri Aug 01 09:06:21 2014 -0400
+++ b/scripts/general/interpn.m	Fri Aug 01 12:10:05 2014 -0400
@@ -86,6 +86,11 @@
     nargs -= 2;
   endif
 
+  if (method(1) == "*")
+    warning ("interpn: ignoring unsupported '*' flag to METHOD");
+    method(1) = [];
+  endif
+
   if (nargs < 3)
     v = varargin{1};
     m = 1;
@@ -318,3 +323,6 @@
 %! assert (interpn (z, "linear"), zout, tol);
 %! assert (interpn (z, "spline"), zout, tol);
 
+%% Test input validation
+%!warning <ignoring unsupported '\*' flag> interpn (rand (3,3), 1, "*linear");
+
--- a/scripts/general/iscolumn.m	Fri Aug 01 09:06:21 2014 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,56 +0,0 @@
-## Copyright (C) 2012-2013 John W. Eaton
-##
-## This file is part of Octave.
-##
-## Octave is free software; you can redistribute it and/or modify it
-## under the terms of the GNU General Public License as published by
-## the Free Software Foundation; either version 3 of the License, or (at
-## your option) any later version.
-##
-## Octave is distributed in the hope that it will be useful, but
-## WITHOUT ANY WARRANTY; without even the implied warranty of
-## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-## General Public License for more details.
-##
-## You should have received a copy of the GNU General Public License
-## along with Octave; see the file COPYING.  If not, see
-## <http://www.gnu.org/licenses/>.
-
-## -*- texinfo -*-
-## @deftypefn {Function File} {} iscolumn (@var{x})
-## Return true if @var{x} is a column vector.
-## @seealso{isrow, isscalar, isvector, ismatrix}
-## @end deftypefn
-
-## Author: Rik Wehbring
-
-function retval = iscolumn (x)
-
-  if (nargin != 1)
-    print_usage ();
-  endif
-
-  sz = size (x);
-  retval = (ndims (x) == 2 && (sz(2) == 1));
-
-endfunction
-
-
-%!assert (iscolumn ([1, 2, 3]), false)
-%!assert (iscolumn ([1; 2; 3]))
-%!assert (iscolumn (1))
-%!assert (iscolumn ([]), false)
-%!assert (iscolumn ([1, 2; 3, 4]), false)
-
-%!assert (iscolumn ("t"))
-%!assert (iscolumn ("test"), false)
-%!assert (iscolumn (["test"; "ing"]), false)
-
-%!test
-%! s.a = 1;
-%! assert (iscolumn (s));
-
-%% Test input validation
-%!error iscolumn ()
-%!error iscolumn ([1, 2], 2)
-
--- a/scripts/general/isequal.m	Fri Aug 01 09:06:21 2014 -0400
+++ b/scripts/general/isequal.m	Fri Aug 01 12:10:05 2014 -0400
@@ -33,53 +33,133 @@
 endfunction
 
 
+## test empty input
+%!assert (isequal ([], []), true)
+%!assert (isequal ([], [], 1), false)
+%!assert (isequal ([], 1, []), false)
+%!assert (isequal (1, [], []), false)
+%!assert (isequal (1, [], []), false)
+
 ## test size and shape
-%!assert (isequal ([1,2,3,4],[1,2,3,4]), true)
-%!assert (isequal ([1;2;3;4],[1;2;3;4]), true)
-%!assert (isequal ([1,2,3,4],[1;2;3;4]), false)
-%!assert (isequal ([1,2,3,4],[1,2;3,4]), false)
-%!assert (isequal ([1,2,3,4],[1,3;2,4]), false)
+%!assert (isequal ([1,2,3,4], [1,2,3,4]), true)
+%!assert (isequal ([1;2;3;4], [1;2;3;4]), true)
+%!assert (isequal ([1,2,3,4], [1;2;3;4]), false)
+%!assert (isequal ([1,2,3,4], [1,2;3,4]), false)
+%!assert (isequal ([1,2,3,4], [1,3;2,4]), false)
 
 %!test
 %! A = 1:8;
 %! B = reshape (A, 2, 2, 2);
 %! assert (isequal (A, B), false);
-
 %!test
 %! A = reshape (1:8, 2, 2, 2);
 %! B = A;
 %! assert (isequal (A, B), true);
-
 %!test
 %! A = reshape (1:8, 2, 4);
 %! B = reshape (A, 2, 2, 2);
 %! assert (isequal (A, B), false);
 
-## test for equality
-%!assert (isequal ([1,2,3,4],[1,2,3,4]), true)
-%!assert (isequal (['a','b','c','d'],['a','b','c','d']), true)
-## Test multi-line strings
-%!assert (isequal (["test";"strings"],["test";"strings"],["test";"strings"]), true)
-## test for inequality
-%!assert (isequal ([1,2,3,4],[1;2;3;4]), false)
-%!assert (isequal ({1,2,3,4},[1,2,3,4]), false)
-%!assert (isequal ([1,2,3,4],{1,2,3,4}), false)
-%!assert (isequal ([1,2,NaN,4],[1,2,NaN,4]), false)
-%!assert (isequal (['a','b','c','d'],['a';'b';'c';'d']), false)
-%!assert (isequal ({'a','b','c','d'},{'a';'b';'c';'d'}), false)
-## test for equality (struct)
-%!assert (isequal (struct ('a',1,'b',2),struct ('a',1,'b',2)), true)
-%!assert (isequal (struct ('a',1,'b',2),struct ('a',1,'b',2),struct ('a',1,'b',2)), true)
-%!assert (isequal (struct ('a',"abc",'b',2),struct ('a',"abc",'b',2)), true)
-## test for inequality (struct)
-%!assert (isequal (struct ('a',NaN,'b',2),struct ('a',NaN,'b',2),struct ('a',NaN,'b',2)), false)
+## test all numeric built-in primitives
+%!assert (isequal (false, logical (0), char (0),
+%!                 int8 (0), int16 (0), int32 (0), int64 (0),
+%!                 uint8 (0), uint16 (0), uint32 (0), uint64 (0),
+%!                 double (0), single (0),
+%!                 double (complex (0,0)), single (complex (0,0))),
+%!        true)
+%!assert (isequal (true, logical (1), char (1), 
+%!                 int8 (1), int16 (1), int32 (1), int64 (1), 
+%!                 uint8 (1), uint16 (1), uint32 (1), uint64 (1), 
+%!                 double (1), single (1),
+%!                 double (complex (1,0)), single (complex (1,0))),
+%!        true)
+
+## test characters and strings
+%!assert (isequal ('a', "a"), true)
+%!assert (isequal ("abab", ["a", "b", "a", "b"]), true)
+%!assert (isequal (["a","b","c","d"], ["a","b","c","d"]), true)
+%!assert (isequal (["test   ";"strings"], ["test   ";"strings"],
+%!                 ["test   ";"strings"]), true)
+%!assert (isequal (["a","b","c","d"], ["a";"b";"c";"d"]), false)
+
+## test function_handle
+%!test
+%! fcn = @(x) x.^2;
+%! assert (isequal (fcn, fcn), true);
+%! assert (isequal (fcn, @(x) x.^2), false);
+%! assert (isequal (@(x) x.^2, fcn), false);
+
+## test structures
+%!assert (isequal (struct ([]),struct ([])), true)
+%!assert (isequal (struct ("a",1), struct ("a",1)), true)
+%!assert (isequal (struct ("a",1), struct ("a",2)), false)
+%!assert (isequal (struct ("a",1), struct ("b",1)), false)
+%!assert (isequal (struct ("a",1,"b",2), struct ("a",1,"b",2)), true)
+%!assert (isequal (struct ("a",1,"b",2), struct ("b",2,"a",1)), true)
+%!assert (isequal (struct ("a",1,"b",2), struct ("a",1,"b",2),
+%!                 struct ("a",1,"b",2)), true)
+%!assert (isequal (struct ("a","abc","b",2), struct ("a","abc","b",2)), true)
+
+## recursive structure
+%!test  
+%! x.a = "a1";
+%! x.b.a = "ba1";
+%! x.b.b = "bb1";
+%! assert (isequal (x, x, x), true);
+%! y = x;
+%! y.b.b = "bb2";
+%! assert (isequal (x, y), false);
+%! y = x;
+%! y.b = rmfield (y.b, "b");
+%! y.b.b.a = "bba1";
+%! assert (isequal (x, y), false);
+
+## test cells
+%!assert (isequal (cell (1,1), cell (1,1)), true)
+%!assert (isequal (cell (1,1), cell (1,2)), false)
+%!assert (isequal ({"a",1}, {"a",1}), true)
+%!assert (isequal ({"a",1}, {"a",2}), false)
+%!assert (isequal ({"a",1}, {"b",1}), false)
+%!assert (isequal ({"a",1,"b",2}, {"a",1,"b",2}), true)
+%!assert (isequal ({"a",1,"b",2}, {"b",2,"a",1}), false)
+%!assert (isequal ({"a",1,"b",2}, {"a",1,"b",2}, {"a",1,"b",2}), true)
+%!assert (isequal ({"a","abc","b",2}, {"a","abc","b",2}), true)
+%!assert (isequal ({"a","b","c","d"}, {"a","b","c","d"}), true)
+%!assert (isequal ({"a","b","c","d"}, {"a";"b";"c";"d"}), false)
+%!assert (isequal (["a","b","c","d"], {"a","b","c","d"}), false)
+
+## recursive cell
+%!test
+%! x = cell (1,3);
+%! x{1} = {[1], [1 2]};
+%! x{2} = true;
+%! x{3} = {{"hello"}, {"world"}};
+%! assert (isequal (x, x));
+%! y = x;
+%! y{3}{1}{1} = "goodbye";
+%! assert (isequal (x, y), false);
 
 ## test for sparse matrices
+%!assert (isequal (sparse ([]), []), true)
+%!assert (isequal ([], sparse ([])), true)
 %!assert (isequal (sparse (0,1), sparse (0,1)), true)
+%!assert (isequal (sparse (0,1), zeros (0,1)), true)
+%!assert (isequal (sparse (2,2), sparse (2,2)), true)
+%!assert (isequal (zeros (2,2), sparse (2,2)), true)
+%!assert (isequal (speye (1), eye (1)), true)
+%!assert (isequal (eye (300), speye (300)), true)
 %!assert (isequal (sparse (0,1), sparse (1,0)), false)
-%!assert (isequal (sparse (2, 2), sparse (2, 2)), true)
 
-## Input validation
+## test NaN
+%!assert (isequal (NaN, NaN), false)
+%!assert (isequal (NaN, Inf), false)
+%!assert (isequal (NaN, 1.0), false)
+%!assert (isequal ([1,2,NaN,4], [1,2,NaN,4]), false)
+%!assert (isequal (struct ("a",NaN,"b",2), struct ("a",NaN,"b",2), 
+%!                 struct ("a",NaN,"b",2)), false)
+
+## test input validation
 %!error isequal ()
 %!error isequal (1)
+%!error isequal ([1,1])
 
--- a/scripts/general/isequaln.m	Fri Aug 01 09:06:21 2014 -0400
+++ b/scripts/general/isequaln.m	Fri Aug 01 12:10:05 2014 -0400
@@ -36,13 +36,14 @@
 
 
 ## test for equality
-%!assert (isequaln ({1,2,NaN,4},{1,2,NaN,4}), true)
-%!assert (isequaln ([1,2,NaN,4],[1,2,NaN,4]), true)
+%!assert (isequaln ({1,2,NaN,4}, {1,2,NaN,4}), true)
+%!assert (isequaln ([1,2,NaN,4], [1,2,NaN,4]), true)
 ## test for inequality
-%!assert (isequaln ([1,2,NaN,4],[1,NaN,3,4]), false)
-%!assert (isequaln ([1,2,NaN,4],[1,2,3,4]), false)
+%!assert (isequaln ([1,2,NaN,4], [1,NaN,3,4]), false)
+%!assert (isequaln ([1,2,NaN,4], [1,2,3,4]), false)
 ## test for equality (struct)
-%!assert (isequaln (struct ('a',NaN,'b',2),struct ('a',NaN,'b',2),struct ('a',NaN,'b',2)), true)
+%!assert (isequaln (struct ("a",NaN,"b",2), struct ("a",NaN,"b",2),
+%!                  struct ("a",NaN,"b",2)), true)
 %!assert (isequaln (1,2,1), false)
 
 ## Input validation
--- a/scripts/general/isrow.m	Fri Aug 01 09:06:21 2014 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,56 +0,0 @@
-## Copyright (C) 2012-2013 John W. Eaton
-##
-## This file is part of Octave.
-##
-## Octave is free software; you can redistribute it and/or modify it
-## under the terms of the GNU General Public License as published by
-## the Free Software Foundation; either version 3 of the License, or (at
-## your option) any later version.
-##
-## Octave is distributed in the hope that it will be useful, but
-## WITHOUT ANY WARRANTY; without even the implied warranty of
-## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-## General Public License for more details.
-##
-## You should have received a copy of the GNU General Public License
-## along with Octave; see the file COPYING.  If not, see
-## <http://www.gnu.org/licenses/>.
-
-## -*- texinfo -*-
-## @deftypefn {Function File} {} isrow (@var{x})
-## Return true if @var{x} is a row vector.
-## @seealso{iscolumn, isscalar, isvector, ismatrix}
-## @end deftypefn
-
-## Author: Rik Wehbring
-
-function retval = isrow (x)
-
-  if (nargin != 1)
-    print_usage ();
-  endif
-
-  sz = size (x);
-  retval = (ndims (x) == 2 && (sz(1) == 1));
-
-endfunction
-
-
-%!assert (isrow ([1, 2, 3]))
-%!assert (isrow ([1; 2; 3]), false)
-%!assert (isrow (1))
-%!assert (isrow ([]), false)
-%!assert (isrow ([1, 2; 3, 4]), false)
-
-%!assert (isrow ("t"))
-%!assert (isrow ("test"))
-%!assert (isrow (["test"; "ing"]), false)
-
-%!test
-%! s.a = 1;
-%! assert (isrow (s));
-
-%% Test input validation
-%!error isrow ()
-%!error isrow ([1, 2], 2)
-
--- a/scripts/general/isscalar.m	Fri Aug 01 09:06:21 2014 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,54 +0,0 @@
-## Copyright (C) 1996-2013 John W. Eaton
-##
-## This file is part of Octave.
-##
-## Octave is free software; you can redistribute it and/or modify it
-## under the terms of the GNU General Public License as published by
-## the Free Software Foundation; either version 3 of the License, or (at
-## your option) any later version.
-##
-## Octave is distributed in the hope that it will be useful, but
-## WITHOUT ANY WARRANTY; without even the implied warranty of
-## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-## General Public License for more details.
-##
-## You should have received a copy of the GNU General Public License
-## along with Octave; see the file COPYING.  If not, see
-## <http://www.gnu.org/licenses/>.
-
-## -*- texinfo -*-
-## @deftypefn {Function File} {} isscalar (@var{x})
-## Return true if @var{x} is a scalar.
-## @seealso{isvector, ismatrix}
-## @end deftypefn
-
-## Author: jwe
-
-function retval = isscalar (x)
-
-  if (nargin != 1)
-    print_usage ();
-  endif
-
-  retval = numel (x) == 1;
-
-endfunction
-
-
-%!assert (isscalar (1))
-%!assert (isscalar ([1, 2]), false)
-%!assert (isscalar ([]), false)
-%!assert (isscalar ([1, 2; 3, 4]), false)
-
-%!assert (isscalar ("t"))
-%!assert (isscalar ("test"), false)
-%!assert (isscalar (["test"; "ing"]), false)
-
-%!test
-%! s.a = 1;
-%! assert (isscalar (s));
-
-%% Test input validation
-%!error isscalar ()
-%!error isscalar (1, 2)
-
--- a/scripts/general/issquare.m	Fri Aug 01 09:06:21 2014 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,63 +0,0 @@
-## Copyright (C) 1996-2013 John W. Eaton
-##
-## This file is part of Octave.
-##
-## Octave is free software; you can redistribute it and/or modify it
-## under the terms of the GNU General Public License as published by
-## the Free Software Foundation; either version 3 of the License, or (at
-## your option) any later version.
-##
-## Octave is distributed in the hope that it will be useful, but
-## WITHOUT ANY WARRANTY; without even the implied warranty of
-## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-## General Public License for more details.
-##
-## You should have received a copy of the GNU General Public License
-## along with Octave; see the file COPYING.  If not, see
-## <http://www.gnu.org/licenses/>.
-
-## -*- texinfo -*-
-## @deftypefn {Function File} {} issquare (@var{x})
-## Return true if @var{x} is a square matrix.
-## @seealso{isscalar, isvector, ismatrix, size}
-## @end deftypefn
-
-## Author: A. S. Hodel <scotte@eng.auburn.edu>
-## Created: August 1993
-## Adapted-By: jwe
-
-function retval = issquare (x)
-
-  if (nargin != 1)
-    print_usage ();
-  endif
-
-  if (ndims (x) == 2)
-    [r, c] = size (x);
-    retval = r == c;
-  else
-    retval = false;
-  endif
-
-endfunction
-
-
-%!assert (issquare ([]))
-%!assert (issquare (1))
-%!assert (! issquare ([1, 2]))
-%!assert (issquare ([1, 2; 3, 4]))
-%!assert (! issquare ([1, 2; 3, 4; 5, 6]))
-%!assert (! issquare (ones (3,3,3)))
-%!assert (issquare ("t"))
-%!assert (! issquare ("test"))
-%!assert (issquare (["test"; "ing"; "1"; "2"]))
-%!test
-%! s.a = 1;
-%! assert (issquare (s));
-%!assert (issquare ({1, 2; 3, 4}))
-%!assert (sparse (([1, 2; 3, 4])))
-
-%% Test input validation
-%!error issquare ()
-%!error issquare ([1, 2; 3, 4], 2)
-
--- a/scripts/general/isvector.m	Fri Aug 01 09:06:21 2014 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,57 +0,0 @@
-## Copyright (C) 1996-2013 John W. Eaton
-##
-## This file is part of Octave.
-##
-## Octave is free software; you can redistribute it and/or modify it
-## under the terms of the GNU General Public License as published by
-## the Free Software Foundation; either version 3 of the License, or (at
-## your option) any later version.
-##
-## Octave is distributed in the hope that it will be useful, but
-## WITHOUT ANY WARRANTY; without even the implied warranty of
-## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-## General Public License for more details.
-##
-## You should have received a copy of the GNU General Public License
-## along with Octave; see the file COPYING.  If not, see
-## <http://www.gnu.org/licenses/>.
-
-## -*- texinfo -*-
-## @deftypefn {Function File} {} isvector (@var{x})
-## Return true if @var{x} is a vector.  A vector is a 2-D array
-## where one of the dimensions is equal to 1.  As a consequence a
-## 1x1 array, or scalar, is also a vector.
-## @seealso{isscalar, ismatrix, size, rows, columns, length}
-## @end deftypefn
-
-## Author: jwe
-
-function retval = isvector (x)
-
-  if (nargin != 1)
-    print_usage ();
-  endif
-
-  sz = size (x);
-  retval = (ndims (x) == 2 && (sz(1) == 1 || sz(2) == 1));
-
-endfunction
-
-
-%!assert (isvector (1))
-%!assert (isvector ([1; 2; 3]))
-%!assert (isvector ([]), false)
-%!assert (isvector ([1, 2; 3, 4]), false)
-
-%!assert (isvector ("t"))
-%!assert (isvector ("test"))
-%!assert (isvector (["test"; "ing"]), false)
-
-%!test
-%! s.a = 1;
-%! assert (isvector (s));
-
-%% Test input validation
-%!error isvector ()
-%!error isvector ([1, 2], 2)
-
--- a/scripts/general/module.mk	Fri Aug 01 09:06:21 2014 -0400
+++ b/scripts/general/module.mk	Fri Aug 01 12:10:05 2014 -0400
@@ -7,7 +7,6 @@
 general_FCN_FILES = \
   general/accumarray.m \
   general/accumdim.m \
-  general/bicubic.m \
   general/bincoeff.m \
   general/bitcmp.m \
   general/bitget.m \
@@ -40,14 +39,9 @@
   general/interp3.m \
   general/interpn.m \
   general/interpft.m \
-  general/iscolumn.m \
   general/isdir.m \
   general/isequal.m \
   general/isequaln.m \
-  general/isrow.m \
-  general/isscalar.m \
-  general/issquare.m \
-  general/isvector.m \
   general/loadobj.m \
   general/logspace.m \
   general/methods.m \
--- a/scripts/general/prepad.m	Fri Aug 01 09:06:21 2014 -0400
+++ b/scripts/general/prepad.m	Fri Aug 01 12:10:05 2014 -0400
@@ -97,7 +97,7 @@
 %!assert (prepad ([1,2], 2, 2, 3), reshape ([2,2,1,2], 1, 2, 2))
 %!assert (prepad ([1;2], 2, 2, 3), reshape ([2;2;1;2], 2, 1, 2))
 
-## FIXME -- we need tests for multidimensional arrays.
+## FIXME: We need tests for multidimensional arrays.
 
 %!error prepad ()
 %!error prepad (1)
--- a/scripts/general/private/__isequal__.m	Fri Aug 01 09:06:21 2014 -0400
+++ b/scripts/general/private/__isequal__.m	Fri Aug 01 12:10:05 2014 -0400
@@ -33,17 +33,19 @@
 ## Algorithm:
 ##
 ## 1. Determine the class of x
-## 2. If x is of the struct, cell, list or char class, for each
-##    argument after x, determine whether it has the same class
-##    and size as x.
-##    Otherwise, for each argument after x, verify that it is not
-##    of the struct, cell, list or char class, and that it has
-##    the same size as x.
+## 2. If x and all other arguments have the same class, then check that the
+##    number of dimensions and then the size of each dimension match.
+##    If not all arguments share the same class, then verify that all of the
+##    arguments belong to a comparable "numeric" class which includes
+##    numeric, logical, and character arrays.  Check that number of dimensions
+##    and size of each dimension match.
 ## 3. For each argument after x, compare it for equality with x:
 ##    a. struct     compare each member by name, not by order (recursive)
-##    b. cell/list  compare each member by order (recursive)
-##    c. char       compare each member with strcmp
-##    d. <other>    compare each nonzero member, and assume NaN == NaN
+##    b. object     converted to struct, and then compared as stated above
+##    c. cell       compare each member by order (recursive)
+##    d. char       compare each member with strcmp
+##    e  fcn_handle compare using overloade 'eq' operator
+##    f. <other>    compare each nonzero member, and assume NaN == NaN
 ##                  if nans_compare_equal is nonzero.
 
 function t = __isequal__ (nans_compare_equal, x, varargin)
@@ -53,39 +55,31 @@
   ## Generic tests.
 
   ## All arguments must either be of the same class or they must be
-  ## numeric values.
+  ## "numeric" values.
   t = (all (strcmp (class (x),
                     cellfun ("class", varargin, "uniformoutput", false)))
-       || ((isnumeric (x) || islogical (x))
-           && all (cellfun ("isnumeric", varargin)
-                   | cellfun ("islogical", varargin))));
+       || ((isreal (x) || isnumeric (x))
+           && all (cellfun ("isreal", varargin)
+                   | cellfun ("isnumeric", varargin))));
 
   if (t)
     ## Test that everything has the same number of dimensions.
-    s_x = size (x);
-    s_v = cellfun (@size, varargin, "uniformoutput", false);
-    t = all (length (s_x) == cellfun ("length", s_v));
+    t = all (ndims (x) == cellfun ("ndims", varargin));
   endif
 
   if (t)
-    ## Test that everything is the same size since it has the same
-    ## dimensionality.
-    l_x = length (s_x);
-    s_v = reshape ([s_v{:}], length (s_x), []);
-    idx = 0;
-    while (t && idx < l_x)
-      idx++;
-      t = all (s_x(idx) == s_v(idx,:));
-    endwhile
+    ## Test that everything is the same size since the dimensionality matches.
+    nd = ndims (x);
+    k = 1;
+    do
+      t = all (size (x,k) == cellfun ("size", varargin, k));
+    until (!t || k++ == nd);
   endif
 
   ## From here on, compare objects as if they were structures.
-  if (isobject (x))
+  if (t && isobject (x))
     x = builtin ("struct", x);
     for i = 1:numel (varargin)
-      if (! isobject (varargin{i}))
-        break;
-      endif
       varargin{i} = builtin ("struct", varargin{i});
     endfor
   endif
@@ -95,9 +89,9 @@
     if (isstruct (x))
       ## Test the number of fields.
       fn_x = fieldnames (x);
-      l_fn_x = length (fn_x);
+      l_fn_x = numfields (x);
       fn_v = cellfun ("fieldnames", varargin, "uniformoutput", false);
-      t = all (l_fn_x == cellfun ("length", fn_v));
+      t = all (l_fn_x == cellfun ("numel", fn_v));
 
       ## Test that all the names are equal.
       idx = 0;
@@ -112,12 +106,12 @@
       while (t && idx < l_fn_x)
         ## Test that all field values are equal.
         idx++;
-        args = {nans_compare_equal, {x.(fn_x{idx})}};
+        args = cell (1, 2+l_v);
+        args(1:2) = {nans_compare_equal, {x.(fn_x{idx})}};
         for argn = 1:l_v
           args{argn+2} = {varargin{argn}.(fn_x{idx})};
         endfor
-        ## Minimize function calls by calling for all the arguments at
-        ## once.
+        ## Minimize function calls by calling for all the arguments at once.
         t = __isequal__ (args{:});
       endwhile
 
@@ -127,24 +121,24 @@
       idx = 0;
       while (t && idx < l_x)
         idx++;
-        args = {nans_compare_equal, x{idx}};
-        for p = 1:l_v
-          args{p+2} = varargin{p}{idx};
-        endfor
+        args = cell (1, 2+l_v);
+        args(1:2) = {nans_compare_equal, x{idx}}; 
+        args(3:end) = [cellindexmat(varargin, idx){:}];
+
         t = __isequal__ (args{:});
       endwhile
 
-    elseif (ischar (x))
-
+    elseif (ischar (x) && all (cellfun ("isclass", varargin, "char")))
       ## Sizes are equal already, so we can just make everything into a
       ## row and test the rows.
+      n_x = numel (x);
+      strings = cell (1, l_v);
       for i = 1:l_v
-        strings{i} = reshape (varargin{i}, 1, []);
+        strings{i} = reshape (varargin{i}, 1, n_x);
       endfor
-      t = all (strcmp (reshape (x, 1, []), strings));
+      t = all (strcmp (reshape (x, 1, n_x), strings));
 
     elseif (isa (x, "function_handle"))
-
       ## The == operator is overloaded for handles.
       t = all (cellfun ("eq", {x}, varargin));
 
@@ -179,11 +173,5 @@
     endif
   endif
 
-  if (!t)
-    t = false;
-  else
-    t = true;
-  endif
-
 endfunction
 
--- a/scripts/general/profshow.m	Fri Aug 01 09:06:21 2014 -0400
+++ b/scripts/general/profshow.m	Fri Aug 01 12:10:05 2014 -0400
@@ -1,4 +1,4 @@
-## Copyright (C) 2012-2013 Daniel Kraft
+## Copyright (C) 2012-2014 Daniel Kraft
 ##
 ## This file is part of Octave.
 ##
@@ -19,17 +19,20 @@
 ## -*- texinfo -*-
 ## @deftypefn  {Function File} {} profshow (@var{data})
 ## @deftypefnx {Function File} {} profshow (@var{data}, @var{n})
-## Show flat profiler results.
+## @deftypefnx {Function File} {} profshow ()
+## @deftypefnx {Function File} {} profshow (@var{n})
+## Display flat per-function profiler results.
 ##
-## This command prints out profiler data as a flat profile.  @var{data} is the
-## structure returned by @code{profile ("info")}.  If @var{n} is given, it
-## specifies the number of functions to show in the profile; functions are
-## sorted in descending order by total time spent in them.  If there are more
-## than @var{n} included in the profile, those will not be shown.  @var{n}
+## Print out profiler data (execution time, number of calls) for the most
+## critical @var{n} functions.  The results are sorted in descending order by
+## the total time spent in each function.  If @var{n} is unspecified it
 ## defaults to 20.
 ##
-## The attribute column shows @samp{R} for recursive functions and nothing
-## otherwise.
+## The input @var{data} is the structure returned by @code{profile ("info")}.
+## If unspecified, @code{profshow} will use the current profile dataset.
+##
+## The attribute column displays @samp{R} for recursive functions, and is blank
+## for all other function types.
 ## @seealso{profexplore, profile}
 ## @end deftypefn
 
@@ -38,10 +41,17 @@
 
 function profshow (data, n = 20)
 
-  if (nargin < 1 || nargin > 2)
+  if (nargin > 2)
     print_usage ();
   endif
 
+  if (nargin == 0)
+    data = profile ("info");
+  elseif (nargin == 1 && ! isstruct (data))
+    n = data;
+    data = profile ("info");
+  endif
+
   n = fix (n);
   if (! isscalar (n) || ! isreal (n) || ! (n > 0))
     error ("profile: N must be a positive integer");
@@ -53,30 +63,32 @@
   ## We want to sort by times in descending order.  For this, extract the
   ## times to an array, then sort this, and use the resulting index permutation
   ## to print out our table.
-  times = -[ data.FunctionTable.TotalTime ];
+  times = [ data.FunctionTable.TotalTime ];
+  totalTime = sum (times);
 
-  [~, p] = sort (times);
+  [~, p] = sort (times, "descend");
 
   ## For printing the table, find out the maximum length of a function name
   ## so that we can proportion the table accordingly.  Based on this,
   ## we can build the format used for printing table rows.
-  nameLen = length ("Function");
-  for i = 1 : n
-    nameLen = max (nameLen, length (data.FunctionTable(p(i)).FunctionName));
-  endfor
-  headerFormat = sprintf ("%%4s %%%ds %%4s %%12s %%12s\n", nameLen);
-  rowFormat = sprintf ("%%4d %%%ds %%4s %%12.3f %%12d\n", nameLen);
+  nameLen = max (length ("Function"),
+                 columns (char (data.FunctionTable(p(1:n)).FunctionName)));
+  headerFormat = sprintf ("%%4s %%%ds %%4s %%12s %%10s %%12s\n", nameLen);
+  rowFormat = sprintf ("%%4d %%%ds %%4s %%12.3f %%10.2f %%12d\n", nameLen);
 
-  printf (headerFormat, "#", "Function", "Attr", "Time (s)", "Calls");
-  printf ("%s\n", repmat ("-", 1, nameLen + 2 * 5 + 2 * 13));
+  printf (headerFormat, ...
+          "#", "Function", "Attr", "Time (s)", "Time (%)", "Calls");
+  printf ("%s\n", repmat ("-", 1, nameLen + 2 * 5 + 11 + 2 * 13));
+
   for i = 1 : n
     row = data.FunctionTable(p(i));
+    timePercent = 100 * row.TotalTime / totalTime;
     attr = "";
     if (row.IsRecursive)
       attr = "R";
     endif
-    printf (rowFormat, p(i), row.FunctionName, attr, ...
-            row.TotalTime, row.NumCalls);
+    printf (rowFormat, p(i), row.FunctionName, attr,
+            row.TotalTime, timePercent, row.NumCalls);
   endfor
 
 endfunction
@@ -96,7 +108,6 @@
 %! profile off;
 %! profshow (profile ("info"), 5);
 
-%!error profshow ()
 %!error profshow (1, 2, 3)
 %!error <N must be a positive integer> profshow (struct (), ones (2))
 %!error <N must be a positive integer> profshow (struct (), 1+i)
--- a/scripts/general/rotdim.m	Fri Aug 01 09:06:21 2014 -0400
+++ b/scripts/general/rotdim.m	Fri Aug 01 12:10:05 2014 -0400
@@ -152,8 +152,8 @@
 %!assert (rotdim (m, 3), rotdim (m, -1))
 %!assert (rotdim (m, 1), rotdim (m))
 
-## FIXME -- we need tests for multidimensional arrays and different
-## values of PLANE.
+## FIXME: We need tests for multidimensional arrays
+##        and different values of PLANE.
 
 %!error rotdim ()
 %!error rotdim (1, 2, 3, 4)
--- a/scripts/geometry/voronoi.m	Fri Aug 01 09:06:21 2014 -0400
+++ b/scripts/geometry/voronoi.m	Fri Aug 01 12:10:05 2014 -0400
@@ -74,14 +74,13 @@
   endif
 
   narg = 1;
+  hax = NaN;
   if (isscalar (varargin{1}) && ishandle (varargin{1}))
     hax = varargin{1};
-    if (! isaxes (harg))
-      error ("imagesc: HAX argument must be an axes object");
+    if (! isaxes (hax))
+      error ("voronoi: HAX argument must be an axes object");
     endif
     narg++;
-  elseif (nargout < 2)
-    hax = gca ();
   endif
 
   if (nargin < 1 + narg || nargin > 3 + narg)
@@ -108,6 +107,8 @@
 
   if (length (x) != length (y))
     error ("voronoi: X and Y must be vectors of the same length");
+  elseif (length (x) < 2)
+    error ("voronoi: minimum of 2 points needed");
   endif
 
   ## Add box to approximate rays to infinity. For Voronoi diagrams the
@@ -142,19 +143,35 @@
   edges = edges(:, [(edges(1, 1 :end - 1) != edges(1, 2 : end) | ...
                      edges(2, 1 :end - 1) != edges(2, 2 : end)), true]);
 
-  ## Eliminate the edges of the diagram representing the box
-  poutside = (1:rows (p)) ...
-      (p(:, 1) < xmin - xdelta | p(:, 1) > xmax + xdelta | ...
-       p(:, 2) < ymin - ydelta | p(:, 2) > ymax + ydelta);
-  edgeoutside = ismember (edges(1, :), poutside) & ...
-                ismember (edges(2, :), poutside);
-  edges(:, edgeoutside) = [];
+  if (numel (x) > 2)
+    ## Eliminate the edges of the diagram representing the box
+    poutside = (1:rows (p)) ...
+        (p(:, 1) < xmin - xdelta | p(:, 1) > xmax + xdelta | ...
+         p(:, 2) < ymin - ydelta | p(:, 2) > ymax + ydelta);
+    edgeoutside = ismember (edges(1, :), poutside) & ...
+                  ismember (edges(2, :), poutside);
+    edges(:, edgeoutside) = [];
+  else
+    ## look for the edge between the two given points
+    for edge = edges(1:2,:) 
+      if (det ([[[1;1],p(edge,1:2)];1,x(1),y(1)])
+          * det ([[[1;1],p(edge,1:2)];1,x(2),y(2)]) < 0)
+        edges = edge;
+        break;
+      endif
+    endfor
+    ## Use larger plot limits to make it more likely single bisector is shown.
+    xdelta = ydelta = max (xdelta, ydelta);
+  endif
 
   ## Get points of the diagram
   Vvx = reshape (p(edges, 1), size (edges));
   Vvy = reshape (p(edges, 2), size (edges));
 
   if (nargout < 2)
+    if (isnan (hax))
+      hax = gca ();
+    endif
     h = plot (hax, Vvx, Vvy, linespec{:}, x, y, '+');
     lim = [xmin, xmax, ymin, ymax];
     axis (lim + 0.1 * [[-1, 1] * xdelta, [-1, 1] * ydelta]);
@@ -179,5 +196,18 @@
 %! assert (vx(2,:), zeros (1, columns (vx)), eps);
 %! assert (vy(2,:), zeros (1, columns (vy)), eps);
 
-%% FIXME: Need input validation tests
+%!testif HAVE_QHULL
+%! ## Special case of just 2 points
+%! x = [0 1];  y = [1 0];
+%! [vx, vy] = voronoi (x,y);
+%! assert (vx, [-0.7; 1.7], eps);
+%! assert (vy, [-0.7; 1.7], eps);
 
+%% Input validation tests
+%!error voronoi ()
+%!error voronoi (ones (3,1))
+%!error voronoi (ones (3,1), ones (3,1), "bogus1", "bogus2", "bogus3")
+%!error <HAX argument must be an axes object> voronoi (0, ones (3,1), ones (3,1))
+%!error <X and Y must be vectors of the same length> voronoi (ones (3,1), ones (4,1))
+%!error <minimum of 2 points needed> voronoi (2.5, 3.5)
+
--- a/scripts/gui/module.mk	Fri Aug 01 09:06:21 2014 -0400
+++ b/scripts/gui/module.mk	Fri Aug 01 12:10:05 2014 -0400
@@ -3,6 +3,7 @@
 gui_PRIVATE_FCN_FILES = \
   gui/private/__file_filter__.m \
   gui/private/__fltk_file_filter__.m \
+  gui/private/__get_funcname__.m \
   gui/private/__is_function__.m \
   gui/private/__uigetdir_fltk__.m \
   gui/private/__uigetfile_fltk__.m \
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/gui/private/__get_funcname__.m	Fri Aug 01 12:10:05 2014 -0400
@@ -0,0 +1,42 @@
+## Copyright (C) 2014 Andreas Weber
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {@var{funcname} =} __get_funcname__ (@var{basename})
+## Internal function.
+##
+## Build function name for the current graphics toolkit according to schema
+## __[basename]_[graphics_toolkit]__, use fltk as default.
+## @end deftypefn
+
+## Author: Andreas Weber
+
+function funcname = __get_funcname__ (basename)
+
+  if (! __octave_link_enabled__ ())
+    tk = graphics_toolkit ();
+    funcname = strcat ("__", basename, "_", tk, "__");
+    if ((numel (tk) > 0) && (! strcmp(tk, "fltk")) && (! __is_function__ (funcname)))
+      warning ("%s: no implementation for toolkit '%s', using 'fltk' instead",basename, tk);
+    endif
+    funcname = strcat ("__", basename, "_fltk__");
+  else
+    funcname = "";
+  endif
+
+endfunction
--- a/scripts/gui/private/__is_function__.m	Fri Aug 01 09:06:21 2014 -0400
+++ b/scripts/gui/private/__is_function__.m	Fri Aug 01 12:10:05 2014 -0400
@@ -26,7 +26,7 @@
 function result = __is_function__ (func)
 
   existval = exist (func);
-  result = (existval == 2 || existval == 3 || existval == 5 || existval == 6);
+  result = (existval == 2 || existval == 3 || existval == 5);
 
 endfunction
 
--- a/scripts/gui/uigetdir.m	Fri Aug 01 09:06:21 2014 -0400
+++ b/scripts/gui/uigetdir.m	Fri Aug 01 12:10:05 2014 -0400
@@ -30,20 +30,7 @@
 
 function dirname = uigetdir (init_path = pwd, dialog_name = "Select Directory to Open")
 
-  if (! __octave_link_enabled__ ())
-    defaulttoolkit = get (0, "defaultfigure__graphics_toolkit__");
-    funcname = ["__uigetdir_", defaulttoolkit, "__"];
-    functype = exist (funcname);
-    if (! __is_function__ (funcname))
-      funcname = "__uigetdir_fltk__";
-      if (! __is_function__ (funcname))
-        error ("uigetdir: fltk graphics toolkit required");
-      elseif (! strcmp (defaulttoolkit, "gnuplot"))
-        warning ("uigetdir: no implementation for toolkit '%s', using 'fltk' instead",
-                 defaulttoolkit);
-      endif
-    endif
-  endif
+  funcname = __get_funcname__ (mfilename ());
 
   if (nargin > 2)
     print_usage ();
--- a/scripts/gui/uigetfile.m	Fri Aug 01 09:06:21 2014 -0400
+++ b/scripts/gui/uigetfile.m	Fri Aug 01 12:10:05 2014 -0400
@@ -66,21 +66,8 @@
 
 function [retfile, retpath, retindex] = uigetfile (varargin)
 
-  if (! __octave_link_enabled__ ())
-    defaulttoolkit = get (0, "defaultfigure__graphics_toolkit__");
-    funcname = ["__uigetfile_", defaulttoolkit, "__"];
-    functype = exist (funcname);
-    if (! __is_function__ (funcname))
-      funcname = "__uigetfile_fltk__";
-      if (! __is_function__ (funcname))
-        error ("uigetfile: fltk graphics toolkit required");
-      elseif (! strcmp (defaulttoolkit, "gnuplot"))
-        warning ("uigetfile: no implementation for toolkit '%s', using 'fltk' instead",
-               defaulttoolkit);
-      endif
-    endif
-  endif
-  
+  funcname = __get_funcname__ (mfilename ());
+
   if (nargin > 7)
     error ("uigetfile: number of input arguments must be less than eight");
   endif
--- a/scripts/gui/uiputfile.m	Fri Aug 01 09:06:21 2014 -0400
+++ b/scripts/gui/uiputfile.m	Fri Aug 01 12:10:05 2014 -0400
@@ -56,20 +56,7 @@
 
 function [retfile, retpath, retindex] = uiputfile (varargin)
 
-  if (! __octave_link_enabled__ ())
-    defaulttoolkit = get (0, "defaultfigure__graphics_toolkit__");
-    funcname = ["__uiputfile_", defaulttoolkit, "__"];
-    functype = exist (funcname);
-    if (! __is_function__ (funcname))
-      funcname = "__uiputfile_fltk__";
-      if (! __is_function__ (funcname))
-        error ("uiputfile: fltk graphics toolkit required");
-      elseif (! strcmp (defaulttoolkit, "gnuplot"))
-        warning ("uiputfile: no implementation for toolkit '%s', using 'fltk' instead",
-               defaulttoolkit);
-      endif
-    endif
-  endif
+  funcname = __get_funcname__ (mfilename ());
 
   if (nargin > 3)
     print_usage ();
--- a/scripts/help/__unimplemented__.m	Fri Aug 01 09:06:21 2014 -0400
+++ b/scripts/help/__unimplemented__.m	Fri Aug 01 12:10:05 2014 -0400
@@ -103,7 +103,7 @@
 
     ## control system
     case {"absorbDelay", "allmargin", "append", "augstate", "balreal", ...
-          "balred", "balredOptions", "bandwidth", "bdschur", "bode", ...
+          "balred", "balredOptions", "bdschur", "bode", ...
           "bodemag", "bodeoptions", "bodeplot", "c2d", "c2dOptions", ...
           "canon", "care", "chgFreqUnit", "chgTimeUnit", "connect", ...
           "connectOptions", "covar", "ctrb", "ctrbf", "ctrlpref", "d2c", ...
@@ -635,7 +635,6 @@
   "graymon",
   "griddedInterpolant",
   "gsvd",
-  "guidata",
   "guide",
   "guihandles",
   "handle",
@@ -649,8 +648,6 @@
   "hdfinfo",
   "hdfread",
   "hgexport",
-  "hgload",
-  "hgsave",
   "hgsetget",
   "hgtransform",
   "ichol",
@@ -671,10 +668,8 @@
   "interpstreamspeed",
   "iscom",
   "isinterface",
-  "isjava",
   "isocaps",
   "isstudent",
-  "javachk",
   "ldl",
   "libfunctions",
   "libfunctionsview",
@@ -684,7 +679,6 @@
   "light",
   "lightangle",
   "lighting",
-  "linkaxes",
   "linkdata",
   "listfonts",
   "loadlibrary",
@@ -736,7 +730,6 @@
   "ordqz",
   "ordschur",
   "padecoef",
-  "pan",
   "parseSoapResponse",
   "pathtool",
   "pcode",
@@ -761,7 +754,6 @@
   "readasync",
   "rng",
   "rotate",
-  "rotate3d",
   "scatteredInterpolant",
   "selectmoveresize",
   "sendmail",
--- a/scripts/help/doc.m	Fri Aug 01 09:06:21 2014 -0400
+++ b/scripts/help/doc.m	Fri Aug 01 12:10:05 2014 -0400
@@ -42,7 +42,7 @@
 
     if (nargin == 1)
       ## Get the directory where the function lives.
-      ## FIXME -- maybe we should have a better way of doing this.
+      ## FIXME: Maybe we should have a better way of doing this?
 
       if (ischar (fname))
         ftype = exist (fname);
@@ -86,7 +86,7 @@
         endif
       endif
 
-      ## FIXME -- don't change the order of the arguments below because
+      ## FIXME: Don't change the order of the arguments below because
       ## the info-emacs-info script currently expects --directory DIR as
       ## the third and fourth arguments.  Someone should fix that.
 
--- a/scripts/help/get_first_help_sentence.m	Fri Aug 01 09:06:21 2014 -0400
+++ b/scripts/help/get_first_help_sentence.m	Fri Aug 01 12:10:05 2014 -0400
@@ -28,7 +28,7 @@
 ##
 ## The optional output argument @var{status} returns the status reported by
 ## @code{makeinfo}.  If only one output argument is requested, and @var{status}
-## is non-zero, a warning is displayed.
+## is nonzero, a warning is displayed.
 ##
 ## As an example, the first sentence of this help text is
 ##
--- a/scripts/help/help.m	Fri Aug 01 09:06:21 2014 -0400
+++ b/scripts/help/help.m	Fri Aug 01 12:10:05 2014 -0400
@@ -163,7 +163,7 @@
 
   found = false;
 
-  dlist = find_dir_in_path (name, "all");
+  dlist = dir_in_loadpath (name, "all");
 
   for i = 1:numel (dlist)
     fname = make_absolute_filename (fullfile (dlist{i}, "Contents.m"));
--- a/scripts/help/which.m	Fri Aug 01 09:06:21 2014 -0400
+++ b/scripts/help/which.m	Fri Aug 01 12:10:05 2014 -0400
@@ -28,9 +28,21 @@
   if (nargin > 0 && iscellstr (varargin))
     m = __which__ (varargin{:});
 
+    ## Check whether each name is a variable, variables take precedence over
+    ## functions in name resolution.
+    for i = 1:nargin
+      m(i).is_variable = evalin ("caller",
+                                 ["exist (\"" m(i).name "\", \"var\")"], false);
+      if (m(i).is_variable)
+        m(i).file = "variable";
+      endif
+    endfor
+
     if (nargout == 0)
       for i = 1:nargin
-        if (isempty (m(i).file))
+        if (m(i).is_variable)
+          printf ("'%s' is a variable\n", m(i).name);
+        elseif (isempty (m(i).file))
           if (! isempty (m(i).type))
             printf ("'%s' is a %s\n",
                     m(i).name, m(i).type);
@@ -64,3 +76,17 @@
 
 %!assert (which ("_NO_SUCH_NAME_"), "")
 
+%!test
+%! x = 3;
+%! str = which ("x");
+%! assert (str, "variable");
+
+%!test
+%! str = which ("amd");
+%! assert (str(end-6:end), "amd.oct");
+%! amd = 12;
+%! str = which ("amd");
+%! assert (str, "variable");
+%! clear amd;
+%! str = which ("amd");
+%! assert (str(end-6:end), "amd.oct");
--- a/scripts/image/image.m	Fri Aug 01 09:06:21 2014 -0400
+++ b/scripts/image/image.m	Fri Aug 01 12:10:05 2014 -0400
@@ -111,6 +111,8 @@
       hax = newplot (hax);
     elseif (isempty (hax))
       hax = gca ();
+    else
+      hax = hax(1);
     endif
 
     htmp = __img__ (hax, do_new, x, y, img, varargin{chararg:end});
@@ -139,26 +141,20 @@
 
 function h = __img__ (hax, do_new, x, y, img, varargin)
 
-  ## FIXME: Hack for integer formats which use zero-based indexing
-  ##        Hack favors correctness of display over size of image in memory.
-  ##        True fix must be done in C++ code for renderer. 
-  if (ndims (img) == 2 && (isinteger (img) || islogical (img)))
-    img = single (img) + 1;
-  endif
-
   if (! isempty (img))
 
     if (isempty (x))
-      x = [1, columns(img)];
+      xdata = [];
+    else
+      xdata = x([1, end])(:).';  # (:).' is a hack to guarantee row vector
     endif
 
     if (isempty (y))
-      y = [1, rows(img)];
+      ydata = [];
+    else
+      ydata = y([1, end])(:).';
     endif
 
-    xdata = x([1, end])(:).';  # (:).' is a hack to guarantee row vector
-    ydata = y([1, end])(:).';
-
     if (numel (x) > 2 && numel (y) > 2)
       ## Test data for non-linear spacing which is unsupported
       tol = .01;  # 1% tolerance.  FIXME: this value was chosen without thought.
@@ -198,7 +194,7 @@
 
     endif  # ! isempty (img)
 
-    set (hax, "view", [0, 90], "ydir", "reverse", "layer", "bottom");
+    set (hax, "view", [0, 90], "ydir", "reverse", "layer", "top");
 
   endif  # do_new
 
@@ -225,4 +221,31 @@
 %!  h = image (-x, -y, img);
 %!  title ("image (-x, -y, img)");
 
+%!test
+%! ## test hidden properties x/ydatamode (bug #42121)
+%! hf = figure ("visible", "off");
+%! unwind_protect
+%!   nx = 64; ny = 64;
+%!   cdata = rand (ny, nx)*127;
+%!   hi = image (cdata);             # x/ydatamode is auto
+%!   assert (get (hi, "xdata"), [1 nx])
+%!   assert (get (hi, "ydata"), [1 ny])
+%!   set (hi, "cdata", cdata(1:2:end, 1:2:end))
+%!   assert (get (hi, "xdata"), [1 nx/2])
+%!   assert (get (hi, "ydata"), [1 ny/2])
+%! 
+%!   set (hi, "xdata", [10 100])     # xdatamode is now manual
+%!   set (hi, "ydata", [10 1000])    # ydatamode is now manual
+%!   set (hi, "cdata", cdata)
+%!   assert (get (hi, "xdata"), [10 100])
+%!   assert (get (hi, "ydata"), [10 1000])
+%! 
+%!   set (hi, "ydata", [])           # ydatamode is now auto
+%!   set (hi, "cdata", cdata(1:2:end, 1:2:end))
+%!   assert (get (hi, "xdata"), [10 100])
+%!   assert (get (hi, "ydata"), [1 ny/2])
+%! unwind_protect_cleanup
+%!   close (hf)
+%! end_unwind_protect
+
 ## FIXME: Need %!tests for linear
--- a/scripts/image/imfinfo.m	Fri Aug 01 09:06:21 2014 -0400
+++ b/scripts/image/imfinfo.m	Fri Aug 01 12:10:05 2014 -0400
@@ -18,8 +18,8 @@
 
 ## -*- texinfo -*-
 ## @deftypefn  {Function File} {@var{info} =} imfinfo (@var{filename})
-## @deftypefnx {Function File} {@var{info} =} imfinfo (@var{filename}, @var{ext})
 ## @deftypefnx {Function File} {@var{info} =} imfinfo (@var{url})
+## @deftypefnx {Function File} {@var{info} =} imfinfo (@dots{}, @var{ext})
 ## Read image information from a file.
 ##
 ## @code{imfinfo} returns a structure containing information about the image
@@ -148,14 +148,32 @@
 
 ## Author: Soren Hauberg <hauberg@gmail.com>
 
-function info = imfinfo (varargin)
+function info = imfinfo (filename, varargin)
   if (nargin < 1 || nargin > 2)
     print_usage ();
-  elseif (! ischar (varargin{1}))
+  elseif (! ischar (filename))
     error ("imfinfo: FILENAME must be a string");
-  elseif (nargin > 1 && ! ischar (varargin{2}))
+  elseif (nargin > 1 && ! ischar (ext))
     error ("imfinfo: EXT must be a string");
   endif
-  info = imageIO (@__imfinfo__, "info", varargin, varargin{:});
+  info = imageIO ("imfinfo", @__imfinfo__, "info", filename, varargin{:});
 endfunction
 
+## This test is the same as the similar one in imread. imfinfo must check
+## if file exists before calling __imfinfo_. This test confirm this.
+%!testif HAVE_MAGICK
+%! fmt = fmt_ori = imformats ("jpg");
+%! fmt.info = @true;
+%! error_thrown = false;
+%! imformats ("update", "jpg", fmt);
+%! unwind_protect
+%!   try
+%!     imread ("I sure hope this file does not exist.jpg");
+%!   catch
+%!     error_thrown = true;
+%!   end_try_catch
+%! unwind_protect_cleanup
+%!   imformats ("update", "jpg", fmt_ori);
+%! end_unwind_protect
+%! assert (error_thrown, true);
+
--- a/scripts/image/imformats.m	Fri Aug 01 09:06:21 2014 -0400
+++ b/scripts/image/imformats.m	Fri Aug 01 12:10:05 2014 -0400
@@ -266,11 +266,10 @@
 endfunction
 
 function match = find_ext_idx (formats, ext)
-  ## FIXME: is matlab sensitive to file extensions?
   ## XXX: what should we do if there's more than one hit?
   ##      Should this function prevent the addition of
   ##      duplicated extensions?
-  match = cellfun (@(x) any (strcmp (x, ext)), {formats.ext});
+  match = cellfun (@(x) any (strcmpi (x, ext)), {formats.ext});
 endfunction
 
 function bool = isa_magick (coder, filename)
@@ -281,34 +280,68 @@
   end_try_catch
 endfunction
 
+## When imread or imfinfo are called, the file must exist or the
+## function defined by imformats will never be called.  Because
+## of this, we must create a file for the tests to work.
 
-## changing the function to read
+## changing the function that does the reading
 %!testif HAVE_MAGICK
-%! fmt = imformats ("jpg");
-%! fmt.read = @(x) size (x, 2);
-%! imformats ("update", "jpg", fmt);
-%! assert (imread ("this is 30 characters long.jpg"), 30);
+%! fname = [tmpnam() ".jpg"];
+%! def_fmt = imformats ();
+%! fid = fopen (fname, "w");
+%! unwind_protect
+%!   fmt = imformats ("jpg");
+%!   fmt.read = @numel;
+%!   imformats ("update", "jpg", fmt);
+%!   assert (imread (fname), numel (fname));
+%! unwind_protect_cleanup
+%!   fclose (fid);
+%!   unlink (fname);
+%!   imformats (def_fmt);
+%! end_unwind_protect
 
 ## adding a new format
 %!testif HAVE_MAGICK
-%! fmt = imformats ("jpg");
-%! fmt.ext = "junk";
-%! fmt.read = @(x) true();
-%! imformats ("add", fmt);
-%! assert (imread ("some file.junk"), true);
+%! fname = [tmpnam() ".new_fmt"];
+%! def_fmt = imformats ();
+%! fid = fopen (fname, "w");
+%! unwind_protect
+%!   fmt = imformats ("jpg"); # take jpg as template
+%!   fmt.ext = "new_fmt";
+%!   fmt.read = @() true ();
+%!   imformats ("add", fmt);
+%!   assert (imread (fname), true);
+%! unwind_protect_cleanup
+%!   fclose (fid);
+%!   unlink (fname);
+%!   imformats (def_fmt);
+%! end_unwind_protect
 
-## adding multiple formats in one way
+## adding multiple formats at the same time
 %!testif HAVE_MAGICK
-%! fmt = imformats ("jpg");
-%! fmt.ext = "junk1";
-%! fmt.read = @(x) true();
-%! fmt(2) = fmt(1);
-%! fmt(2).ext = "junk2";
-%! imformats ("add", fmt);
-%! assert (imread ("some file.junk1"), true);
-%! assert (imread ("some file.junk2"), true);
+%! fname1 = [tmpnam() ".new_fmt1"];
+%! fid1 = fopen (fname1, "w");
+%! fname2 = [tmpnam() ".new_fmt2"];
+%! fid2 = fopen (fname2, "w");
+%! def_fmt = imformats ();
+%! unwind_protect
+%!   fmt = imformats ("jpg"); # take jpg as template
+%!   fmt.ext = "new_fmt1";
+%!   fmt.read = @() true();
+%!   fmt(2) = fmt(1);
+%!   fmt(2).ext = "new_fmt2";
+%!   imformats ("add", fmt);
+%!   assert (imread (fname1), true);
+%!   assert (imread (fname2), true);
+%! unwind_protect_cleanup
+%!   fclose (fid1);
+%!   fclose (fid2);
+%!   unlink (fname1);
+%!   unlink (fname2);
+%!   imformats (def_fmt);
+%! end_unwind_protect
 
-## changing format
+## changing format and resetting back to default
 %!testif HAVE_MAGICK
 %! ori_fmt = mod_fmt = imformats ("jpg");
 %! mod_fmt.description = "Another description";
@@ -319,10 +352,15 @@
 %! new_fmt = imformats ("jpg");
 %! assert (new_fmt.description, ori_fmt.description);
 
-## FIXME: how to test for error together with testif?
-## update to an invalid format
-#%!testif HAVE_MAGICK
-#%! fmt = imformats ("jpg");
-#%! fmt = rmfield (fmt, "read");
-#%! error imformats ("update", "jpg", fmt);
+## updating to an invalid format should cause an error
+%!testif HAVE_MAGICK
+%! fmt = imformats ("jpg");
+%! fmt = rmfield (fmt, "read");
+%! error_thrown = false;
+%! try
+%!   imformats ("update", "jpg", fmt);
+%! catch
+%!   error_thrown = true;
+%! end_try_catch
+%! assert (error_thrown, true);
 
--- a/scripts/image/imread.m	Fri Aug 01 09:06:21 2014 -0400
+++ b/scripts/image/imread.m	Fri Aug 01 12:10:05 2014 -0400
@@ -23,16 +23,16 @@
 
 ## -*- texinfo -*-
 ## @deftypefn  {Function File} {[@var{img}, @var{map}, @var{alpha}] =} imread (@var{filename})
-## @deftypefnx {Function File} {[@dots{}] =} imread (@var{filename}, @var{ext})
 ## @deftypefnx {Function File} {[@dots{}] =} imread (@var{url})
+## @deftypefnx {Function File} {[@dots{}] =} imread (@dots{}, @var{ext})
 ## @deftypefnx {Function File} {[@dots{}] =} imread (@dots{}, @var{idx})
 ## @deftypefnx {Function File} {[@dots{}] =} imread (@dots{}, @var{param1}, @var{val1}, @dots{})
 ## Read images from various file formats.
 ##
 ## Reads an image as a matrix from the file @var{filename}.  If there is
 ## no file @var{filename}, and @var{ext} was specified, it will look for
-## a file named @var{filename} and extension @var{ext}, i.e., a file named
-## @var{filename}.@var{ext}.
+## a file with the extension @var{ext}.  Finally, it will attempt to download
+## and read an image from @var{url}.
 ##
 ## The size and class of the output depends on the
 ## format of the image.  A color image is returned as an
@@ -75,7 +75,17 @@
 ## Controls the image region that is read.  Takes as value a cell array
 ## with two arrays of 3 elements @code{@{@var{rows} @var{cols}@}}.  The
 ## elements in the array are the start, increment and end pixel to be
-## read.  If the increment value is omitted, defaults to 1.
+## read.  If the increment value is omitted, defaults to 1.  For example,
+## the following are all equivalent:
+##
+## @example
+## @group
+## imread (filename, "PixelRegion", @{[200 600] [300 700]@});
+## imread (filename, "PixelRegion", @{[200 1 600] [300 1 700]@});
+## imread (filename)(200:600, 300:700);
+## @end group
+## @end example
+##
 ## @end table
 ##
 ## @seealso{imwrite, imfinfo, imformats}
@@ -88,23 +98,14 @@
 ## Author: Stefan van der Walt <stefan@sun.ac.za>
 ## Author: Andy Adler
 
-function [img, varargout] = imread (varargin)
+function [img, varargout] = imread (filename, varargin)
   if (nargin < 1)
     print_usage ();
-  elseif (! ischar (varargin{1}))
+  elseif (! ischar (filename))
     error ("imread: FILENAME must be a string");
   endif
-  ## In case the file format was specified as a separate argument we
-  ## do this. imageIO() will ignore the second part if filename on its
-  ## own is enough. And if the second argument was a parameter name instead
-  ## of an extension, it is still going to be passed to the next function
-  ## since we are passing the whole function input as well.
-  filename = {varargin{1}};
-  if (nargin > 1 && ischar (varargin {2}))
-    filename{2} = varargin{2};
-  endif
 
-  [img, varargout{1:nargout-1}] = imageIO (@__imread__, "read", filename, varargin{:});
+  [img, varargout{1:nargout-1}] = imageIO ("imread", @__imread__, "read", filename, varargin{:});
 endfunction
 
 
@@ -139,3 +140,66 @@
 %! assert (A(:,:,2), uint8 ([0, 255, 0; 255,  28, 255; 0, 255, 0]));
 %! assert (A(:,:,3), uint8 ([0, 255, 0; 255,  36, 255; 0, 255, 0]));
 
+%!function [r, cmap, a] = write_and_read (w, varargin)
+%!  filename = [tmpnam() ".tif"];
+%!  unwind_protect
+%!    imwrite (w, filename);
+%!    [r, cmap, a] = imread (filename, varargin{:});
+%!  unwind_protect_cleanup
+%!    unlink (filename);
+%!  end_unwind_protect
+%!endfunction
+
+## test PixelRegion option
+%!testif HAVE_MAGICK
+%! w = randi (255, 100, 100, "uint8");
+%! [r, cmap, a] = write_and_read (w, "PixelRegion", {[50 70] [20 40]});
+%! assert (r, w(50:70, 20:40))
+%! [r, cmap, a] = write_and_read (w, "PixelRegion", {[50 2 70] [20 3 40]});
+%! assert (r, w(50:2:70, 20:3:40))
+
+## If a file does not exist, it's the job of imread to check the file
+## exists before sending it over to __imread__ or whatever function
+## is defined in imformats to handle that specific format.  This is the
+## same in imfinfo.  So in this test we replace one format in imformats
+## with something that will not give an error if the file is missing
+## and make sure we do get an error.
+%!testif HAVE_MAGICK
+%! fmt = fmt_ori = imformats ("jpg");
+%! fmt.read = @true;
+%! error_thrown = false;
+%! imformats ("update", "jpg", fmt);
+%! unwind_protect
+%!   try
+%!     imread ("I sure hope this file does not exist.jpg");
+%!   catch
+%!     error_thrown = true;
+%!   end_try_catch
+%! unwind_protect_cleanup
+%!   imformats ("update", "jpg", fmt_ori);
+%! end_unwind_protect
+%! assert (error_thrown, true);
+
+## make one of the formats read, return what it received as input to
+## confirm that the input parsing is working correcly
+%!testif HAVE_MAGICK
+%! fname = [tmpnam() ".jpg"];
+%! def_fmt = imformats ();
+%! fid = fopen (fname, "w");
+%! unwind_protect
+%!   fmt = imformats ("jpg");
+%!   fmt.read = @(varargin) varargin;
+%!   imformats ("update", "jpg", fmt);
+%!   assert (imread (fname), {fname});
+%!   assert (imread (fname, "jpg"), {fname});
+%!   assert (imread (fname(1:end-4), "jpg"), {fname});
+%!   extra_inputs = {"some", 89, i, {6 7 8}};
+%!   assert (imread (fname, extra_inputs{:}), {fname, extra_inputs{:}});
+%!   assert (imread (fname, "jpg", extra_inputs{:}), {fname, extra_inputs{:}});
+%!   assert (imread (fname(1:end-4), "jpg", extra_inputs{:}), {fname, extra_inputs{:}});
+%! unwind_protect_cleanup
+%!   fclose (fid);
+%!   unlink (fname);
+%!   imformats (def_fmt);
+%! end_unwind_protect
+
--- a/scripts/image/imshow.m	Fri Aug 01 09:06:21 2014 -0400
+++ b/scripts/image/imshow.m	Fri Aug 01 12:10:05 2014 -0400
@@ -45,6 +45,9 @@
 ## @table @asis
 ## @item @qcode{"displayrange"}
 ## @var{value1} is the display range as described above.
+##
+## @item @qcode{"colormap"}
+## @var{value1} is the colormap to use when displaying an indexed image.
 ## 
 ## @item @qcode{"xdata"}
 ## If @var{value1} is a two element vector, it must contain horizontal axis
@@ -75,7 +78,7 @@
   endif
 
   display_range = NA;
-  true_color = false;
+  truecolor = false;
   indexed = false;
   xdata = ydata = [];
 
@@ -98,9 +101,9 @@
     endif
   elseif (size (im, 3) == 3)
     if (ismember (class (im), {"uint8", "uint16", "double", "single"}))
-      true_color = true;
+      truecolor = true;
     else
-      error ("imshow: color image must be uint8, uint16, double, or single");
+      error ("imshow: TrueColor image must be uint8, uint16, double, or single");
     endif
   else
     error ("imshow: expecting MxN or MxNx3 matrix for image");
@@ -114,34 +117,47 @@
         display_range = arg;
       elseif (columns (arg) == 3)
         indexed = true;
-        colormap (arg);
+        if (iscolormap (arg))
+          colormap (arg);
+        else
+          error ("imshow: invalid colormap MAP");
+        endif
       elseif (! isempty (arg))
-        error ("imshow: argument number %d is invalid", narg+1);
+        error ("imshow: argument number %d is invalid", narg);
       endif
     elseif (ischar (arg))
       switch (tolower (arg))
-        case "displayrange";
+        case "colormap"
+          map = varargin{narg++};
+          if (iscolormap (map))
+            colormap (map);
+          else
+            error ("imshow: invalid colormap");
+          endif
+        case "displayrange"
           display_range = varargin{narg++};
-        case "xdata";
+        case "parent"
+          warning ("imshow: parent argument is not implemented");
+        case {"truesize", "initialmagnification"}
+          warning ("image: zoom argument ignored -- use GUI features");
+        case "xdata"
           xdata = varargin{narg++};
           if (! isvector (xdata))
             error ("imshow: xdata must be a vector")
           endif
           xdata = [xdata(1) xdata(end)];
-        case "ydata";
+        case "ydata"
           ydata = varargin{narg++};
           if (! isvector (ydata))
-            error ("imshow: expect a vector for ydata")
+            error ("imshow: ydata must be a vector")
           endif
           ydata = [ydata(1) ydata(end)];
-        case {"truesize", "initialmagnification"}
-          warning ("image: zoom argument ignored -- use GUI features");
         otherwise
           warning ("imshow: unrecognized property %s", arg);
           narg++;
       endswitch
     else
-      error ("imshow: argument number %d is invalid", narg+1);
+      error ("imshow: argument number %d is invalid", narg);
     endif
   endwhile
 
@@ -159,46 +175,44 @@
     switch (t)
       case {"double", "single", "logical"}
         display_range = [0, 1];
-      case {"int8", "int16", "int32", "uint8", "uint16", "uint32"}
+      case {"uint8", "uint16", "int16"}
         display_range = [intmin(t), intmax(t)];
       otherwise
         error ("imshow: invalid data type for image");
     endswitch
   endif
 
-  nans = isnan (im(:));
-  if (any (nans))
-    warning ("Octave:imshow-NaN",
-             "imshow: pixels with NaN or NA values are set to minimum pixel value");
-    im(nans) = display_range(1);
-  endif
-
-  ## This is for compatibility.
-  if (! (indexed || (true_color && isinteger (im))) || islogical (im))
-    im = double (im);
+  if (isfloat (im))
+    nans = isnan (im(:));
+    if (any (nans))
+      warning ("Octave:imshow-NaN",
+               "imshow: pixels with NaN or NA values are set to minimum pixel value");
+      im(nans) = display_range(1);
+    endif
   endif
 
+  ## FIXME: Commented out 2014/05/01.  imagesc and 'clim' will automatically
+  ## take care of displaying out-of-range data clamped to the limits.
+  ## Eventually, this can be deleted if no problems arise.
   ## Clamp the image to the range boundaries
-  if (! (true_color || indexed || islogical (im)))
-    low = display_range(1);
-    high = display_range(2);
-    im(im < low) = low;
-    im(im > high) = high;
-  endif
+  ##if (! (truecolor || indexed || islogical (im)))
+  ##  low = display_range(1);
+  ##  high = display_range(2);
+  ##  im(im < low) = low;
+  ##  im(im > high) = high;
+  ##endif
 
-  if (true_color || indexed)
-    tmp = image (xdata, ydata, im);
+  if (truecolor || indexed)
+    htmp = image (xdata, ydata, im);
   else
-    tmp = image (xdata, ydata, im);
-    set (tmp, "cdatamapping", "scaled");
-    ## The backend is responsible for scaling to clim if necessary.
+    htmp = imagesc (xdata, ydata, im, display_range);
     set (gca (), "clim", display_range);
   endif
-  set (gca (), "visible", "off", "ydir", "reverse");
+  set (gca (), "visible", "off", "view", [0, 90], "ydir", "reverse", "layer", "top");
   axis ("image");
 
   if (nargout > 0)
-    h = tmp;
+    h = htmp;
   endif
 
 endfunction
@@ -244,5 +258,22 @@
 %% Test input validation
 %!error imshow ()
 %!error <IM must be an image> imshow ({"cell"})
+%!error <TrueColor image must be uint8> imshow (ones (3,3,3, "uint32"))
+%!error <TrueColor image must be uint8> imshow (ones (3,3,3, "int16"))
 %!error <expecting MxN or MxNx3 matrix> imshow (ones (4,4,4))
 
+%!test
+%! hf = figure ("visible", "off");
+%! unwind_protect
+%!   fail ("imshow ([1,1], [2 0 0])", "invalid colormap MAP");
+%!   fail ("imshow ([1,1], [1 0 0 0])", "argument number 2 is invalid"); 
+%!   fail ('imshow ([1,1], "colormap", [2 0 0])', "invalid colormap"); 
+%!   fail ('imshow ([1,1], "xdata", ones (2,2))', "xdata must be a vector"); 
+%!   fail ('imshow ([1,1], "ydata", ones (2,2))', "ydata must be a vector"); 
+%!   fail ('imshow ([1,1], "foobar")', "warning", "unrecognized property foobar")
+%!   fail ("imshow ([1,1], {1})", "argument number 2 is invalid"); 
+%!   fail ("imshow ([1+i,1-i])", "warning", "only showing real part of complex image");
+%! unwind_protect_cleanup
+%!   close (hf);
+%! end_unwind_protect
+
--- a/scripts/image/imwrite.m	Fri Aug 01 09:06:21 2014 -0400
+++ b/scripts/image/imwrite.m	Fri Aug 01 12:10:05 2014 -0400
@@ -49,7 +49,7 @@
 ##
 ## @item DelayTime
 ## For formats that accept animations (such as GIF), controls for how long a
-## frame is displayed until it moves to the next one. The value must be scalar
+## frame is displayed until it moves to the next one.  The value must be scalar
 ## (which will applied to all frames in @var{img}), or a vector of length
 ## equal to the number of frames in @var{im}.  The value is in seconds, must
 ## be between 0 and 655.35, and defaults to 0.5.
@@ -100,7 +100,7 @@
   fmt = imformats (ext);
   ## When there is no match, fmt will be a 1x1 structure with
   ## no fields, so we can't just use `isempty (fmt)'.
-  if (isempty (fieldnames (fmt)))
+  if (numfields (fmt) == 0)
     if (isempty (ext))
       error ("imwrite: no extension found for %s to identify the image format",
              filename);
--- a/scripts/image/ind2gray.m	Fri Aug 01 09:06:21 2014 -0400
+++ b/scripts/image/ind2gray.m	Fri Aug 01 12:10:05 2014 -0400
@@ -69,18 +69,19 @@
 
 %!shared i2g
 %! i2g = ind2gray (1:100, gray (100));
-%!assert (i2g, 0:1/99:1, eps);
-%!assert (gray2ind (i2g, 100), uint8 (0:99));
+%!
+%!assert (i2g, 0:1/99:1, eps)
+%!assert (gray2ind (i2g, 100), uint8 (0:99))
 
 %% Test input validation
 %!error ind2gray ()
 %!error ind2gray (1)
 %!error ind2gray (1,2,3)
-%!error <X must be an indexed image> ind2gray ({1}, jet (64))
+%!error <X must be an indexed image> ind2gray (ones (3,3,3), jet (64))
 %!error <X must be an indexed image> ind2gray (1+i, jet (64))
 %!error <X must be an indexed image> ind2gray (sparse (1), jet (64))
-%!error <X must be an indexed image> ind2gray (0, jet (64))
 %!error <X must be an indexed image> ind2gray (1.1, jet (64))
+%!error <X must be an indexed image> ind2gray ({1}, jet (64))
 %!error <MAP must be a valid colormap> ind2gray (1, {1})
 %!error <MAP must be a valid colormap> ind2gray (1, 1+i)
 %!error <MAP must be a valid colormap> ind2gray (1, ones (2,2,2))
@@ -88,3 +89,7 @@
 %!error <MAP must be a valid colormap> ind2gray (1, [-1])
 %!error <MAP must be a valid colormap> ind2gray (1, [2])
 
+%!warning <contains colors outside of colormap> ind2gray ([0 1 2], gray (5));
+%!warning <contains colors outside of colormap> ind2gray ([1 2 6], gray (5));
+%!warning <contains colors outside of colormap> ind2gray (uint8 ([1 2 5]), gray (5));
+
--- a/scripts/image/ind2rgb.m	Fri Aug 01 09:06:21 2014 -0400
+++ b/scripts/image/ind2rgb.m	Fri Aug 01 12:10:05 2014 -0400
@@ -82,23 +82,28 @@
 %! ## test basic usage with 1 and 3 outputs
 %! [rgb] = ind2rgb (img, map);
 %! [r, g, b] = ind2rgb (img, map);
-%!assert (ergb, rgb);
-%!assert (ergb, reshape ([r(:) g(:) b(:)], [size(img) 3]));
+%!
+%!assert (ergb, rgb)
+%!assert (ergb, reshape ([r(:) g(:) b(:)], [size(img) 3]))
+%!test
 %! ## test correction for integers
-%! img = uint8 (img -1);
+%! img = uint8 (img - 1);
 %! [rgb] = ind2rgb (img, map);
-%!assert (ergb, rgb);
-%! ## check it fails when image is a float with an index value of 0
-%!fail ("[rgb] = ind2rgb (double(img), map)")
+%! assert (ergb, rgb);
+%!test
+%! ## Check that values below lower bound are mapped to first color value 
+%! rgb = ind2rgb ([-1 0 2], gray (64));
+%! assert (rgb(:,1:2,:), zeros (1,2,3));
+%! assert (rgb(:,3,:), 1/63 * ones (1,1,3));
 
 %% Test input validation
 %!error ind2rgb ()
 %!error ind2rgb (1,2,3)
-%!error <X must be an indexed image> ind2rgb ({1}, jet (64))
+%!error <X must be an indexed image> ind2rgb (ones (3,3,3), jet (64))
 %!error <X must be an indexed image> ind2rgb (1+i, jet (64))
 %!error <X must be an indexed image> ind2rgb (sparse (1), jet (64))
-%!error <X must be an indexed image> ind2rgb (0, jet (64))
 %!error <X must be an indexed image> ind2rgb (1.1, jet (64))
+%!error <X must be an indexed image> ind2rgb ({1}, jet (64))
 %!error <MAP must be a valid colormap> ind2rgb (1, {1})
 %!error <MAP must be a valid colormap> ind2rgb (1, 1+i)
 %!error <MAP must be a valid colormap> ind2rgb (1, ones (2,2,2))
@@ -106,3 +111,8 @@
 %!error <MAP must be a valid colormap> ind2rgb (1, [-1])
 %!error <MAP must be a valid colormap> ind2rgb (1, [2])
 
+%!warning <contains colors outside of colormap> ind2rgb ([-1 1], jet (64));
+%!warning <contains colors outside of colormap> ind2rgb ([0 1 2], gray (5));
+%!warning <contains colors outside of colormap> ind2rgb ([1 2 6], gray (5));
+%!warning <contains colors outside of colormap> ind2rgb (uint8 ([1 2 5]), gray (5));
+
--- a/scripts/image/private/__imfinfo__.m	Fri Aug 01 09:06:21 2014 -0400
+++ b/scripts/image/private/__imfinfo__.m	Fri Aug 01 12:10:05 2014 -0400
@@ -17,56 +17,22 @@
 ## along with Octave; see the file COPYING.  If not, see
 ## <http://www.gnu.org/licenses/>.
 
-## This function does al the work of imfinfo. It exists here as private
+## This function does all the work of imfinfo. It exists here as private
 ## function so that imfinfo can use other functions if imformats is
 ## configured to. It is also needed so that imformats can create a
 ## function handle for it.
 
 ## Author: Soren Hauberg <hauberg@gmail.com>
 
-function info = __imfinfo__ (filename, ext)
+function info = __imfinfo__ (filename)
 
-  if (nargin < 1 || nargin > 2)
+  if (nargin != 1)
     print_usage ("imfinfo");
+  elseif (! ischar (filename))
+    error ("imfinfo: FILENAME must be a string");
   endif
 
-  if (! ischar (filename))
-    error ("imfinfo: FILENAME must be a string");
-  elseif (nargin >= 2 && ! ischar (ext))
-    error ("imfinfo: EXT must be a string");
-  endif
-  filename = tilde_expand (filename);
-
-  delete_file = false;
-  unwind_protect
-
-    fn = file_in_path (IMAGE_PATH, filename);
-    if (isempty (fn))
-      ## We couldn't find the file so...
-      if (nargin >= 2)
-        ## try adding a possible file extesion
-        filename  = [filename "." ext];
-        fn        = file_in_path (IMAGE_PATH, filename);
-        if (isempty (fn))
-          error ("imfinfo: cannot find file %s", filename);
-        endif
-      else
-        ## try filename as an URL
-        [fn, status, msg] = urlwrite (filename, tmpnam ());
-        if (! status)
-          error ("imfinfo: cannot find or download %s: %s", filename, msg);
-        endif
-        delete_file = true;
-      endif
-    endif
-
-    info = __magick_finfo__ (fn);
-
-  unwind_protect_cleanup
-    if (delete_file)
-      unlink (fn);
-    endif
-  end_unwind_protect
+  info = __magick_finfo__ (filename);
 
 endfunction
 
--- a/scripts/image/private/__imread__.m	Fri Aug 01 09:06:21 2014 -0400
+++ b/scripts/image/private/__imread__.m	Fri Aug 01 12:10:05 2014 -0400
@@ -44,18 +44,6 @@
   ## keep track of the varargin offset we're looking at each moment
   offset    = 1;
 
-  filename  = tilde_expand (filename);
-  fn        = file_in_path (IMAGE_PATH, filename);
-  if (isempty (fn) && nargin >= offset + 1 && ischar (varargin{offset}))
-    ## if we can't find the file, check if the next input is the file extension
-    filename  = [filename "." varargin{offset}];
-    fn        = file_in_path (IMAGE_PATH, filename);
-    offset++;
-  endif
-  if (isempty (fn))
-    error ("imread: cannot find %s", filename);
-  endif
-
   ## It is possible for an file with multiple pages to have very different
   ## images on each page. Specifically, they may have different sizes. Because
   ## of this, we need to first find out the index of the images to read so
@@ -90,114 +78,62 @@
     endif
   endif
 
-  try
-    ## Use information from the first image to be read to set defaults.
-    if (ischar (options.index) && strcmpi (options.index, "all"))
-      info = __magick_ping__ (fn, 1);
-    else
-      info = __magick_ping__ (fn, options.index(1));
-    endif
+  ## Use information from the first image to be read to set defaults.
+  if (ischar (options.index) && strcmpi (options.index, "all"))
+    info = __magick_ping__ (filename, 1);
+  else
+    info = __magick_ping__ (filename, options.index(1));
+  endif
 
-    ## Set default for options.
-    options.region = {1:1:info.rows 1:1:info.columns};
+  ## Set default for options.
+  options.region = {1:1:info.rows 1:1:info.columns};
+
+  for idx = offset:2:(numel (varargin) - offset + 1)
+    switch (tolower (varargin{idx}))
 
-    for idx = offset:2:(numel (varargin) - offset + 1)
-      switch (tolower (varargin{idx}))
+      case {"frames", "index"}
+        ## Do nothing. This options were already processed before the loop.
 
-        case {"frames", "index"}
-          ## Do nothing. This options were already processed before the loop.
-
-        case "pixelregion",
-          options.region = varargin{idx+1};
-          if (! iscell (options.region) || numel (options.region) != 2)
-            error ("imread: value for %s must be a 2 element cell array",
+      case "pixelregion",
+        options.region = varargin{idx+1};
+        if (! iscell (options.region) || numel (options.region) != 2)
+          error ("imread: value for %s must be a 2 element cell array",
+                 varargin{idx});
+        endif
+        for reg_idx = 1:2
+          if (numel (options.region{reg_idx}) == 3)
+            ## do nothing
+          elseif (numel (options.region{reg_idx}) == 2)
+            options.region{reg_idx}(3) = options.region{reg_idx}(2);
+            options.region{reg_idx}(2) = 1;
+          else
+            error ("imread: range for %s must be a 2 or 3 element vector",
                    varargin{idx});
           endif
-          for reg_idx = 1:2
-            if (numel (options.region{reg_idx}) == 3)
-              ## do nothing
-            elseif (numel (options.region{reg_idx}) == 2)
-              options.region{reg_idx}(3) = options.region{reg_idx}(2);
-              options.region{reg_idx}(2) = 1;
-            else
-              error ("imread: range for %s must be a 2 or 3 element vector",
-                     varargin{idx});
-            endif
-            options.region{reg_idx} = floor (options.region{reg_idx}(1)): ...
-                                      floor (options.region{reg_idx}(2)): ...
-                                      floor (options.region{reg_idx}(3));
-          endfor
-          if (options.region{1}(end) > info.rows)
-            error ("imread: end ROWS for PixelRegions option is larger than image height");
-          elseif (options.region{2}(end) > info.columns)
-            error ("imread: end COLS for PixelRegions option is larger than image width");
-          endif
-
-        case "info",
-          ## We ignore this option. This parameter exists in Matlab to
-          ## speed up the reading of multipage TIFF by passing a structure
-          ## that contains information about the start on the file of each
-          ## page.  We can't control it through GraphicsMagic but at least
-          ## we allow to load multiple pages with one command.
-
-        otherwise
-          error ("imread: invalid PARAMETER `%s'", varargin{idx});
-
-      endswitch
-    endfor
-
-    [varargout{1:nargout}] = __magick_read__ (fn, options);
+          options.region{reg_idx} = floor (options.region{reg_idx}(1)): ...
+                                    floor (options.region{reg_idx}(2)): ...
+                                    floor (options.region{reg_idx}(3));
+        endfor
+        if (options.region{1}(end) > info.rows)
+          error ("imread: end ROWS for PixelRegions option is larger than image height");
+        elseif (options.region{2}(end) > info.columns)
+          error ("imread: end COLS for PixelRegions option is larger than image width");
+        endif
 
-  catch
-    ## If we can't read it with Magick, maybe the image is in Octave's
-    ## native image format.  This is from back before Octave had 'imread'
-    ## and 'imwrite'. Then we had the functions 'loadimage' and 'saveimage'.
-    ##
-    ## This "image format" seems to be any file that can be read with
-    ## load() and contains 2 variables.  The variable named "map" is a
-    ## colormap and must exist whether the image is indexed or not. The
-    ## other variable must be named "img" or "X" for a "normal" or
-    ## indexed image.
-    ##
-    ## FIXME: this has been deprecated for the next major release (3.8 or 4.0).
-    ##        If someone wants to revive this as yet another image format, a
-    ##        separate Octave package can be written for it, that register the
-    ##        format through imformats.
-
-    magick_error = lasterr ();
-
-    img_field = false;
-    x_field   = false;
-    map_field = false;
+      case "info",
+        ## We ignore this option. This parameter exists in Matlab to
+        ## speed up the reading of multipage TIFF by passing a structure
+        ## that contains information about the start on the file of each
+        ## page.  We can't control it through GraphicsMagic but at least
+        ## we allow to load multiple pages with one command.
 
-    try
-      vars = load (fn);
-      if (isstruct (vars))
-        img_field = isfield (vars, "img");
-        x_field   = isfield (vars, "X");
-        map_field = isfield (vars, "map");
-      endif
-    catch
-      error ("imread: invalid image file: %s", magick_error);
-    end_try_catch
+      otherwise
+        error ("imread: invalid PARAMETER `%s'", varargin{idx});
 
-    if (map_field && (img_field || x_field))
-      varargout{2} = vars.map;
-      if (img_field)
-        varargout{1} = vars.img;
-      else
-        varargout{1} = vars.X;
-      endif
-      persistent warned = false;
-      if (! warned)
-        warning ("Octave's native image format has been deprecated.");
-        warned = true;
-      endif
-    else
-      error ("imread: invalid Octave image file format");
-    endif
+    endswitch
+  endfor
 
-  end_try_catch
+  [varargout{1:nargout}] = __magick_read__ (filename, options);
 
 endfunction
 
@@ -205,10 +141,6 @@
 ## can be defined in two places, but only in one place can it also be the
 ## string "all"
 function bool = is_valid_index_option (arg)
-  ## is the index option
-  bool = false;
-  if (isvector (arg) && isnumeric (arg) && isreal (arg))
-    bool = true;
-  endif
+  bool = isvector (arg) && isnumeric (arg) && isreal (arg);
 endfunction
 
--- a/scripts/image/private/imageIO.m	Fri Aug 01 09:06:21 2014 -0400
+++ b/scripts/image/private/imageIO.m	Fri Aug 01 12:10:05 2014 -0400
@@ -16,54 +16,111 @@
 ## along with Octave; see the file COPYING.  If not, see
 ## <http://www.gnu.org/licenses/>.
 
-## This function simply connects imread and imfinfo() to the function
-## to be used based on their format. It does it by checking the file extension
-## of the file and redirecting to the appropriate function after checking
-## with imformats.
+## This function the image input functions imread() and imfinfo() to the
+## functions that will actually be used, based on their format.  See below
+## on the details on how it identifies the format, and to what it defaults.
+##
+## It will change the input arguments that were passed to imread() and
+## imfinfo().  It will change the filename to provide the absolute filepath
+## for the file, it will extract the possible format name from the rest of
+## the input arguments (in case there was one), and will give an error if
+## the file can't be found.
 ##
-## First argument is a function handle for the default imageIO function (what
-## to use if the file extension for the image file is not listed by imformats).
-## Second argument is the fieldname in the struct returned by imformats with a
-## function handle for the function to use. Third argument is a cell array, its
-## first element the filename, and the second, an optional file extension to
-## add to filename, if filename alone does not exist. All the others are the
-## original input arguments passed to the original imageIO function which will
-## be passed on to the destination function.
+## Usage:
 ##
-## No input checking whatsoever is performed. That should be performed by the
-## function calling it.
-
-function varargout = imageIO (core_func, fieldname, filename, varargin)
+## func      - Function name to use on error message.
+## core_func - Function handle for the default function to use if we can't
+##             find the format in imformats.
+## fieldname - Name of the field in the struct returned by imformats that
+##             has the function to use.
+## filename  - Most likely the first input argument from the function that
+##             called this. May be missing the file extension which can be
+##             on varargin.
+## varargin  - Followed by all the OTHER arguments passed to imread and
+##             imfinfo.
 
-  ## It should not be this function job to check if the file exists or not.
-  ## However, we need to know the file extension to use with imformats and
-  ## that means we need to know the actual filename that will be used which
-  ## is dependent on whether a file exists.
-  ##
-  ## If a file named filename{1} exists, then that's it, we will use that
-  ## wether it has an extension or not. If it does not exist and we have
-  ## something in filename{2}, then we will consider it the file extension.
-  ## Note the detail that if we find a file using filename{1} only, then we
-  ## should completely ignore filename{2}. It won't even be used by
-  ## imformats() at all, even if filename{1} has no extension to use with
-  ## imformats().
-  if (isscalar (filename) || ! isempty (file_in_path (IMAGE_PATH, filename{1})))
-    [~, ~, ext] = fileparts (filename{1});
-    if (! isempty (ext))
-      ## remove dot from extension
-      ext = ext(2:end);
-    endif
-  else
-    ext = filename{2};
+function varargout = imageIO (func, core_func, fieldname, filename, varargin)
+
+  ## First thing: figure out the filename and possibly download it.
+  ## The first attempt is to try the filename and see if it exists.  If it
+  ## does not, we try to add the next argument since the file extension can
+  ## be given as a separate argument.  If we still can't find the file, it
+  ## can be a URL.  Lastly, if we still didn't found a file, try adding the
+  ## extension to the URL
+
+  file_2_delete = false;  # will we have to remove the file in the end?
+  persistent abs_path = @(x) file_in_path (IMAGE_PATH, tilde_expand (x));
+
+  ## Filename was given with file extension
+  fn = abs_path (filename);
+  if (isempty (fn) && ! isempty (varargin))
+    ## Maybe if we add a file extension
+    fn = abs_path ([filename "." varargin{1}]);
   endif
 
-  fmt = imformats (ext);
-  ## When there is no match, fmt will be a 1x1 structure with no fields,
-  ## so we can't just use `isempty (fmt)'.
-  if (isempty (fieldnames (fmt)))
-    [varargout{1:nargout}] = core_func (varargin{:});
-  else
-    [varargout{1:nargout}] = fmt.(fieldname) (varargin{:});
+  ## Maybe we have an URL
+  if (isempty (fn))
+    file_2_delete = true; # mark file for deletion
+    [fn, ~] = urlwrite (filename, tmpnam ());
+    ## Maybe the URL is missing the file extension
+    if (isempty (fn) && ! isempty (varargin))
+      [fn, ~] = urlwrite ([filename "." varargin{1}], tmpnam ());
+    endif
+
+    if (isempty (fn))
+      error ("%s: unable to find file %s", func, filename);
+    endif
   endif
+
+  ## unwind_protect block because we may have a file to remove in the end
+  unwind_protect
+
+    ## When guessing the format to use, we first check if the second
+    ## argument is a format defined in imformats.  If so, we remove it
+    ## from the rest of arguments before passing them on.  If not, we
+    ## try to guess the format from the file extension.  Finally, if
+    ## we still don't know the format, we use the Octave core functions
+    ## which is the same for all formats.
+    foo = []; # the function we will use
+
+    ## We check if the call to imformats (ext) worked using
+    ## "numfields (fmt) > 0 because when it fails, the returned
+    ## struct is not considered empty.
+
+    ## try the second input argument
+    if (! isempty (varargin) && ischar (varargin{1}))
+      fmt = imformats (varargin{1});
+      if (numfields (fmt) > 0)
+        foo = fmt.(fieldname);
+        varargin(1) = []; # remove format name from arguments
+      endif
+    endif
+
+    ## try extension from file name
+    if (isempty (foo))
+      [~, ~, ext] = fileparts (fn);
+      if (! isempty (ext))
+        ## remove dot from extension
+        ext = ext(2:end);
+      endif
+      fmt = imformats (ext);
+      if (numfields (fmt) > 0)
+        foo = fmt.(fieldname);
+      endif
+    endif
+
+    ## use the core function
+    if (isempty (foo))
+      foo = core_func;
+    endif
+
+    [varargout{1:nargout}] = foo (fn, varargin{:});
+
+  unwind_protect_cleanup
+    if (file_2_delete)
+      unlink (fn);
+    endif
+  end_unwind_protect
+
 endfunction
 
--- a/scripts/image/private/ind2x.m	Fri Aug 01 09:06:21 2014 -0400
+++ b/scripts/image/private/ind2x.m	Fri Aug 01 12:10:05 2014 -0400
@@ -22,12 +22,13 @@
 function [x, map] = ind2x (caller, x, map)
 
   ## Check if X is an indexed image.
-  ## an indexed image is defined has having only 2D, and that's how Matlab
+  ## An indexed image is defined has having only 2D, and that's how Matlab
   ## behaves.  But we want to support ND images, so we will allow up to 4D
-  ## and check that the 3rd is a singleton
-  if (all (ndims (x) != [2 4]) || size (x, 3) != 1 || issparse (x) ||
-      (isfloat (x) && ! isindex (x)) ||
-      ! any (strcmp (class (x), {"uint8", "uint16", "single", "double"})))
+  ## and check that the 3rd dimension is a singleton.
+  if (all (ndims (x) != [2 4]) || size (x, 3) != 1
+      || iscomplex (x) || issparse (x)
+      || (isfloat (x) && x != fix (x))
+      || ! any (strcmp (class (x), {"uint8", "uint16", "single", "double"})))
     error ("%s: X must be an indexed image", caller);
   endif
 
@@ -36,10 +37,20 @@
     error ("%s: MAP must be a valid colormap", caller);
   endif
 
-  ## Do we have enough colors in the color map?
-  ## there's an offset of 1 when the indexed image is an integer class so we fix
-  ## it now and convert it to float only if really necessary and even then only
-  ## to single precision since that is enough for both uint8 and uint16.
+  ## Any color indices below the lower bound of the color map are modified
+  ## to point to the first color in the map (see bug #41851).
+  if (isfloat (x))
+    invalid_idx = x < 1;
+    if (any (invalid_idx(:)))
+      warning (["Octave:" caller ":invalid-idx-img"],
+               [caller ": indexed image contains colors outside of colormap"]);
+      x(invalid_idx) = 1;
+    endif
+  endif
+
+  ## Switch to using 1-based indexing.
+  ## It is possible that an integer storage class may not have enough room
+  ## to make the switch, in which case we convert the data to single.
   maxidx = max (x(:));
   if (isinteger (x))
     if (maxidx == intmax (class (x)))
@@ -49,9 +60,12 @@
     maxidx += 1;
   endif
 
+  ## When there are more colors in the image, than there are in the map,
+  ## pad the colormap with the last color in the map for Matlab compatibility.
   num_colors = rows (map);
   if (num_colors < maxidx)
-    ## Pad with the last color in the map for Matlab compatibility
+    warning (["Octave:" caller ":invalid-idx-img"],
+             [caller ": indexed image contains colors outside of colormap"]);
     pad = repmat (map(end,:), maxidx - num_colors, 1);
     map(end+1:maxidx, :) = pad;
   endif
--- a/scripts/io/importdata.m	Fri Aug 01 09:06:21 2014 -0400
+++ b/scripts/io/importdata.m	Fri Aug 01 12:10:05 2014 -0400
@@ -146,8 +146,7 @@
     ## i.e., output = output.onlyFieldLeft
 
     ## Update the list of fields
-    fields = fieldnames (output);
-    if (numel (fields) == 1)
+    if (numfields (output) == 1)
       output = output.(fields{1});
     endif
   endif
@@ -210,11 +209,33 @@
 
   endwhile
 
-  fclose (fid);
+  if (row == -1)
+    ## No numeric data found => return file as cellstr array
+    ## 1. Read as char string
+    fseek (fid, 0, "bof");
+    output = fread (fid, Inf, "*char")';
+    fclose (fid);
+    ## 2. Find EOL type
+    idx = find (output(1:min (4096, length (output))) == "\n", 1) - 1;
+    if (isindex (idx) && output(idx) == "\r")
+      dlm = "\r\n";
+    else
+      dlm = "\n";
+    endif
+    ## 3. Split each line into a cell (column vector)
+    output = strsplit (output, dlm)';
+    ## 4. Remove last cell (for files with -proper- EOL before EOF)
+    if (isempty (output{end}))
+      output(end) = [];
+    endif
+    ## 5. Return after setting some output data
+    delimiter = "";
+    header_rows = numel (output);
+    return;
+  else
+    fclose (fid);
+  endif
 
-  if (row == -1)
-    error ("importdata: Unable to determine delimiter");
-  endif
   if (num_header_rows >= 0)
     header_rows = num_header_rows;
   endif
@@ -498,6 +519,30 @@
 %! assert (d, "\t");
 %! assert (h, 0);
 
+%!test
+%! ## Only text / no numeric data; \n as EOL
+%! fn  = tmpnam ();
+%! fid = fopen (fn, "w");
+%! fputs (fid, "aaaa 11\nbbbbb 22\nccccc 3\n");
+%! fclose (fid);
+%! [a, d, h] = importdata (fn);
+%! unlink (fn);
+%! assert (a, {"aaaa 11"; "bbbbb 22"; "ccccc 3"});
+%! assert (d, "");
+%! assert (h, 3);
+
+%!test
+%! ## Only text / no numeric data; \r\n as EOL; missing last EOL before EOF
+%! fn  = tmpnam ();
+%! fid = fopen (fn, "w");
+%! fputs (fid, "aaaa 11\r\nbbbbb 22\r\nccccc 3");
+%! fclose (fid);
+%! [a, d, h] = importdata (fn);
+%! unlink (fn);
+%! assert (a, {"aaaa 11"; "bbbbb 22"; "ccccc 3"});
+%! assert (d, "");
+%! assert (h, 3);
+
 %!error importdata ()
 %!error importdata (1,2,3,4)
 %!error <FNAME must be a string> importdata (1)
--- a/scripts/io/strread.m	Fri Aug 01 09:06:21 2014 -0400
+++ b/scripts/io/strread.m	Fri Aug 01 12:10:05 2014 -0400
@@ -249,8 +249,8 @@
             elseif (iscellstr (varargin{n+1}) && numel (varargin{n+1}) == 2)
               [comment_start, comment_end] = deal (varargin{n+1}{:});
             else
-              ## FIXME - a user may have numeric values specified: {'//', 7}
-              ##         this will lead to an error in the warning message
+              ## FIXME: A user may have numeric values specified: {'//', 7}
+              ##        this will lead to an error in the warning message
               error ("strread: unknown or unrecognized comment style '%s'",
                       varargin{n+1});
             endif
@@ -690,8 +690,8 @@
       endif
 
       ## Map to format
-      ## FIXME - add support for formats like "<%s>", "%[a-zA-Z]"
-      ##         Someone with regexp experience is needed.
+      ## FIXME: Add support for formats like "<%s>", "%[a-zA-Z]"
+      ##        Someone with regexp experience is needed.
       switch (fmt_words{m}(1:min (2, length (fmt_words{m}))))
         case "%s"
           if (pad_out)
@@ -701,7 +701,7 @@
           k++;
         case {"%d", "%u", "%f", "%n"}
           n = cellfun ("isempty", data);
-          ### FIXME - erroneously formatted data lead to NaN, not an error
+          ### FIXME: Erroneously formatted data lead to NaN, not an error
           data = str2double (data);
           if (! isempty (regexp (fmt_words{m}, "%[du]")))
             ## Cast to integer
@@ -722,8 +722,8 @@
           switch (fmt_words{m}(ew+1))
             case {"d", "u", "f", "n"}
               n = cellfun ("isempty", data);
-              ### FIXME - erroneously formatted data lead to NaN, not an error
-              ###         => ReturnOnError can't be implemented for numeric data
+              ### FIXME: Erroneously formatted data lead to NaN, not an error
+              ###        => ReturnOnError can't be implemented for numeric data
               data = str2double (strtrunc (data, swidth));
               data(n) = numeric_fill_value;
               if (pad_out)
--- a/scripts/io/textread.m	Fri Aug 01 09:06:21 2014 -0400
+++ b/scripts/io/textread.m	Fri Aug 01 12:10:05 2014 -0400
@@ -135,7 +135,7 @@
   endif
  
   ## Now that we know what EOL looks like, we can process format_repeat_count.
-  ## FIXME The below isn't ML-compatible: counts lines, not format string uses
+  ## FIXME: The below isn't ML-compatible: counts lines, not format string uses
   if (isfinite (nlines) && (nlines > 0))
     l_eol_char = length (eol_char);
     eoi = findstr (str, eol_char);
--- a/scripts/io/textscan.m	Fri Aug 01 09:06:21 2014 -0400
+++ b/scripts/io/textscan.m	Fri Aug 01 12:10:05 2014 -0400
@@ -316,13 +316,15 @@
       ## See if lowermost data row must be completed
       pad = mod (numel (C{1}), ncols);
       if (pad)
-        ## Textscan returns NaNs for empty fields
-        C(1) = [C{1}; NaN(ncols - pad, 1)]; 
-      endif
-      ## Replace NaNs with EmptyValue, if any
-      ipos = find (strcmpi (args, "emptyvalue"));
-      if (ipos)
-        C{1}(find (isnan (C{1}))) = args{ipos+1};
+        ## Pad output with emptyvalues (rest has been done by stread.m)
+        emptv = find (strcmpi (args, "emptyvalue"));
+        if (isempty (emptv))
+          ## By default textscan returns NaNs for empty fields
+          C(1) = [C{1}; NaN(ncols - pad, 1)];
+        else
+          ## Otherwise return supplied emptyvalue. Pick last occurrence
+          C(1) = [C{1}; repmat(args{emptv(end)+1}, ncols - pad, 1)];
+        endif
       endif
       ## Compute nr. of rows
       nrows = floor (numel (C{1}) / ncols);
@@ -666,3 +668,12 @@
 %!test
 %! assert (textscan ("123", "", "whitespace", " "){:}, 123);
 
+%% Bug #42343-1, just test supplied emptyvalue (actually done by strread.m)
+%!test
+%! assert (textscan (",NaN", "", "delimiter", "," ,"emptyValue" ,Inf), {Inf, NaN});
+
+%% Bug #42343-2, test padding with supplied emptyvalue (done by textscan.m)
+%!test
+%! a = textscan (",1,,4\nInf,  ,NaN", "", "delimiter", ",", "emptyvalue", -10);
+%! assert (cell2mat (a), [-10, 1, -10, 4; Inf, -10, NaN, -10]);
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/java/javachk.m	Fri Aug 01 12:10:05 2014 -0400
@@ -0,0 +1,151 @@
+## Copyright (C) 2014 Philip Nienhuis
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn  {Function File} {} javachk (@var{feature})
+## @deftypefnx {Function File} {} javachk (@var{feature}, @var{component})
+## @deftypefnx {Function File} {@var{msg} =} javachk (@dots{})
+## Check for the presence of the Java @var{feature} in the current session
+## and print or return an error message if it is not.
+##
+## Possible features are:
+##
+## @table @asis
+## @item @qcode{"awt"}
+## Abstract Window Toolkit for GUIs.
+##
+## @item @qcode{"desktop"}
+## Interactive desktop is running.
+##
+## @item @qcode{"jvm"}
+## Java Virtual Machine.
+##
+## @item @qcode{"swing"}
+## Swing components for lightweight GUIs.
+## @end table
+##
+## If @var{feature} is supported and:
+##
+## @itemize @bullet
+## @item
+## No output argument is requested:
+##
+## Return an empty string
+##
+## @item
+## An output argument is requested:
+##
+## Return a struct with fields @qcode{"feature"} and @qcode{"identifier"}
+## both empty
+##
+## @end itemize
+##
+## If @var{feature} is not supported and:
+##
+## @itemize @bullet
+## @item
+## No output argument is requested:
+##
+## Emit an error message.
+##
+## @item
+## An output argument is requested:
+##
+## Return a struct with field @qcode{"feature"} set to @var{feature} and
+## field @qcode{"identifier"} set to @var{component}
+##
+## @end itemize
+##
+## The optional input @var{component} will be used in place of @var{feature}
+## in any error messages for greater specificity.
+##
+## @code{javachk} determines if specific Java features are available in an
+## Octave session.  This function is provided for scripts which may alter
+## their behavior based on the availability of Java.  The feature
+## @qcode{"desktop"} is never available as Octave has no Java-based desktop.
+## Other features may be available if Octave was compiled with the Java
+## Interface and Java is installed.
+##
+## @seealso{error, usejava}
+## @end deftypefn
+
+## Author: Philip Nienhuis <prnienhuis at users.sf.net>
+## Created: 2014-04-19
+
+function msg = javachk (feature, component="")
+
+  msg = "";
+  chk = false;
+  switch (feature)
+    ## For each feature, try methods() on a Java class of a feature
+    case "awt"
+      try
+        dum = methods ("java.awt.Frame");
+        chk = true;
+      end_try_catch
+    case "desktop"
+      ## Octave has no Java based GUI/desktop, leave chk = false
+    case "jvm"
+      try
+        dum = methods ("java.lang.Runtime");
+        chk = true;
+      end_try_catch
+    case "swing"
+      try
+        dum = methods ("javax.swing.Popup");
+        chk = true;
+      end_try_catch
+    otherwise
+      error ("javachk: unrecognized feature '%s', can be one of 'awt'|'desktop'|'jvm'|'swing'\n", feature);
+  endswitch
+
+  if (! chk)
+    ## Desired feature not present
+    if (nargout >= 1)
+      msg.message = sprintf ("javachk: %s is not supported", feature);
+      msg.identifier = component;
+    else
+      if (! isempty (component))
+        err = sprintf ("javachk: %s is not supported\n", component);
+      else
+        err = sprintf ("javachk: %s is not supported\n", feature);
+      endif
+      error (err);
+    endif
+  endif
+
+endfunction
+
+
+%!error <javachk: desktop is not supported> javachk ("desktop")
+%!error <Java DESKTOP is not supported> javachk ("desktop", "Java DESKTOP")
+%!test
+%! msg = javachk ("desktop");
+%! assert (msg.message, "javachk: desktop is not supported");
+%! assert (msg.identifier, "");
+%!test
+%! msg = javachk ("desktop", "Java DESKTOP");
+%! assert (msg.message, "javachk: desktop is not supported");
+%! assert (msg.identifier, "Java DESKTOP");
+
+%!testif HAVE_JAVA
+%! assert (javachk ("jvm"), "");
+
+%% Test input validation
+%!error <javachk: unrecognized feature 'foobar'> javachk ("foobar")
+
--- a/scripts/java/javaclasspath.m	Fri Aug 01 09:06:21 2014 -0400
+++ b/scripts/java/javaclasspath.m	Fri Aug 01 12:10:05 2014 -0400
@@ -54,7 +54,11 @@
 ## @seealso{javaaddpath, javarmpath}
 ## @end deftypefn
 
-function varargout = javaclasspath (which)
+function [path1, path2] = javaclasspath (which)
+
+  if (nargin > 1)
+    print_usage ();
+  endif
 
   ## dynamic classpath
   dynamic_path = javaMethod ("getClassPath", "org.octave.ClassHelper");
@@ -70,46 +74,39 @@
     static_path_list = {};
   endif
 
-  switch (nargin)
-    case 0
-      switch (nargout)
-        case 0
-          disp_path_list ("STATIC", static_path_list)
-          disp ("");
-          disp_path_list ("DYNAMIC", dynamic_path_list)
+  if (nargout == 0)
+    if (! nargin)
+      which = "-all";
+    endif
+    switch (tolower (which))
+      case "-dynamic", disp_path_list ("DYNAMIC", dynamic_path_list);
+      case "-static",  disp_path_list ("STATIC", static_path_list);
+      case "-all"
+        disp_path_list ("STATIC", static_path_list);
+        disp ("");
+        disp_path_list ("DYNAMIC", dynamic_path_list);
+      otherwise
+        error ("javaclasspath: invalid value for WHAT");
+    endswitch
 
-        case 1
-          varargout{1} = cellstr (dynamic_path_list);
-
-        case 2
-          varargout{1} = cellstr (dynamic_path_list);
-          varargout{2} = cellstr (static_path_list);
+  else
+    if (! nargin)
+      ## This is to allow retrieval of both paths in separate variables with
+      ## a single call to javaclasspath(). Matlab returns only the -dynamic
+      ## path in this case but this won't break compatibility.
+      path1 = cellstr (dynamic_path_list);
+      path2 = cellstr (static_path_list);
+    else
+      switch (tolower (which))
+        case "-all",     path1 = cellstr ([static_path_list, dynamic_path_list]);
+        case "-dynamic", path1 = cellstr (dynamic_path_list);
+        case "-static",  path1 = cellstr (static_path_list);
+        otherwise
+          error ("javaclasspath: invalid value for WHAT");
       endswitch
-        
-    case 1
-      switch (nargout)
-        case 0
-          if (strcmp (which, "-static"))
-            disp_path_list ("STATIC", static_path_list)
-          elseif (strcmp (which, "-dynamic"))
-            disp_path_list ("DYNAMIC", dynamic_path_list)
-          elseif (strcmp (which, "-all") == 1)
-            disp_path_list ("STATIC", static_path_list)
-            disp ("");
-            disp_path_list ("DYNAMIC", dynamic_path_list)
-          endif
+    endif
+  endif
 
-        case 1
-          if (strcmp (which, "-static") == 1)
-            varargout{1} = cellstr (static_path_list);
-          elseif (strcmp (which, "-dynamic") == 1)
-            varargout{1} = cellstr (dynamic_path_list);
-          elseif (strcmp (which, "-all") == 1)
-            varargout{1} = cellstr ([static_path_list, dynamic_path_list]);
-          endif
-      endswitch
-  endswitch
-  
 endfunction
 
 ## Display cell array of paths
--- a/scripts/java/javamem.m	Fri Aug 01 09:06:21 2014 -0400
+++ b/scripts/java/javamem.m	Fri Aug 01 12:10:05 2014 -0400
@@ -36,7 +36,7 @@
 ## determined by the environment variable @w{@env{OCTAVE_JAVA_DIR}}.
 ## If unset, the directory where @file{javaaddpath.m} resides is used instead
 ## (typically
-## @file{@w{@env{OCTAVE_HOME}}/share/octave/@w{@env{OCTAVE_VERSION}}/m/java/}
+## @file{@w{@env{OCTAVE_HOME}}/share/octave/@w{@env{OCTAVE_VERSION}}/m/java/}).
 ##
 ## @file{java.opts} is a plain text file with one option per line.  The
 ## default initial memory size and default maximum memory size (which
--- a/scripts/java/module.mk	Fri Aug 01 09:06:21 2014 -0400
+++ b/scripts/java/module.mk	Fri Aug 01 12:10:05 2014 -0400
@@ -5,6 +5,7 @@
   java/java_set.m \
   java/javaArray.m \
   java/javaaddpath.m \
+  java/javachk.m \
   java/javaclasspath.m \
   java/javamem.m \
   java/javarmpath.m \
--- a/scripts/java/org/octave/ClassHelper.java	Fri Aug 01 09:06:21 2014 -0400
+++ b/scripts/java/org/octave/ClassHelper.java	Fri Aug 01 12:10:05 2014 -0400
@@ -199,7 +199,7 @@
           {
             sb.append (";");
           }
-        sb.append (theField[i].toString ());
+        sb.append (theField[i].getName ());
       }
 
     return (sb.toString ());
--- a/scripts/java/usejava.m	Fri Aug 01 09:06:21 2014 -0400
+++ b/scripts/java/usejava.m	Fri Aug 01 12:10:05 2014 -0400
@@ -43,6 +43,7 @@
 ## @qcode{"desktop"} always returns @code{false} as Octave has no Java-based
 ## desktop.  Other features may be available if Octave was compiled with the
 ## Java Interface and Java is installed.
+## @seealso{javachk}
 ## @end deftypefn
 
 ## Author: Rik Wehbring
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/linear-algebra/bandwidth.m	Fri Aug 01 12:10:05 2014 -0400
@@ -0,0 +1,110 @@
+## Copyright (C) 2014 Massimiliano Fasi
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn  {Function File} {@var{bw} =} bandwidth (@var{A}, @var{type})
+## @deftypefnx {Function File} {[@var{lower}, @var{upper}] =} bandwidth (@var{A})
+## Compute the bandwidth of @var{A}.
+##
+## The @var{type} argument is the string @qcode{"lower"} for the lower
+## bandwidth and @qcode{"upper"} for the upper bandwidth.
+## If no @var{type} is specified return both the lower and upper bandwidth
+## of @var{A}. 
+##
+## The lower/upper bandwidth of a matrix is the number of
+## subdiagonals/superdiagonals with nonzero entries.
+## 
+## @seealso{isbanded, isdiag, istril, istriu}
+## @end deftypefn
+
+## Author: Massimiliano Fasi
+
+function [lower, upper] = bandwidth (A, type)
+
+  if (! ((nargin == 1 && nargout == 2) || (nargin == 2 && nargout <= 1)))
+    print_usage ();
+  endif
+
+  if (! isnumeric (A) && ! islogical (A) || ndims (A) != 2)
+    error ("bandwidth: A must be a 2-D numeric or logical matrix");
+  elseif (nargin == 2 && ! (strcmp (type, "lower") || strcmp (type, "upper")))
+    error ('bandwidth: TYPE must be "lower" or "upper"');
+  endif
+
+  if (nargin == 1)
+    [i, j] = find (A);
+    if (isempty (i))
+      lower = upper = 0;
+    else
+      lower = max (i - j);
+      upper = max (j - i);
+    endif
+  else
+    [i, j] = find (A);
+    if (isempty (i))
+      lower = 0;
+    elseif (strcmp (type, "lower"))
+      lower = max (i - j);
+    else
+      lower = max (j - i);
+    endif
+  endif
+
+endfunction
+
+
+%!test
+%! [a,b] = bandwidth (speye (100));
+%! assert ([a,b] == [0,0]);
+%! assert (bandwidth (speye (100), "upper"), 0);
+%! assert (bandwidth (speye (100), "lower"), 0);
+
+%!test
+%! A = [2 3 0 0 0; 1 2 3 0 0; 0 1 2 3 0; 0 0 1 2 3; 0 0 0 1 2];
+%! [a,b] = bandwidth (A);
+%! assert ([a,b] == [1,1]);
+%! assert (bandwidth (A, "lower"), 1);
+%! assert (bandwidth (A, "upper"), 1);
+
+%!assert (bandwidth ([], "lower"), 0)
+%!assert (bandwidth ([], "upper"), 0)
+%!assert (bandwidth (zeros (3,3), "lower"), 0)
+%!assert (bandwidth (zeros (3,3), "upper"), 0)
+%!assert (bandwidth (ones (5,5), "lower"), 4)
+%!assert (bandwidth (ones (5,5), "upper"), 4)
+
+%!test
+%! [a,b] = bandwidth ([]);
+%! assert ([a,b] == [0,0]);
+%!test
+%! [a,b] = bandwidth (zeros (3,3));
+%! assert ([a,b] == [0,0]);
+%!test
+%! [a,b] = bandwidth (ones (5,5));
+%! assert ([a,b] == [4,4]);
+
+%% Test input validation
+%!error bandwidth ()
+%!error bandwidth (1,2,3)
+%!error [a,b,c] = bandwidth (ones (2))
+%!error [a,b] = bandwidth (ones (2), "upper")
+%!error <A must be a 2-D numeric or logical> bandwidth ("string", "lower")
+%!error <A must be a 2-D numeric or logical> bandwidth (ones (3,3,3), "lower")
+%!error <TYPE must be "lower" or "upper"> bandwidth (ones (2), "uper")
+%!error <TYPE must be "lower" or "upper"> bandwidth (ones (2), "uppper")
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/linear-algebra/isbanded.m	Fri Aug 01 12:10:05 2014 -0400
@@ -0,0 +1,86 @@
+## Copyright (C) 2014 Massimiliano Fasi
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} isbanded (@var{A}, @var{lower}, @var{upper})
+## Return true if @var{A} is a matrix with entries confined between
+## @var{lower} diagonals below the main diagonal and @var{upper} diagonals
+## above the main diagonal.
+##
+## @var{lower} and @var{upper} must be non-negative integers.
+## @seealso{isdiag, istril, istriu, bandwidth}
+## @end deftypefn
+
+## Author: Massimiliano Fasi
+
+function retval = isbanded (A, lower, upper)
+
+  if (nargin != 3)
+    print_usage ();
+  endif
+
+  if (! isreal (lower) || ! isreal (upper) || lower < 0 || upper < 0)
+    error ("isbanded: LOWER and UPPER must be non-negative integers");
+  endif
+
+  if (isempty (A))
+    retval = [];
+  else 
+    retval = (isnumeric (A) || islogical (A)) && ndims (A) == 2;
+    if (retval)
+      [i, j] = find (A);
+      pupp = j >= i;
+      retval = all (j(pupp) - i(pupp) <= upper);
+      if (retval)
+        plow = i >= j;
+        retval = all (i(plow) - j(plow) <= lower);
+      endif
+    endif
+  endif
+
+endfunction
+
+
+%!assert (! isbanded ("string", 0, 0))
+%!assert (! isbanded (zeros (2,2,2), 0, 0))
+%!assert (isbanded ([], 0, 0))
+%!assert (isbanded (1,0,0))
+%!assert (isbanded (1,10,10))
+
+%!assert (isbanded ([1, 1],1,1))
+%!assert (isbanded ([1; 1],1,1))
+%!assert (isbanded (eye(10),0,0))
+%!assert (isbanded (eye(10),1,1))
+%!assert (isbanded (i*eye(10),1,1))
+%!assert (isbanded (logical (eye (10)),1,1))
+
+%! A = [2 3 0 0 0; 1 2 3 0 0; 0 1 2 3 0; 0 0 1 2 3; 0 0 0 1 2];
+%! assert (isbanded (A,1,1))
+%! assert (! isbanded (A,0,1))
+%! assert (! isbanded (A,1,0))
+
+%% Test input validation
+%!error isbanded ()
+%!error isbanded (1)
+%!error isbanded (1,2)
+%!error isbanded (1,2,3,4)
+%!error <LOWER and UPPER must be non-negative> isbanded (1, -1, 1)
+%!error <LOWER and UPPER must be non-negative> isbanded (1, 1, -1)
+%!error <LOWER and UPPER must be non-negative> isbanded (1, {1}, 1)
+%!error <LOWER and UPPER must be non-negative> isbanded (1, 1, {1})
+
--- a/scripts/linear-algebra/isdefinite.m	Fri Aug 01 09:06:21 2014 -0400
+++ b/scripts/linear-algebra/isdefinite.m	Fri Aug 01 12:10:05 2014 -0400
@@ -17,13 +17,13 @@
 ## <http://www.gnu.org/licenses/>.
 
 ## -*- texinfo -*-
-## @deftypefn  {Function File} {} isdefinite (@var{x})
-## @deftypefnx {Function File} {} isdefinite (@var{x}, @var{tol})
-## Return 1 if @var{x} is symmetric positive definite within the
-## tolerance specified by @var{tol} or 0 if @var{x} is symmetric
+## @deftypefn  {Function File} {} isdefinite (@var{A})
+## @deftypefnx {Function File} {} isdefinite (@var{A}, @var{tol})
+## Return 1 if @var{A} is symmetric positive definite within the
+## tolerance specified by @var{tol} or 0 if @var{A} is symmetric
 ## positive semidefinite.  Otherwise, return -1.  If @var{tol}
 ## is omitted, use a tolerance of
-## @code{100 * eps * norm (@var{x}, "fro")}
+## @code{100 * eps * norm (@var{A}, "fro")}
 ## @seealso{issymmetric, ishermitian}
 ## @end deftypefn
 
@@ -31,30 +31,30 @@
 ## Created: November 2003
 ## Adapted-By: jwe
 
-function retval = isdefinite (x, tol)
+function retval = isdefinite (A, tol)
 
   if (nargin < 1 || nargin > 2)
     print_usage ();
   endif
 
-  if (! isfloat (x))
-    x = double (x);
+  if (! isfloat (A))
+    A = double (A);
   endif
 
   if (nargin == 1)
-    tol = 100 * eps (class (x)) * norm (x, "fro");
+    tol = 100 * eps (class (A)) * norm (A, "fro");
   endif
 
-  if (! ishermitian (x, tol))
-    error ("isdefinite: X must be a Hermitian matrix");
+  if (! ishermitian (A, tol))
+    error ("isdefinite: A must be a Hermitian matrix");
   endif
 
-  e = tol * eye (rows (x));
-  [r, p] = chol (x - e);
+  e = tol * eye (rows (A));
+  [r, p] = chol (A - e);
   if (p == 0)
     retval = 1;
   else
-    [r, p] = chol (x + e);
+    [r, p] = chol (A + e);
     if (p == 0)
       retval = 0;
     else
@@ -83,5 +83,5 @@
 
 %!error isdefinite ()
 %!error isdefinite (1,2,3)
-%!error <X must be a Hermitian matrix> isdefinite ([1 2; 3 4])
+%!error <A must be a Hermitian matrix> isdefinite ([1 2; 3 4])
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/linear-algebra/isdiag.m	Fri Aug 01 12:10:05 2014 -0400
@@ -0,0 +1,56 @@
+## Copyright (C) 2014 Massimiliano Fasi
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} isdiag (@var{A})
+## Return true if @var{A} is a diagonal matrix.
+## @seealso{isbanded, istril, istriu, diag, bandwidth}
+## @end deftypefn
+
+## Author: Massimiliano Fasi
+
+function retval = isdiag (A)
+
+  if (nargin != 1)
+    print_usage ();
+  endif
+
+  retval = (isnumeric (A) || islogical (A)) && ndims (A) == 2;
+  if (retval)
+    [i, j] = find (A);
+    retval = all (i == j);
+  endif
+
+endfunction
+
+
+%!assert (! isdiag ("string"))
+%!assert (isdiag ([]))
+
+%!assert (isdiag (1))
+%!assert (! isdiag ([1, 1]))
+%!assert (! isdiag ([1; 1]))
+%!assert (isdiag (eye (10)))
+%!assert (issymmetric ([i, 0; 0, 1 + i]))
+%!assert (isdiag (speye (1000000)))
+%!assert (isdiag (logical (eye (10))))
+
+%% Test input validation
+%!error isdiag ()
+%!error isdiag (1,2)
+
--- a/scripts/linear-algebra/ishermitian.m	Fri Aug 01 09:06:21 2014 -0400
+++ b/scripts/linear-algebra/ishermitian.m	Fri Aug 01 12:10:05 2014 -0400
@@ -18,13 +18,14 @@
 ## <http://www.gnu.org/licenses/>.
 
 ## -*- texinfo -*-
-## @deftypefn  {Function File} {} ishermitian (@var{x})
-## @deftypefnx {Function File} {} ishermitian (@var{x}, @var{tol})
-## Return true if @var{x} is Hermitian within the tolerance specified by
+## @deftypefn  {Function File} {} ishermitian (@var{A})
+## @deftypefnx {Function File} {} ishermitian (@var{A}, @var{tol})
+## Return true if @var{A} is Hermitian within the tolerance specified by
 ## @var{tol}.
+##
 ## The default tolerance is zero (uses faster code).
-## Matrix @var{x} is considered symmetric if
-## @code{norm (@var{x} - @var{x}', Inf) / norm (@var{x}, Inf) < @var{tol}}.
+## Matrix @var{A} is considered symmetric if
+## @code{norm (@var{A} - @var{A}', Inf) / norm (@var{A}, Inf) < @var{tol}}.
 ## @seealso{issymmetric, isdefinite}
 ## @end deftypefn
 
@@ -32,19 +33,19 @@
 ## Created: August 1993
 ## Adapted-By: jwe
 
-function retval = ishermitian (x, tol = 0)
+function retval = ishermitian (A, tol = 0)
 
   if (nargin < 1 || nargin > 2)
     print_usage ();
   endif
 
-  retval = isnumeric (x) && issquare (x);
+  retval = isnumeric (A) && issquare (A);
   if (retval)
     if (tol == 0)
-      retval = all ((x == x')(:));
+      retval = all ((A == A')(:));
     else
-      norm_x = norm (x, inf);
-      retval = norm_x == 0 || norm (x - x', inf) / norm_x <= tol;
+      norm_x = norm (A, inf);
+      retval = norm_x == 0 || norm (A - A', inf) / norm_x <= tol;
     endif
   endif
 
--- a/scripts/linear-algebra/issymmetric.m	Fri Aug 01 09:06:21 2014 -0400
+++ b/scripts/linear-algebra/issymmetric.m	Fri Aug 01 12:10:05 2014 -0400
@@ -18,12 +18,14 @@
 ## <http://www.gnu.org/licenses/>.
 
 ## -*- texinfo -*-
-## @deftypefn  {Function File} {} issymmetric (@var{x})
-## @deftypefnx {Function File} {} issymmetric (@var{x}, @var{tol})
-## Return true if @var{x} is a symmetric matrix within the tolerance specified
-## by @var{tol}.  The default tolerance is zero (uses faster code).
-## Matrix @var{x} is considered symmetric if
-## @code{norm (@var{x} - @var{x}.', Inf) / norm (@var{x}, Inf) < @var{tol}}.
+## @deftypefn  {Function File} {} issymmetric (@var{A})
+## @deftypefnx {Function File} {} issymmetric (@var{A}, @var{tol})
+## Return true if @var{A} is a symmetric matrix within the tolerance specified
+## by @var{tol}.
+##
+## The default tolerance is zero (uses faster code).
+## Matrix @var{A} is considered symmetric if
+## @code{norm (@var{A} - @var{A}.', Inf) / norm (@var{A}, Inf) < @var{tol}}.
 ## @seealso{ishermitian, isdefinite}
 ## @end deftypefn
 
@@ -31,19 +33,20 @@
 ## Created: August 1993
 ## Adapted-By: jwe
 
-function retval = issymmetric (x, tol = 0)
+function retval = issymmetric (A, tol = 0)
 
   if (nargin < 1 || nargin > 2)
     print_usage ();
   endif
 
-  retval = isnumeric (x) && issquare (x);
+  retval = (isnumeric (A) || islogical (A)) && issquare (A);
   if (retval)
     if (tol == 0)
-      retval = all ((x == x.')(:));
+      ## Handle large sparse matrices as well as full ones
+      retval = nnz (A != A.') == 0;
     else
-      norm_x = norm (x, inf);
-      retval = norm_x == 0 || norm (x - x.', inf) / norm_x <= tol;
+      norm_x = norm (A, inf);
+      retval = norm_x == 0 || norm (A - A.', inf) / norm_x <= tol;
     endif
   endif
 
@@ -59,6 +62,8 @@
 %!assert (issymmetric ([1, 2i; 2i, 1]))
 %!assert (! (issymmetric ("t")))
 %!assert (! (issymmetric (["te"; "et"])))
+%!assert (issymmetric (speye (100000)))
+%!assert (issymmetric (logical (eye (2))))
 
 %!test
 %! s.a = 1;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/linear-algebra/istril.m	Fri Aug 01 12:10:05 2014 -0400
@@ -0,0 +1,61 @@
+## Copyright (C) 2014 Massimiliano Fasi
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} istril (@var{A})
+## Return true if @var{A} is a lower triangular matrix.
+##
+## A lower triangular matrix has nonzero entries only on the main diagonal
+## and below.
+## @seealso{istriu, isbanded, isdiag, tril, bandwidth}
+## @end deftypefn
+
+## Author: Massimiliano Fasi
+
+function retval = istril (A)
+
+  if (nargin != 1)
+    print_usage ();
+  endif
+
+  retval = (isnumeric (A) || islogical (A)) && ndims (A) == 2;
+  if (retval)
+    [i, j] = find (A);
+    retval = all (i >= j);
+  endif
+
+endfunction
+
+
+%!assert (! istril ("string"))
+%!assert (istril ([]))
+%!assert (! istril (zeros (2,2,2)))
+
+%!assert (istril (1))
+%!assert (! istril ([1, 1]))
+%!assert (istril ([1; 1]))
+%!assert (istril (eye (10)))
+%!assert (istril (speye (100)))
+
+%!assert (istril (tril (randn (10))))
+%!assert (! istril (randn (10)))
+
+%% Test input validation
+%!error istril ()
+%!error istril (1,2)
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/linear-algebra/istriu.m	Fri Aug 01 12:10:05 2014 -0400
@@ -0,0 +1,61 @@
+## Copyright (C) 2014 Massimiliano Fasi
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} istriu (@var{A})
+## Return true if @var{A} is an upper triangular matrix.
+##
+## An upper triangular matrix has nonzero entries only on the main diagonal
+## and above.
+## @seealso{isdiag, isbanded, istril, triu, bandwidth}
+## @end deftypefn
+
+## Author: Massimiliano Fasi
+
+function retval = istriu (A)
+
+  if (nargin != 1)
+    print_usage ();
+  endif
+
+  retval = (isnumeric (A) || islogical (A)) && ndims (A) == 2;
+  if (retval)
+    [i, j] = find (A);
+    retval = all (i <= j);
+  endif
+
+endfunction
+
+
+%!assert (! istriu ("string"))
+%!assert (istriu ([]))
+%!assert (! istriu (zeros (2,2,2)))
+
+%!assert (istriu (1))
+%!assert (istriu ([1, 1]))
+%!assert (! istriu ([1; 1]))
+%!assert (istriu (eye (10)))
+%!assert (istriu (speye (100)))
+
+%!assert (istriu (triu (randn (10))))
+%!assert (! istriu (randn (10)))
+
+%% Test input validation
+%!error istriu ()
+%!error istriu (1,2)
+
--- a/scripts/linear-algebra/krylov.m	Fri Aug 01 09:06:21 2014 -0400
+++ b/scripts/linear-algebra/krylov.m	Fri Aug 01 12:10:05 2014 -0400
@@ -133,8 +133,8 @@
         nv = columns (V);
         if (jj != nv)
           [V(:,jj), V(:,nv)] = swap (V(:,jj), V(:,nv));
-          ## FIXME -- H columns should be swapped too.  Not done
-          ## since Block Hessenberg structure is lost anyway.
+          ## FIXME: H columns should be swapped too.
+          ##        Not done since Block Hessenberg structure is lost anyway.
         endif
         V = V(:,1:(nv-1));
         ## One less reflection.
@@ -167,7 +167,7 @@
         ## Reduce V per the reflection.
         V(idx,:) = V(idx,:) - av*hv*(hv' * V(idx,:));
         if(iter > 1)
-          ## FIXME -- not done correctly for block case.
+          ## FIXME: not done correctly for block case.
           H(nu,nu-1) = V(pivot_vec(nu),jj);
         endif
 
--- a/scripts/linear-algebra/module.mk	Fri Aug 01 09:06:21 2014 -0400
+++ b/scripts/linear-algebra/module.mk	Fri Aug 01 12:10:05 2014 -0400
@@ -1,6 +1,7 @@
 FCN_FILE_DIRS += linear-algebra
 
 linear_algebra_FCN_FILES = \
+  linear-algebra/bandwidth.m \
   linear-algebra/commutation_matrix.m \
   linear-algebra/cond.m \
   linear-algebra/condest.m \
@@ -8,9 +9,13 @@
   linear-algebra/duplication_matrix.m \
   linear-algebra/expm.m \
   linear-algebra/housh.m \
+  linear-algebra/isbanded.m \
   linear-algebra/isdefinite.m \
+  linear-algebra/isdiag.m \
   linear-algebra/ishermitian.m \
   linear-algebra/issymmetric.m \
+  linear-algebra/istril.m \
+  linear-algebra/istriu.m \
   linear-algebra/krylov.m \
   linear-algebra/linsolve.m \
   linear-algebra/logm.m \
--- a/scripts/miscellaneous/cast.m	Fri Aug 01 09:06:21 2014 -0400
+++ b/scripts/miscellaneous/cast.m	Fri Aug 01 12:10:05 2014 -0400
@@ -19,27 +19,41 @@
 ## -*- texinfo -*-
 ## @deftypefn {Function File} {} cast (@var{val}, @var{type})
 ## Convert @var{val} to data type @var{type}.
-## @seealso{int8, uint8, int16, uint16, int32, uint32, int64, uint64, double}
+##
+## The value @var{val} may be modified to fit within the range of the new type.
+##
+## Examples:
+##
+## @example
+## @group
+## cast (-5, "uint8")
+##    @result{} 0
+## cast (300, "int8")
+##    @result{} 127
+## @end group
+## @end example
+##
+## @seealso{typecast, int8, uint8, int16, uint16, int32, uint32, int64, uint64, double, single, logical, char}
 ## @end deftypefn
 
 ## Author: jwe
 
 function retval = cast (val, typ)
 
-  if (nargin == 2)
-    if (ischar (typ))
-      if (any (strcmp (typ, {"int8"; "uint8"; "int16"; "uint16";
-                             "int32"; "uint32"; "int64"; "uint64";
-                             "double"; "single"; "logical"; "char"})))
-        retval = feval (typ, val);
-      else
-        error ("cast: type name '%s' is not a built-in type", typ);
-      endif
+  if (nargin != 2)
+    print_usage ();
+  endif
+
+  if (ischar (typ))
+    if (any (strcmp (typ, {"int8"; "uint8"; "int16"; "uint16";
+                           "int32"; "uint32"; "int64"; "uint64";
+                           "double"; "single"; "logical"; "char"})))
+      retval = feval (typ, val);
     else
-      error ("cast: expecting TYPE name as second argument");
+      error ("cast: type name '%s' is not a built-in type", typ);
     endif
   else
-    print_usage ();
+    error ("cast: expecting TYPE name as second argument");
   endif
 
 endfunction
--- a/scripts/miscellaneous/colon.m	Fri Aug 01 09:06:21 2014 -0400
+++ b/scripts/miscellaneous/colon.m	Fri Aug 01 12:10:05 2014 -0400
@@ -42,5 +42,5 @@
 
 %!error colon (1)
 
-## FIXME -- what does colon () mean since it doesn't set a return value?
+## FIXME: What does colon () mean since it doesn't set a return value?
 
--- a/scripts/miscellaneous/dump_prefs.m	Fri Aug 01 09:06:21 2014 -0400
+++ b/scripts/miscellaneous/dump_prefs.m	Fri Aug 01 12:10:05 2014 -0400
@@ -32,7 +32,7 @@
     file = stdout;
   endif
 
-  ## FIXME -- it would be nice to be able to get the list of
+  ## FIXME: It would be nice to be able to get the list of
   ## built-in variables directly from Octave so that we wouldn't have to
   ## remember to update it each time the list of preference variables
   ## changes
--- a/scripts/miscellaneous/edit.m	Fri Aug 01 09:06:21 2014 -0400
+++ b/scripts/miscellaneous/edit.m	Fri Aug 01 12:10:05 2014 -0400
@@ -23,7 +23,7 @@
 ## Edit the named function, or change editor settings.
 ##
 ## If @code{edit} is called with the name of a file or function as
-## its argument it will be opened in the text editor defined by @code{EDITOR}.
+## its argument it will be opened in the text editor defined by @env{EDITOR}.
 ##
 ## @itemize @bullet
 ## @item
@@ -330,7 +330,7 @@
 
     ## If editing a new file, prompt for creation if gui is running
     if (isguirunning ())
-      if (! __octave_link_edit_file__ (file,"prompt"));
+      if (! __octave_link_edit_file__ (file, "prompt"));
         return;
       endif
     endif
@@ -340,12 +340,22 @@
     ## If in gui-mode, create it before or editor would prompt again.
     fileandpath = file;
     idx = rindex (file, ".");
-    name = file(1:idx-1);
-    ext = file(idx+1:end);
+    if (idx)
+      name = file(1:idx-1);
+      ext = file(idx+1:end);
+    else
+      name = file;
+      ext = "";
+    endif
     if (! any (strcmp (ext, {"cc", "m"})))
       ## Some unknown file.  Create and open it or just open it.
+      if (isempty (ext))
+        fileandpath = [fileandpath ".m"];  # Add .m extension per default
+      endif
       if (isguirunning ())
         ## Write the initial file (if there is anything to write)
+        ## Give user the opportunity to change the file extension
+        fileandpath = uiputfile (fileandpath);
         fid = fopen (fileandpath, "wt");
         if (fid < 0)
           error ("edit: could not create %s", fileandpath);
--- a/scripts/miscellaneous/fact.m	Fri Aug 01 09:06:21 2014 -0400
+++ b/scripts/miscellaneous/fact.m	Fri Aug 01 12:10:05 2014 -0400
@@ -115,7 +115,7 @@
        "When Richard Stallman executes ps -e, you show up.";
        "When Richard Stallman gets angry he doesn't swear; he recurses.";
        "On Richard Stallman's computer the bootloader is contained in his .emacs.";
-       "Richard Satallman can make any operating system free, free from drivers.";
+       "Richard Stallman can make any operating system free, free from drivers.";
        "Richard Stallman programmed Chuck Norris.";
        "Behind Richard Stallman's beard there is another fist, to code faster.";
        "Richard Stallman won a Sudoku that started with only one number in each line.";
--- a/scripts/miscellaneous/fileattrib.m	Fri Aug 01 09:06:21 2014 -0400
+++ b/scripts/miscellaneous/fileattrib.m	Fri Aug 01 12:10:05 2014 -0400
@@ -108,7 +108,7 @@
         r_s{i} = NaN;
         r_h{i} = NaN;
         r_d{i} = S_ISDIR (info.mode);
-        ## FIXME -- maybe we should have S_IRUSR etc. masks?
+        ## FIXME: Maybe we should have S_IRUSR etc. masks?
         modestr = info.modestr;
         r_u_r{i} = modestr(2) == "r";
         r_u_w{i} = modestr(3) == "w";
--- a/scripts/miscellaneous/genvarname.m	Fri Aug 01 09:06:21 2014 -0400
+++ b/scripts/miscellaneous/genvarname.m	Fri Aug 01 12:10:05 2014 -0400
@@ -80,7 +80,7 @@
 ## Since variable names may only contain letters, digits and underscores,
 ## genvarname replaces any sequence of disallowed characters with
 ## an underscore.  Also, variables may not begin with a digit; in this
-## case an underscore is added before the variable name.
+## case an x is added before the variable name.
 ##
 ## Variable names beginning and ending with two underscores @qcode{"__"} are
 ## valid but they are used internally by octave and should generally be
@@ -131,22 +131,20 @@
     str{i}(! ismember (str{i}, validchars)) = "_";
     ## do not use keywords
     if (iskeyword (str{i}))
-      str{i} = ["_" str{i}];
-    endif
-    ## double underscores at the beginning and end are reserved variables
-    underscores = (str{i} == "_");
-    if (any (underscores))
-      firstnon = find (!underscores, 1);
-      lastnon = find (!underscores, 1, "last");
-      str{i}([1:firstnon-2, lastnon+2:end]) = [];
+      firstcharacter = toupper (str{i}(1));
+      str{i} = ["x", firstcharacter, str{i}(2:end)];
     endif
     ## The variable cannot be empty
     if (isempty (str{i}))
       str{i} = "x";
     endif
+    ## Leading underscores are not Matlab compatible
+    if (str{i}(1) == "_")
+      str{i} = ["x", str{i}];
+    endif
     ## it cannot start with a number
     if (ismember (str{i}(1), "0":"9"))
-      str{i} = ["_" str{i}];
+      str{i} = ["x", str{i}];
     endif
 
     ## make sure that the variable is unique relative to other variables
@@ -199,12 +197,12 @@
 ## more than one repetition not in order
 %!assert (genvarname ({"a" "b" "a" "b" "a"}), {"a" "b" "a1" "b1" "a2"})
 ## Variable name munging
-%!assert (genvarname ("__x__"), "_x_")
-%!assert (genvarname ("123456789"), "_123456789")
-%!assert (genvarname ("_$1__"), "_1_")
-%!assert (genvarname ("__foo__", "_foo_"), "_foo_1")
-%!assert (genvarname ("1million_and1", "_1million_and1"), "_1million_and1_1")
+%!assert (genvarname ("__x__"), "x__x__")
+%!assert (genvarname ("123456789"), "x123456789")
+%!assert (genvarname ("_$1__"), "x__1__")
+%!assert (genvarname ("__foo__", "x__foo__"), "x__foo__1")
+%!assert (genvarname ("1million_and1", "x1million_and1"), "x1million_and1_1")
 %!assert (genvarname ({"", "", ""}), {"x", "x1", "x2"})
-%!assert (genvarname ("if"), "_if")
-%!assert (genvarname ({"if", "if", "if"}), {"_if", "_if1", "_if2"})
+%!assert (genvarname ("if"), "xIf")
+%!assert (genvarname ({"if", "if", "if"}), {"xIf", "xIf1", "xIf2"})
 
--- a/scripts/miscellaneous/getappdata.m	Fri Aug 01 09:06:21 2014 -0400
+++ b/scripts/miscellaneous/getappdata.m	Fri Aug 01 12:10:05 2014 -0400
@@ -35,8 +35,8 @@
 function val = getappdata (h, name)
 
   if (all (ishandle (h)) && nargin == 2 && ischar (name))
-    ## FIXME - Is there a better way to handle non-existent appdata
-    ## and missing fields?
+    ## FIXME: Is there a better way to handle non-existent appdata
+    ##        and missing fields?
     val = cell (numel (h), 1);
     appdata = struct ();
     for nh = 1:numel (h)
--- a/scripts/miscellaneous/gzip.m	Fri Aug 01 09:06:21 2014 -0400
+++ b/scripts/miscellaneous/gzip.m	Fri Aug 01 12:10:05 2014 -0400
@@ -58,10 +58,17 @@
 %!     error ("gzipped file cannot be found!");
 %!   endif
 %!   gunzip (entry);
-%!   if (system (sprintf ("diff %s %s%c%s%s", filename, dirname, filesep,
-%!                                            basename, extension)))
+%!   fid = fopen (filename, "rb");
+%!   assert (fid >= 0);
+%!   orig_data = fread (fid);
+%!   fclose (fid);
+%!   fid = fopen ([dirname filesep basename extension], "rb");
+%!   assert (fid >= 0);
+%!   new_data = fread (fid);
+%!   fclose (fid);
+%!   if (orig_data != new_data)
 %!     error ("unzipped file not equal to original file!");
-%!   end
+%!   endif
 %! unwind_protect_cleanup
 %!   delete (filename);
 %!   delete ([dirname, filesep, basename, extension]);
--- a/scripts/miscellaneous/inputname.m	Fri Aug 01 09:06:21 2014 -0400
+++ b/scripts/miscellaneous/inputname.m	Fri Aug 01 12:10:05 2014 -0400
@@ -57,3 +57,8 @@
 %!assert (inputname (1), "hello")
 %!assert (inputname (2), "worldly")
 
+%!function r = foo (x, y)
+%!  r = inputname (2);
+%!endfunction
+%!assert (foo (pi, e), "e");
+%!assert (feval (@foo, pi, e), "e");
--- a/scripts/miscellaneous/ls.m	Fri Aug 01 09:06:21 2014 -0400
+++ b/scripts/miscellaneous/ls.m	Fri Aug 01 12:10:05 2014 -0400
@@ -61,14 +61,14 @@
   if (nargin > 0)
     args = tilde_expand (varargin);
     if (ispc () && ! isunix ())
+      idx = ! strncmp (args, '/', 1);
+      ## Enclose paths, potentially having spaces, in double quotes:
+      args(idx) = strcat ('"', args(idx), '"');    
       ## shell (cmd.exe) on MinGW uses '^' as escape character
-      args = regexprep (args, '([^\w.*? -])', '^$1');
-      ## Strip UNIX directory character which looks like an option to dir cmd.
-      if (args{end}(end) == '/')
-        args{end}(end) = "";
-      endif
+      args = regexprep (args, '([^\w.*?])', '^$1');
     else
-      args = regexprep (args, '([^\w.*? -])', '\\$1');
+      ## Escape any special characters in filename
+      args = regexprep (args, '([^\w.*?-[]])', '\\$1');
     endif
     args = sprintf ("%s ", args{:});
   else
--- a/scripts/miscellaneous/mex.m	Fri Aug 01 09:06:21 2014 -0400
+++ b/scripts/miscellaneous/mex.m	Fri Aug 01 12:10:05 2014 -0400
@@ -23,8 +23,16 @@
 ## @seealso{mkoctfile}
 ## @end deftypefn
 
-function mex (varargin)
-  args = {"--mex", varargin{:}};
-  mkoctfile (args{:});
+function retval = mex (varargin)
+
+  [output, status] = mkoctfile ("--mex", varargin{:});
+
+  if (! isempty (output))
+    disp (output);
+  endif
+  if (nargout > 0)
+    retval = status;
+  endif
+
 endfunction
 
--- a/scripts/miscellaneous/private/__xzip__.m	Fri Aug 01 09:06:21 2014 -0400
+++ b/scripts/miscellaneous/private/__xzip__.m	Fri Aug 01 12:10:05 2014 -0400
@@ -83,7 +83,7 @@
       movefile (cellfun (@(x) sprintf ("%s.%s", x, extension), f,
                         "uniformoutput", false), cwd);
       if (nargout > 0)
-        ## FIXME this does not work when you try to compress directories
+        ## FIXME: This does not work when you try to compress directories
         entries  = cellfun (@(x) sprintf ("%s.%s", x, extension),
                             files, "uniformoutput", false);
       endif
@@ -109,8 +109,7 @@
 endfunction
 
 
-## FIXME -- reinstate these tests if we invent a way to test private
-## functions directly.
+## FIXME: Reinstate tests if we invent a way to test private functions directly.
 ##
 ## %!error <extension has to be a string with finite length>
 ## %!  __xzip__ ("gzip", "", "gzip -r %s", "bla");
--- a/scripts/miscellaneous/run.m	Fri Aug 01 09:06:21 2014 -0400
+++ b/scripts/miscellaneous/run.m	Fri Aug 01 12:10:05 2014 -0400
@@ -31,9 +31,10 @@
 ## falling back to the script name without an extension.
 ##
 ## Implementation Note: If @var{script} includes a path component, then
-## @code{run} first changes the directory to the directory where @var{script}
-## is found.  @code{run} then executes the script, and returns to the original
-## directory. 
+## @code{run} first changes the working directory to the directory where
+## @var{script} is found.  Next, the script is executed.  Finally, @code{run}
+## returns to the original working directory unless @code{script} has
+## specifically changed directories.
 ## @seealso{path, addpath, source}
 ## @end deftypefn
 
@@ -65,7 +66,9 @@
         evalin ("caller", sprintf ('source ("%s%s");', f, ext),
                 "rethrow (lasterror ())");
       unwind_protect_cleanup
-        cd (wd);
+        if (strcmp (d, pwd ()))
+          cd (wd);
+        endif
       end_unwind_protect
     else
       error ("run: the path %s doesn't exist", d);
--- a/scripts/miscellaneous/unpack.m	Fri Aug 01 09:06:21 2014 -0400
+++ b/scripts/miscellaneous/unpack.m	Fri Aug 01 12:10:05 2014 -0400
@@ -84,10 +84,10 @@
 
     ## If the file is a URL, download it and then work with that file.
     if (! isempty (strfind (file, "://")))
-      ## FIXME -- the above is not a perfect test for a URL
+      ## FIXME: The above is not a perfect test for a URL
       urlfile = file;
-      ## FIXME -- should we name the file that we download with the
-      ## same file name as the URL requests?
+      ## FIXME: Should we name the file that we download with the
+      ##        same file name as the URL requests?
       tmpfile = [tmpnam() ext];
       [file, success, msg] = urlwrite (urlfile, tmpfile);
       if (! success)
@@ -194,7 +194,7 @@
 
   if (nargout > 0 || needmove)
     ## Trim the last CR if needed.
-    ## FIXME -- will this need to change to a check for "\r\n" for windows?
+    ## FIXME: Will this need to change to a check for "\r\n" for windows?
     if (output(end) == "\n")
       output(end) = [];
     endif
--- a/scripts/miscellaneous/what.m	Fri Aug 01 09:06:21 2014 -0400
+++ b/scripts/miscellaneous/what.m	Fri Aug 01 12:10:05 2014 -0400
@@ -37,7 +37,7 @@
       if (d(end) == '/' || d(end) == '\')
         d(end) = [];
       endif
-      dtmp = find_dir_in_path (d);
+      dtmp = dir_in_loadpath (d);
       if (isempty (dtmp))
         error ("what: could not find the directory %s", d);
       endif
@@ -45,7 +45,7 @@
     d = dtmp;
   endif
 
-  files = dir (d);
+  files = readdir (d);
   w.path = d;
   w.m = cell (0, 1);
   w.mex = cell (0, 1);
@@ -56,7 +56,7 @@
   w.classes = cell (0, 1);
 
   for i = 1 : length (files)
-    n = files(i).name;
+    n = files{i};
     ## Ignore . and ..
     if (strcmp (n, ".") || strcmp (n, ".."))
       continue;
@@ -71,7 +71,7 @@
         w.mex{end+1} = n;
       elseif (strcmp (e, ".mat"))
         w.mat{end+1} = n;
-      elseif (strcmp (n(1), "@"))
+      elseif (strcmp (n(1), "@") && isdir (n))
         w.classes{end+1} = n;
       endif
     endif
--- a/scripts/mkdoc	Fri Aug 01 09:06:21 2014 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,69 +0,0 @@
-#! /bin/sh
-#
-# Copyright (C) 1999-2013 John W. Eaton
-#
-# This file is part of Octave.
-#
-# Octave is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License as published by the
-# Free Software Foundation; either version 3 of the License, or (at
-# your option) any later version.
-#
-# Octave is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-# for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with Octave; see the file COPYING.  If not, see
-# <http://www.gnu.org/licenses/>.
-
-## Expecting arguments in this order:
-##
-##  SRCDIR SRCDIR-FILES ... -- LOCAL-FILES ...
-
-set -e
-
-PERL=${PERL:-'perl'}
-
-prefix="$1/"
-shift
-
-if test -f gethelp; then
-  cat << EOF
-### DO NOT EDIT!
-###
-### This file is generated automatically from the Octave sources.
-### Edit those files instead and run make to update this file.
-
-EOF
-  for arg
-  do
-    if [ "$arg" = "--" ]; then
-      prefix="./"
-    else
-      $PERL -w -e '
-        unless (@ARGV == 2) { die "Usage: $0 srcdir m_filename" ; }
-        ($srcdir, $m_fname) = ($ARGV[0], $ARGV[1]);
-        $full_fname = $srcdir . $m_fname;
-        exit unless ( $full_fname =~ m{(.*)/(@|)([^/]*)/(.*)\.m} );
-        if ($2) {
-          $fcn = "$2$3/$4";
-        } else {
-          $fcn = $4;
-        }
-        $re_srcdir = quotemeta($srcdir);
-        for (qx{ ./gethelp $fcn "$full_fname" < "$full_fname"} ) {
-          s/^\s+\@/\@/ unless $in_example;
-          s/^\s+\@group/\@group/;
-          s/^\s+\@end\s+group/\@end group/;
-          s|\@c $fcn $re_srcdir|\@c $fcn scripts/|o;
-          $in_example = (/\s*\@example\b/ .. /\s*\@end\s+example\b/);
-          print;
-        }' "$prefix" "$arg"
-    fi
-  done
-else
-  echo "gethelp program seems to be missing!" 1>&2
-  exit 1
-fi
--- a/scripts/mkdoc.pl	Fri Aug 01 09:06:21 2014 -0400
+++ b/scripts/mkdoc.pl	Fri Aug 01 12:10:05 2014 -0400
@@ -1,5 +1,6 @@
-#! /usr/bin/perl -w
-#
+#! /usr/bin/perl
+use utf8;
+
 # Copyright (C) 2012-2013 Rik Wehbring
 #
 # This file is part of Octave.
@@ -18,13 +19,18 @@
 # along with Octave; see the file COPYING.  If not, see
 # <http://www.gnu.org/licenses/>.
 
+use strict;
+use warnings;
+use File::Spec;
+use Cwd;
+
 ## Expecting arguments in this order:
 ##
 ##  SRCDIR SRCDIR-FILES ... -- LOCAL-FILES ...
 
 unless (@ARGV >= 2) { die "Usage: $0 srcdir m_filename1 ..." ; }
 
-$srcdir = shift (@ARGV) . '/';
+my $srcdir = shift (@ARGV);
 
 print <<__END_OF_MSG__;
 ### DO NOT EDIT!
@@ -34,35 +40,38 @@
 
 __END_OF_MSG__
 
-MFILE: foreach $m_fname (@ARGV)
+MFILE: foreach my $m_fname (@ARGV)
 {
   if ($m_fname eq "--")
-  {
-    $srcdir = "./";
-    next MFILE;
-  }
+    {
+      $srcdir = getcwd ();
+      next MFILE;
+    }
 
-  $full_fname = $srcdir . $m_fname;
-  next MFILE unless ( $full_fname =~ m{(.*)/(@|)([^/]*)/(.*)\.m} );
-  if ($2)
-    { $fcn = "$2$3/$4"; }
-  else
-    { $fcn = $4; }
+  my $full_fname = File::Spec->catfile ($srcdir, $m_fname);
+  my @paths = File::Spec->splitdir ($full_fname);
+  if (@paths < 3
+      || $paths[-2] eq "private"   # skip private directories
+      || $paths[-1] !~ s/\.m$//i)  # skip non m-files, and remove extension
+    { next MFILE; }
 
-  @help_txt = gethelp ($fcn, $full_fname);
-  next MFILE if ($help_txt[0] eq "");
+  ## @classes will have @class/method as their function name
+  my $fcn = $paths[-2] =~ m/^@/ ? File::Spec->catfile (@paths[-2, -1])
+                                : $paths[-1];
+
+  my @help_txt = gethelp ($fcn, $full_fname);
+  next MFILE unless @help_txt;
 
   print "\x{1d}$fcn\n";
-  print "\@c $fcn scripts/$m_fname\n";
+  print "\@c $fcn ", File::Spec->catfile ("scripts", $m_fname), "\n";
 
   foreach $_ (@help_txt)
-  {
-    s/^\s+\@/\@/ unless $in_example;
-    s/^\s+\@group/\@group/;
-    s/^\s+\@end\s+group/\@end group/;
-    $in_example = (/\s*\@example\b/ .. /\s*\@end\s+example\b/);
-    print $_;
-  }
+    {
+      my $in_example = (m/\s*\@example\b/ .. m/\s*\@end\s+example\b/);
+      s/^\s+\@/\@/ unless $in_example;
+      s/^\s+(\@(?:end)\s+(group|example))/$1/;
+      print $_;
+    }
 }
 
 ################################################################################
@@ -70,34 +79,32 @@
 ################################################################################
 sub gethelp
 {
-  ($fcn, $fname) = @_[0..1]; 
-  open (FH, $fname) or return "";
+  my $fcn   = shift;
+  my $fname = shift;
+  open (my $fh, "<", $fname) or return;
 
-  do
-  {
-    @help_txt = ();
+  my @help_txt;
+  while (my $line = <$fh>)
+    {
+      next if $line =~ m/^\s*$/;      # skip empty lines
+      last if $line !~ m/^\s*(#|%)/;  # out of here once code starts
+
+      my $reading_block = sub {defined ($line = <$fh>) && $line !~ m/^\s*$/};
 
-    ## Advance to non-blank line
-    while (defined ($_ = <FH>) and /^\s*$/) {;}
-
-    if (! /^\s*(?:#|%)/ or eof (FH))
-    {
-      ## No comment block found.  Return empty string
-      close (FH);
-      return "";
+      ## Skip this block
+      if ($line =~ /(Copyright|Author)/)
+        { while (&$reading_block ()) {} }
+      else
+        {
+          do
+            {
+              $line =~ s/^\s*(%|#)+ ?//;
+              push (@help_txt, $line);
+            } while (&$reading_block ());
+          last;
+        }
     }
 
-    ## Extract help text stopping when comment block ends
-    do
-    {
-      ## Remove comment characters at start of line
-      s/^\s*(?:#|%){1,2} ?//;
-      push (@help_txt, $_);
-    } until (! defined ($_ = <FH>) or ! /^\s*(?:#|%)/);
-
-  } until ($help_txt[0] !~ /^(?:Copyright|Author)/); 
-
-  close (FH);
-
+  close ($fh);
   return @help_txt;
 }
--- a/scripts/optimization/fminbnd.m	Fri Aug 01 09:06:21 2014 -0400
+++ b/scripts/optimization/fminbnd.m	Fri Aug 01 12:10:05 2014 -0400
@@ -170,7 +170,7 @@
 
     ## update  a, b, v, w, and x
 
-    if (fu <= fval)
+    if (fu < fval)
       if (u < x)
         b = x;
       else
@@ -283,4 +283,5 @@
 %!assert (fminbnd (@(x) (x - 1e-3)^4, -1, 1, opt0), 1e-3, 10e-3*sqrt (eps))
 %!assert (fminbnd (@(x) abs (x-1e7), 0, 1e10, opt0), 1e7, 10e7*sqrt (eps))
 %!assert (fminbnd (@(x) x^2 + sin (2*pi*x), 0.4, 1, opt0), fzero (@(x) 2*x + 2*pi*cos (2*pi*x), [0.4, 1], opt0), sqrt (eps))
+%!assert (fminbnd (@(x) x > 0.3, 0, 1) < 0.3) 
 
--- a/scripts/optimization/fminunc.m	Fri Aug 01 09:06:21 2014 -0400
+++ b/scripts/optimization/fminunc.m	Fri Aug 01 12:10:05 2014 -0400
@@ -63,11 +63,11 @@
 ## Last relative change in function value was less than @code{TolFun}.
 ##
 ## @item 0
-## Iteration limit exceeded---either maximum numer of algorithm iterations
+## Iteration limit exceeded---either maximum number of algorithm iterations
 ## @code{MaxIter} or maximum number of function evaluations @code{MaxFunEvals}.
 ##
 ## @item -1
-## Alogrithm terminated by @code{OutputFcn}.
+## Algorithm terminated by @code{OutputFcn}.
 ##
 ## @item -3
 ## The trust region radius became excessively small.
--- a/scripts/optimization/fsolve.m	Fri Aug 01 09:06:21 2014 -0400
+++ b/scripts/optimization/fsolve.m	Fri Aug 01 12:10:05 2014 -0400
@@ -382,7 +382,7 @@
       ## iterations, so we need scaling-independent tolerances wherever
       ## possible.
 
-      ## FIXME -- why tolf*n*xn? If abs (e) ~ abs(x) * eps is a vector
+      ## FIXME: Why tolf*n*xn? If abs (e) ~ abs(x) * eps is a vector
       ## of perturbations of x, then norm (fjac*e) <= eps*n*xn, i.e. by
       ## tolf ~ eps we demand as much accuracy as we can expect.
       if (fn <= tolf*n*xn)
--- a/scripts/optimization/fzero.m	Fri Aug 01 09:06:21 2014 -0400
+++ b/scripts/optimization/fzero.m	Fri Aug 01 12:10:05 2014 -0400
@@ -100,7 +100,7 @@
 
   ## Get default options if requested.
   if (nargin == 1 && ischar (fun) && strcmp (fun, 'defaults'))
-    x = optimset ("MaxIter", Inf, "MaxFunEvals", Inf, "TolX", 1e-8,
+    x = optimset ("MaxIter", Inf, "MaxFunEvals", Inf, "TolX", eps,
                   "OutputFcn", [], "FunValCheck", "off");
     return;
   endif
@@ -117,7 +117,7 @@
   ## displev = optimget (options, "Display", "notify");
   funvalchk = strcmpi (optimget (options, "FunValCheck", "off"), "on");
   outfcn = optimget (options, "OutputFcn");
-  tolx = optimget (options, "TolX", 1e-8);
+  tolx = optimget (options, "TolX", eps);
   maxiter = optimget (options, "MaxIter", Inf);
   maxfev = optimget (options, "MaxFunEvals", Inf);
 
@@ -302,7 +302,7 @@
     endif
 
     ## If there's an output function, use it now.
-    if (outfcn)
+    if (! isempty (outfcn))
       optv.funccount = nfev;
       optv.fval = fval;
       optv.iteration = niter;
--- a/scripts/optimization/glpk.m	Fri Aug 01 09:06:21 2014 -0400
+++ b/scripts/optimization/glpk.m	Fri Aug 01 12:10:05 2014 -0400
@@ -123,7 +123,7 @@
 ##
 ## @item @qcode{"D"}
 ## An inequality constraint with both upper and lower bounds
-## (@code{A(i,:)*x >= -b(i)} @emph{and} (@code{A(i,:)*x <= b(i)}).
+## (@code{A(i,:)*x >= -b(i)}) @emph{and} (@code{A(i,:)*x <= b(i)}).
 ## @end table
 ##
 ## @item vartype
--- a/scripts/optimization/optimget.m	Fri Aug 01 09:06:21 2014 -0400
+++ b/scripts/optimization/optimget.m	Fri Aug 01 12:10:05 2014 -0400
@@ -20,10 +20,12 @@
 ## -*- texinfo -*-
 ## @deftypefn  {Function File} {} optimget (@var{options}, @var{parname})
 ## @deftypefnx {Function File} {} optimget (@var{options}, @var{parname}, @var{default})
-## Return a specific option from a structure created by
-## @code{optimset}.  If @var{parname} is not a field of the @var{options}
-## structure, return @var{default} if supplied, otherwise return an
-## empty matrix.
+## Return the specific option @var{parname} from the optimization options
+## structure @var{options} created by @code{optimset}.
+##
+## If @var{parname} is not defined then return @var{default} if supplied,
+## otherwise return an empty matrix.
+## @seealso{optimset}
 ## @end deftypefn
 
 function retval = optimget (options, parname, default)
@@ -32,21 +34,22 @@
     print_usage ();
   endif
 
+  ## Expand partial-length names into full names
   opts = __all_opts__ ();
   idx = strncmpi (opts, parname, length (parname));
-
   nmatch = sum (idx);
 
   if (nmatch == 1)
     parname = opts{idx};
   elseif (nmatch == 0)
-    warning ("unrecognized option: %s", parname);
+    warning ("optimget: unrecognized option: %s", parname);
   else
-    fmt = sprintf ("ambiguous option: %%s (%s%%s)",
+    fmt = sprintf ("optimget: ambiguous option: %%s (%s%%s)",
                    repmat ("%s, ", 1, nmatch-1));
     warning (fmt, parname, opts{idx});
   endif
-  if (isfield (options, parname))
+
+  if (isfield (options, parname) && ! isempty (options.(parname)))
     retval = options.(parname);
   elseif (nargin > 2)
     retval = default;
@@ -57,13 +60,20 @@
 endfunction
 
 
-%!error optimget ()
-
 %!shared opts
 %! opts = optimset ("tolx", 0.1, "maxit", 100);
-%!assert (optimget (opts, "TolX"), 0.1);
-%!assert (optimget (opts, "maxit"), 100);
-%!assert (optimget (opts, "MaxITer"), 100);
-%!warning (optimget (opts, "Max"));
-%!warning (optimget (opts, "foobar"));
+%!assert (optimget (opts, "TolX"), 0.1)
+%!assert (optimget (opts, "maxit"), 100)
+%!assert (optimget (opts, "MaxITer"), 100)
+%!assert (optimget (opts, "TolFun"), [])
+%!assert (optimget (opts, "TolFun", 1e-3), 1e-3)
 
+%% Test input validation
+%!error optimget ()
+%!error optimget (1)
+%!error optimget (1,2,3,4,5)
+%!error optimget (1, "name")
+%!error optimget (struct (), 2)
+%!warning <unrecognized option: foobar> (optimget (opts, "foobar"));
+%!warning <ambiguous option: Max> (optimget (opts, "Max"));
+
--- a/scripts/optimization/optimset.m	Fri Aug 01 09:06:21 2014 -0400
+++ b/scripts/optimization/optimset.m	Fri Aug 01 12:10:05 2014 -0400
@@ -19,10 +19,24 @@
 
 ## -*- texinfo -*-
 ## @deftypefn  {Function File} {} optimset ()
-## @deftypefnx {Function File} {} optimset (@var{par}, @var{val}, @dots{})
-## @deftypefnx {Function File} {} optimset (@var{old}, @var{par}, @var{val}, @dots{})
-## @deftypefnx {Function File} {} optimset (@var{old}, @var{new})
-## Create options struct for optimization functions.
+## @deftypefnx {Function File} {@var{options} =} optimset ()
+## @deftypefnx {Function File} {@var{options} =} optimset (@var{par}, @var{val}, @dots{})
+## @deftypefnx {Function File} {@var{options} =} optimset (@var{old}, @var{par}, @var{val}, @dots{})
+## @deftypefnx {Function File} {@var{options} =} optimset (@var{old}, @var{new})
+## Create options structure for optimization functions.
+##
+## When called without any input or output arguments, @code{optimset} prints
+## a list of all valid optimization parameters.
+##
+## When called with one output and no inputs, return an options structure with
+## all valid option parameters initialized to @code{[]}.
+##
+## When called with a list of parameter/value pairs, return an options
+## structure with only the named parameters initialized.
+##
+## When the first input is an existing options structure @var{old}, the values
+## are updated from either the @var{par}/@var{val} list or from the options
+## structure @var{new}.
 ##
 ## Valid parameters are:
 ##
@@ -96,13 +110,13 @@
 ##
 ## @item Updating
 ## @end table
+## @seealso{optimget}
 ## @end deftypefn
 
 function retval = optimset (varargin)
 
   nargs = nargin ();
 
-  ## Add more as needed.
   opts = __all_opts__ ();
 
   if (nargs == 0)
@@ -124,8 +138,8 @@
       error ("optimset: no defaults for function '%s'", fcn);
     end_try_catch
   elseif (nargs == 2 && isstruct (varargin{1}) && isstruct (varargin{2}))
-    ## Set slots in old from nonempties in new.  Should we be checking
-    ## to ensure that the field names are expected?
+    ## Set slots in old from non-empties in new.
+    ## Should we be checking to ensure that the field names are expected?
     old = varargin{1};
     new = varargin{2};
     fnames = fieldnames (old);
@@ -140,9 +154,9 @@
         if (nmatch == 1)
           key = opts{find (i)};
         elseif (nmatch == 0)
-          warning ("unrecognized option: %s", key);
+          warning ("optimset: unrecognized option: %s", key);
         else
-          fmt = sprintf ("ambiguous option: %%s (%s%%s)",
+          fmt = sprintf ("optimset: ambiguous option: %%s (%s%%s)",
                          repmat ("%s, ", 1, nmatch-1));
           warning (fmt, key, opts{i});
         endif
@@ -155,8 +169,8 @@
     pairs = reshape (varargin(2:end), 2, []);
     retval = optimset (varargin{1}, cell2struct (pairs(2, :), pairs(1, :), 2));
   elseif (rem (nargs, 2) == 0)
-    ## Create struct.  Default values are replaced by those specified by
-    ## name/value pairs.
+    ## Create struct.
+    ## Default values are replaced by those specified by name/value pairs.
     pairs = reshape (varargin, 2, []);
     retval = optimset (struct (), cell2struct (pairs(2, :), pairs(1, :), 2));
   else
@@ -166,10 +180,13 @@
 endfunction
 
 
-%!assert (optimget (optimset ("tolx", 1e-2), "tOLx"), 1e-2)
+%!assert (isfield (optimset (), "TolFun"))
 %!assert (isfield (optimset ("tolFun", 1e-3), "TolFun"))
-%!warning (optimset ("Max", 10));
-%!warning (optimset ("foobar", 13));
+%!assert (optimget (optimset ("tolx", 1e-2), "tOLx"), 1e-2)
 
-%!error (optimset ("%NOT_A_REAL_FUNCTION_NAME%"))
+%% Test input validation
+%!error optimset ("1_Parameter")
+%!error <no defaults for function> optimset ("%NOT_A_REAL_FUNCTION_NAME%")
+%!warning <unrecognized option: foobar> optimset ("foobar", 13);
+%!warning <ambiguous option: Max> optimset ("Max", 10);
 
--- a/scripts/optimization/sqp.m	Fri Aug 01 09:06:21 2014 -0400
+++ b/scripts/optimization/sqp.m	Fri Aug 01 12:10:05 2014 -0400
@@ -1,4 +1,5 @@
 ## Copyright (C) 2005-2013 John W. Eaton
+## Copyright (C) 2013 Arun Giridhar
 ##
 ## This file is part of Octave.
 ##
@@ -128,8 +129,17 @@
 ##
 ## @table @asis
 ## @item 101
-## The algorithm terminated normally.
-## Either all constraints meet the requested tolerance, or the stepsize,
+## The algorithm terminated normally. 
+## All constraints meet the specified tolerance.
+##
+## @item 102
+## The BFGS update failed.
+##
+## @item 103
+## The maximum number of iterations was reached.
+##
+## @item 104
+## The stepsize has become too small, i.e., 
 ## @tex
 ## $\Delta x,$
 ## @end tex
@@ -137,12 +147,6 @@
 ## delta @var{x},
 ## @end ifnottex
 ## is less than @code{@var{tol} * norm (x)}.
-##
-## @item 102
-## The BFGS update failed.
-##
-## @item 103
-## The maximum number of iterations was reached.
 ## @end table
 ##
 ## An example of calling @code{sqp}:
@@ -394,6 +398,8 @@
     t3 = all (lambda_i >= 0);
     t4 = norm (lambda .* con);
 
+    ## Normal convergence.  All constraints are satisfied
+    ## and objective has converged.
     if (t2 && t3 && max ([t0; t1; t4]) < tol)
       info = 101;
       break;
@@ -408,8 +414,8 @@
 
     info = INFO.info;
 
-    ## FIXME -- check QP solution and attempt to recover if it has
-    ## failed.  For now, just warn about possible problems.
+    ## FIXME: check QP solution and attempt to recover if it has failed.
+    ##        For now, just warn about possible problems.
     
     id = "Octave:SQP-QP-subproblem";
     switch (info)
@@ -453,8 +459,9 @@
 
     delx = x_new - x;
 
+    ## Check if step size has become too small (indicates lack of progress).
     if (norm (delx) < tol * norm (x))
-      info = 101;
+      info = 104;
       break;
     endif
 
@@ -483,6 +490,8 @@
 
       d2 = delxt*r;
 
+      ## Check if the next BFGS update will work properly.
+      ## If d1 or d2 vanish, the BFGS update will fail.
       if (d1 == 0 || d2 == 0)
         info = 102;
         break;
@@ -510,6 +519,7 @@
 
   endwhile
 
+  ## Check if we've spent too many iterations without converging.
   if (iter >= iter_max)
     info = 103;
   endif
--- a/scripts/pkg/module.mk	Fri Aug 01 09:06:21 2014 -0400
+++ b/scripts/pkg/module.mk	Fri Aug 01 12:10:05 2014 -0400
@@ -5,6 +5,7 @@
   pkg/private/configure_make.m \
   pkg/private/copy_files.m \
   pkg/private/create_pkgadddel.m \
+  pkg/private/default_prefix.m \
   pkg/private/describe.m \
   pkg/private/dirempty.m \
   pkg/private/extract_pkg.m \
--- a/scripts/pkg/pkg.m	Fri Aug 01 09:06:21 2014 -0400
+++ b/scripts/pkg/pkg.m	Fri Aug 01 12:10:05 2014 -0400
@@ -280,14 +280,7 @@
   global_install = ((ispc () && ! isunix ()) || (geteuid () == 0));
 
   if (isbool (prefix))
-    if (global_install)
-      prefix = fullfile (OCTAVE_HOME (), "share", "octave", "packages");
-      archprefix = fullfile (octave_config_info ("libdir"),
-                             "octave", "packages");
-    else
-      prefix = fullfile ("~", "octave");
-      archprefix = prefix;
-    endif
+    [prefix, archprefix] = default_prefix (global_install);
     prefix = tilde_expand (prefix);
     archprefix = tilde_expand (archprefix);
   endif
@@ -326,15 +319,12 @@
       case "-local"
         global_install = false;
         if (! user_prefix)
-          prefix = tilde_expand (fullfile ("~", "octave"));
-          archprefix = prefix;
+          [prefix, archprefix] = default_prefix (global_install);
         endif
       case "-global"
         global_install = true;
         if (! user_prefix)
-          prefix = fullfile (OCTAVE_HOME (), "share", "octave", "packages");
-          archprefix = fullfile (octave_config_info ("libdir"),
-                                 "octave", "packages");
+          [prefix, archprefix] = default_prefix (global_install);
         endif
       case available_actions
         if (strcmp (action, "none"))
--- a/scripts/pkg/private/configure_make.m	Fri Aug 01 09:06:21 2014 -0400
+++ b/scripts/pkg/private/configure_make.m	Fri Aug 01 12:10:05 2014 -0400
@@ -32,11 +32,6 @@
     mkoctfile_program = fullfile (octave_bindir, sprintf ("mkoctfile-%s%s", ver, ext));
     octave_config_program = fullfile (octave_bindir, sprintf ("octave-config-%s%s", ver, ext));
     octave_binary = fullfile (octave_bindir, sprintf ("octave-%s%s", ver, ext));
-    cenv = {"MKOCTFILE"; mkoctfile_program;
-            "OCTAVE_CONFIG"; octave_config_program;
-            "OCTAVE"; octave_binary;
-            "INSTALLDIR"; desc.dir};
-    scenv = sprintf ("%s=\"%s\" ", cenv{:});
 
     if (! exist (mkoctfile_program, "file"))
       __gripe_missing_component__ ("pkg", "mkoctfile");
@@ -48,6 +43,16 @@
       __gripe_missing_component__ ("pkg", "octave");
     endif
 
+    if (verbose)
+      mkoctfile_program = [mkoctfile_program " --verbose"];
+    endif
+
+    cenv = {"MKOCTFILE"; mkoctfile_program;
+            "OCTAVE_CONFIG"; octave_config_program;
+            "OCTAVE"; octave_binary;
+            "INSTALLDIR"; desc.dir};
+    scenv = sprintf ("%s=\"%s\" ", cenv{:});
+
     ## Configure.
     if (exist (fullfile (src, "configure"), "file"))
       flags = "";
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/pkg/private/default_prefix.m	Fri Aug 01 12:10:05 2014 -0400
@@ -0,0 +1,40 @@
+## Copyright (C) 2014 Carlo de Falco
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {[@var{prefix}, @var{archprefix} =} @
+## default_prefix (@var{global_install})
+## Undocumented internal function.
+## @end deftypefn
+
+function [prefix, archprefix] = default_prefix (global_install, desc)
+  if (global_install)
+    prefix = fullfile (OCTAVE_HOME (), "share", "octave", "packages");
+    if (nargin == 2)
+      archprefix = fullfile (octave_config_info ("libdir"), "octave",
+                             "packages", [desc.name "-" desc.version]);
+    else
+      archprefix = fullfile (octave_config_info ("libdir"), "octave",
+                             "packages");
+    endif
+  else
+    prefix = tilde_expand (fullfile ("~", "octave"));
+    archprefix = prefix;
+  endif
+endfunction
+
--- a/scripts/pkg/private/getarchprefix.m	Fri Aug 01 09:06:21 2014 -0400
+++ b/scripts/pkg/private/getarchprefix.m	Fri Aug 01 12:10:05 2014 -0400
@@ -24,8 +24,7 @@
 
 function archprefix = getarchprefix (desc, global_install)
   if (global_install)
-    archprefix = fullfile (octave_config_info ("libdir"), "octave",
-                           "packages", [desc.name "-" desc.version]);
+    [~, archprefix] = default_prefix (global_install, desc);
   else
     archprefix = desc.dir;
   endif
--- a/scripts/plot/appearance/__getlegenddata__.m	Fri Aug 01 09:06:21 2014 -0400
+++ b/scripts/plot/appearance/__getlegenddata__.m	Fri Aug 01 12:10:05 2014 -0400
@@ -29,7 +29,7 @@
   if (numel (ca) == 1)
     kids = get (ca, "children");
   else
-    kids = [get(kids, "children"){:}];
+    kids = [get(ca, "children"){:}];
   endif
 
   for i = numel (kids):-1:1
--- a/scripts/plot/appearance/axis.m	Fri Aug 01 09:06:21 2014 -0400
+++ b/scripts/plot/appearance/axis.m	Fri Aug 01 12:10:05 2014 -0400
@@ -30,7 +30,9 @@
 ## The argument @var{limits} should be a 2-, 4-, or 6-element vector.  The
 ## first and second elements specify the lower and upper limits for the
 ## x-axis.  The third and fourth specify the limits for the y-axis, and the
-## fifth and sixth specify the limits for the z-axis.
+## fifth and sixth specify the limits for the z-axis.  The special values
+## -Inf and Inf may be used to indicate that the limit should automatically be
+## computed based on the data in the axis.
 ##
 ## Without any arguments, @code{axis} turns autoscaling on.
 ##
@@ -192,7 +194,7 @@
                "plotboxaspectratio", [1, 1, 1]);
     elseif (strcmp (ax, "equal"))
       if (strcmp (get (get (ca, "parent"), "__graphics_toolkit__"), "gnuplot"))
-        ## FIXME - gnuplot applies the aspect ratio activepostionproperty.
+        ## FIXME: gnuplot applies the aspect ratio activepostionproperty.
         set (ca, "activepositionproperty", "position");
         ## The following line is a trick used to trigger the recalculation of
         ## aspect related magnitudes even if the aspect ratio is the same
@@ -297,15 +299,15 @@
     endfor
 
     if (len > 1)
-      set (ca, "xlim", [ax(1), ax(2)]);
+      xlim (ca, ax(1:2));
     endif
 
     if (len > 3)
-      set (ca, "ylim", [ax(3), ax(4)]);
+      ylim (ca, ax(3:4));
     endif
 
     if (len > 5)
-      set (ca, "zlim", [ax(5), ax(6)]);
+      zlim (ca, ax(5:6));
     endif
 
   else
--- a/scripts/plot/appearance/datetick.m	Fri Aug 01 09:06:21 2014 -0400
+++ b/scripts/plot/appearance/datetick.m	Fri Aug 01 12:10:05 2014 -0400
@@ -45,8 +45,8 @@
 
   unwind_protect
     ## FIXME: This will bring the axes to the top of the stack.
-    ##        This may not always be desirable if there are multiple axes
-    ##        objects.
+    ##        This may not be desirable if there are multiple axes objects,
+    ##        such as can occur with plotyy.
     axes (hax);
     __datetick__ (varargin{:});
   unwind_protect_cleanup
@@ -64,22 +64,22 @@
 %! pop = [76.094, 92.407, 106.461, 123.077 131.954, 151.868, 179.979, ...
 %!        203.984, 227.225, 249.623, 282.224];
 %! plot (datenum (yr, 1, 1), pop);
-%! title ("US population (millions)");
-%! xlabel ("Year");
-%! datetick ("x", "YYYY");
+%! title ('US population (millions)');
+%! xlabel ('Year');
+%! datetick ('x', 'YYYY');
 
 %!demo
 %! clf;
 %! yr = 1988:2:2002;
 %! yr = datenum (yr,1,1);
 %! pr = [12.1 13.3 12.6 13.1 13.3 14.1 14.4 15.2];
-%! plot (yr, pr, "-o");
-%! xlabel ("year");
-%! ylabel ("average price");
+%! plot (yr, pr, '-o');
+%! xlabel ('year');
+%! ylabel ('average price');
 %! ax = gca;
-%! set (ax, "xtick", datenum (1990:5:2005,1,1));
-%! datetick (2, "keepticks");
-%! set (ax, "ytick", 12:16);
+%! set (ax, 'xtick', datenum (1990:5:2005,1,1));
+%! datetick (2, 'x', 'keepticks');
+%! set (ax, 'ytick', 12:16);
 
 ## Remove from test statistics.  No real tests possible.
 %!assert (1)
--- a/scripts/plot/appearance/diffuse.m	Fri Aug 01 09:06:21 2014 -0400
+++ b/scripts/plot/appearance/diffuse.m	Fri Aug 01 12:10:05 2014 -0400
@@ -18,11 +18,11 @@
 
 ## -*- texinfo -*-
 ## @deftypefn {Function File} {} diffuse (@var{sx}, @var{sy}, @var{sz}, @var{lv})
-## Calculate diffuse reflection strength of a surface defined by the normal
+## Calculate the diffuse reflection strength of a surface defined by the normal
 ## vector elements @var{sx}, @var{sy}, @var{sz}.
 ##
-## The light source location vector @var{lv} can be given as 2-element vector
-## [azimuth, elevation] in degrees or as 3-element vector [lx, ly, lz].
+## The light source location vector @var{lv} can be given as a 2-element vector
+## [azimuth, elevation] in degrees or as a 3-element vector [x, y, z].
 ## @seealso{specular, surfl}
 ## @end deftypefn
 
@@ -34,13 +34,13 @@
     print_usage ();
   endif
 
-  ## check for normal vector
-  if (!size_equal (sx, sy, sz))
-    error ("diffuse: SX, SY, and SZ must have same size");
+  ## Check normal vectors
+  if (! size_equal (sx, sy, sz))
+    error ("diffuse: SX, SY, and SZ must be the same size");
   endif
 
-  ## check for light vector (lv) argument
-  if (length (lv) < 2 || length (lv) > 3)
+  ## Check light vector (lv) argument
+  if (! isvector (lv) || length (lv) < 2 || length (lv) > 3)
     error ("diffuse: light vector LV must be a 2- or 3-element vector");
   elseif (length (lv) == 2)
     [lv(1), lv(2), lv(3)] = sph2cart (lv(1) * pi/180, lv(2) * pi/180, 1.0);
@@ -48,7 +48,7 @@
 
   ## Normalize view and light vector.
   if (sum (abs (lv)) > 0)
-    lv  /= norm (lv);
+    lv /= norm (lv);
   endif
 
   ns = sqrt (sx.^2 + sy.^2 + sz.^2);
--- a/scripts/plot/appearance/grid.m	Fri Aug 01 09:06:21 2014 -0400
+++ b/scripts/plot/appearance/grid.m	Fri Aug 01 12:10:05 2014 -0400
@@ -58,13 +58,10 @@
     print_usage ();
   endif
 
-  grid_on = (   strcmp (get (hax, "xgrid"), "on")
-             && strcmp (get (hax, "ygrid"), "on")
-             && strcmp (get (hax, "zgrid"), "on"));
+  grid_on = any (strcmp (get (hax, {"xgrid", "ygrid", "zgrid"}), "on"));
 
-  minor_on = (   strcmp (get (hax, "xminorgrid"), "on")
-              && strcmp (get (hax, "yminorgrid"), "on")
-              && strcmp (get (hax, "zminorgrid"), "on"));
+  minor_on = any (strcmp (get (hax, {"xminorgrid", "yminorgrid", "zminorgrid"}),
+                         "on"));
 
   minor_auto = true;
   if (nargs == 0)
@@ -102,9 +99,15 @@
   endif
 
   if (grid_on)
-    set (hax, "xgrid", "on", "ygrid", "on", "zgrid", "on");
+    set (hax, "xgrid", "on", "ygrid", "on", "zgrid", "on",
+              "gridlinestyle", ":");
     if (minor_on)
-      set (hax, "xminorgrid", "on", "yminorgrid", "on", "zminorgrid", "on");
+      set (hax, "xminorgrid", "on", "yminorgrid", "on", "zminorgrid", "on",
+                "gridlinestyle", "-", "minorgridlinestyle", ":");
+      xg = ifelse (strcmp (get (hax, "xscale"), "log"), "off", "on");
+      yg = ifelse (strcmp (get (hax, "yscale"), "log"), "off", "on");
+      zg = ifelse (strcmp (get (hax, "zscale"), "log"), "off", "on");
+      set (hax, "xgrid", xg, "ygrid", yg, "zgrid", zg);
     elseif (minor_auto)
       xmg = ifelse (strcmp (get (hax, "xscale"), "log"), "on", "off");
       ymg = ifelse (strcmp (get (hax, "yscale"), "log"), "on", "off");
@@ -133,8 +136,26 @@
 %!  title ('grid on');
 %! subplot (2,2,3);
 %!  plot (1:100);
+%!  grid off;
+%!  title ('no grid');
+%! subplot (2,2,4);
+%!  plot (1:100);
 %!  grid minor;
 %!  title ('grid minor');
+
+%!demo
+%! subplot (2,2,1);
+%!  semilogy (1:100);
+%!  grid off;
+%!  title ('no grid');
+%! subplot (2,2,2);
+%!  semilogy (1:100);
+%!  grid on;
+%!  title ('grid on');
+%! subplot (2,2,3);
+%!  semilogy (1:100);
+%!  grid off;
+%!  title ('no grid');
 %! subplot (2,2,4);
 %!  semilogy (1:100);
 %!  grid minor;
--- a/scripts/plot/appearance/legend.m	Fri Aug 01 09:06:21 2014 -0400
+++ b/scripts/plot/appearance/legend.m	Fri Aug 01 12:10:05 2014 -0400
@@ -166,11 +166,27 @@
   nargs = numel (varargin);
   nkids = numel (kids);
 
+  ## Find any existing legend object on figure
+  hlegend = [];
+  fkids = get (fig, "children");
+  for i = 1 : numel (fkids)
+    if (   strcmp (get (fkids(i), "type"), "axes")
+        && strcmp (get (fkids(i), "tag"), "legend"))
+      udata = get (fkids(i), "userdata");
+      if (any (ismember (udata.handle, ca)))
+        hlegend = fkids(i);
+        break;
+      endif
+    endif
+  endfor
+
   orientation = "default";
   location = "default";
   show = "create";
   textpos = "default";
   box = "default";
+  delete_leg = false;
+  find_leg_hdl = (nargs == 0);
 
   ## Process old way of specifying location with a number rather than a string.
   if (nargs > 0)
@@ -229,20 +245,6 @@
       error ("legend: unrecognized legend location");
   endswitch
 
-  ## Find any existing legend object on figure
-  hlegend = [];
-  fkids = get (fig, "children");
-  for i = 1 : numel (fkids)
-    if (   strcmp (get (fkids(i), "type"), "axes")
-        && strcmp (get (fkids(i), "tag"), "legend"))
-      udata = get (fkids(i), "userdata");
-      if (any (udata.handle == ca))
-        hlegend = fkids(i);
-        break;
-      endif
-    endif
-  endfor
-
   if (nargs == 1)
     arg = varargin{1};
     if (ischar (arg))
@@ -250,8 +252,7 @@
         str = tolower (strtrim (arg));
         switch (str)
           case "off"
-            delete (hlegend);
-            return;
+            delete_leg = true;
           case "hide"
             show = "off";
             nargs--;
@@ -305,24 +306,26 @@
   endif
 
   have_labels = (nargs > 0);
+  hobjects = [];
+  hplots  = [];
+  text_strings = {};
 
-  if (strcmp (show, "off"))
+  if (delete_leg)
+    delete (hlegend);
+    hlegend = [];
+  elseif (find_leg_hdl)
+    ## Don't change anything about legend.
+    ## hleg output will be assigned hlegend value at end of function.
+  elseif (strcmp (show, "off"))
     if (! isempty (hlegend))
       set (findobj (hlegend), "visible", "off");
       hlegend = [];
     endif
-    hobjects = [];
-    hplots  = [];
-    text_strings = {};
   elseif (strcmp (show, "on"))
     if (! isempty (hlegend))
       set (findobj (hlegend), "visible", "on");
-      ## NOTE - Matlab sets both "visible", and "box" to "on"
+      ## NOTE: Matlab sets both "visible" and "box" to "on"
       set (hlegend, "visible", get (hlegend, "box"));
-    else
-      hobjects = [];
-      hplots  = [];
-      text_strings = {};
     endif
   elseif (strcmp (box, "on"))
     if (! isempty (hlegend))
@@ -332,26 +335,24 @@
     if (! isempty (hlegend))
       set (hlegend, "box", "off", "visible", "off");
     endif
-  elseif (! have_labels && ! (strcmp (location, "default") &&
-                              strcmp (orientation, "default")))
+  elseif (! have_labels && ! isempty (hlegend)
+          && ! (strcmp (location, "default") && strcmp (orientation, "default")))
     ## Changing location or orientation of existing legend
-    if (! isempty (hlegend))
-      if (strcmp (location, "default"))
-        set (hlegend, "orientation", orientation);
-      elseif (strcmp (orientation, "default"))
-        if (outside)
-          set (hlegend, "location", [location "outside"]);
-        else
-          set (hlegend, "location", location);
-        endif
+    if (strcmp (location, "default"))
+      set (hlegend, "orientation", orientation);
+    elseif (strcmp (orientation, "default"))
+      if (outside)
+        set (hlegend, "location", [location "outside"]);
       else
-        if (outside)
-          set (hlegend, "location", [location "outside"],
-                        "orientation", orientation);
-        else
-          set (hlegend, "location", location,
-                        "orientation", orientation);
-        endif
+        set (hlegend, "location", location);
+      endif
+    else
+      if (outside)
+        set (hlegend, "location", [location "outside"],
+                      "orientation", orientation);
+      else
+        set (hlegend, "location", location,
+                      "orientation", orientation);
       endif
     endif
   else
@@ -565,6 +566,12 @@
       linelength = 15;
 
       ## Create the axis first
+      oldfig = get (0, "currentfigure");
+      if (oldfig != fig)
+        set (0, "currentfigure", fig);
+      else
+        oldfig = [];
+      endif
       curaxes = get (fig, "currentaxes");
       unwind_protect
         ud = ancestor (hplots, "axes");
@@ -829,10 +836,11 @@
             case "line"
               color = get (hplots(k), "color");
               style = get (hplots(k), "linestyle");
+              lwidth = min (get (hplots(k), "linewidth"), 5);
               if (! strcmp (style, "none"))
                 l1 = line ("xdata", ([xoffset, xoffset + linelength] + xk * xstep) / lpos(3),
                            "ydata", [1, 1] .* (lpos(4) - yoffset - yk * ystep) / lpos(4),
-                           "color", color, "linestyle", style,
+                           "color", color, "linestyle", style, "linewidth", lwidth,
                            "marker", "none",
                            "userdata", hplots(k));
                 hobjects(end+1) = l1;
@@ -841,11 +849,11 @@
               if (! strcmp (marker, "none"))
                 l1 = line ("xdata", (xoffset + 0.5 * linelength  + xk * xstep) / lpos(3),
                            "ydata", (lpos(4) - yoffset - yk * ystep) / lpos(4),
-                           "color", color, "linestyle", "none",
+                           "color", color, "linestyle", "none", "linewidth", lwidth,
                            "marker", marker,
                            "markeredgecolor",get (hplots(k), "markeredgecolor"),
                            "markerfacecolor",get (hplots(k), "markerfacecolor"),
-                           "markersize", get (hplots(k), "markersize"),
+                           "markersize", min (get (hplots(k), "markersize"),10),
                            "userdata", hplots(k));
                 hobjects(end+1) = l1;
               endif
@@ -855,6 +863,8 @@
                              {@updateline, hlegend, linelength, false});
                 addlistener (hplots(k), "linestyle",
                              {@updateline, hlegend, linelength, false});
+                addlistener (hplots(k), "linewidth",
+                             {@updateline, hlegend, linelength, false});
                 addlistener (hplots(k), "marker",
                              {@updateline, hlegend, linelength, false});
                 addlistener (hplots(k), "markeredgecolor",
@@ -876,13 +886,24 @@
                                       xoffset + xk * xstep) / lpos(3),
                             "ydata", (lpos(4) - yoffset -
                                       [yk-0.3, yk-0.3, yk+0.3, yk+0.3] .* ystep) / lpos(4),
-                           "facecolor", facecolor, "edgecolor", edgecolor,
-                           "cdata", cdata, "userdata", hplots(k));
-                hobjects(end+1) = p1;
-                ## Copy clim from axes so that colors work out.
-                set (hlegend, "clim", get (ca(1), "clim"));
+                            "facecolor", facecolor, "edgecolor", edgecolor,
+                            "cdata", cdata, "userdata", hplots(k));
+              else
+                ## non-standard patch only making use of marker styles
+                ## such as scatter plot.
+                p1 = patch ("xdata", (xoffset + 0.5 * linelength  + xk * xstep) / lpos(3),
+                            "ydata", (lpos(4) - yoffset - yk * ystep) / lpos(4),
+                            "marker", get (hplots(k), "marker"),
+                            "markeredgecolor",get (hplots(k),"markeredgecolor"),
+                            "markerfacecolor",get (hplots(k),"markerfacecolor"),
+                            "markersize", min (get (hplots(k),"markersize"),10),
+                            "cdata", cdata, "userdata", hplots(k));
               endif
-              ## FIXME: Probably need listeners, as for line objects
+              hobjects(end+1) = p1;
+              ## Copy clim from axes so that colors work out.
+              set (hlegend, "clim", get (ca(1), "clim"));
+
+              ## FIXME: Need listeners, as for line objects.
               ##        Changing clim, for example, won't update colors
 
             case "surface"
@@ -894,11 +915,11 @@
                                       xoffset + xk * xstep) / lpos(3),
                             "ydata", (lpos(4) - yoffset -
                                       [yk-0.3, yk-0.3, yk+0.3, yk+0.3] .* ystep) / lpos(4),
-                           "facecolor", facecolor, "edgecolor", edgecolor,
-                           "cdata", cdata, "userdata", hplots(k));
+                            "facecolor", facecolor, "edgecolor", edgecolor,
+                            "cdata", cdata, "userdata", hplots(k));
                 hobjects(end+1) = p1;
               endif
-              ## FIXME: Probably need listeners, as for line objects
+              ## FIXME: Need listeners, as for line objects.
 
           endswitch
 
@@ -1032,6 +1053,9 @@
         endif
       unwind_protect_cleanup
         set (fig, "currentaxes", curaxes);
+        if (! isempty (oldfig))
+          set (0, "currentfigure", oldfig);
+        endif
       end_unwind_protect
     endif
   endif
@@ -1065,8 +1089,9 @@
           set (hax, "position", position);
           set (hax, "outerposition", outerposition);
       endswitch
-      set (hax, "units", units);
-      h = legend (hax, hplots, get (h, "string"));
+      set (hax, {"units"}, units);
+
+      h = legend (hax(1), hplots, get (h, "string"));
     unwind_protect_cleanup
       recursive = false;
     end_unwind_protect
@@ -1149,6 +1174,7 @@
     if (ishandle (hplots(i)) && strcmp (get (hplots(i), "type"), "line"))
       dellistener (hplots(i), "color");
       dellistener (hplots(i), "linestyle");
+      dellistener (hplots(i), "linewidth");
       dellistener (hplots(i), "marker");
       dellistener (hplots(i), "markeredgecolor");
       dellistener (hplots(i), "markerfacecolor");
@@ -1163,7 +1189,7 @@
   if (update_name)
     ## When string changes, have to rebuild legend completely
     [hplots, text_strings] = __getlegenddata__ (hlegend);
-    legend (hplots, text_strings);
+    legend (get (hplots(1), "parent"), hplots, text_strings);
   else
     kids = get (hlegend, "children");
     ll = lm = [];
@@ -1198,14 +1224,18 @@
 
     if (! strcmp (linestyle, "none"))
       line ("xdata", xpos1, "ydata", ypos1, "color", get (h, "color"),
-            "linestyle", get (h, "linestyle"), "marker", "none",
+            "linestyle", get (h, "linestyle"),
+            "linewidth", min (get (h, "linewidth"), 5),
+            "marker", "none",
             "userdata", h, "parent", hlegend);
     endif
     if (! strcmp (marker, "none"))
       line ("xdata", xpos2, "ydata", ypos2, "color", get (h, "color"),
             "marker", marker, "markeredgecolor", get (h, "markeredgecolor"),
             "markerfacecolor", get (h, "markerfacecolor"),
-            "markersize", get (h, "markersize"), "linestyle", "none",
+            "markersize", min (get (h, "markersize"), 10),
+            "linestyle", "none",
+            "linewidth", min (get (h, "linewidth"), 5),
             "userdata", h, "parent", hlegend);
     endif
   endif
@@ -1217,22 +1247,22 @@
 %! plot (rand (2));
 %! title ('legend called with cellstr and string inputs for labels');
 %! h = legend ({'foo'}, 'bar');
-%! legend location northeastoutside
+%! legend (h, 'location', 'northeastoutside');
 %! set (h, 'fontsize', 20);
 
 %!demo
 %! clf;
 %! plot (rand (3));
-%! title ('legend() without inputs creates default labels');
-%! h = legend ();
+%! title ('legend("show") without inputs creates default labels');
+%! h = legend ('show');
 
 %!demo
 %! clf;
 %! x = 0:1;
 %! plot (x,x,';I am Blue;', x,2*x, x,3*x,';I am Red;');
-%! legend location northeastoutside
+%! h = legend ('location', 'northeastoutside');
 %! ## Placing legend inside should return axes to original size
-%! legend location northeast
+%! legend (h, 'location', 'northeast');
 %! title ('Blue and Red keys, with Green missing');
 
 %!demo
@@ -1368,9 +1398,9 @@
 %! rand_2x3_data2 = [0.44804, 0.84368, 0.23012; 0.72311, 0.58335, 0.90531];
 %! bar (rand_2x3_data2);
 %! ylim ([0 1.2]);
-%! title ('legend() works for bar graphs (hggroups)');
+%! title ('"left" option places text label west of colors');
 %! legend ('1st Bar', '2nd Bar', '3rd Bar');
-%! legend right;
+%! legend left;
 
 %!demo
 %! clf;
@@ -1605,3 +1635,20 @@
 %!   graphics_toolkit (toolkit);
 %! end_unwind_protect
 
+%!test
+%! ## bug #42035
+%! h = figure ("visible", "off");
+%! unwind_protect
+%!   hax1 = subplot (1,2,1);
+%!   plot (1:10);
+%!   hax2 = subplot (1,2,2);
+%!   plot (1:10);
+%!   hleg1 = legend (hax1, "foo");
+%!   assert (get (hleg1, "userdata").handle, hax1)
+%!   assert (gca (), hax2);
+%!   hleg2 = legend ("bar");
+%!   assert (get (hleg2, "userdata").handle, gca ())
+%! unwind_protect_cleanup
+%!   close (h);
+%! end_unwind_protect
+
--- a/scripts/plot/appearance/private/__axis_limits__.m	Fri Aug 01 09:06:21 2014 -0400
+++ b/scripts/plot/appearance/private/__axis_limits__.m	Fri Aug 01 12:10:05 2014 -0400
@@ -48,6 +48,11 @@
         if (arg(1) >= arg(2))
           error ("%s: axis limits must be increasing", fcn);
         else
+          autoscale = isinf (arg);
+          if (any (autoscale))
+            set (hax, fcnmode, "auto");
+            arg(autoscale) = get (hax, fcn)(autoscale);
+          endif
           set (hax, fcn, arg(:));
         endif
       endif
--- a/scripts/plot/appearance/specular.m	Fri Aug 01 09:06:21 2014 -0400
+++ b/scripts/plot/appearance/specular.m	Fri Aug 01 12:10:05 2014 -0400
@@ -19,15 +19,17 @@
 ## -*- texinfo -*-
 ## @deftypefn  {Function File} {} specular (@var{sx}, @var{sy}, @var{sz}, @var{lv}, @var{vv})
 ## @deftypefnx {Function File} {} specular (@var{sx}, @var{sy}, @var{sz}, @var{lv}, @var{vv}, @var{se})
-## Calculate specular reflection strength of a surface defined by the normal
-## vector elements @var{sx}, @var{sy}, @var{sz} using Phong's approximation.
+## Calculate the specular reflection strength of a surface defined by the
+## normal vector elements @var{sx}, @var{sy}, @var{sz} using Phong's
+## approximation.
 ##
-## The light source location and viewer location vectors can be specified using
-## parameter @var{lv} and @var{vv} respectively.  The location vectors can
+## The light source location and viewer location vectors are specified using
+## parameters @var{lv} and @var{vv} respectively.  The location vectors can
 ## given as 2-element vectors [azimuth, elevation] in degrees or as 3-element
 ## vectors [x, y, z].
 ##
-## An optional sixth argument describes the specular exponent (spread) @var{se}.
+## An optional sixth argument specifies the specular exponent (spread) @var{se}.
+## If not given, @var{se} defaults to 10.
 ## @seealso{diffuse, surfl}
 ## @end deftypefn
 
@@ -39,54 +41,52 @@
     print_usage ();
   endif
 
-  ## Checks for specular exponent (se).
-  if (nargin < 6)
-    se = 10;
-  else
-    if (!isnumeric (se) || numel (se) != 1 || se <= 0)
-      error ("specular: exponent must be positive scalar");
-    endif
+  ## Check normal vectors
+  if (! size_equal (sx, sy, sz))
+    error ("specular: SX, SY, and SZ must be the same size");
   endif
 
-  ## Checks for normal vector.
-  if (!size_equal (sx, sy, sz))
-    error ("specular: SX, SY, and SZ must have same size");
-  endif
-
-  ## Check for light vector (lv) argument.
-  if (length (lv) < 2 || length (lv) > 3)
+  ## Check light vector (lv) argument
+  if (! isvector (lv) || length (lv) < 2 || length (lv) > 3)
     error ("specular: light vector LV must be a 2- or 3-element vector");
   elseif (length (lv) == 2)
     [lv(1), lv(2), lv(3)] = sph2cart (lv(1) * pi/180, lv(2) * pi/180, 1.0);
   endif
 
-  ## Check for view vector (vv) argument.
-  if (length (vv) < 2 || length (lv) > 3)
+  ## Check view vector (vv) argument
+  if (! isvector (vv) || length (vv) < 2 || length (lv) > 3)
     error ("specular: view vector VV must be a 2- or 3-element vector");
   elseif (length (vv) == 2)
     [vv(1), vv(2), vv(3)] = sph2cart (vv(1) * pi / 180, vv(2) * pi / 180, 1.0);
   endif
 
-  ## Normalize view and light vector.
+  ## Check specular exponent (se) argument
+  if (nargin < 6)
+    se = 10;
+  elseif (! (isnumeric (se) && numel (se) == 1 && se > 0))
+    error ("specular: exponent SE must be a positive scalar");
+  endif
+
+  ## Normalize view and light vectors
   if (sum (abs (lv)) > 0)
-    lv  /= norm (lv);
+    lv /= norm (lv);
   endif
   if (sum (abs (vv)) > 0)
-    vv  /= norm (vv);
+    vv /= norm (vv);
   endif
 
-  ## Calculate normal vector lengths and dot-products.
+  ## Calculate normal vector lengths and dot-products
   ns = sqrt (sx.^2 + sy.^2 + sz.^2);
   l_dot_n = (sx * lv(1) + sy * lv(2) + sz * lv(3)) ./ ns;
   v_dot_n = (sx * vv(1) + sy * vv(2) + sz * vv(3)) ./ ns;
 
-  ## Calculate specular reflection using Phong's approximation.
+  ## Calculate specular reflection using Phong's approximation
   retval = 2 * l_dot_n .* v_dot_n - dot (lv, vv);
 
-  ## Set zero if light is on the other side.
+  ## Set reflectance to zero if light is on the other side
   retval(l_dot_n < 0) = 0;
 
-  ## Allow postive values only.
+  ## Allow postive values only
   retval(retval < 0) = 0;
   retval = retval .^ se;
 
--- a/scripts/plot/appearance/text.m	Fri Aug 01 09:06:21 2014 -0400
+++ b/scripts/plot/appearance/text.m	Fri Aug 01 12:10:05 2014 -0400
@@ -129,6 +129,8 @@
 
   if (isempty (hax))
     hax = gca ();
+  else
+    hax = hax(1);
   endif
 
   ## Position argument may alse be in PROP/VAL pair
--- a/scripts/plot/draw/area.m	Fri Aug 01 09:06:21 2014 -0400
+++ b/scripts/plot/draw/area.m	Fri Aug 01 12:10:05 2014 -0400
@@ -49,7 +49,7 @@
 ## @example
 ## @group
 ## t = linspace (0, 2*pi, 100)';
-## y = [sin(t).^2, cos(t).^2)];
+## y = [sin(t).^2, cos(t).^2];
 ## area (t, y);
 ## legend ("sin^2", "cos^2", "location", "NorthEastOutside");
 ## @end group
--- a/scripts/plot/draw/colorbar.m	Fri Aug 01 09:06:21 2014 -0400
+++ b/scripts/plot/draw/colorbar.m	Fri Aug 01 12:10:05 2014 -0400
@@ -207,11 +207,11 @@
       if (mirror)
         set (cax, "xtick", [], "xdir", "normal", "ydir", "normal",
                   "ylim", cext, "ylimmode", "manual",
-                  "yaxislocation", "right", args{:});
+                  "yaxislocation", "right", "layer", "top", args{:});
       else
         set (cax, "xtick", [], "xdir", "normal", "ydir", "normal",
                   "ylim", cext, "ylimmode", "manual",
-                  "yaxislocation", "left", args{:});
+                  "yaxislocation", "left", "layer", "top", args{:});
       endif
     else
       hi = image (cax, "xdata", [cmin, cmax], "ydata", [0,1],
@@ -219,11 +219,11 @@
       if (mirror)
         set (cax, "ytick", [], "xdir", "normal", "ydir", "normal",
                   "xlim", cext, "xlimmode", "manual",
-                  "xaxislocation", "top", args{:});
+                  "xaxislocation", "top", "layer", "top", args{:});
       else
         set (cax, "ytick", [], "xdir", "normal", "ydir", "normal",
                   "xlim", cext, "xlimmode", "manual",
-                  "xaxislocation", "bottom", args{:});
+                  "xaxislocation", "bottom", "layer", "top", args{:});
       endif
     endif
 
@@ -310,24 +310,6 @@
       set (hi, "xdata", [cmin, cmax]);
       set (hiax, "xlim", cext);
     endif
-
-    ## FIXME: Setting xlim or ylim from within a listener callback
-    ##        causes the axis to change size rather than change limits.
-    ##        Workaround it by jiggling the position property which forces
-    ##        a redraw of the axis object.
-    ##
-    ## Debug Example:
-    ## Uncomment the line below.
-    ##   keyboard;
-    ## Now run the the following code.
-    ##   clf; colorbar (); contour (peaks ())
-    ## Once the keyboard command has been hit in the debugger try
-    ##   set (hiax, "ylim", [0 0.5]) 
-    pos = get (hiax, "position");
-    pos(1) += eps;
-    set (hiax, "position", pos);
-    pos(1) -= eps;
-    set (hiax, "position", pos);
   endif
 endfunction
 
--- a/scripts/plot/draw/errorbar.m	Fri Aug 01 09:06:21 2014 -0400
+++ b/scripts/plot/draw/errorbar.m	Fri Aug 01 12:10:05 2014 -0400
@@ -213,7 +213,7 @@
 %! y1 = sin (x);
 %! y2 = cos (x);
 %! errorbar (x, y1, err, '~', x, y2, err, '>');
-%! legend ("Y errbar", "X errbar");
+%! legend ('Y errbar', 'X errbar');
 %! title ('errorbar() with 2 datasets');
 
 
@@ -224,7 +224,7 @@
 %! y1 = sin (x);
 %! y2 = cos (x);
 %! errorbar (x, y1, err, err, '#r', x, y2, err, err, '#~');
-%! legend ("X errbox", "Y errbox");
+%! legend ('X errbox', 'Y errbox');
 %! title ('errorbar() with error boxes');
 
 %!demo
@@ -235,7 +235,7 @@
 %! y2 = cos (x);
 %! errorbar (x, y1, err, err, err, err, '~>', ...
 %!           x, y2, err, err, err, err, '#~>-*');
-%! legend ("X-Y errbars", "X-Y errboxes");
+%! legend ('X-Y errbars', 'X-Y errboxes');
 %! title ('errorbar() with X-Y errorbars and error boxes');
 
 ## Invisible figure used for tests
--- a/scripts/plot/draw/fill.m	Fri Aug 01 09:06:21 2014 -0400
+++ b/scripts/plot/draw/fill.m	Fri Aug 01 12:10:05 2014 -0400
@@ -92,17 +92,28 @@
       set (hax, "nextplot", "add");
 
       for i = 1 : length (iargs)
+        x = varargin{iargs(i)};
+        y = varargin{iargs(i) + 1};
         cdata = varargin{iargs(i) + 2};
+
+        if (! size_equal (x,y))
+          if (iscolumn (y) && rows (y) == rows (x))
+            y = repmat (y, [1, columns(x)]);
+          elseif (iscolumn (x) && rows (x) == rows (y))
+            x = repmat (x, [1, columns(y)]);
+          else
+            error ("fill: X annd Y must have same number of rows");
+          endif
+        endif
         ## For Matlab compatibility, replicate cdata to match size of data
-        if (iscolumn (cdata))
-          sz = size (varargin{iargs(i)});
+        if (iscolumn (cdata) && ! ischar (cdata))
+          sz = size (x);
           if (all (sz > 1))
             cdata = repmat (cdata, [1, sz(2)]);
           endif
         endif
 
-        [htmp, fail] = __patch__ (hax, varargin{iargs(i)+(0:1)}, cdata,
-                                       opts{:});
+        [htmp, fail] = __patch__ (hax, x, y, cdata, opts{:});
         if (fail)
           print_usage ();
         endif
@@ -160,4 +171,30 @@
 %! x2 = sin (t2) + 0.8;
 %! y2 = cos (t2);
 %! h = fill (x1,y1,'r', x2,y2,'g');
+%! title ({'fill() function'; 'cdata specified with string'});
 
+%!demo
+%! clf;
+%! t1 = (1/16:1/8:1) * 2*pi;
+%! t2 = ((1/16:1/8:1) + 1/32) * 2*pi;
+%! x1 = sin (t1) - 0.8;
+%! y1 = cos (t1);
+%! x2 = sin (t2) + 0.8;
+%! y2 = cos (t2);
+%! h = fill (x1,y1,1, x2,y2,2);
+%! title ({'fill() function'; 'cdata = row vector produces FaceColor = "flat"'});
+
+%!demo
+%! clf;
+%! x = [0 0
+%!      1 0.5
+%!      1 0.5
+%!      0 0];
+%! y = [0 0
+%!      0 0
+%!      1 0.5
+%!      1 0.5];
+%! c = [1 2 3 4]';
+%! fill (x, y, c);
+%! title ({'fill() function'; 'cdata = column vector produces FaceColor = "interp"'});
+
--- a/scripts/plot/draw/line.m	Fri Aug 01 09:06:21 2014 -0400
+++ b/scripts/plot/draw/line.m	Fri Aug 01 12:10:05 2014 -0400
@@ -49,6 +49,8 @@
 
   if (isempty (hax))
     hax = gca ();
+  else
+    hax = hax(1);
   endif
 
   htmp = __line__ (hax, varargin{:});
@@ -62,6 +64,16 @@
 
 %!demo
 %! clf
+%! line ([0 1], [0.8 0.8], 'linestyle', '-', 'color', 'b');
+%! line ([0 1], [0.6 0.6], 'linestyle', '--', 'color', 'g');
+%! line ([0 1], [0.4 0.4], 'linestyle', ':', 'color', 'r');
+%! line ([0 1], [0.2 0.2], 'linestyle', '-.', 'color', 'k');
+%! ylim ([0 1]);
+%! title ('line() with various linestyles');
+%! legend ('"-"', '"--"', '":"', '"-."', 'location', 'eastoutside');
+
+%!demo
+%! clf
 %! x = 0:0.3:10;
 %! y1 = cos (x);
 %! y2 = sin (x);
--- a/scripts/plot/draw/mesh.m	Fri Aug 01 09:06:21 2014 -0400
+++ b/scripts/plot/draw/mesh.m	Fri Aug 01 12:10:05 2014 -0400
@@ -70,10 +70,15 @@
   unwind_protect
     hax = newplot (hax);
 
-    htmp = surface (varargin{:});
+    mesh_props = {"facecolor", "w", "edgecolor", "flat"};
+    chararg = find (cellfun ("isclass", varargin, "char"), 1);
+    if (isempty (chararg))
+      htmp = surface (varargin{:}, mesh_props{:});
+    else
+      htmp = surface (varargin{1:chararg-1}, mesh_props{:},
+                      varargin{chararg:end});
+    endif
 
-    set (htmp, "facecolor", "w");
-    set (htmp, "edgecolor", "flat");
     if (! ishold ())
       set (hax, "view", [-37.5, 30],
                 "xgrid", "on", "ygrid", "on", "zgrid", "on");
@@ -121,7 +126,21 @@
 %! ylabel 'Y-axis';
 %! zlabel 'log scale';
 %! title ({'mesh() with color proportional to Z^2', 'Z-axis is log scale'});
-%! if (strcmp (get (gcf, '__graphics_toolkit__'), 'gnuplot'))
-%!   title ({'Gnuplot: mesh color is wrong', 'This is a Gnuplot bug'});
-%! endif
+%! try
+%!   if (strcmp (get (gcf, '__graphics_toolkit__'), 'gnuplot'))
+%!     title ({'Gnuplot: mesh color is wrong', 'This is a Gnuplot bug'});
+%!   endif
+%! catch
+%! end
 
+%!demo
+%! clf;
+%! x = logspace (0,1,11);
+%! z = x'*x;
+%! mesh (x, x, z, 'facecolor', 'none', 'edgecolor', 'c');
+%! xlabel 'X-axis';
+%! ylabel 'Y-axis';
+%! zlabel 'Z-axis';
+%! title ({'mesh() default properties overriden', ...
+%!         'transparent mesh with cyan color'});
+
--- a/scripts/plot/draw/meshc.m	Fri Aug 01 09:06:21 2014 -0400
+++ b/scripts/plot/draw/meshc.m	Fri Aug 01 12:10:05 2014 -0400
@@ -68,13 +68,18 @@
   unwind_protect
     hax = newplot (hax);
 
-    htmp = surface (varargin{:});
+    ## FIXME: gnuplot does not support a filled surface and a
+    ##        non-filled contour.  3D filled patches are also not supported.
+    ##        Thus, the facecolor will be transparent for the gnuplot backend.
+    mesh_props = {"facecolor", "w", "edgecolor", "flat"};
+    chararg = find (cellfun ("isclass", varargin, "char"), 1);
+    if (isempty (chararg))
+      htmp = surface (varargin{:}, mesh_props{:});
+    else
+      htmp = surface (varargin{1:chararg-1}, mesh_props{:},
+                      varargin{chararg:end});
+    endif
 
-    ## FIXME - gnuplot does not support a filled surface and a
-    ## non-filled contour.  3D filled patches are also not supported.
-    ## Thus, the facecolor will be transparent for the gnuplot backend.
-    set (htmp, "facecolor", "w");
-    set (htmp, "edgecolor", "flat");
     if (! ishold ())
       set (hax, "view", [-37.5, 30],
                 "xgrid", "on", "ygrid", "on", "zgrid", "on",
--- a/scripts/plot/draw/meshz.m	Fri Aug 01 09:06:21 2014 -0400
+++ b/scripts/plot/draw/meshz.m	Fri Aug 01 12:10:05 2014 -0400
@@ -30,7 +30,7 @@
 ## over a 2-D rectangular region in the x-y plane.  @var{z} determines the
 ## height above the plane of each vertex.  If only a single @var{z} matrix is
 ## given, then it is plotted over the meshgrid
-## @code{@var{x} = 1:columns (@var{z}), @var{y} = 1:rows (@var{z})}.
+## @code{@var{x} = 0:columns (@var{z}) - 1, @var{y} = 0:rows (@var{z}) - 1}.
 ## Thus, columns of @var{z} correspond to different @var{x} values and rows
 ## of @var{z} correspond to different @var{y} values.
 ##
@@ -64,52 +64,65 @@
   ## Find where property/value pairs start
   charidx = find (cellfun ("isclass", varargin, "char"), 1);
 
-  have_c = false;
   if (isempty (charidx))
-    if (nargin == 2 || nargin == 4) 
-      have_c = true;
-      charidx = nargin;   # bundle C matrix back into varargin 
-    else
-      charidx = nargin + 1;
-    endif
+    charidx = nargin + 1;
   endif
 
-  if (charidx == 2)
+  if (nargin == 1)
+    z = varargin{1};
+    [m, n] = size (z);
+    x = 0:(n-1);
+    y = (0:(m-1)).';
+    c = z;
+  elseif (nargin == 2)
     z = varargin{1};
     [m, n] = size (z);
-    x = 1:n;
-    y = (1:m).';
+    x = 0:(n-1);
+    y = (0:(m-1)).';
+    c = varargin{2};
+  elseif (charidx == 4)
+    x = varargin{1};
+    y = varargin{2};
+    z = varargin{3};
+    c = z;
   else
     x = varargin{1};
     y = varargin{2};
     z = varargin{3};
+    c = varargin{4};
   endif
 
+  ## Create a border of one rectangle (2 points) as the curtain around
+  ## the data and draw it with the mean (max + min / 2) color of the data.
+
   if (isvector (x) && isvector (y))
-    x = [x(1), x(:).', x(end)];
-    y = [y(1); y(:); y(end)];
+    x = [x(1), x(1), x(:).', x(end), x(end)];
+    y = [y(1); y(1); y(:); y(end); y(end)];
   else
-    x = [x(1,1), x(1,:), x(1,end);
-         x(:,1), x, x(:,end);
-         x(end,1), x(end,:), x(end,end)];
-    y = [y(1,1), y(1,:), y(1,end);
-         y(:,1), y, y(:,end);
-         y(end,1), y(end,:), y(end,end)];
+    x = [x(1,1), x(1,1), x(1,:), x(1,end), x(1,end);
+         x(1,1), x(1,1), x(1,:), x(1,end), x(1,end);
+         x(:,1), x(:,1), x, x(:,end), x(:,end);
+         x(end,1), x(end,1), x(end,:), x(end,end), x(end,end);
+         x(end,1), x(end,1), x(end,:), x(end,end), x(end,end) ];
+    y = [y(1,1), y(1,1), y(1,:), y(1,end), y(1,end);
+         y(1,1), y(1,1), y(1,:), y(1,end), y(1,end);
+         y(:,1), y(:,1), y, y(:,end), y(:,end);
+         y(end,1), y(end,1), y(end,:), y(end,end), y(end,end);
+         y(end,1), y(end,1), y(end,:), y(end,end), y(end,end) ];
   endif
 
   zref = min (z(isfinite (z)));
-  z = [zref .* ones(1, columns(z) + 2);
-       zref .* ones(rows(z), 1), z, zref .* ones(rows(z), 1);
-       zref .* ones(1, columns(z) + 2)];
+  z = [zref .* ones(1, columns(z) + 4);
+       zref .* ones(1, 2), z(1,:), zref .* ones(1, 2);
+       zref .* ones(rows(z), 1), z(:,1),z, z(:,end), zref .* ones(rows(z), 1);
+       zref .* ones(1, 2), z(end,:), zref .* ones(1, 2);
+       zref .* ones(1, columns(z) + 4)];
 
-  if (have_c)
-    c = varargin{charidx};
-    cref = min (c(isfinite (c)));
-    c = [cref .* ones(1, columns(c) + 2);
-         cref .* ones(rows(c), 1), c, cref .* ones(rows(c), 1);
-         cref .* ones(1, columns(c) + 2)];
-    varargin(charidx) = c;
-  endif
+  cdat = c(isfinite (c(:)));
+  cref = (min (cdat) + max (cdat)) / 2;
+  c = [cref .* ones(2, columns(c) + 4);
+       cref .* ones(rows(c), 2), c, cref .* ones(rows(c), 2);
+       cref .* ones(2, columns(c) + 4)];
     
   oldfig = [];
   if (! isempty (hax))
@@ -117,7 +130,7 @@
   endif
   unwind_protect
     hax = newplot (hax);
-    htmp = mesh (x, y, z, varargin{charidx:end});
+    htmp = mesh (x, y, z, c, varargin{charidx:end});
   unwind_protect_cleanup
     if (! isempty (oldfig))
       set (0, "currentfigure", oldfig);
--- a/scripts/plot/draw/pareto.m	Fri Aug 01 09:06:21 2014 -0400
+++ b/scripts/plot/draw/pareto.m	Fri Aug 01 12:10:05 2014 -0400
@@ -104,7 +104,9 @@
   axis (ax(1), [1 - 0.6, idx95 + 0.6, 0, maxcdf]);
   axis (ax(2), [1 - 0.6, idx95 + 0.6, 0, 100]);
   set (ax(2), "ytick", [0, 20, 40, 60, 80, 100],
-              "yticklabel", {"0%", "20%", "40%", "60%", "80%", "100%"});
+              "yticklabel", {"0%", "20%", "40%", "60%", "80%", "100%"},
+              "ycolor", get (ax(1), "ycolor"));
+  set (hline, "color", get (ax(1), "colororder")(1,:));
   set (ax(1:2), "xtick", 1:idx95, "xticklabel", x(1:idx95));
 
   if (nargout > 0)
--- a/scripts/plot/draw/patch.m	Fri Aug 01 09:06:21 2014 -0400
+++ b/scripts/plot/draw/patch.m	Fri Aug 01 12:10:05 2014 -0400
@@ -80,6 +80,8 @@
   
   if (isempty (hax))
     hax = gca ();
+  else
+    hax = hax(1);
   endif
   
   [htmp, failed] = __patch__ (hax, varargin{:});
@@ -88,6 +90,15 @@
     print_usage ();
   endif
 
+  ## FIXME: This is a hack to get 'layer' command to work for 2D patches
+  ##        Alternative is much more complicated surgery in graphics.cc.
+  ##        of get_children_limits() for 'z' axis and 'patch' object type.
+  if (! ishold ())
+    if (isempty (get (htmp, "zdata")))
+      set (hax, "zlim", [-1 1]);
+    endif
+  endif
+
   if (nargout > 0)
     h = htmp;
   endif
@@ -141,7 +152,8 @@
 %! y2 = cos (t2);
 %! vert = [x1, y1; x2, y2];
 %! fac = [1:8,NaN(1,8);9:24];
-%! patch ('Faces',fac, 'Vertices',vert, 'FaceVertexCData',[0, 1, 0; 0, 0, 1]);
+%! patch ('Faces',fac, 'Vertices',vert, ...
+%!        'FaceVertexCData',[0, 1, 0; 0, 0, 1], 'FaceColor', 'flat');
 
 %!demo
 %! %% Property change on multiple patches
@@ -223,7 +235,7 @@
 %! colormap (jet (64));
 %! x = [ 0 0; 1 1; 1 0 ];
 %! y = [ 0 0; 0 1; 1 1 ];
-%! p = patch (x, y, 'facecolor', 'b');
+%! p = patch (x, y, 'b');
 %! set (p, 'cdatamapping', 'direct', 'facecolor', 'flat', 'cdata', [1 32]);
 %! title ('Direct mapping of colors: Light-Green UL and Blue LR triangles');
 
--- a/scripts/plot/draw/peaks.m	Fri Aug 01 09:06:21 2014 -0400
+++ b/scripts/plot/draw/peaks.m	Fri Aug 01 12:10:05 2014 -0400
@@ -27,7 +27,7 @@
 ## The function has the form
 ##
 ## @tex
-## $$f(x,y) = 3 (1 - x) ^ 2 e ^ {\left(-x^2 - (y+1)^2\right)} - 10 \left({x \over 5} - x^3 - y^5)\right) - {1 \over 3} e^{\left(-(x+1)^2 - y^2\right)}$$
+## $$f(x,y) = 3 (1 - x) ^ 2 e ^ {\left(-x^2 - (y+1)^2\right)} - 10 \left({x \over 5} - x^3 - y^5\right) - {1 \over 3} e^{\left(-(x+1)^2 - y^2\right)}$$
 ## @end tex
 ## @ifnottex
 ## @verbatim
--- a/scripts/plot/draw/pie.m	Fri Aug 01 09:06:21 2014 -0400
+++ b/scripts/plot/draw/pie.m	Fri Aug 01 12:10:05 2014 -0400
@@ -30,7 +30,7 @@
 ## @code{pct = @var{x}(i) / sum (@var{x})}. 
 ##
 ## The optional input @var{explode} is a vector of the same length as @var{x}
-## that, if non-zero, "explodes" the slice from the pie chart.
+## that, if nonzero, "explodes" the slice from the pie chart.
 ##
 ## The optional input @var{labels} is a cell array of strings of the same
 ## length as @var{x} specifying the label for each slice.
--- a/scripts/plot/draw/pie3.m	Fri Aug 01 09:06:21 2014 -0400
+++ b/scripts/plot/draw/pie3.m	Fri Aug 01 12:10:05 2014 -0400
@@ -31,7 +31,7 @@
 ## @code{pct = @var{x}(i) / sum (@var{x})}. 
 ##
 ## The optional input @var{explode} is a vector of the same length as @var{x}
-## that, if non-zero, "explodes" the slice from the pie chart.
+## that, if nonzero, "explodes" the slice from the pie chart.
 ##
 ## The optional input @var{labels} is a cell array of strings of the same
 ## length as @var{x} specifying the label for each slice.
--- a/scripts/plot/draw/plot3.m	Fri Aug 01 09:06:21 2014 -0400
+++ b/scripts/plot/draw/plot3.m	Fri Aug 01 12:10:05 2014 -0400
@@ -377,12 +377,14 @@
 %!demo
 %! clf;
 %! z = [0:0.05:5];
-%! plot3 (cos (2*pi*z), sin (2*pi*z), z, ';helix;');
+%! plot3 (cos (2*pi*z), sin (2*pi*z), z)
+%! legend ('helix');
 %! title ('plot3() of a helix');
 
 %!demo
 %! clf;
 %! z = [0:0.05:5];
-%! plot3 (z, exp (2i*pi*z), ';complex sinusoid;');
+%! plot3 (z, exp (2i*pi*z));
+%! legend ('complex sinusoid');
 %! title ('plot3() with complex input');
 
--- a/scripts/plot/draw/plotyy.m	Fri Aug 01 09:06:21 2014 -0400
+++ b/scripts/plot/draw/plotyy.m	Fri Aug 01 12:10:05 2014 -0400
@@ -22,7 +22,7 @@
 ## @deftypefnx {Function File} {} plotyy (@dots{}, @var{fun1}, @var{fun2})
 ## @deftypefnx {Function File} {} plotyy (@var{hax}, @dots{})
 ## @deftypefnx {Function File} {[@var{ax}, @var{h1}, @var{h2}] =} plotyy (@dots{})
-## Plot two sets of data with independent y-axes.
+## Plot two sets of data with independent y-axes and a common x-axis.
 ##
 ## The arguments @var{x1} and @var{y1} define the arguments for the first plot
 ## and @var{x1} and @var{y2} for the second.
@@ -40,7 +40,7 @@
 ## the principal axis in which to plot the @var{x1} and @var{y1} data.
 ##
 ## The return value @var{ax} is a vector with the axis handles of the two
-## y axes.  @var{h1} and @var{h2} are handles to the objects generated by the
+## y-axes.  @var{h1} and @var{h2} are handles to the objects generated by the
 ## plot commands.
 ##
 ## @example
@@ -57,113 +57,66 @@
 ## @seealso{plot}
 ## @end deftypefn
 
-function [Ax, H1, H2] = plotyy (varargin)
+function [ax, h1, h2] = plotyy (varargin)
 
-  ## Don't use __plt_get_axis_arg__ here as ax is a two vector for plotyy
-  if (nargin > 1 && length (varargin{1}) == 2 && ishandle (varargin{1}(1))
-      && ishandle (varargin{1}(2))
-      && all (floor (varargin{1}) != varargin{1}))
-    obj1 = get (varargin{1}(1));
-    obj2 = get (varargin{1}(2));
-    if (strcmp (obj1.type, "axes") || strcmp (obj2.type, "axes"))
-      ax = [obj1, obj2];
-      varargin(1) = [];
-      if (isempty (varargin))
-        varargin = {};
-      endif
-    else
-      error ("plotyy: expecting first argument to be axes handle");
-    endif
-    oldh = gca ();
-  else
-    f = get (0, "currentfigure");
-    if (isempty (f))
-      f = figure ();
-    endif
-    ca = get (f, "currentaxes");
-    if (isempty (ca))
-      ax = [];
-    elseif (ishandle (ca) && isprop (ca, "__plotyy_axes__"))
-      ax = get (ca, "__plotyy_axes__");
-    else
-      ax = ca;
-    endif
-    if (length (ax) > 2)
-      for i = 3 : length (ax)
-        delete (ax (i));
-      endfor
-      ax = ax(1:2);
-    elseif (length (ax) == 1)
-      ax(2) = axes ();
-      set (ax(2), "nextplot", get (ax(1), "nextplot"));
-    elseif (isempty (ax))
-      ax(1) = axes ();
-      ax(2) = axes ();
-      ca = ax(2);
-    endif
-    if (nargin < 2)
-      varargin = {};
-    endif
-    oldh = ca;
-  endif
+  [hax, varargin] = __plt_get_axis_arg__ ("plotyy", varargin{:});
 
-  if (nargin < 4)
+  nargin = numel (varargin);
+  if (nargin < 4 || nargin > 6)
     print_usage ();
   endif
 
+  oldfig = [];
+  if (! isempty (hax))
+    oldfig = get (0, "currentfigure");
+  endif
   unwind_protect
-    [ax, h1, h2] = __plotyy__ (ax, varargin{:});
+    hax = newplot (hax);
+
+    ## FIXME: Second conditional test shouldn't be required.
+    ##        'cla reset' needs to delete user properties like __plotyy_axes__.
+    if (isprop (hax, "__plotyy_axes__")
+        && isaxes (get (hax, "__plotyy_axes__")) == [true true])
+      hax = get (hax, "__plotyy_axes__");
+    else
+      hax(2) = axes ("nextplot", get (hax(1), "nextplot"));
+    endif
+
+    [axtmp, h1tmp, h2tmp] = __plotyy__ (hax, varargin{:});
+
+    set (gcf, "currentaxes", hax(1));
+     
   unwind_protect_cleanup
-    ## Only change back to the old axis if we didn't delete it
-    if (isaxes (oldh))
-      axes (oldh);
+    if (! isempty (oldfig))
+      set (0, "currentfigure", oldfig);
     endif
   end_unwind_protect
 
   if (nargout > 0)
-    Ax = ax;
-    H1 = h1;
-    H2 = h2;
+    ax = axtmp;
+    h1 = h1tmp;
+    h2 = h2tmp;
   endif
 
 endfunction
 
-function [ax, h1, h2] = __plotyy__ (ax, x1, y1, x2, y2, varargin)
-  if (nargin > 5)
-    fun1 = varargin{1};
-  else
-    fun1 = @plot;
-  endif
-  if (nargin > 6)
-    fun2 = varargin{2};
-  else
+function [ax, h1, h2] = __plotyy__ (ax, x1, y1, x2, y2, fun1 = @plot, fun2)
+
+  if (nargin < 7)
     fun2 = fun1;
   endif
 
   xlim = [min([x1(:); x2(:)]), max([x1(:); x2(:)])];
 
-  if (isaxes (ax(1)))
-    axes (ax(1));
-  else
-    ax(1) = axes ();
-  endif
-  newplot ();
+  axes (ax(1));
+
   h1 = feval (fun1, x1, y1);
 
-  set (ax(1), "ycolor", getcolor (h1(1)));
-  set (ax(1), "xlim", xlim);
-  set (ax(1), "color", "none");
-
-  cf = gcf ();
-  set (cf, "nextplot", "add");
+  set (ax(1), "color", "none", "ycolor", getcolor (h1(1)), "xlim", xlim);
 
-  if (isaxes (ax(2)))
-    axes (ax(2));
-  else
-    ax(2) = axes ();
-    set (ax(2), "nextplot", get (ax(1), "nextplot"));
-  endif
-  newplot ();
+  set (gcf (), "nextplot", "add");
+
+  axes (ax(2));
 
   colors = get (ax(1), "colororder");
   set (ax(2), "colororder", [colors(2:end,:); colors(1,:)]);
@@ -174,35 +127,38 @@
     set (ax, "activepositionproperty", "position");
   endif
 
-  ## Kluge, until __plt_get_axis_arg__ and newplot are reworked. 
-  set (ax(2), "nextplot", "replacechildren");
+  ## Don't replace axis which has colororder property already modified
+  if (strcmp (get (ax(1), "nextplot"), "replace"))
+    set (ax(2), "nextplot", "replacechildren");
+  endif
   h2 = feval (fun2, ax(2), x2, y2);
-  set (ax(2), "yaxislocation", "right");
-  set (ax(2), "ycolor", getcolor (h2(1)));
+
+  set (ax(2), "yaxislocation", "right", "color", "none",
+              "ycolor", getcolor (h2(1)), "box", "off", "xlim", xlim);
 
   if (strcmp (get(ax(1), "activepositionproperty"), "position"))
     set (ax(2), "position", get (ax(1), "position"));
   else
-    set (ax(2), "outerposition", get (ax(1), "outerposition"));
-    set (ax(2), "looseinset", get (ax(1), "looseinset"));
+    set (ax(2), {"outerposition", "looseinset"},
+                get (ax(1), {"outerposition", "looseinset"}));
   endif
 
-  set (ax(2), "xlim", xlim);
-  set (ax(2), "color", "none");
-  set (ax(2), "box", "off");
+  ## Restore nextplot value by copying value from axis #1
+  set (ax(2), "nextplot", get (ax(1), "nextplot"));
 
   ## Add invisible text objects that when destroyed,
   ## also remove the other axis
   t1 = text (0, 0, "", "parent", ax(1), "tag", "plotyy",
-             "handlevisibility", "off", "visible", "off",
+             "visible", "off", "handlevisibility", "off",
              "xliminclude", "off", "yliminclude", "off");
   t2 = text (0, 0, "", "parent", ax(2), "tag", "plotyy",
-             "handlevisibility", "off", "visible", "off",
+             "visible", "off", "handlevisibility", "off",
              "xliminclude", "off", "yliminclude", "off");
 
   set (t1, "deletefcn", {@deleteplotyy, ax(2), t2});
   set (t2, "deletefcn", {@deleteplotyy, ax(1), t1});
 
+  ## Add cross-listeners so a change in one axes' attributes updates the other.
   addlistener (ax(1), "position", {@update_position, ax(2)});
   addlistener (ax(2), "position", {@update_position, ax(1)});
   addlistener (ax(1), "outerposition", {@update_position, ax(2)});
@@ -235,6 +191,80 @@
   endif
 endfunction
 
+function deleteplotyy (h, ~, ax2, t2)
+  if (isaxes (ax2)
+      && (isempty (gcbf ()) || strcmp (get (gcbf (), "beingdeleted"), "off"))
+      && strcmp (get (ax2, "beingdeleted"), "off"))
+    set (t2, "deletefcn", []);
+    delete (ax2);
+  endif
+endfunction
+
+function update_nextplot (h, ~, ax2)
+  persistent recursion = false;
+  if (! recursion)
+    unwind_protect
+      recursion = true;
+      set (ax2, "nextplot", get (h, "nextplot"));
+    unwind_protect_cleanup
+      recursion = false;
+    end_unwind_protect
+  endif
+endfunction
+
+function update_position (h, ~, ax2)
+  persistent recursion = false;
+
+  ## Don't allow recursion
+  if (! recursion)
+    unwind_protect
+      recursion = true;
+      view = get (h, "view");
+      oldview = get (ax2, "view");
+      plotboxaspectratio = get (h, "plotboxaspectratio");
+      oldplotboxaspectratio = get (ax2, "plotboxaspectratio");
+      plotboxaspectratiomode = get (h, "plotboxaspectratiomode");
+      oldplotboxaspectratiomode = get (ax2, "plotboxaspectratiomode");
+
+      if (strcmp (get (h, "activepositionproperty"), "position"))
+        position = get (h, "position");
+        oldposition = get (ax2, "position");
+        if (! (isequal (position, oldposition) && isequal (view, oldview)))
+          set (ax2, "position", position, "view", view);
+        endif
+      else
+        outerposition = get (h, "outerposition");
+        oldouterposition = get (ax2, "outerposition");
+        if (! (isequal (outerposition, oldouterposition)
+               && isequal (view, oldview)))
+          set (ax2, "outerposition", outerposition, "view", view);
+        endif
+      endif
+
+      if (! (isequal (plotboxaspectratio, oldplotboxaspectratio)
+             && isequal (plotboxaspectratiomode, oldplotboxaspectratiomode)))
+        set (ax2, "plotboxaspectratio", plotboxaspectratio,
+                  "plotboxaspectratiomode", plotboxaspectratiomode);
+      endif
+    unwind_protect_cleanup
+      recursion = false;
+    end_unwind_protect
+  endif
+endfunction
+
+function color = getcolor (ax)
+  obj = get (ax);
+  if (isfield (obj, "color"))
+    color = obj.color;
+  elseif (isfield (obj, "facecolor") && ! ischar (obj.facecolor))
+    color = obj.facecolor;
+  elseif (isfield (obj, "edgecolor") && ! ischar (obj.edgecolor))
+    color = obj.edgecolor;
+  else
+    color = [0, 0, 0];
+  endif
+endfunction
+
 
 %!demo
 %! clf;
@@ -245,12 +275,11 @@
 %! xlabel ('X');
 %! ylabel (ax(1), 'Axis 1');
 %! ylabel (ax(2), 'Axis 2');
-%! axes (ax(1));
 %! text (0.5, 0.5, 'Left Axis', ...
-%!       'color', [0 0 1], 'horizontalalignment', 'center');
-%! axes (ax(2));
+%!       'color', [0 0 1], 'horizontalalignment', 'center', 'parent', ax(1));
 %! text (4.5, 80, 'Right Axis', ...
-%!       'color', [0 0.5 0], 'horizontalalignment', 'center');
+%!       'color', [0 0.5 0], 'horizontalalignment', 'center', 'parent', ax(2));
+%! title ({'plotyy() example'; 'Left axis uses @plot, Right axis uses @semilogy'});
 
 %!demo
 %! clf;
@@ -267,14 +296,6 @@
 %! axis square;
 
 %!demo
-%! clf;
-%! x = linspace (-1, 1, 201);
-%! hax = plotyy (x, sin (pi*x), x, cos (pi*x));
-%! ylabel (hax(1), 'Blue on the Left');
-%! ylabel (hax(2), 'Green on the Right');
-%! xlabel ('xlabel');
-
-%!demo
 %! clf
 %! hold on
 %! t = (0:0.1:9);
@@ -284,81 +305,7 @@
 %! [~, h3, h4] = plotyy (t+1, x, t+1, y);
 %! set ([h3, h4], 'linestyle', '--');
 %! xlabel (hax(1), 'xlabel');
-%! title (hax(2), 'title');
+%! title (hax(2), 'Two plotyy graphs on same figure using "hold on"');
 %! ylabel (hax(1), 'Left axis is Blue');
 %! ylabel (hax(2), 'Right axis is Green');
 
-function deleteplotyy (h, d, ax2, t2)
-  if (isaxes (ax2)
-      && (isempty (gcbf ()) || strcmp (get (gcbf (), "beingdeleted"),"off"))
-      && strcmp (get (ax2, "beingdeleted"), "off"))
-    set (t2, "deletefcn", []);
-    delete (ax2);
-  endif
-endfunction
-
-function update_nextplot (h, d, ax2)
-  persistent recursion = false;
-  prop = "nextplot";
-  if (! recursion)
-    unwind_protect
-      recursion = true;
-      set (ax2, prop, get (h, prop));
-    unwind_protect_cleanup
-      recursion = false;
-    end_unwind_protect
-  endif
-endfunction
-
-function update_position (h, d, ax2)
-  persistent recursion = false;
-
-  ## Don't allow recursion
-  if (! recursion)
-    unwind_protect
-      recursion = true;
-      view = get (h, "view");
-      oldview = get (ax2, "view");
-      plotboxaspectratio = get (h, "plotboxaspectratio");
-      oldplotboxaspectratio = get (ax2, "plotboxaspectratio");
-      plotboxaspectratiomode = get (h, "plotboxaspectratiomode");
-      oldplotboxaspectratiomode = get (ax2, "plotboxaspectratiomode");
-
-      if (strcmp (get(h, "activepositionproperty"), "position"))
-        position = get (h, "position");
-        oldposition = get (ax2, "position");
-        if (! (isequal (position, oldposition) && isequal (view, oldview)))
-          set (ax2, "position", position, "view", view);
-        endif
-      else
-        outerposition = get (h, "outerposition");
-        oldouterposition = get (ax2, "outerposition");
-        if (! (isequal (outerposition, oldouterposition) && isequal (view, oldview)))
-          set (ax2, "outerposition", outerposition, "view", view);
-        endif
-      endif
-
-      if (! (isequal (plotboxaspectratio, oldplotboxaspectratio)
-             && isequal (plotboxaspectratiomode, oldplotboxaspectratiomode)))
-        set (ax2, "plotboxaspectratio", plotboxaspectratio);
-        set (ax2, "plotboxaspectratiomode", plotboxaspectratiomode);
-      endif
-    unwind_protect_cleanup
-      recursion = false;
-    end_unwind_protect
-  endif
-endfunction
-
-function color = getcolor (ax)
-  obj = get (ax);
-  if (isfield (obj, "color"))
-    color = obj.color;
-  elseif (isfield (obj, "facecolor") && ! ischar (obj.facecolor))
-    color = obj.facecolor;
-  elseif (isfield (obj, "edgecolor") && !  ischar (obj.edgecolor))
-    color = obj.edgecolor;
-  else
-    color = [0, 0, 0];
-  endif
-endfunction
-
--- a/scripts/plot/draw/polar.m	Fri Aug 01 09:06:21 2014 -0400
+++ b/scripts/plot/draw/polar.m	Fri Aug 01 12:10:05 2014 -0400
@@ -36,6 +36,14 @@
 ##
 ## The optional return value @var{h} is a graphics handle to the created plot.
 ##
+## Implementation Note: The polar axis is drawn using line and text objects
+## encapsulated in an hggroup.  The hggroup properties are linked to the
+## original axes object such that altering an appearance property, for example
+## @code{fontname}, will update the polar axis.  Two new properties are
+## added to the original axes--@code{rtick}, @code{ttick}--which replace
+## @code{xtick}, @code{ytick}.  The first is a list of tick locations in the
+## radial (rho) direction; The second is a list of tick locations in the
+## angular (theta) direction specified in degrees, i.e., in the range 0--359.
 ## @seealso{rose, compass, plot}
 ## @end deftypefn
 
@@ -87,9 +95,51 @@
       print_usage ();
     endif
 
-    set (hax, "xlim", [-maxr, maxr], "ylim", [-maxr, maxr],
-              "xaxislocation", "zero", "yaxislocation", "zero",
-              "plotboxaspectratio", [1, 1, 1]);
+    if (! ishold (hax))
+      hg = hggroup (hax, "tag", "polar_grid", "handlevisibility", "off");
+
+      set (hax, "visible", "off", "plotboxaspectratio", [1, 1, 1],
+                "zlim", [-1 1]);
+
+      if (! isprop (hax, "rtick"))
+        addproperty ("rtick", hax, "data");
+      endif
+
+      set (hax, "rtick", __calc_rtick__ (hax, maxr));
+
+      ## add t(heta)tick
+      if (! isprop (hax, "ttick"))
+        addproperty ("ttick", hax, "data");
+      endif
+
+      ## theta(angular) ticks in degrees
+      set (hax, "ttick", 0:30:330);
+
+      __update_polar_grid__ (hax, [], hg);
+
+      set (hg, "deletefcn", {@resetaxis, hax});
+
+      addlistener (hax, "rtick", {@__update_polar_grid__, hg});
+      addlistener (hax, "ttick", {@__update_polar_grid__, hg});
+      addlistener (hax, "color", {@__update_patch__, hg});
+      addlistener (hax, "fontangle", {@__update_text__, hg, "fontangle"});
+      addlistener (hax, "fontname", {@__update_text__, hg, "fontname"});
+      addlistener (hax, "fontsize", {@__update_text__, hg, "fontsize"});
+      addlistener (hax, "fontunits", {@__update_text__, hg, "fontunits"});
+      addlistener (hax, "fontweight", {@__update_text__, hg, "fontweight"});
+      addlistener (hax, "interpreter", {@__update_text__, hg, "interpreter"});
+      addlistener (hax, "layer", {@__update_layer__, hg});
+      addlistener (hax, "gridlinestyle",{@__update_lines__,hg,"gridlinestyle"});
+      addlistener (hax, "linewidth", {@__update_lines__, hg, "linewidth"});
+    else
+      hg = findall (hax, "tag", "polar_grid");
+      if (! isempty (hg))
+        oldrtick = max (get (hax, "rtick"));
+        if (maxr > oldrtick)
+          set (hax, "rtick", __calc_rtick__ (hax, maxr));
+        endif
+      endif
+    endif
 
   unwind_protect_cleanup
     if (! isempty (oldfig))
@@ -103,6 +153,19 @@
 
 endfunction
 
+function rtick = __calc_rtick__ (hax, maxr)
+  ## FIXME: workaround: calculate r(ho)tick from xtick
+  savexlim = get (hax, "xlim");
+  saveylim = get (hax, "ylim");
+  set (hax, "xlim", [-maxr maxr], "ylim", [-maxr maxr]);
+  xtick = get (hax, "xtick");
+  rtick = xtick(find (xtick > 0, 1):find (xtick >= maxr, 1));
+  if (isempty (rtick))
+    rtick = [0.5 1];
+  endif
+  set (hax, "xlim", savexlim, "ylim", saveylim);
+endfunction
+
 function retval = __plr1__ (h, theta, fmt)
 
   theta = theta(:);
@@ -193,6 +256,133 @@
 
 endfunction
 
+## Callback functions for listeners
+
+function __update_text__ (hax, ~, hg, prop)
+
+  kids = get (hg, "children");
+  idx = strcmp (get (kids, "type"), "text");
+  set (kids(idx).', prop, get (hax, prop));
+
+endfunction
+
+function __update_lines__ (hax,  ~, hg, prop)
+
+  kids = get (hg, "children");
+  idx = strcmp (get (kids, "type"), "line");
+  lprop = prop;
+  if (strcmp (prop, "gridlinestyle"))
+    lprop = "linestyle";
+  endif
+  set (kids(idx).', lprop, get (hax, prop));
+
+endfunction
+
+function __update_patch__ (hax, ~, hg)
+
+  kids = get (hg, "children");
+  idx = strcmp (get (kids, "type"), "patch");
+  set (kids(idx).', "facecolor", get (hax, "color"));
+
+endfunction
+
+function __update_layer__ (hax,  ~, hg)
+
+  set (hg, "handlevisibility", "on");
+  kids = get (hax, "children");
+  if (strcmp (get (hax, "layer"), "bottom"))
+    set (hax, "children", [kids(kids != hg); hg]); 
+  else
+    set (hax, "children", [hg; kids(kids != hg)]); 
+  endif
+  set (hg, "handlevisibility", "off");
+
+endfunction
+
+function __update_polar_grid__ (hax, ~, hg)
+
+  ## Delete existing polar grid
+  delete (get (hg, "children"));
+
+  rtick = unique (get (hax, "rtick")(:)');
+  rtick = rtick(rtick > 0);
+  if (isempty (rtick))
+    rtick = [0.5 1];
+  endif
+
+  ttick = unique (get (hax, "ttick")(:)');
+  ttick = ttick(ttick >= 0);
+  if (isempty (ttick))
+    ttick = 0:30:330;
+  endif
+
+  lprops = {"linestyle", get(hax, "gridlinestyle"), ...
+            "linewidth", get(hax, "linewidth")};
+  ## "fontunits" should be first because it affects "fontsize" property.
+  tprops(1:2:12) = {"fontunits", "fontangle", "fontname", "fontsize", ...
+                    "fontweight", "interpreter"};
+  tprops(2:2:12) = get (hax, tprops(1:2:12));
+
+  ## The number of points used for a circle
+  circle_points = 50;
+  t = linspace (0, 2*pi, circle_points)';
+  x = kron (cos (t), rtick);
+  y = kron (sin (t), rtick);
+
+  ## Draw colored disk under axes at Z-depth = -1
+  patch (x(:,end), y(:,end), -ones (circle_points, 1),
+         get (hax, "color"), "parent", hg);
+
+  ## Plot dotted circles
+  line (x(:,1:end-1), y(:,1:end-1), lprops{:}, "parent", hg);
+
+  ## Outer circle is drawn solid
+  line (x(:,end), y(:,end), lprops{:}, "linestyle", "-", "parent", hg);
+
+  ## Add radial labels
+  [x, y] = pol2cart (0.42 * pi, rtick);
+  text (x, y, num2cell (rtick), "verticalalignment", "bottom", tprops{:},
+        "parent", hg);
+
+  ## add radial lines
+  s = rtick(end) * sin (ttick * pi / 180);
+  c = rtick(end) * cos (ttick * pi / 180);
+  x = [zeros(1, numel (ttick)); c];
+  y = [zeros(1, numel (ttick)); s];
+  line (x, y, "linestyle", ":", lprops{:}, "parent", hg);
+
+  ## add angular labels
+  tticklabel = num2cell (ttick);
+  ## FIXME: This tm factor does not work as fontsize increases
+  tm = 1.08;
+  text (tm * c, tm * s, tticklabel, "horizontalalignment", "center",
+        tprops{:}, "parent", hg);
+
+  lim = 1.1 * rtick(end);
+  set (hax, "xlim", [-lim, lim], "ylim", [-lim, lim]);
+
+  ## Put polar grid behind or ahead of plot
+  __update_layer__ (hax, [], hg);
+
+endfunction
+
+function resetaxis (~, ~, hax)
+  if (isaxes (hax))
+    dellistener (hax, "rtick");
+    dellistener (hax, "ttick");
+    dellistener (hax, "color");
+    dellistener (hax, "fontangle");
+    dellistener (hax, "fontname");
+    dellistener (hax, "fontsize");
+    dellistener (hax, "fontunits");
+    dellistener (hax, "fontweight");
+    dellistener (hax, "interpreter");
+    dellistener (hax, "layer");
+    dellistener (hax, "gridlinestyle");
+    dellistener (hax, "linewidth");
+  endif
+endfunction
+
 
 %!demo
 %! clf;
@@ -210,8 +400,25 @@
 
 %!demo
 %! clf;
+%! theta = linspace (0,2*pi,1000);
+%! rho = sin (2*theta).*cos (2*theta);
+%! polar (theta, rho, '--r');
+%! set (gca, 'rtick', 0.1:0.1:0.6, 'ttick', 0:20:340);
+%! title ('polar() plot with finer grid');
+
+%!demo
+%! clf;
+%! theta = linspace (0,2*pi,1000);
+%! rho = sin (2*theta).*cos (2*theta);
+%! polar (theta, rho, '--b');
+%! set (gca, 'fontsize', 12, 'linewidth', 2, 'color', [0.8 0.8 0.8]);
+%! title ('polar() plot with modified axis appearance');
+
+%!demo
+%! clf;
 %! theta = linspace (0,8*pi,1000);
 %! rho = sin (5/4*theta);
 %! polar (theta, rho);
+%! set (gca, 'rtick', 0.2:0.2:1);
 %! title ('polar() plot');
 
--- a/scripts/plot/draw/private/__ezplot__.m	Fri Aug 01 09:06:21 2014 -0400
+++ b/scripts/plot/draw/private/__ezplot__.m	Fri Aug 01 12:10:05 2014 -0400
@@ -448,8 +448,12 @@
       axis (hax, domain);
     elseif (isplot || ispolar)
       h = feval (pltfunc, hax, X, Z);
-      if (isplot && ! parametric)
-        axis (hax, domain);
+      if (isplot)
+        if (! parametric)
+          axis (hax, domain);
+        else
+          axis ("equal");
+        endif
       endif
     elseif (isplot3)
       if (animate)
--- a/scripts/plot/draw/private/__patch__.m	Fri Aug 01 09:06:21 2014 -0400
+++ b/scripts/plot/draw/private/__patch__.m	Fri Aug 01 12:10:05 2014 -0400
@@ -35,8 +35,7 @@
   is_numeric_arg = cellfun (@isnumeric, varargin);
 
   if (isempty (varargin))
-    args = {"xdata", [0; 1; 0], "ydata", [1; 1; 0], "facecolor", [0, 0, 0]};
-    args = setvertexdata (args);
+    args = varargin;
   elseif (isstruct (varargin{1}))
     if (isfield (varargin{1}, "vertices") && isfield (varargin{1}, "faces"))
       args{1} = "faces";
@@ -50,7 +49,6 @@
         args{6} = [];
       endif
       args = [args; varargin(2:end)];
-      args = setdata (args);
     else
       failed = true;
     endif
@@ -58,7 +56,6 @@
     if (nargin < 3 || ! is_numeric_arg(2))
       failed = true;
     else
-
       if (nargin > 4 && all (is_numeric_arg(1:4)))
         x = varargin{1};
         y = varargin{2};
@@ -70,7 +67,7 @@
         y = varargin{2};
         iarg = 4;
         if (rem (nargin - iarg, 2) == 1)
-          c = varargin {iarg};
+          c = varargin{iarg};
           z = varargin{3};
           iarg = 5;
         else
@@ -83,7 +80,7 @@
         z = [];
         iarg = 3;
         if (rem (nargin - iarg, 2) == 1)
-          c = varargin {iarg};
+          c = varargin{iarg};
           iarg++; 
         else
           c = [];
@@ -127,7 +124,7 @@
             args{9} = "cdata";
             args{10} = c;
           else
-            error ("patch: color value not valid");
+            error ("patch: color data C must be numeric");
           endif
         elseif (isvector (c) && numel (c) == 3)
           args{7} = "facecolor";
@@ -150,7 +147,7 @@
             args{9} = "cdata";
             args{10} = c;
           else
-            error ("patch: color value not valid");
+            error ("patch: Invalid TrueColor data C");
           endif
         else
           ## Color Vectors
@@ -159,212 +156,35 @@
             args{8} = "interp";
             args{9} = "cdata";
             args{10} = [];
-          elseif (isequal (size (c), size (x)) && isequal (size (c), size (y)))
+          elseif (size_equal (c, x) && size_equal (c, y))
             args{7} = "facecolor";
             args{8} = "interp";
             args{9} = "cdata";
             args{10} = c;
           else
-            error ("patch: size of x, y, and c must be equal");
+            error ("patch: size of X, Y, and C must be equal");
           endif
         endif
       elseif (ischar (c) && rem (nargin - iarg, 2) == 0)
-        ## Assume that any additional argument over an even number is
-        ## color string.
+        ## Assume any additional argument over an even number is a color string.
         args{7} = "facecolor";
         args{8} =  tolower (c);
         args{9} = "cdata";
         args{10} = [];
       else
         args{7} = "facecolor";
-        args{8} = [0, 1, 0];
+        args{8} = [0, 0, 0];
         args{9} = "cdata";
         args{10} = [];
       endif
 
       args = [args, varargin(iarg:end)];
-      args = setvertexdata (args);
     endif
   else
     args = varargin;
-    if (any (strcmpi (args, "faces") | strcmpi (args, "vertices")))
-      args = setdata (args);
-    else
-      args = setvertexdata (args);
-    endif
   endif
 
   if (!failed)
-    h = __go_patch__ (p, args {:});
-
-    ## Setup listener functions
-    addlistener (h, "xdata", @update_data);
-    addlistener (h, "ydata", @update_data);
-    addlistener (h, "zdata", @update_data);
-    addlistener (h, "cdata", @update_data);
-
-    addlistener (h, "faces", @update_fvc);
-    addlistener (h, "vertices", @update_fvc);
-    addlistener (h, "facevertexcdata", @update_fvc);
+    h = __go_patch__ (p, args{:});
   endif
 endfunction
-
-function args = delfields (args, flds)
-  idx = cellfun ("isclass", args, "char");
-  idx(idx) = ismember (args(idx), flds);
-  if (rows (idx) == 1)
-    idx |= [false, idx(1:end-1)];
-  else
-    idx |= [false; idx(1:end-1)];
-  endif
-  args(idx) = [];
-endfunction
-
-function args = setdata (args)
-  args = delfields (args, {"xdata", "ydata", "zdata", "cdata"});
-  ## Remove the readonly fields as well
-  args = delfields (args, {"type", "uicontextmenu"});
-  nargs = length (args);
-  idx = find (strcmpi (args, "faces"), 1, "last") + 1;
-  if (idx > nargs)
-    faces = [];
-  else
-    faces = args {idx};
-  endif
-  idx = find (strcmpi (args, "vertices"), 1, "last") + 1;
-  if (idx > nargs)
-    vert = [];
-  else
-    vert = args {idx};
-  endif
-  idx = find (strcmpi (args, "facevertexcdata"), 1, "last") + 1;
-  if (isempty (idx) || idx > nargs)
-    fvc = [];
-  else
-    fvc = args {idx};
-  endif
-  idx = find (strcmpi (args, "facecolor"), 1, "last") + 1;
-  if (isempty (idx) || idx > nargs)
-    if (!isempty (fvc))
-      fc = "flat";
-    else
-      fc = [0, 1, 0];
-    endif
-    args = {"facecolor", fc, args{:}};
-  endif
-
-  nc = rows (faces);
-  idx = faces .';
-  t1 = isnan (idx);
-  for i = find (any (t1))
-    first_idx_in_column = find (t1(:,i), 1);
-    idx(first_idx_in_column:end,i) = idx(first_idx_in_column-1,i);
-  endfor
-  x = reshape (vert(:,1)(idx), size (idx));
-  y = reshape (vert(:,2)(idx), size (idx));
-  if (columns (vert) > 2)
-    z = reshape (vert(:,3)(idx), size (idx));
-  else
-    z = [];
-  endif
-
-  if (rows (fvc) == nc || rows (fvc) == 1)
-    c = reshape (fvc, [1, size(fvc)]);
-  else
-    if (columns (fvc) == 3)
-      c = cat (3, reshape (fvc(idx, 1), size (idx)),
-               reshape (fvc(idx, 2), size (idx)),
-               reshape (fvc(idx, 3), size (idx)));
-    elseif (isempty (fvc))
-      c = [];
-    else ## if (columnns (fvc) == 1)
-      c = permute (fvc(faces), [2, 1]);
-    endif
-  endif
-  args = {"xdata", x, "ydata", y, "zdata", z, "cdata", c, args{:}};
-endfunction
-
-function args = setvertexdata (args)
-  args = delfields (args, {"vertices", "faces", "facevertexcdata"});
-  ## Remove the readonly fields as well
-  args = delfields (args, {"type", "uicontextmenu"});
-  nargs = length (args);
-  idx = find (strcmpi (args, "xdata"), 1, "last") + 1;
-  if (idx > nargs)
-    x = [];
-  else
-    x = args {idx};
-  endif
-  idx = find (strcmpi (args, "ydata"), 1, "last") + 1;
-  if (idx > nargs)
-    y = [];
-  else
-    y = args {idx};
-  endif
-  idx = find (strcmpi (args, "zdata"), 1, "last") + 1;
-  if (isempty (idx) || idx > nargs)
-    z = [];
-  else
-    z = args {idx};
-  endif
-  idx = find (strcmpi (args, "cdata"), 1, "last") + 1;
-  if (isempty (idx) || idx > nargs)
-    c = [];
-  else
-    c = args {idx};
-  endif
-  idx = find (strcmpi (args, "facecolor"), 1, "last") + 1;
-  if (isempty (idx) || idx > nargs)
-    if (!isempty (c))
-      fc = "flat";
-    else
-      fc = [0, 1, 0];
-    endif
-    args = {"facecolor", fc, args{:}};
-  endif
-
-  [nr, nc] = size (x);
-  if (nr == 1 && nc > 1)
-    nr = nc;
-    nc = 1;
-  endif
-  if (!isempty (z))
-    vert = [x(:), y(:), z(:)];
-  else
-    vert = [x(:), y(:)];
-  endif
-  faces = reshape (1:numel (x), nr, nc);
-  faces = faces';
-
-  if (ndims (c) == 3)
-    fvc = reshape (c, rows (c) * columns (c), size (c, 3));
-  else
-    fvc = c(:);
-  endif
-
-  args = {"faces", faces, "vertices", vert, "facevertexcdata", fvc, args{:}};
-endfunction
-
-function update_data (h, d)
-  update_handle (h, false);
-endfunction
-
-function update_fvc (h, d)
-  update_handle (h, true);
-endfunction
-
-function update_handle (h, isfv)
-  persistent recursive = false;
-
-  if (! recursive)
-    recursive = true;
-    f = get (h);
-    if (isfv)
-      set (h, setdata ([fieldnames(f), struct2cell(f)].'(:)){:});
-    else
-      set (h, setvertexdata ([fieldnames(f), struct2cell(f)].'(:)){:});
-    endif
-    recursive = false;
-  endif
-endfunction
-
--- a/scripts/plot/draw/private/__scatter__.m	Fri Aug 01 09:06:21 2014 -0400
+++ b/scripts/plot/draw/private/__scatter__.m	Fri Aug 01 12:10:05 2014 -0400
@@ -84,6 +84,21 @@
     c = [];
   endif
 
+  ## Validate inputs
+  if (nd == 2 && ! size_equal (x, y)) 
+    error ([fcn ": X and Y must have the same size"]);
+  elseif (nd == 3 && ! size_equal (x, y, z)) 
+    error ([fcn ": X, Y, and Z must have the same size"]);
+  endif
+
+  if (! isscalar (s) && ! size_equal (x, s))
+    error ([fcn ": size of S must match X, Y, and Z"]);
+  endif
+
+  if (rows (c) > 1 && rows (c) != rows (x))
+    error ([fcn ": number of colors in C must match number of points in X"]);
+  endif
+
   newargs = {};
   filled = false;
   have_marker = false;
--- a/scripts/plot/draw/private/__stem__.m	Fri Aug 01 09:06:21 2014 -0400
+++ b/scripts/plot/draw/private/__stem__.m	Fri Aug 01 12:10:05 2014 -0400
@@ -48,6 +48,8 @@
 
     h = [];
     nx = rows (x);
+    h_baseline = [];
+    
     for i = 1 : columns (x)
       if (have_z)
         xt = x(:)';
@@ -90,19 +92,19 @@
         __line__ (hax, xt, yt, zt, "color", lc, "linestyle", ls, "parent", hg);
         __line__ (hax, x, y, z, "color", mc, "linestyle", "none",
                        "marker", ms, "markerfacecolor", fc, "parent", hg);
-        h_baseline = [];
       else
         __line__ (hax, xt, yt, "color", lc, "linestyle", ls, "parent", hg);
         __line__ (hax, x(:,i), y(:, i), "color", mc, "linestyle", "none",
                        "marker", ms, "markerfacecolor", fc, "parent", hg);
+        
         x_axis_range = get (hax, "xlim");
-        h_baseline = line (hax, x_axis_range, [0, 0], "color", [0, 0, 0]);
-        set (h_baseline, "handlevisibility", "off", "xliminclude", "off");
-        addlistener (hax, "xlim", @update_xlim);
-        addproperty ("basevalue", h_baseline, "data", 0);
-        addlistener (h_baseline, "basevalue", {@update_baseline, 0});
-        addlistener (h_baseline, "ydata", {@update_baseline, 1});
-        addlistener (h_baseline, "visible", {@update_baseline, 2});
+        if (isempty (h_baseline))
+          h_baseline = line (hax, x_axis_range, [0, 0], "color", [0, 0, 0]);
+          set (h_baseline, "handlevisibility", "off", "xliminclude", "off");
+          addproperty ("basevalue", h_baseline, "data", 0);
+        else
+          set (h_baseline, "xdata", x_axis_range);
+        endif
       endif
 
       ## Setup the hggroup and listeners.
@@ -110,11 +112,6 @@
       addproperty ("baseline", hg, "data", h_baseline);
       addproperty ("basevalue", hg, "data", 0);
 
-      if (! have_z)
-        addlistener (hg, "showbaseline", @show_baseline);
-        addlistener (hg, "basevalue", @move_baseline);
-      endif
-
       addproperty ("color", hg, "linecolor", lc);
       addproperty ("linestyle", hg, "linelinestyle", ls);
       addproperty ("linewidth", hg, "linelinewidth", 0.5);
@@ -146,14 +143,28 @@
       ## Matlab property, although Octave does not implement it.
       addproperty ("hittestarea", hg, "radio", "on|{off}", "off");
 
-      if (! isempty (args))
-        set (hg, args{:});
-      endif
-      if (i == 1 && ! isempty (h_baseline))
-        set (h_baseline, "parent", get (hg, "parent"));
-      endif
     endfor
 
+    ## baseline listeners
+    if (! isempty (h_baseline))
+      addlistener (hax, "xlim", @update_xlim);
+      for hg = h'
+        addlistener (hg, "showbaseline", @show_baseline);
+        addlistener (hg, "visible", {@show_baseline, h});
+        addlistener (hg, "basevalue", @move_baseline);
+      endfor
+      
+      addlistener (h_baseline, "basevalue", {@update_baseline, 0});
+      addlistener (h_baseline, "ydata", {@update_baseline, 1});
+      addlistener (h_baseline, "visible", {@update_baseline, 2});
+      set (h_baseline, "parent", get (hg(1), "parent"));
+    endif
+
+    ## property/value pairs
+    if (! isempty (args))
+        set (h, args{:});
+    endif
+
     if (! strcmp (hold_state, "add") && have_z)
       set (hax, "view", [-37.5 30],
                 "xgrid", "on", "ygrid", "on", "zgrid", "on");
@@ -365,8 +376,16 @@
   endfor
 endfunction
 
-function show_baseline (h, ~)
-  set (get (h, "baseline"), "visible", get (h, "showbaseline"));
+function show_baseline (h, ~, hg = [])
+  if (isempty (hg))
+    set (get (h, "baseline"), "visible", get (h, "showbaseline"));
+  else
+    if (all (strcmp (get (hg, "visible"), "off")))
+      set (get (h, "baseline"), "visible", "off");
+    else
+      set (get (h, "baseline"), "visible", "on");
+    endif
+  endif
 endfunction
 
 function move_baseline (h, ~)
@@ -374,6 +393,7 @@
   bl = get (h, "baseline");
 
   set (bl, "ydata", [b0, b0]);
+  set (bl, "basevalue", b0);
 
   kids = get (h, "children");
   yt = get (h, "ydata")(:)';
--- a/scripts/plot/draw/rose.m	Fri Aug 01 09:06:21 2014 -0400
+++ b/scripts/plot/draw/rose.m	Fri Aug 01 12:10:05 2014 -0400
@@ -116,6 +116,11 @@
 
 %!demo
 %! clf;
+%! rose (2*randn (1e5, 1), 8);
+%! title ('rose() angular histogram plot with 8 bins');
+
+%!demo
+%! clf;
 %! rose ([2*randn(1e5, 1), pi + 2*randn(1e5, 1)]);
-%! title ('rose() angular histogram plot');
+%! title ('rose() angular histogram plot with 2 data series');
 
--- a/scripts/plot/draw/shrinkfaces.m	Fri Aug 01 09:06:21 2014 -0400
+++ b/scripts/plot/draw/shrinkfaces.m	Fri Aug 01 12:10:05 2014 -0400
@@ -23,24 +23,29 @@
 ## @deftypefnx {Function File} {@var{nfv} =} shrinkfaces (@var{f}, @var{v}, @var{sf})
 ## @deftypefnx {Function File} {[@var{nf}, @var{nv}] =} shrinkfaces (@dots{})
 ##
-## Reduce the faces area for a given patch, structure or explicit faces
-## and points matrices by a scale factor @var{sf}.  The structure
-## @var{fv} must contain the fields @qcode{"faces"} and @qcode{"vertices"}. 
-## If the factor @var{sf} is omitted then a default of 0.3 is used.
+## Reduce the size of faces in a patch by the shrink factor @var{sf}.
+##
+## The patch object can be specified by a graphics handle (@var{p}), a patch
+## structure (@var{fv}) with the fields @qcode{"faces"} and @qcode{"vertices"},
+## or as two separate matrices (@var{f}, @var{v}) of faces and vertices.
 ##
-## Given a patch handle as the first input argument and no output
-## parameters, perform the shrinking of the patch faces in place and
-## redraw the patch.
+## The shrink factor @var{sf} is a positive number specifying the percentage
+## of the original area the new face will occupy.  If no factor is given the
+## default is 0.3 (a reduction to 30% of the original size).  A factor greater
+## than 1.0 will result in the expansion of faces.
+##
+## Given a patch handle as the first input argument and no output parameters,
+## perform the shrinking of the patch faces in place and redraw the patch.
 ##
 ## If called with one output argument, return a structure with fields
 ## @qcode{"faces"}, @qcode{"vertices"}, and @qcode{"facevertexcdata"}
-## containing the data after shrinking which can then directly be used as an
-## input argument for the @code{patch} function.
+## containing the data after shrinking.  This structure can be used directly
+## as an input argument to the @code{patch} function.
 ##
-## Performing the shrinking on faces which are not convex can lead to
-## undesired results.
+## @strong{Caution:}: Performing the shrink operation on faces which are not
+## convex can lead to undesirable results.
 ##
-## For example,
+## Example: a triangulated 3/4 circle and the corresponding shrunken version.
 ##
 ## @example
 ## @group
@@ -56,9 +61,6 @@
 ## @end group
 ## @end example
 ##
-## @noindent
-## draws a triangulated 3/4 circle and the corresponding shrunken
-## version.
 ## @seealso{patch}
 ## @end deftypefn
 
@@ -71,8 +73,8 @@
   endif
   
   sf = 0.3;
+  colors = [];
   p = varargin{1};
-  colors = [];
 
   if (ishandle (p) && nargin < 3)
     faces = get (p, "Faces");
@@ -104,8 +106,8 @@
     error ("shrinkfaces: scale factor must be a positive scalar");
   endif
 
-  n = columns (vertices);
-  if (n < 2 || n > 3)
+  nc = columns (vertices);
+  if (nc < 2 || nc > 3)
     error ("shrinkfaces: only 2-D and 3-D patches are supported");
   endif
 
@@ -120,14 +122,12 @@
   elseif (rows (colors) == rows (vertices))
     c = colors(faces'(:), :);
   else
-    ## Discard inconsistent color data.
-    c = [];
+    c = [];  # Discard inconsistent color data.
   endif
   sv = rows (v);
-  ## we have to deal with a probably very large number of vertices, so
-  ## use sparse we use as midpoint (1/m, ..., 1/m) in generalized
-  ## barycentric coordinates.
-  midpoints = full (kron ( speye (sv / m), ones (m, m) / m) * sparse (v));
+  ## We have to deal with a possibly very large number of vertices, so use
+  ## sparse as midpoint (1/m, ..., 1/m) in generalized barycentric coordinates.
+  midpoints = full (kron (speye (sv / m), ones (m, m) / m) * sparse (v));
   v = sqrt (sf) * (v - midpoints) + midpoints;
   f = reshape (1:sv, m, sv / m)';
   
@@ -216,3 +216,13 @@
 %!assert (size (nfv.vertices), [3 3])
 %!assert (norm (nfv2.vertices - vertices), 0, 2*eps)
 
+%% Test input validation
+%!error shrinkfaces ()
+%!error shrinkfaces (1,2,3,4)
+%!error [a,b,c] = shrinkfaces (1)
+%!error <scale factor must be a positive scalar> shrinkfaces (nfv, ones (2))
+%!error <scale factor must be a positive scalar> shrinkfaces (nfv, 0)
+%!error <only 2-D and 3-D patches are supported> shrinkfaces (faces, ones (3,1))
+%!error <only 2-D and 3-D patches are supported> shrinkfaces (faces, ones (3,4))
+%!error <faces must consist of at least 3 vertices> shrinkfaces (faces(1:2), vertices)
+
--- a/scripts/plot/draw/stem.m	Fri Aug 01 09:06:21 2014 -0400
+++ b/scripts/plot/draw/stem.m	Fri Aug 01 12:10:05 2014 -0400
@@ -187,7 +187,7 @@
 %! y = [sin(x), cos(x)];
 %! h = stem (x, y);
 %! set (h(2), 'color', 'g');
-%! set (h(1), 'basevalue', -1);
+%! set (h(1), 'basevalue', -0.75);
 %! title ('stem plots modified through hggroup handle');
 
 %!demo
@@ -213,3 +213,18 @@
 %!error <inconsistent sizes for X and Y> stem (ones (2,2), ones (3,3))
 %!error <No value specified for property "FOO"> stem (1, "FOO")
 
+%!test
+%! ## stemseries share the same baseline and basevalue
+%! hf = figure ("visible", "off");
+%! unwind_protect
+%!   h = stem ([1 2; 1.5 2.5], [1 1;2 2]);
+%!   assert (get (h(1), "baseline"), get (h(2), "baseline"))
+%!   bv = 0.3;
+%!   set (h(1), "basevalue", bv)
+%!   assert (get (get (h(1), "baseline"), "basevalue"), bv)
+%!   assert (get (h(1), "basevalue"), bv)
+%!   assert (get (h(2), "basevalue"), bv)
+%! unwind_protect_cleanup
+%!   close (hf);
+%! end_unwind_protect
+
--- a/scripts/plot/draw/stemleaf.m	Fri Aug 01 09:06:21 2014 -0400
+++ b/scripts/plot/draw/stemleaf.m	Fri Aug 01 12:10:05 2014 -0400
@@ -185,7 +185,7 @@
   hl = xs(hlidx);               # lower hinge
   hu = xs(huidx);               # upper hinge
   h_spread = hu - hl;           # h_spread: difference between hinges
-  step = 1.5*h_spread;          # step: 1.5 * h_spread
+  step = fix(1.5*h_spread);     # step: 1.5 * h_spread
   i_fence_l = hl - step;        # inner fences: outside hinges + step
   o_fence_l = hl - 2*step;      # outer fences: outside hinges + 2*step
   i_fence_h = hu + step;
@@ -349,13 +349,13 @@
 %! " "                                  ,
 %! "         Fenced Letter Display"     ,
 %! " "                                  ,
-%! "     #138|___________________"      ,     
-%! "     M 69|          52      |"      ,     
+%! "     #138|___________________"      ,
+%! "     M 69|          52      |"      ,
 %! "     H 35|   30          116|   86" ,
 %! "     1   |  -28          146|"      ,
 %! "               _______"             ,
 %! "         ______|  129|_______"      ,
-%! "        f|  -99          245|"      ,     
+%! "        f|  -99          245|"      ,
 %! "         |    0            0|  out" ,
 %! "        F| -228          374|"      ,
 %! "         |    0            0|  far" ,
@@ -389,13 +389,13 @@
 %! " "                                   ,
 %! "         Fenced Letter Display"      ,
 %! " "                                   ,
-%! "     # 14|___________________"       ,     
-%! "     M  7|          22      |"       ,     
+%! "     # 14|___________________"       ,
+%! "     M  7|          22      |"       ,
 %! "     H  4|   12           42|   30"  ,
 %! "     1   |    5           52|"       ,
 %! "               _______"              ,
 %! "         ______|   45|_______"       ,
-%! "        f|  -33           87|"       ,     
+%! "        f|  -33           87|"       ,
 %! "         |    0            0|  out"  ,
 %! "        F|  -78          132|"       ,
 %! "         |    0            0|  far"  ,
@@ -418,13 +418,13 @@
 %! " "                                   ,
 %! "         Fenced Letter Display"      ,
 %! " "                                   ,
-%! "     # 14|___________________"       ,     
-%! "     M  7|         -28      |"       ,     
+%! "     # 14|___________________"       ,
+%! "     M  7|         -28      |"       ,
 %! "     H  4|  -42          -12|   30"  ,
 %! "     1   |  -52           -5|"       ,
 %! "               _______"              ,
 %! "         ______|   45|_______"       ,
-%! "        f|  -87           33|"       ,     
+%! "        f|  -87           33|"       ,
 %! "         |    0            0|  out"  ,
 %! "        F| -132           78|"       ,
 %! "         |    0            0|  far"  ,
@@ -446,15 +446,15 @@
 %! " "                                  ,
 %! "         Fenced Letter Display"     ,
 %! " "                                  ,
-%! "     # 15|___________________"      ,     
-%! "     M  8|          22      |"      ,     
+%! "     # 15|___________________"      ,
+%! "     M  8|          22      |"      ,
 %! "     H  4|   11           42|   31" ,
 %! "     1   |    0           52|"      ,
 %! "               _______"             ,
 %! "         ______|   46|_______"      ,
-%! "        f|  -35           88|"      ,     
+%! "        f|  -35           88|"      ,
 %! "         |    0            0|  out" ,
-%! "        F|  -82          135|"      ,
+%! "        F|  -81          134|"      ,
 %! "         |    0            0|  far" ,
 %! " "                                  ,
 %! "   0 | 20"                          ,
@@ -475,15 +475,15 @@
 %! " "                                  ,
 %! "         Fenced Letter Display"     ,
 %! " "                                  ,
-%! "     # 15|___________________"      ,     
-%! "     M  8|         -22      |"      ,     
+%! "     # 15|___________________"      ,
+%! "     M  8|         -22      |"      ,
 %! "     H  4|  -42          -11|   31" ,
 %! "     1   |  -52            0|"      ,
 %! "               _______"             ,
 %! "         ______|   46|_______"      ,
-%! "        f|  -88           35|"      ,     
+%! "        f|  -88           35|"      ,
 %! "         |    0            0|  out" ,
-%! "        F| -135           82|"      ,
+%! "        F| -134           81|"      ,
 %! "         |    0            0|  far" ,
 %! " "                                  ,
 %! "  -5 | 2"                           ,
@@ -503,15 +503,15 @@
 %! " "                                  ,
 %! "         Fenced Letter Display"     ,
 %! " "                                  ,
-%! "     #  5|___________________"      ,     
-%! "     M  3|           0      |"      ,     
+%! "     #  5|___________________"      ,
+%! "     M  3|           0      |"      ,
 %! "     H  2|   -7            0|   7"  ,
 %! "     1   |   -9            0|"      ,
 %! "               _______"             ,
 %! "         ______|   10|_______"      ,
-%! "        f|  -17           10|"      ,     
+%! "        f|  -17           10|"      ,
 %! "         |    0            0|  out" ,
-%! "        F|  -28           21|"      ,
+%! "        F|  -27           20|"      ,
 %! "         |    0            0|  far" ,
 %! " "                                  ,
 %! "  -0 | 9700"                        ,
@@ -527,15 +527,15 @@
 %! " "                                    ,
 %! "         Fenced Letter Display"       ,
 %! " "                                    ,
-%! "     #  4|___________________"        ,     
-%! "     M  2|          -7      |"        ,     
+%! "     #  4|___________________"        ,
+%! "     M  2|          -7      |"        ,
 %! "     H  1|   -9            0|   9"    ,
 %! "     1   |   -9            0|"        ,
 %! "               _______"               ,
 %! "         ______|   13|_______"        ,
-%! "        f|  -22           13|"        ,     
+%! "        f|  -22           13|"        ,
 %! "         |    0            0|  out"   ,
-%! "        F|  -36           27|"        ,
+%! "        F|  -35           26|"        ,
 %! "         |    0            0|  far"   ,
 %! " "                                    ,
 %! "  -0 | 970"                           ,
@@ -552,7 +552,7 @@
 %! " "                                      ,
 %! "         Fenced Letter Display"         ,
 %! " "                                      ,
-%! "     # 17|___________________"          ,          
+%! "     # 17|___________________"          ,
 %! "     M  9|         895      |"          ,
 %! "     H  5|  795         1499|   704"    ,
 %! "     1   |  150         1995|"          ,
--- a/scripts/plot/draw/surface.m	Fri Aug 01 09:06:21 2014 -0400
+++ b/scripts/plot/draw/surface.m	Fri Aug 01 12:10:05 2014 -0400
@@ -73,109 +73,110 @@
 
   h = 0;
   bad_usage = false;
-  firststring = nargin;
-  for i = 1 : (nargin - 1)
-    if (ischar (varargin{i}))
-      firststring = i;
-      break;
-    endif
-  endfor
+  firststring = find (cellfun ("isclass", varargin, "char"), 1);
+  if (isempty (firststring))
+    firststring = nargin;
+  endif
 
-  if (firststring > 5)
-    bad_usage = true;
-    return;
-  elseif (firststring == 5)
-    x = varargin{1};
-    y = varargin{2};
-    z = varargin{3};
-    c = varargin{4};
+  switch (firststring)
+    case 5
+      x = varargin{1};
+      y = varargin{2};
+      z = varargin{3};
+      c = varargin{4};
 
-    if (iscomplex (x) || iscomplex (y) || iscomplex (z) || iscomplex (c))
-      error ("mesh: X, Y, Z, C arguments must be real");
-    endif
+      if (iscomplex (x) || iscomplex (y) || iscomplex (z) || iscomplex (c))
+        error ("mesh: X, Y, Z, C arguments must be real");
+      endif
+
+      [z_nr, z_nc] = size (z);
+      [c_nr, c_nc, c_np] = size (c);
+      if (! (z_nr == c_nr && z_nc == c_nc && (c_np == 1 || c_np == 3)))
+        error ("surface: Z and C must have the same size");
+      endif
 
-    [z_nr, z_nc] = size (z);
-    [c_nr, c_nc, c_np] = size (c);
-    if (! (z_nr == c_nr && z_nc == c_nc && (c_np == 1 || c_np == 3)))
-      error ("surface: Z and C must have the same size");
-    endif
-
-    if (isvector (x) && isvector (y) && ismatrix (z))
-      if (rows (z) == length (y) && columns (z) == length (x))
-        x = x(:)';
-        y = y(:);
+      if (isvector (x) && isvector (y) && ismatrix (z))
+        if (rows (z) == length (y) && columns (z) == length (x))
+          x = x(:)';
+          y = y(:);
+        else
+          error ("surface: rows (Z) must be the same as length (Y) and columns (Z) must be the same as length (X)");
+        endif
+      elseif (ismatrix (x) && ismatrix (y) && ismatrix (z))
+        if (! size_equal (x, y, z))
+          error ("surface: X, Y, and Z must have the same dimensions");
+        endif
       else
-        error ("surface: rows (Z) must be the same as length (Y) and columns (Z) must be the same as length (X)");
+        error ("surface: X and Y must be vectors and Z must be a matrix");
       endif
-    elseif (ismatrix (x) && ismatrix (y) && ismatrix (z))
-      if (! size_equal (x, y, z))
-        error ("surface: X, Y, and Z must have the same dimensions");
+
+    case 4
+      x = varargin{1};
+      y = varargin{2};
+      z = varargin{3};
+      c = z;
+
+      if (iscomplex (x) || iscomplex (y) || iscomplex (z))
+        error ("mesh: X, Y, Z arguments must be real");
       endif
-    else
-      error ("surface: X and Y must be vectors and Z must be a matrix");
-    endif
-  elseif (firststring == 4)
-    x = varargin{1};
-    y = varargin{2};
-    z = varargin{3};
-    c = z;
-
-    if (iscomplex (x) || iscomplex (y) || iscomplex (z))
-      error ("mesh: X, Y, Z arguments must be real");
-    endif
 
-    if (isvector (x) && isvector (y) && ismatrix (z))
-      if (rows (z) == length (y) && columns (z) == length (x))
-        x = x(:)';
-        y = y(:);
+      if (isvector (x) && isvector (y) && ismatrix (z))
+        if (rows (z) == length (y) && columns (z) == length (x))
+          x = x(:)';
+          y = y(:);
+        else
+          error ("surface: rows (Z) must be the same as length (Y) and columns (Z) must be the same as length (X)");
+        endif
+      elseif (ismatrix (x) && ismatrix (y) && ismatrix (z))
+        if (! size_equal (x, y, z))
+          error ("surface: X, Y, and Z must have the same dimensions");
+        endif
       else
-        error ("surface: rows (Z) must be the same as length (Y) and columns (Z) must be the same as length (X)");
-      endif
-    elseif (ismatrix (x) && ismatrix (y) && ismatrix (z))
-      if (! size_equal (x, y, z))
-        error ("surface: X, Y, and Z must have the same dimensions");
+        error ("surface: X and Y must be vectors and Z must be a matrix");
       endif
-    else
-      error ("surface: X and Y must be vectors and Z must be a matrix");
-    endif
-  elseif (firststring == 3)
-    z = varargin{1};
-    c = varargin{2};
 
-    if (iscomplex (z) || iscomplex (c))
-      error ("mesh: X, C arguments must be real");
-    endif
+    case 3
+      z = varargin{1};
+      c = varargin{2};
+
+      if (iscomplex (z) || iscomplex (c))
+        error ("mesh: X, C arguments must be real");
+      endif
 
-    if (ismatrix (z) && !isvector (z) && !isscalar (z))
-      [nr, nc] = size (z);
-      x = 1:nc;
-      y = (1:nr)';
-    else
-      error ("surface: Z argument must be a matrix");
-    endif
-  elseif (firststring == 2)
-    z = varargin{1};
-    c = z;
+      if (ismatrix (z) && !isvector (z) && !isscalar (z))
+        [nr, nc] = size (z);
+        x = 1:nc;
+        y = (1:nr)';
+      else
+        error ("surface: Z argument must be a matrix");
+      endif
 
-    if (iscomplex (z))
-      error ("mesh: Z argument must be real");
-    endif
+    case 2
+      z = varargin{1};
+      c = z;
+
+      if (iscomplex (z))
+        error ("mesh: Z argument must be real");
+      endif
 
-    if (ismatrix (z) && !isvector (z) && !isscalar (z))
-      [nr, nc] = size (z);
-      x = 1:nc;
-      y = (1:nr)';
-    else
-      error ("surface: Z argument must be a matrix");
-    endif
-  elseif (firststring == 1)
-    x = 1:3;
-    y = x';
-    c = z = eye (3);
-  else
-    bad_usage = true;
-    return;
-  endif
+      if (ismatrix (z) && !isvector (z) && !isscalar (z))
+        [nr, nc] = size (z);
+        x = 1:nc;
+        y = (1:nr)';
+      else
+        error ("surface: Z argument must be a matrix");
+      endif
+
+    case 1
+      x = 1:3;
+      y = x';
+      c = z = eye (3);
+
+    otherwise
+      bad_usage = true;
+      return;
+  
+  endswitch
 
   if (firststring < nargin)
     other_args = varargin(firststring:end);
--- a/scripts/plot/draw/surfc.m	Fri Aug 01 09:06:21 2014 -0400
+++ b/scripts/plot/draw/surfc.m	Fri Aug 01 12:10:05 2014 -0400
@@ -71,9 +71,15 @@
   unwind_protect
     hax = newplot (hax);
     
-    htmp = surface (varargin{:});
+    surfc_props = {"facecolor", "flat"};
+    chararg = find (cellfun ("isclass", varargin, "char"), 1);
+    if (isempty (chararg))
+      htmp = surface (varargin{:}, surfc_props{:});
+    else
+      htmp = surface (varargin{1:chararg-1}, surfc_props{:},
+                      varargin{chararg:end});
+    endif
 
-    set (htmp, "facecolor", "flat");
     if (! ishold ())
       set (hax, "view", [-37.5, 30],
                 "xgrid", "on", "ygrid", "on", "zgrid", "on",
--- a/scripts/plot/draw/surfl.m	Fri Aug 01 09:06:21 2014 -0400
+++ b/scripts/plot/draw/surfl.m	Fri Aug 01 12:10:05 2014 -0400
@@ -164,7 +164,7 @@
     endif
 
     vn = get (htmp, "vertexnormals");
-    dar = get (hax, "plotboxaspectratio");
+    dar = get (hax, "dataaspectratio");
     vn(:,:,1) *= dar(1);
     vn(:,:,2) *= dar(2);
     vn(:,:,3) *= dar(3);
@@ -206,8 +206,7 @@
 %! clf;
 %! [X,Y,Z] = sombrero ();
 %! colormap (copper (64));
-%! [az, el] = view ();
-%! surfl (X,Y,Z, [az+225,el], [0.2 0.6 0.4 25]);
+%! surfl (X,Y,Z, [62.50,30], [0.2 0.6 0.4 25]);
 %! shading interp;
 %! title ('surfl() with lighting vector and material properties');
 
--- a/scripts/plot/draw/surfnorm.m	Fri Aug 01 09:06:21 2014 -0400
+++ b/scripts/plot/draw/surfnorm.m	Fri Aug 01 12:10:05 2014 -0400
@@ -19,49 +19,56 @@
 ## -*- texinfo -*-
 ## @deftypefn  {Function File} {} surfnorm (@var{x}, @var{y}, @var{z})
 ## @deftypefnx {Function File} {} surfnorm (@var{z})
+## @deftypefnx {Function File} {} surfnorm (@dots{}, @var{prop}, @var{val}, @dots{})
+## @deftypefnx {Function File} {} surfnorm (@var{hax}, @dots{})
 ## @deftypefnx {Function File} {[@var{nx}, @var{ny}, @var{nz}] =} surfnorm (@dots{})
-## @deftypefnx {Function File} {} surfnorm (@var{h}, @dots{})
-## Find the vectors normal to a meshgridded surface.  The meshed gridded
-## surface is defined by @var{x}, @var{y}, and @var{z}.  If @var{x} and
-## @var{y} are not defined, then it is assumed that they are given by
+## Find the vectors normal to a meshgridded surface.
 ##
-## @example
-## @group
-## [@var{x}, @var{y}] = meshgrid (1:rows (@var{z}),
-##                    1:columns (@var{z}));
-## @end group
-## @end example
+## If @var{x} and @var{y} are vectors, then a typical vertex is
+## (@var{x}(j), @var{y}(i), @var{z}(i,j)).  Thus, columns of @var{z} correspond
+## to different @var{x} values and rows of @var{z} correspond to different
+## @var{y} values.  If only a single input @var{z} is given then @var{x} is
+## taken to be @code{1:rows (@var{z})} and @var{y} is
+## @code{1:columns (@var{z})}.
 ##
 ## If no return arguments are requested, a surface plot with the normal
-## vectors to the surface is plotted.  Otherwise the components of the normal
-## vectors at the mesh gridded points are returned in @var{nx}, @var{ny},
-## and @var{nz}.
+## vectors to the surface is plotted.
 ##
-## The normal vectors are calculated by taking the cross product of the
-## diagonals of each of the quadrilaterals in the meshgrid to find the
-## normal vectors of the centers of these quadrilaterals.  The four nearest
-## normal vectors to the meshgrid points are then averaged to obtain the
-## normal to the surface at the meshgridded points.
+## Any property/value input pairs are assigned to the surface object.
+## 
+## If the first argument @var{hax} is an axes handle, then plot into this axis,
+## rather than the current axes returned by @code{gca}.
+##
+## If output arguments are requested then the components of the normal
+## vectors are returne in @var{nx}, @var{ny}, and @var{nz} and no plot is
+## made.
 ##
 ## An example of the use of @code{surfnorm} is
 ##
 ## @example
 ## surfnorm (peaks (25));
 ## @end example
-## @seealso{surf, quiver3}
+##
+## Algorithm: The normal vectors are calculated by taking the cross product
+## of the diagonals of each of the quadrilaterals in the meshgrid to find the
+## normal vectors of the centers of these quadrilaterals.  The four nearest
+## normal vectors to the meshgrid points are then averaged to obtain the
+## normal to the surface at the meshgridded points.
+##
+## @seealso{isonormals, quiver3, surf, meshgrid}
 ## @end deftypefn
 
 function [Nx, Ny, Nz] = surfnorm (varargin)
 
   [hax, varargin, nargin] = __plt_get_axis_arg__ ("surfnorm", varargin{:});
 
-  if (nargin != 1 && nargin != 3)
+  if (nargin == 0 || nargin == 2)
     print_usage ();
   endif
 
   if (nargin == 1)
     z = varargin{1};
-    [x, y] = meshgrid (1:rows (z), 1:columns (z));
+    [x, y] = meshgrid (1:columns (z), 1:rows (z));
     ioff = 2;
   else
     x = varargin{1};
@@ -70,22 +77,24 @@
     ioff = 4;
   endif
 
-  if (!ismatrix (z) || isvector (z) || isscalar (z))
-    error ("surfnorm: Z argument must be a matrix");
+  if (iscomplex (z) || iscomplex (x) || iscomplex (y))
+    error ("surfnorm: X, Y, and Z must be 2-D real matrices");
   endif
   if (! size_equal (x, y, z))
     error ("surfnorm: X, Y, and Z must have the same dimensions");
   endif
 
-  ## Make life easier, and avoid having to do the extrapolation later, do
-  ## a simpler linear extrapolation here. This is approximative, and works
-  ## badly for closed surfaces like spheres.
-  xx = [2 .* x(:,1) - x(:,2), x, 2 .* x(:,end) - x(:,end-1)];
-  xx = [2 .* xx(1,:) - xx(2,:); xx; 2 .* xx(end,:) - xx(end-1,:)];
-  yy = [2 .* y(:,1) - y(:,2), y, 2 .* y(:,end) - y(:,end-1)];
-  yy = [2 .* yy(1,:) - yy(2,:); yy; 2 .* yy(end,:) - yy(end-1,:)];
-  zz = [2 .* z(:,1) - z(:,2), z, 2 .* z(:,end) - z(:,end-1)];
-  zz = [2 .* zz(1,:) - zz(2,:); zz; 2 .* zz(end,:) - zz(end-1,:)];
+  ## Do a linear extrapolation for mesh points on the boundary so that the mesh
+  ## is increased by 1 on each side.  This allows each original meshgrid point
+  ## to be surrounded by four quadrilaterals and the same calculation can be
+  ## used for interior and boundary points.  The extrapolation works badly for
+  ## closed surfaces like spheres.
+  xx = [2 * x(:,1) - x(:,2), x, 2 * x(:,end) - x(:,end-1)];
+  xx = [2 * xx(1,:) - xx(2,:); xx; 2 * xx(end,:) - xx(end-1,:)];
+  yy = [2 * y(:,1) - y(:,2), y, 2 * y(:,end) - y(:,end-1)];
+  yy = [2 * yy(1,:) - yy(2,:); yy; 2 * yy(end,:) - yy(end-1,:)];
+  zz = [2 * z(:,1) - z(:,2), z, 2 * z(:,end) - z(:,end-1)];
+  zz = [2 * zz(1,:) - zz(2,:); zz; 2 * zz(end,:) - zz(end-1,:)];
 
   u.x = xx(1:end-1,1:end-1) - xx(2:end,2:end);
   u.y = yy(1:end-1,1:end-1) - yy(2:end,2:end);
@@ -101,17 +110,19 @@
 
   ## Create normal vectors as mesh vectices from normals at mesh centers
   nx = (w.x(1:end-1,1:end-1) + w.x(1:end-1,2:end) +
-        w.x(2:end,1:end-1) + w.x(2:end,2:end)) ./ 4;
+        w.x(2:end,1:end-1) + w.x(2:end,2:end)) / 4;
   ny = (w.y(1:end-1,1:end-1) + w.y(1:end-1,2:end) +
-        w.y(2:end,1:end-1) + w.y(2:end,2:end)) ./ 4;
+        w.y(2:end,1:end-1) + w.y(2:end,2:end)) / 4;
   nz = (w.z(1:end-1,1:end-1) + w.z(1:end-1,2:end) +
-        w.z(2:end,1:end-1) + w.z(2:end,2:end)) ./ 4;
+        w.z(2:end,1:end-1) + w.z(2:end,2:end)) / 4;
 
+  ## FIXME: According to Matlab documentation the vertex normals
+  ##        returned are not normalized.
   ## Normalize the normal vectors
   len = sqrt (nx.^2 + ny.^2 + nz.^2);
-  nx = nx ./ len;
-  ny = ny ./ len;
-  nz = nz ./ len;
+  nx ./= len;
+  ny ./= len;
+  nz ./= len;
 
   if (nargout == 0)
     oldfig = [];
@@ -125,10 +136,26 @@
       old_hold_state = get (hax, "nextplot");
       unwind_protect
         set (hax, "nextplot", "add");
-        plot3 ([x(:)'; x(:).' + nx(:).' ; NaN(size(x(:).'))](:),
-               [y(:)'; y(:).' + ny(:).' ; NaN(size(y(:).'))](:),
-               [z(:)'; z(:).' + nz(:).' ; NaN(size(z(:).'))](:),
-               varargin{ioff:end});
+
+        ## FIXME: Scale unit normals by data aspect ratio in order for
+        ##        normals to appear correct.
+        ##daratio = daspect (hax);
+        ##daspect ("manual");
+        ##len = norm (daratio);
+        ## This assumes an even meshgrid which isn't a great assumption
+        ##dx = x(1,2) - x(1,1);  
+        ##dy = y(2,1) - y(1,1);  
+        ##nx *= daratio(1);
+        ##ny *= daratio(2);
+        ##nz *= daratio(3);
+        ##len = sqrt (nx.^2 + ny.^2 + nz.^2);
+        ##nx ./= len;
+        ##ny ./= len;
+        ##nz ./= len;
+        plot3 ([x(:).'; x(:).' + nx(:).' ; NaN(size(x(:).'))](:),
+               [y(:).'; y(:).' + ny(:).' ; NaN(size(y(:).'))](:),
+               [z(:).'; z(:).' + nz(:).' ; NaN(size(z(:).'))](:),
+               "r");
       unwind_protect_cleanup
         set (hax, "nextplot", old_hold_state);
       end_unwind_protect
@@ -150,17 +177,25 @@
 %!demo
 %! clf;
 %! colormap ('default');
-%! [x, y, z] = peaks (10);
-%! surfnorm (x, y, z);
+%! surfnorm (peaks (32));
+%! shading interp;
+%! title ({'surfnorm() shows surface and normals at each vertex', ...
+%!         'peaks() function with 32 faces'});
 
 %!demo
 %! clf;
 %! colormap ('default');
-%! surfnorm (peaks (10));
+%! [x, y, z] = sombrero (10);
+%! surfnorm (x, y, z);
 
-%!demo
-%! clf;
-%! colormap ('default');
-%! surfnorm (peaks (32));
-%! shading interp;
+%% Test input validation
+%!error surfnorm ()
+%!error surfnorm (1,2)
+%!error <X, Y, and Z must be 2-D real matrices> surfnorm (i)
+%!error <X, Y, and Z must be 2-D real matrices> surfnorm (i, 1, 1)
+%!error <X, Y, and Z must be 2-D real matrices> surfnorm (1, i, 1)
+%!error <X, Y, and Z must be 2-D real matrices> surfnorm (1, 1, i)
+%!error <X, Y, and Z must have the same dimensions> surfnorm ([1 2], 1, 1)
+%!error <X, Y, and Z must have the same dimensions> surfnorm (1, [1 2], 1)
+%!error <X, Y, and Z must have the same dimensions> surfnorm (1, 1, [1 2])
 
--- a/scripts/plot/util/colstyle.m	Fri Aug 01 09:06:21 2014 -0400
+++ b/scripts/plot/util/colstyle.m	Fri Aug 01 12:10:05 2014 -0400
@@ -36,10 +36,7 @@
   try
     opt = __pltopt__ ("colstyle", style);
     l = opt.linestyle;
-    c = opt.color;
-    m = opt.marker;
-    msg = [];
-    switch (c)
+    switch (opt.color)
       case [0 0 0]
         c = "k";
       case [1 0 0]
@@ -56,7 +53,11 @@
         c = "c";
       case [0 1 1]
         c = "w";
+      otherwise
+        c = opt.color;
     endswitch
+    m = opt.marker;
+    msg = [];
   catch
     l = c = m = [];
     msg = lasterr ();
@@ -86,5 +87,5 @@
 %% Test input validation
 %!error colstyle ()
 %!error colstyle (1, 2)
-%!error colstyle (1.5)
+%!error <STYLE must be a string> colstyle (1.5)
 
--- a/scripts/plot/util/copyobj.m	Fri Aug 01 09:06:21 2014 -0400
+++ b/scripts/plot/util/copyobj.m	Fri Aug 01 12:10:05 2014 -0400
@@ -46,7 +46,7 @@
 
   ## current figure and axes
   cf = gcf ();
-  ca = gca ();
+  ca = get (cf, "currentaxes");
   
   ## compatibility of input handles
   kididx = find (strcmp (alltypes, get (horig).type));
@@ -65,53 +65,67 @@
 
   ## reset current figure (and eventually axes) to original
   set (0, "currentfigure", cf);
-  if (get (hnew, "parent") == cf)
+  if (get (hnew, "parent") == cf && ! isempty (ca))
     set (cf, "currentaxes", ca)
   endif
   
 endfunction
 
 
+## Absurd number of drawnow() function calls in demos is due to problem
+## with FLTK backend which is not respecting the set ('position') call.
+
 %!demo
-%! hdl = figure (1234);
-%! clf;
+%! hobj = figure ('name', 'Original', 'numbertitle', 'off');
 %! hold on;
 %! x = 1:10;
 %! y = x.^2;
 %! dy = 2 * (.2 * x);
 %! y2 = (x - 3).^2;
-%! hg = errorbar (x, y, dy,'#~');
+%! hg = errorbar (x, y, dy);
 %! set (hg, 'marker', '^', 'markerfacecolor', rand (1,3));
 %! plot (x, y2, 'ok-');
 %! legend ('errorbar', 'line');
-%! hnew = copyobj (hdl);
+%! drawnow ();
+%! pos = get (hobj, 'position');
+%! scrn = get (0, 'screensize');
+%! set (hobj, 'position', [scrn(3)/2-pos(3)-10, scrn(4)/2-pos(4)/2, pos(3:4)]);
+%! drawnow ();
+%! hnew = copyobj (hobj);
+%! drawnow ();
+%! set (hnew, 'name', 'Copyobj');
+%! drawnow ();
+%! set (hnew, 'position', [scrn(3)/2, scrn(4)/2-pos(4)/2, pos(3:4)]);
+%! drawnow ();
 
-%!#demo
-%! ## FIXME: This demo fails for an obscure reason.
-%! ## It appears that there is something wrong with Octave code for patches.
-%! ## This demo must remain commented out until patch() has been reworked.
-%! unwind_protect
-%!   hdl = figure (1234);
-%!   clf;
-%!   subplot (2,2,1);
-%!   hold on;
-%!   contourf (rand (10, 10));
-%!   colorbar ();
-%!   subplot (2,2,2);
-%!   quiver (rand (10, 10), rand (10, 10));
-%!   subplot (2,2,3);
-%!   colormap (jet (64));
-%!   hold on;
-%!   sombrero ();
-%!   colorbar ('peer', gca, 'NorthOutside');
-%!   subplot (2,2,4);
-%!   imagesc (rand (30, 30));
-%!   text (15, 15, 'Rotated text', ...
-%!         'HorizontAlalignment', 'Center', 'Rotation', 30);
-%!   hnew = copyobj (hdl);
-%! unwind_protect_cleanup
-%!   close all;
-%! end_unwind_protect
+%!demo
+%! hobj = figure ('name', 'Original', 'numbertitle', 'off');
+%! subplot (2,2,1);
+%! hold on;
+%! contourf (rand (10, 10));
+%! colorbar ();
+%! subplot (2,2,2);
+%! quiver (rand (10, 10), rand (10, 10));
+%! subplot (2,2,3);
+%! colormap (jet (64));
+%! hold on;
+%! sombrero ();
+%! colorbar ('peer', gca, 'NorthOutside');
+%! subplot (2,2,4);
+%! imagesc (rand (30, 30));
+%! text (15, 15, 'Rotated text', ...
+%!       'HorizontAlalignment', 'Center', 'Rotation', 30);
+%! drawnow ();
+%! pos = get (hobj, 'position');
+%! scrn = get (0, 'screensize');
+%! set (hobj, 'position', [scrn(3)/2-pos(3)-10, scrn(4)/2-pos(4)/2, pos(3:4)]);
+%! drawnow ();
+%! hnew = copyobj (hobj);
+%! drawnow ();
+%! set (hnew, 'name', 'Copyobj');
+%! drawnow ();
+%! set (hnew, 'position', [scrn(3)/2, scrn(4)/2-pos(4)/2, pos(3:4)]);
+%! drawnow ();
 
 %!testif HAVE_MAGICK
 %! toolkit = graphics_toolkit ();
@@ -154,3 +168,17 @@
 %!   graphics_toolkit (toolkit);
 %! end_unwind_protect
 
+%!test 
+%! unwind_protect
+%!   tag = "foo";
+%!   hf = figure ("visible", "off");
+%!   hax = axes ("tag", tag);
+%!   hpa = patch ();
+%!   set (hpa, "facecolor", [.5 .5 .5], "tag", tag)
+%!   hax2 = copyobj (hax, hf);
+%!   assert (get (hax2, "tag"), tag)
+%!   hpa2 = get (hax2, "children");
+%!   assert (get (hpa2, "facecolor"), [.5 .5 .5])
+%! unwind_protect_cleanup
+%!   close (hf)
+%! end_unwind_protect
--- a/scripts/plot/util/findall.m	Fri Aug 01 09:06:21 2014 -0400
+++ b/scripts/plot/util/findall.m	Fri Aug 01 12:10:05 2014 -0400
@@ -56,7 +56,7 @@
 %! unwind_protect
 %!   h = findall (hf);
 %!   all_handles(1) = {"figure"};
-%!   all_handles(2:12,1) = {"uimenu"};
+%!   all_handles(2:18,1) = {"uimenu"};
 %!   assert (get (h, "type"), all_handles);
 %! unwind_protect_cleanup
 %!   close (hf);
--- a/scripts/plot/util/hdl2struct.m	Fri Aug 01 09:06:21 2014 -0400
+++ b/scripts/plot/util/hdl2struct.m	Fri Aug 01 12:10:05 2014 -0400
@@ -23,7 +23,7 @@
 ##
 ## The fields of the structure @var{s} are @qcode{"type"}, @qcode{"handle"},
 ## @qcode{"properties"}, @qcode{"children"}, and @qcode{"special"}.
-## @seealso{struct2hdl, findobj}
+## @seealso{struct2hdl, hgsave, findobj}
 ## @end deftypefn
 
 ## Author: pdiribarne <pdiribarne@new-host.home>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/plot/util/hgload.m	Fri Aug 01 12:10:05 2014 -0400
@@ -0,0 +1,69 @@
+## Copyright (C) 2014 Massimiliano Fasi
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {@var{h} =} hgload (@var{filename})
+## Load the graphics object in @var{filename} into the graphics handle @var{h}.
+##
+## If @var{filename} has no extension, Octave will try to find the file with
+## and without the standard extension of @file{.ofig}.
+## @seealso{hgsave, struct2hdl}
+## @end deftypefn
+
+## Author: Massimiliano Fasi
+
+function h = hgload (filename)
+
+  ## Check input arguments
+  if (nargin != 1)
+    print_usage ();
+  endif
+
+  ## Check file existence
+  [~, ~, ext] = fileparts (filename);
+  if (isempty (ext))
+    if (! isempty (file_in_loadpath ([filename ".ofig"])))
+      filename = [filename ".ofig"];
+    elseif (isempty (file_in_loadpath (filename)))
+      error ("hgload: unable to locate file %s", filename);
+    endif
+  else
+    if (isempty (file_in_loadpath (filename)))
+      error ("hgload: unable to locate file %s", filename);
+    endif
+  endif
+    
+  ## Load the handle
+  try
+    stmp = load (filename, "s_oct40");
+  catch
+    error ("hgload: could not load hgsave-formatted object in file %s", filename);
+  end_try_catch
+
+  h = struct2hdl (stmp.s_oct40);
+  
+endfunction
+
+
+## Functional test for hgload/hgsave pair is in hgsave.m
+
+%% Test input validation
+%!error hgload ()
+%!error hgload (1, 2)
+%!error <unable to locate file> hgload ("%%_A_REALLY_UNLIKELY_FILENAME_%%")
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/plot/util/hgsave.m	Fri Aug 01 12:10:05 2014 -0400
@@ -0,0 +1,128 @@
+## Copyright (C) 2014 Massimiliano Fasi
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn  {Function File} {} hgsave (@var{filename})
+## @deftypefnx {Function File} {} hgsave (@var{h}, @var{filename})
+## @deftypefnx {Function File} {} hgsave (@var{h}, @var{filename}, @var{fmt})
+## Save the graphics handle @var{h} to the file @var{filename} in the format
+## @var{fmt}.
+##
+## If unspecified, @var{h} is the current figure as returned by @code{gcf}. 
+## When @var{filename} does not have an extension the default filename
+## extension @file{.ofig} will be appended.  If present, @var{fmt} should 
+## should be one of the following:
+##
+## @itemize @bullet
+## @item @option{-binary}, @option{-float-binary}
+##
+## @item @option{-hdf5}, @option{-float-hdf5}
+##
+## @item @option{-V7}, @option{-v7}, @code{-7}, @option{-mat7-binary}
+##
+## @item @option{-V6}, @option{-v6}, @code{-6}, @option{-mat6-binary}
+##
+## @item @option{-text}
+##
+## @item @option{-zip}, @option{-z}
+## @end itemize
+##
+## When producing graphics for final publication use @code{print} or
+## @code{saveas}.  When it is important to be able to continue to edit a
+## figure as an Octave object, use @code{hgsave}/@code{hgload}.
+## @seealso{hgload, hdl2struct, saveas, print}
+## @end deftypefn
+
+## Author: Massimiliano Fasi
+
+function hgsave (h, filename, fmt = "-binary")
+
+  if (nargin < 1 || nargin > 3)
+    print_usage ();
+  endif
+
+  ## Check input arguments
+  if (nargin == 1 && ischar (h))
+    filename = h;
+    h = get (0, "currentfigure");
+    if (isempty (h))
+      error ("hgsave: No current figure to save");
+    endif
+  elseif (! (ishandle (h) && ischar (filename)))
+    print_usage ();
+  endif
+
+  ## Check file extension
+  [~, ~, ext] = fileparts (filename);
+  if (isempty (ext))
+    filename = [filename ".ofig"];
+  endif
+
+  s_oct40 = hdl2struct (h);
+  save (fmt, filename, "s_oct40");
+
+endfunction
+
+
+%!testif HAVE_MAGICK
+%! toolkit = graphics_toolkit ();
+%! graphics_toolkit ("gnuplot");
+%! unwind_protect
+%!   h1 = figure ("visible", "off");
+%!   x = 0:0.1:2*pi;
+%!   y1 = sin (x);
+%!   y2 = exp (x - 1);
+%!   ax = plotyy (x,y1, x-1,y2, @plot, @semilogy);
+%!   xlabel ("X");
+%!   ylabel (ax(1), "Axis 1");
+%!   ylabel (ax(2), "Axis 2");
+%!   axes (ax(1));
+%!   text (0.5, 0.5, "Left Axis", ...
+%!         "color", [0 0 1], "horizontalalignment", "center");
+%!   axes (ax(2));
+%!   text (4.5, 80, "Right Axis", ...
+%!         "color", [0 0.5 0], "horizontalalignment", "center");
+%!   ftmp = [tmpnam() ".ofig"];
+%!   png1 = [tmpnam() ".png"];
+%!   png2 = [tmpnam() ".png"];
+%!   unwind_protect
+%!     hgsave (h1, ftmp);
+%!     print (h1, png1);
+%!     [img1, map1, alpha1] = imread (png1);
+%!     h2 = hgload (ftmp);
+%!     print (h2, png2);
+%!     [img2, map2, alpha2] = imread (png2);
+%!   unwind_protect_cleanup
+%!     unlink (ftmp);
+%!     unlink (png1);
+%!     unlink (png2);
+%!   end_unwind_protect
+%!   assert (img1, img2);
+%!   assert (map1, map2);
+%!   assert (alpha1, alpha2);
+%! unwind_protect_cleanup
+%!   close (h1);
+%!   close (h2);
+%!   graphics_toolkit (toolkit);
+%! end_unwind_protect
+
+%% Test input validation
+%!error hgsave ()
+%!error hgsave (1, 2, 3, 4)
+%!error hgsave ("abc", "def")
+
--- a/scripts/plot/util/isprop.m	Fri Aug 01 09:06:21 2014 -0400
+++ b/scripts/plot/util/isprop.m	Fri Aug 01 12:10:05 2014 -0400
@@ -17,11 +17,14 @@
 ## <http://www.gnu.org/licenses/>.
 
 ## -*- texinfo -*-
-## @deftypefn {Function File} {@var{res} =} isprop (@var{h}, "@var{prop}")
-## Return true if @var{prop} is a property of the object with handle @var{h}.
+## @deftypefn {Function File} {@var{res} =} isprop (@var{obj}, "@var{prop}")
+## Return true if @var{prop} is a property of the object @var{obj}.
 ##
-## @var{h} may also be an array of handles in which case @var{res} will be a
+## @var{obj} may also be an array of objects in which case @var{res} will be a
 ## logical array indicating whether each handle has the property @var{prop}.
+## 
+## For plotting, @var{obj} is a handle to a graphics object.  Otherwise,
+## @var{obj} should be an instance of a class.
 ## @seealso{get, set, ismethod, isobject}
 ## @end deftypefn
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/plot/util/linkaxes.m	Fri Aug 01 12:10:05 2014 -0400
@@ -0,0 +1,167 @@
+## Copyright (C) 2014 Willem Atsma
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn  {Function File} {} linkaxes (@var{hax})
+## @deftypefnx {Function File} {} linkaxes (@var{hax}, @var{optstr})
+## Link the axis limits of 2-D plots such that a change in one is
+## propagated to the others.
+##
+## The axes handles to be linked are passed as the first argument @var{hax}.
+##
+## The optional second argument is a string which defines which axis limits
+## will be linked.  The possible values for @var{optstr} are:
+##
+## @table @asis
+## @item @qcode{"x"}
+## Link x-axes
+##
+## @item @qcode{"y"}
+## Link y-axes
+##
+## @item @qcode{"xy"} (default)
+## Link both axes
+##
+## @item @qcode{"off"}
+## Turn off linking
+## @end table
+##
+## If unspecified the default is to link both X and Y axes.
+##
+## When linking, the limits from the first axes in @var{hax} are applied to the
+## other axes in the list.  Subsequent changes to any one of the axes will be
+## propagated to the others.
+##
+## @seealso{linkprop, addproperty}
+## @end deftypefn
+
+## Author: Willem Atsma willem.atsma at tanglebridge.com
+## Created: 2014-03-18
+
+function linkaxes (hax, optstr = "xy")
+
+  if  (nargin < 1 || nargin > 2)
+    print_usage ();
+  endif
+
+  if (numel (hax) < 2)
+    error ("linkaxes: HAX must contain at least 2 handles");
+  elseif (! all (isaxes (hax(:))))
+    error ("linkaxes: HAX must be a vector of axes handles");
+  endif
+
+  ## Check if axes are linked already and clear if found.
+  ## Otherwise, add the necessary linkaxes_data property.
+  for i = 1:length (hax)
+    if (isprop (hax(i), "linkaxes_data"))
+      hld = get (hax(i), "linkaxes_data");
+      try
+        rmappdata (hld, "linkprop_data");
+      end_try_catch
+    else
+      addproperty ("linkaxes_data", hax(i), "any");
+    endif
+  endfor
+
+  switch  (optstr)
+    case "x"
+      hlink = linkprop (hax, "xlim");
+    case "y"
+      hlink = linkprop (hax, "ylim");
+    case "xy"
+      hlink = linkprop (hax, {"xlim" "ylim"});
+    case "off"
+      ## do nothing - link already deleted
+      hlink = [];
+    otherwise
+      error ("linkaxes: unrecognized OPTSTR '%s'", optstr);
+  endswitch
+
+  if (! isempty (hlink))
+    setappdata (hax(1), "linkprop_data", hlink);
+    set (hax, "linkaxes_data", hax(1));
+  else
+    set (hax, "linkaxes_data", []);
+  endif
+
+endfunction
+
+
+%!demo
+%! clf;
+%! hax1 = subplot (3,1,1);
+%! bar (rand (4, 1), 'facecolor', 'r');
+%! hax2 = subplot (3,1,2);
+%! bar (5*rand (4, 1), 'facecolor', 'g');
+%! hax3 = subplot (3,1,3);
+%! bar (10*rand (4, 1), 'facecolor', 'b');
+%! input ('Type <RETURN> to link axes');
+%! linkaxes ([hax1, hax2, hax3]);
+%! input ('Type <RETURN> to change ylim');
+%! ylim (hax3, [0 10]);
+
+%!test
+%! hf1 = figure ("visible", "off");
+%! hax1 = axes ();
+%! plot (1:10);
+%! hf2 = figure ("visible", "off");
+%! hax2 = axes ();
+%! plot (10:-1:1, "-*g");
+%! hf3 = figure ("visible", "off");
+%! hax3 = axes ();
+%! plot (1:10:100, "-xb");
+%!  unwind_protect
+%!   linkaxes ([hax1, hax2, hax3]);
+%!   ## Test initial values taken from first object in list
+%!   assert (xlim (hax3), [0 10]);
+%!   assert (ylim (hax3), [0 10]);
+%!   ## Test linking
+%!   xlim (hax2, [2 8]);
+%!   assert (xlim (hax1), [2 8]);
+%!   assert (xlim (hax3), [2 8]);
+%!   ylim (hax3, "auto");
+%!   assert (ylim (hax1), [0 100]);
+%!   assert (ylim (hax2), [0 100]);
+%!   ## Test re-linking removes old link
+%!   linkaxes ([hax1, hax2]);
+%!   ylim (hax3, [0 50]);
+%!   assert (ylim (hax1), [0 100]);
+%!   assert (ylim (hax2), [0 100]);
+%!   xlim (hax1, [0 4]);
+%!   assert (xlim (hax2), [0 4]);
+%!   ## Test linking of remaining objects after deletion of one object
+%!   linkaxes ([hax1, hax2, hax3]);
+%!   xlim (hax2, [0 1]);
+%!   assert (xlim (hax1), [0 1]);
+%!   assert (xlim (hax3), [0 1]);
+%!   delete (hax2);
+%!   xlim (hax3, [0 2]);
+%!   assert (xlim (hax1), [0 2]);
+%!   ## Test deletion of link
+%!   linkaxes ([hax1, hax3], "off");
+%!   xlim (hax3, [0 3]);
+%!   assert (xlim (hax1), [0 2]);
+%!  unwind_protect_cleanup
+%!   close ([hf1 hf2 hf3]);
+%!  end_unwind_protect
+
+%% Test input validation
+%!error linkaxes ()
+%!error linkaxes (1,2,3)
+%!error <HAX must be a vector of axes handles> linkaxes ([pi, e])
+
--- a/scripts/plot/util/linkprop.m	Fri Aug 01 09:06:21 2014 -0400
+++ b/scripts/plot/util/linkprop.m	Fri Aug 01 12:10:05 2014 -0400
@@ -17,14 +17,24 @@
 ## <http://www.gnu.org/licenses/>.
 
 ## -*- texinfo -*-
-## @deftypefn  {Function File} {@var{hlink} =} linkprop (@var{h}, @var{prop})
-## @deftypefnx {Function File} {@var{hlink} =} linkprop (@var{h}, @{@var{prop1}, @var{prop2}, @dots{}@})
-## Link graphics object properties, such that a change in one is
-## propagated to the others.
+## @deftypefn  {Function File} {@var{hlink} =} linkprop (@var{h}, "@var{prop}")
+## @deftypefnx {Function File} {@var{hlink} =} linkprop (@var{h}, @{"@var{prop1}", "@var{prop2}", @dots{}@})
+## Link graphic object properties, such that a change in one is propagated to
+## the others.
+##
+## The input @var{h} is a vector of graphic handles to link.
 ##
-## @var{prop} can be a string for a single property, or a cell array of strings
-## for multiple properties.  @var{h} is an array of graphics handles which
-## will have their properties linked.
+## @var{prop} may be a string when linking a single property, or a cell array
+## of strings for multiple properties.  During the linking process all
+## properties in @var{prop} will initially be set to the values that exist on
+## the first object in the list @var{h}.
+##
+## The function returns @var{hlink} which is a special object describing the
+## link.  As long as the reference @var{hlink} exists the link between graphic
+## objects will be active.  This means that @var{hlink} must be preserved in
+## a workspace variable, a global variable, or otherwise stored using a
+## function such as @code{setappdata}, @code{guidata}.  To unlink properties,
+## execute @code{clear @var{hlink}}.
 ##
 ## An example of the use of @code{linkprop} is
 ##
@@ -41,62 +51,122 @@
 ## @end group
 ## @end example
 ##
+## @seealso{linkaxes}
 ## @end deftypefn
 
 function hlink = linkprop (h, prop)
+
+  if (nargin != 2)
+    print_usage ();
+  endif
+
+  if (numel (h) < 2)
+    error ("linkprop: H must contain at least 2 handles");
+  elseif (! all (ishandle (h(:))))
+    error ("linkprop: invalid graphic handle in input H");
+  endif
+
   if (ischar (prop))
     prop = {prop};
-  elseif (!iscellstr (prop))
-    error ("linkprop: properties must be a string or cell string array");
+  elseif (! iscellstr (prop))
+    error ("linkprop: PROP must be a string or cell string array");
   endif
 
+  h = h(:)';  # set() prefers column vectors
+  ## Match all objects to the first one in the list before linking 
+  for j = 1 : numel (prop)
+    set (h(2:end), prop{j}, get (h(1), prop{j})); 
+  endfor
+
+  ## Add listeners to all objects
   for i = 1 : numel (h)
     for j = 1 : numel (prop)
-      addlistener (h(i), prop{j}, {@update_prop, h, prop{j}});
+      addlistener (h(i), prop{j},
+                   {@update_prop, [h(1:i-1),h(i+1:end)], prop{j}});
     endfor
   endfor
 
-  ## This should be an object that when destroyed removes the links
-  ## The below is not quite right. As when you call "clear hlink" the
-  ## hggroup continues to exist.
-  hlink = hggroup ();
-  set (hlink, "deletefcn", {@delete_prop, h, prop});
+  hlink = onCleanup (@() delete_linkprop (h, prop));
+
 endfunction
 
-function update_prop (h, d, hlist, prop)
+function update_prop (h, ~, hlist, prop)
   persistent recursion = false;
 
   ## Don't allow recursion
   if (! recursion)
     unwind_protect
       recursion = true;
-      val = get (h, prop);
-      for hh = hlist(:)'
-        if (hh != h)
-          oldval = get (hh, prop);
-          if (! isequal (val, oldval))
-            set (hh, prop, val);
-          endif
-        endif
-      endfor
+      set (hlist(ishandle (hlist)), prop, get (h, prop));
     unwind_protect_cleanup
       recursion = false;
     end_unwind_protect
   endif
 endfunction
 
-function delete_prop (h, d, hlist, prop)
-  ## FIXME. Actually need to delete the linked properties.
-  ## However, only warn if the graphics objects aren't being deleted.
-  warn = false;
-  for h = hlist(:)'
-    if (ishandle (h) && !strcmpi (get (h, "beingdeleted"), "on"))
-      warn = true;
-      break;
+function delete_linkprop (hlist, prop)
+
+  for i = 1 : numel (hlist)
+    if (ishandle (hlist(i)))
+      for j = 1 : numel (prop)
+        dellistener (hlist(i), prop{j}),
+      endfor
     endif
   endfor
-  if (warn)
-    warning ("linkprop: can not remove linked properties");
-  endif
+
 endfunction
 
+
+%!demo
+%! clf;
+%! x = 0:0.1:10;
+%! subplot (1,2,1);
+%! h1 = plot (x, sin (x), 'r');
+%! subplot (1,2,2);
+%! h2 = plot (x, cos (x), 'b');
+%! input ('Type <RETURN> to link plots');
+%! hlink = linkprop ([h1, h2], {'color', 'linestyle'});
+%! input ('Type <RETURN> to change color');
+%! set (h1, 'color', 'green');
+%! input ('Type <RETURN> to change linestyle');
+%! set (h2, 'linestyle', '--');
+
+%!test
+%! hf1 = figure ("visible", "off");
+%! hl1 = plot (1:10, "or");
+%! hf2 = figure ("visible", "off");
+%! hl2 = plot (1:10, "-*g");
+%! hf3 = figure ("visible", "off");
+%! hl3 = plot (1:10, "-xb");
+%! unwind_protect
+%!   hlink = linkprop ([hl1, hl2, hl3], {"color", "linestyle"});
+%!   ## Test initial values taken from first object in list
+%!   assert (get (hl2, "color"), [1 0 0]);
+%!   assert (get (hl3, "linestyle"), "none");
+%!   ## Test linking
+%!   set (hl2, "color", "b");
+%!   assert (get (hl1, "color"), [0 0 1]);
+%!   assert (get (hl3, "color"), [0 0 1]);
+%!   set (hl3, "linestyle", "--");
+%!   assert (get (hl1, "linestyle"), "--");
+%!   assert (get (hl2, "linestyle"), "--");
+%!   ## Test linking of remaining objects after deletion of one object
+%!   delete (hl2);
+%!   set (hl1, "linestyle", ":");
+%!   assert (get (hl3, "linestyle"), ":");
+%!   ## Test deletion of link
+%!   clear hlink;
+%!   set (hl1, "color", "g");
+%!   assert (get (hl3, "color"), [0 0 1]);
+%! unwind_protect_cleanup
+%!   close ([hf1 hf2 hf3]);
+%! end_unwind_protect
+
+%% Test input validation
+%!error linkprop ()
+%!error linkprop (1)
+%!error linkprop (1,2,3)
+%!error <H must contain at least 2 handles> linkprop (1, "color")
+%!error <invalid graphic handle in input H> linkprop ([pi, e], "color")
+%!error <PROP must be a string or cell string array> linkprop ([0, 0], 1)
+
--- a/scripts/plot/util/module.mk	Fri Aug 01 09:06:21 2014 -0400
+++ b/scripts/plot/util/module.mk	Fri Aug 01 12:10:05 2014 -0400
@@ -48,24 +48,29 @@
   plot/util/graphics_toolkit.m \
   plot/util/hdl2struct.m \
   plot/util/hggroup.m \
+  plot/util/hgload.m \
+  plot/util/hgsave.m \
   plot/util/hold.m \
   plot/util/isaxes.m \
   plot/util/isfigure.m \
   plot/util/ishghandle.m \
   plot/util/ishold.m \
   plot/util/isprop.m \
+  plot/util/linkaxes.m \
   plot/util/linkprop.m \
   plot/util/meshgrid.m \
   plot/util/ndgrid.m \
   plot/util/newplot.m \
   plot/util/__next_line_color__.m \
   plot/util/__next_line_style__.m \
+  plot/util/pan.m \
   plot/util/__plt_get_axis_arg__.m \
   plot/util/__pltopt__.m \
   plot/util/printd.m \
   plot/util/print.m \
   plot/util/refreshdata.m \
   plot/util/refresh.m \
+  plot/util/rotate3d.m \
   plot/util/saveas.m \
   plot/util/shg.m \
   plot/util/struct2hdl.m \
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/plot/util/pan.m	Fri Aug 01 12:10:05 2014 -0400
@@ -0,0 +1,77 @@
+## Copyright (C) 2014 Andreas Weber
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn  {Command} {} pan
+## @deftypefnx {Command} {} pan on
+## @deftypefnx {Command} {} pan xon
+## @deftypefnx {Command} {} pan yon
+## @deftypefnx {Command} {} pan off
+## @deftypefnx {Function File} {} pan (@var{hax}, @dots{})
+## Control panning mode of interactive graph in GUI.
+##
+## The function state input may be either @qcode{"on"}, @qcode{"xon"},
+## @qcode{"yon"} or @qcode{"off"}.
+##
+## If it is omitted the current state is toggled (@qcode{"xon"} and
+## @qcode{"yon"} are treated as @qcode{"on"}).
+##
+## @qcode{"xon"} limits panning to the x-axis, @qcode{"yon"} to the
+## y-axis.
+##
+## If the first argument @var{hax} is an axes handle, then operate on
+## this axis rather than the current axes returned by @code{gca}.
+##
+## To query the current mode use the @code{get}
+## function.  For example:
+## @example
+## mode = get (gca, "pan");
+## @end example
+## @seealso{rotate3d}
+## @end deftypefn
+
+function pan (varargin)
+
+  if (numel (varargin) > 0 && isaxes (varargin{1}))
+    hax = varargin{1};
+    varargin(1) = [];
+  else
+    hax = gca ();
+  endif
+
+  toolkit = get (ancestor (hax, "figure"), "__graphics_toolkit__");
+  if (! strcmp (toolkit, "fltk"))
+    warning ("pan: Only implemented for graphics_toolkit FLTK");
+  endif
+
+  if (numel (varargin) > 1)
+    print_usage ();
+  elseif (numel (varargin) == 0)
+    # toggle
+    m = get (hax, "pan");
+    if (findstr (m, "on") > 0)
+      set (hax, "pan", "off");
+    else
+      set (hax, "pan", "on");
+    endif
+  elseif (numel (varargin) == 1)
+    set (hax, "pan", varargin{1});
+  endif
+
+endfunction
+
--- a/scripts/plot/util/print.m	Fri Aug 01 09:06:21 2014 -0400
+++ b/scripts/plot/util/print.m	Fri Aug 01 12:10:05 2014 -0400
@@ -103,18 +103,29 @@
 ##     Encapsulated PostScript (level 1 and 2, mono and color).  The FLTK
 ## graphic toolkit generates PostScript level 3.0.
 ##
-##   @item  tex
+##   @item  pslatex
 ##   @itemx epslatex
-##   @itemx epslatexstandalone
-##   @itemx pstex
-##   @itemx pslatex
 ##   @itemx pdflatex
-##     Generate a @LaTeX{} (or @TeX{}) file for labels and eps/ps/pdf
-## for graphics.  The file produced by @code{epslatexstandalone} can be
-## processed directly by @LaTeX{}.  The other formats are intended to
-## be included in a @LaTeX{} (or @TeX{}) document.  The @code{tex} device
-## is the same as the @code{epslatex} device.  The @code{pdflatex} device
-## is only available for the FLTK graphics toolkit.
+##   @itemx pslatexstandalone
+##   @itemx epslatexstandalone
+##   @itemx pdflatexstandalone
+##     Generate a @LaTeX{} file @file{@var{filename}.tex} for the text
+## portions of a plot and a file @file{@var{filename}.(ps|eps|pdf)} for the
+## remaining graphics.  The graphics file suffix .ps|eps|pdf is determined
+## by the specified device type.  The @LaTeX{} file produced by the
+## @samp{standalone} option can be processed directly by @LaTeX{}.  The file
+## generated without the @samp{standalone} option is intended to be included
+## from another @LaTeX{} document.  In either case, the @LaTeX{} file
+## contains an @code{\includegraphics} command so that the generated graphics
+## file is automatically included when the @LaTeX{} file is processed.  The
+## text that is written to the @LaTeX{} file contains the strings
+## @strong{exactly} as they were specified in the plot.  If any special
+## characters of the @TeX{} mode interpreter were used, the file must be
+## edited before @LaTeX{} processing.  Specifically, the special characters
+## must be enclosed with dollar signs (@code{$ @dots{} $}), and other
+## characters that are recognized by @LaTeX{} may also need editing (.e.g.,
+## braces).  The @samp{pdflatex} device, and any of the @samp{standalone}
+## formats, are not available with the Gnuplot toolkit.
 ##
 ##   @item tikz
 ##     Generate a @LaTeX{} file using PGF/TikZ@.  For the FLTK toolkit
@@ -175,29 +186,17 @@
 ## Some examples are;
 ##
 ##   @table @code
+##   @item pdfwrite
+##     Produces pdf output from eps
+##
 ##   @item ljet2p
 ##     HP LaserJet @nospell{IIP}
 ##
-##   @item ljet3
-##     HP LaserJet III
-##
-##   @item deskjet
-##     HP DeskJet and DeskJet Plus
-##
-##   @item cdj550
-##     HP DeskJet 550C
-##
-##   @item paintjet
-##     HP PointJet
-##
 ##   @item pcx24b
 ##     24-bit color PCX file format
 ##
 ##   @item ppm
 ##     Portable Pixel Map file format
-##
-##   @item pdfwrite
-##     Produces pdf output from eps
 ##   @end table
 ##
 ##   For a complete list, type @code{system ("gs -h")} to see what formats
@@ -254,28 +253,38 @@
 ##
 ## The filename and options can be given in any order.
 ##
-## Example: Print to a file using the svg device.
+## Example: Print to a file using the pdf device.
 ##
 ## @example
 ## @group
 ## figure (1);
 ## clf ();
 ## surf (peaks);
-## print -dsvg figure1.svg
+## print figure1.pdf
 ## @end group
 ## @end example
 ##
-## Example: Print to an HP DeskJet 550C.
+## Example: Print to a file using jpg device.
 ##
 ## @example
 ## @group
 ## clf ();
 ## surf (peaks);
-## print -dcdj550
+## print -djpg figure2.jpg
 ## @end group
 ## @end example
 ##
-## @seealso{saveas, orient, figure}
+## Example: Print to printer named PS_printer using ps format.
+##
+## @example
+## @group
+## clf ();
+## surf (peaks);
+## print -dpswrite -PPS_printer 
+## @end group
+## @end example
+##
+## @seealso{saveas, hgsave, orient, figure}
 ## @end deftypefn
 
 function print (varargin)
@@ -288,7 +297,7 @@
   opts.lpr_cmd = @lpr;
   opts.epstool_cmd = @epstool;
 
-  if (! isfigure (opts.figure))
+  if (isempty (opts.figure) || ! isfigure (opts.figure))
     error ("print: no figure to print");
   endif
 
@@ -414,7 +423,7 @@
       endif
     endif
 
-    ## call the graphcis toolkit print script
+    ## call the graphics toolkit print script
     switch (get (opts.figure, "__graphics_toolkit__"))
       case "gnuplot"
         opts = __gnuplot_print__ (opts);
@@ -610,7 +619,7 @@
   dos_shell = (ispc () && ! isunix ());
   if (! isempty (opts.fig2dev_binary))
     if (dos_shell)
-      ## FIXME - is this the right thing to do for DOS?
+      ## FIXME: Is this the right thing to do for DOS?
       cmd = sprintf ("%s -L %s 2> NUL", opts.fig2dev_binary, devopt);
     else
       cmd = sprintf ("%s -L %s 2> /dev/null", opts.fig2dev_binary, devopt);
@@ -689,7 +698,7 @@
       cmd = sprintf ("%s %s", cmd, opts.lpr_options);
     endif
     if (! isempty (opts.printer))
-      cmd = sprintf ("%s -P %s", cmd, opts.printer);
+      cmd = sprintf ("%s %s", cmd, opts.printer);
     endif
   elseif (isempty (opts.lpr_binary))
     error ("print:nolpr", "print.m: 'lpr' not found in PATH");
@@ -708,7 +717,7 @@
     if (dos_shell)
       cmd = sprintf ("%s -f %s 2> NUL", opts.pstoedit_binary, devopt);
     else
-      ## FIXME - is this the right thing to do for DOS?
+      ## FIXME: Is this the right thing to do for DOS?
       cmd = sprintf ("%s -f %s 2> /dev/null", opts.pstoedit_binary, devopt);
     endif
   elseif (isempty (opts.pstoedit_binary))
--- a/scripts/plot/util/printd.m	Fri Aug 01 09:06:21 2014 -0400
+++ b/scripts/plot/util/printd.m	Fri Aug 01 12:10:05 2014 -0400
@@ -86,13 +86,13 @@
 
 
 %!demo
-%! r2 = char (
-%! 'stem step: 10, data: unsorted.',
-%! 'Hinges:    lo: 12, hi: 42'     ,
-%! '   1 | 22118'                  ,
-%! '   2 | 28'                     ,
-%! '   3 | 98'                     ,
-%! '   4 | 244'                    ,
+%! r2 = char ( ...
+%! 'stem step: 10, data: unsorted.', ...
+%! 'Hinges:    lo: 12, hi: 42'     , ...
+%! '   1 | 22118'                  , ...
+%! '   2 | 28'                     , ...
+%! '   3 | 98'                     , ...
+%! '   4 | 244'                    , ...
 %! '   5 | 2'                      );
 %! printd (r2, 'test_p.txt');
 %! system ('cat test_p.txt');
--- a/scripts/plot/util/private/__add_default_menu__.m	Fri Aug 01 09:06:21 2014 -0400
+++ b/scripts/plot/util/private/__add_default_menu__.m	Fri Aug 01 12:10:05 2014 -0400
@@ -33,12 +33,6 @@
 
   obj = findall (fig, "-depth", 1, "tag", "__default_menu__", "label", "&File");
   if (isempty (obj))
-    ## FIXME: uimenu() will cause menubar to be displayed, even though property
-    ##        menubar remains set at "none".  So, forcibly turn menubar status
-    ##        on and then off to force figure to hide menubar.
-    menubar_state = get (fig, "menubar");
-    set (fig, "menubar", "figure");
-
     __f = uimenu (fig, "label", "&File", "handlevisibility", "off",
                        "tag", "__default_menu__");
       uimenu (__f, "label", "Save &As", "callback", @save_cb);
@@ -47,19 +41,19 @@
 
     __e = uimenu (fig, "label", "&Edit", "handlevisibility", "off",
                        "tag", "__default_menu__");
-      uimenu (__e, "label", "&Grid", "callback", @grid_cb);
-      uimenu (__e, "label", "Auto&scale", "callback", @autoscale_cb);
-      gm = uimenu (__e, "label", "GUI &Mode");
-        uimenu (gm, "label", "Pan+Zoom", "callback", @guimode_cb);
-        uimenu (gm, "label", "Rotate+Zoom", "callback", @guimode_cb);
-        uimenu (gm, "label", "None+Zoom", "callback", @guimode_cb);
+      uimenu (__e, "label", "Toggle &grid on all axes", "tag", "toggle", "callback", @grid_cb);
+      uimenu (__e, "label", "Show grid on all axes", "tag", "on", "callback", @grid_cb);
+      uimenu (__e, "label", "Hide grid on all axes", "tag", "off", "callback", @grid_cb);
+      uimenu (__e, "label", "Auto&scale all axes", "callback", @autoscale_cb);
+      gm = uimenu (__e, "label", "GUI &Mode (on all axes)");
+        uimenu (gm, "label", "Pan x and y", "tag", "pan_on", "callback", @guimode_cb);
+        uimenu (gm, "label", "Pan x only", "tag", "pan_xon", "callback", @guimode_cb);
+        uimenu (gm, "label", "Pan y only", "tag", "pan_yon", "callback", @guimode_cb);
+        uimenu (gm, "label", "Disable pan and rotate", "tag", "no_pan_rotate", "callback", @guimode_cb);
+        uimenu (gm, "label", "Rotate on", "tag", "rotate3d", "callback", @guimode_cb);
+        uimenu (gm, "label", "Enable mousezoom", "tag", "zoom_on", "callback", @guimode_cb);
+        uimenu (gm, "label", "Disable mousezoom", "tag", "zoom_off", "callback", @guimode_cb);
 
-    ## FIXME: This drawnow () must occur after at least one menu item has
-    ##        been defined to avoid sizing issues in new figures.
-    ##        This may lead to flicker.  The real fix must be in the C++ code. 
-    drawnow ();
-
-    set (fig, "menubar", menubar_state);
   endif
 
 endfunction
@@ -93,23 +87,51 @@
   endif
 endfunction
 
+
+function hax = __get_axes__ (h)
+  ## Get parent figure
+  fig = ancestor (h, "figure");
+
+  ## Find all axes which aren't legends
+  hax = findobj (fig, "type", "axes", "-not", "tag", "legend");
+endfunction
+
 function grid_cb (h, e)
-  grid;
+  hax = __get_axes__ (h);
+  id = get (h, "tag");
+  switch (id)
+    case "toggle"
+      arrayfun (@grid, hax);
+    otherwise
+      arrayfun (@(h) grid(h, id), hax);
+  endswitch
+  drawnow ();
 endfunction
 
 function autoscale_cb (h, e)
-  axis ("auto");
+  hax = __get_axes__ (h);
+  arrayfun (@(h) axis (h, "auto"), hax)
+  drawnow ();
 endfunction
 
 function guimode_cb (h, e)
-  lbl = get (h, "label");
-  switch (lbl)
-    case "Pan+Zoom"
-      gui_mode ("2D");
-    case "Rotate+Zoom"
-      gui_mode ("3D");
-    case "None"
-      gui_mode ("None");
+  hax = __get_axes__ (h);
+  id = get (h, "tag");
+  switch (id)
+    case "pan_on"
+      arrayfun (@(h) pan (h, "on"), hax)
+    case "pan_xon"
+      arrayfun (@(h) pan (h, "xon"), hax)
+    case "pan_yon"
+      arrayfun (@(h) pan (h, "yon"), hax)
+    case "rotate3d"
+      arrayfun (@(h) rotate3d (h, "on"), hax)
+    case "no_pan_rotate"
+      arrayfun (@(h) pan (h, "off"), hax)
+      arrayfun (@(h) rotate3d (h, "off"), hax)
+    case "zoom_on"
+      arrayfun (@(h) set (h, "mouse_wheel_zoom", 0.05), hax);
+    case "zoom_off"
+      arrayfun (@(h) set (h, "mouse_wheel_zoom", 0.0), hax);
   endswitch
 endfunction
-
--- a/scripts/plot/util/private/__ghostscript__.m	Fri Aug 01 09:06:21 2014 -0400
+++ b/scripts/plot/util/private/__ghostscript__.m	Fri Aug 01 12:10:05 2014 -0400
@@ -143,9 +143,9 @@
   endif
   if (! isempty (opts.prepend)
       && any (strcmpi (opts.device, {"pswrite", "ps2write", "pdfwrite"})))
-    ## FIXME - Fonts get may be mangled when appending ps/ps2.
-    ##         See "How to concatenate several PS files" at the link,
-    ##         http://en.wikibooks.org/wiki/PostScript_FAQ
+    ## FIXME: Fonts get may be mangled when appending ps/ps2.
+    ##        See "How to concatenate several PS files" at the link,
+    ##        http://en.wikibooks.org/wiki/PostScript_FAQ
     cmd = sprintf ("%s %s", cmd, opts.prepend);
     if (isempty (cleanup_cmd))
       cleanup_cmd = sprintf ("rm %s", opts.prepend);
--- a/scripts/plot/util/private/__go_draw_axes__.m	Fri Aug 01 09:06:21 2014 -0400
+++ b/scripts/plot/util/private/__go_draw_axes__.m	Fri Aug 01 12:10:05 2014 -0400
@@ -63,7 +63,7 @@
       && strcmp (axis_obj.xlimmode, "manual")
       && strcmp (axis_obj.ylimmode, "manual")
       && (nd == 2 || all (mod (axis_obj.view, 90) == 0)))
-    ## FIXME - adjust plotboxaspectratio to respect other
+    ## FIXME: adjust plotboxaspectratio to respect other
     fpos = get (axis_obj.parent, "position");
     apos = axis_obj.position;
   endif
@@ -75,7 +75,7 @@
     if (nd == 2 || all (mod (axis_obj.view, 90) == 0))
       dr = dr(1) / dr(2);
     else
-      ## FIXME - need to properly implement 3D
+      ## FIXME: need to properly implement 3D
       dr = mean (dr(1:2)) / dr(3);
     endif
   else
@@ -106,7 +106,7 @@
       fprintf (plot_stream, "set rmargin 0;\n");
 
       if (nd == 3 && all (axis_obj.view == [0, 90]))
-        ## FIXME -- Kludge to allow colorbar to be added to a pcolor() plot
+        ## FIXME: Kludge to allow colorbar to be added to a pcolor() plot
         pos(3:4) = pos(3:4) * 1.4;
         pos(1:2) = pos(1:2) - pos(3:4) * 0.125;
       endif
@@ -139,8 +139,8 @@
   endif
 
   ## Reset all labels, axis-labels, tick-labels, and title
-  ## FIXME - We should have an function to initialize the axis.
-  ##         Presently, this is dispersed in this function.
+  ## FIXME: We should have an function to initialize the axis.
+  ##        Presently, this is dispersed in this function.
   fputs (plot_stream, "unset label;\n");
   fputs (plot_stream, "unset xtics;\n");
   fputs (plot_stream, "unset ytics;\n");
@@ -323,9 +323,9 @@
     fputs (plot_stream, "set border front;\n");
   else
     fputs (plot_stream, "set grid layerdefault;\n");
-    ## FIXME -- the gnuplot help says that "layerdefault" should work
-    ## for set border too, but it fails for me with gnuplot 4.2.5.  So
-    ## use "back" instead.
+    ## FIXME: The gnuplot help says that "layerdefault" should work
+    ##        for set border too, but it fails for me with gnuplot 4.2.5.
+    ##        So, use "back" instead.
     fputs (plot_stream, "set border back;\n");
   endif
 
@@ -800,12 +800,11 @@
            endif
 
            if (isfield (obj, "edgecolor"))
-             ## FIXME
-             ## This is the wrong thing to do as edgecolor, markeredgecolor
-             ## and markerfacecolor can have different values and we should
-             ## treat them seperately. However, the below allow the scatter
-             ## functions to work as expected, where only one of these values
-             ## is set
+             ## FIXME: This is the wrong thing to do as edgecolor,
+             ## markeredgecolor and markerfacecolor can have different values
+             ## and we should treat them seperately. However, the code below
+             ## allows the scatter functions to work as expected, where only
+             ## one of these values is set.
              if (strcmp (obj.edgecolor, "none"))
                if (strcmp (obj.markeredgecolor, "none"))
                  ec = obj.markerfacecolor;
@@ -1969,19 +1968,19 @@
         pt = "10";
         pt2 = "11";
       case ">"
-        ## FIXME: should be triangle pointing right, use triangle pointing up
+        ## FIXME: Should be triangle pointing right, use triangle pointing up
         pt = "8";
         pt2 = "9";
       case "<"
-        ## FIXME: should be triangle pointing left, use triangle pointing down
+        ## FIXME: Should be triangle pointing left, use triangle pointing down
         pt = "10";
         pt2 = "11";
       case {"pentagram", "p"}
-        ## FIXME: should be pentagram, using pentagon
+        ## FIXME: Should be pentagram, using pentagon
         pt = "14";
         pt2 = "15";
       case {"hexagram", "h"}
-        ## FIXME: should be 6 pt start, using "*" instead
+        ## FIXME: Should be 6 pt start, using "*" instead
         pt = pt2 = "3";
       case "none"
         pt = pt2 = "";
@@ -1997,7 +1996,7 @@
 
   ## DATA is already transposed.
 
-  ## FIXME -- this may need to be converted to C++ for speed.
+  ## FIXME: this may need to be converted to C++ for speed.
 
   ## Convert NA elements to normal NaN values because fprintf writes
   ## "NA" and that confuses gnuplot.
@@ -2145,54 +2144,38 @@
     num_mtics = 5;
   endif
   colorspec = get_text_colorspec (color, mono);
-  if (strcmpi (ticmode, "manual") || strcmpi (labelmode, "manual"))
+  fprintf (plot_stream, "set format %s \"%s\";\n", ax, fmt);
+  if (strcmpi (ticmode, "manual"))
     if (isempty (tics))
       fprintf (plot_stream, "unset %stics;\nunset m%stics;\n", ax, ax);
       return
     endif
-    if (strcmpi (ticmode, "manual"))
-      fprintf (plot_stream, "set format %s \"%s\";\n", ax, fmt);
-      fprintf (plot_stream, "set %stics %s %s %s %s (", ax, tickdir,
-               ticklength, axispos, mirror);
-      fprintf (plot_stream, " %.15g,", tics(1:end-1));
-      fprintf (plot_stream, " %.15g) %s;\n", tics(end), fontspec);
-    endif
-    if (strcmpi (labelmode, "manual"))
-      if (ischar (labels))
-        labels = cellstr (labels);
-      endif
-      if (isnumeric (labels))
-        labels = num2str (real (labels(:)));
-      endif
-      if (ischar (labels))
-        labels = permute (cellstr (labels), [2, 1]);
-      endif
-      if (iscellstr (labels))
-        k = 1;
-        ntics = numel (tics);
-        nlabels = numel (labels);
-        fprintf (plot_stream, "set %stics add %s %s %s %s (", ax,
-                 tickdir, ticklength, axispos, mirror);
-        labels = strrep (labels, "%", "%%");
-        for i = 1:ntics
-          fprintf (plot_stream, " \"%s\" %.15g", labels{k++}, tics(i));
-          if (i < ntics)
-            fputs (plot_stream, ", ");
-          endif
-          if (k > nlabels)
-            k = 1;
-          endif
-        endfor
-        fprintf (plot_stream, ") %s %s;\n", colorspec, fontspec);
-      else
-        error ("__go_draw_axes__: unsupported type of ticklabel");
-      endif
-    endif
+    fprintf (plot_stream, "set %stics %s %s %s %s (", ax, tickdir,
+             ticklength, axispos, mirror);
+    fprintf (plot_stream, " %.15g,", tics(1:end-1));
+    fprintf (plot_stream, " %.15g) %s;\n", tics(end), fontspec);
   else
-    fprintf (plot_stream, "set format %s \"%s\";\n", ax, fmt);
     fprintf (plot_stream, "set %stics %s %s %s %s %s %s;\n", ax,
              tickdir, ticklength, axispos, mirror, colorspec, fontspec);
   endif
+  if (strcmpi (labelmode, "manual"))
+    k = 1;
+    ntics = numel (tics);
+    nlabels = numel (labels);
+    fprintf (plot_stream, "set %stics add %s %s %s %s (", ax,
+             tickdir, ticklength, axispos, mirror);
+    labels = strrep (labels, "%", "%%");
+    for i = 1:ntics
+      fprintf (plot_stream, " \"%s\" %.15g", labels{k++}, tics(i));
+      if (i < ntics)
+        fputs (plot_stream, ", ");
+      endif
+      if (k > nlabels)
+        k = 1;
+      endif
+    endfor
+    fprintf (plot_stream, ") %s %s;\n", colorspec, fontspec);
+  endif
   if (strcmp (mtics, "on"))
     fprintf (plot_stream, "set m%stics %d;\n", ax, num_mtics);
   else
@@ -2201,20 +2184,12 @@
 endfunction
 
 function ticklabel = ticklabel_to_cell (ticklabel)
-  if (isnumeric (ticklabel))
-    ## Use upto 5 significant digits
-    ticklabel = num2str (ticklabel(:), 5);
-  endif
   if (ischar (ticklabel))
-    if (rows (ticklabel) == 1 && any (ticklabel == "|"))
-      ticklabel = ostrsplit (ticklabel, "|");
-    else
-      ticklabel = cellstr (ticklabel);
-    endif
-  elseif (isempty (ticklabel))
-    ticklabel = {""};
+    ticklabel = cellstr (ticklabel);
+  elseif (iscellstr (ticklabel))
+    ticklabel = ticklabel;
   else
-    ticklabel = ticklabel;
+    error ("__go_draw_axes__: unsupported type of ticklabel");
   endif
 endfunction
 
@@ -2322,7 +2297,7 @@
       f = m{i}(2:end);
       if (isfield (sym, f))
         g = getfield (sym, f);
-        ## FIXME The symbol font doesn't seem to support bold or italic
+        ## FIXME: The symbol font doesn't seem to support bold or italic
         ##if (bld)
         ##  if (it)
         ##    g = regexprep (g, '/Symbol', '/Symbol-bolditalic');
@@ -2352,7 +2327,7 @@
           str = [str(1:s(i) - 1) '/' fnt '-bold ' str(s(i) + 3:end)];
         endif
       elseif (strcmpi (f, "color"))
-        ## FIXME Ignore \color but remove trailing {} block as well
+        ## FIXME: Ignore \color but remove trailing {} block as well
         d = strfind (str(e(i) + 1:end),'}');
         if (isempty (d))
           warning ('syntax error in \color argument');
@@ -2383,7 +2358,7 @@
         for j = 1 : length (flds)
           if (strncmp (flds{j}, f, length (flds{j})))
             g = getfield (sym, flds{j});
-            ## FIXME The symbol font doesn't seem to support bold or italic
+            ## FIXME: The symbol font doesn't seem to support bold or italic
             ##if (bld)
             ##  if (it)
             ##    g = regexprep (g, '/Symbol', '/Symbol-bolditalic');
@@ -2407,7 +2382,7 @@
   ## shortest.. Don't have to worry about things like ^\theta as they
   ## are already converted to ^{/Symbol q}.
 
-  ## FIXME -- This is a mess... Is it worth it just for a "@" character?
+  ## FIXME: This is a mess... Is it worth it just for a "@" character?
 
   [s, m] = regexp (str,'[_\^]','start','matches');
   i = 1;
--- a/scripts/plot/util/private/__print_parse_opts__.m	Fri Aug 01 09:06:21 2014 -0400
+++ b/scripts/plot/util/private/__print_parse_opts__.m	Fri Aug 01 12:10:05 2014 -0400
@@ -298,7 +298,7 @@
     arg_st.devopt = aliases.(arg_st.devopt);
   endif
 
-  ## FIXME - eps2 & epsc2 needs to be handled
+  ## FIXME: eps2 & epsc2 needs to be handled
   if (strcmp (arg_st.devopt, "pswrite"))
     arg_st.ghostscript.level = 1;
   elseif (strcmp (arg_st.devopt, "ps2write"))
@@ -334,10 +334,9 @@
     else
       error ("print: a file name may not specified when spooling to a printer")
     endif
-    if (! any (strcmp (arg_st.devopt, gs_device_list))
-      || ! any (strcmp (arg_st.devopt, {"pswrite", "ps2write"})))
-      ## Only postscript and supported ghostscript devices
-      error ("print: invalid format for spooling to a printer")
+    if (! any (strcmp (arg_st.devopt, gs_device_list)))
+      ## Only supported ghostscript devices
+      error ("print: format must be a valid Ghostscript format for spooling to a printer")
     endif
   elseif (isempty (arg_st.name))
     error ("print: an output file name must be specified")
@@ -581,8 +580,8 @@
     paperposition = convert2points (paperposition, paperunits);
   endif
 
-  ## FIXME - This will be obsoleted by listeners for paper properties.
-  ##         Papersize is tall when portrait,and wide when landscape.
+  ## FIXME: This will be obsoleted by listeners for paper properties.
+  ##        Papersize is tall when portrait,and wide when landscape.
   if ((papersize(1) > papersize(2) && strcmpi (paperorientation, "portrait"))
       || (papersize(1) < papersize(2) && strcmpi (paperorientation, "landscape")))
     papersize = papersize([2,1]);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/plot/util/rotate3d.m	Fri Aug 01 12:10:05 2014 -0400
@@ -0,0 +1,73 @@
+## Copyright (C) 2014 Andreas Weber
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn  {Command} {} rotate3d
+## @deftypefnx {Command} {} rotate3d on
+## @deftypefnx {Command} {} rotate3d off
+## @deftypefnx {Function File} {} rotate3d (@var{hax}, @dots{})
+## Control 3D rotation mode of interactive graph in GUI.
+##
+## The function state input may be either @qcode{"on"} or @qcode{"off"}
+## and can only be set for 3D plots.
+##
+## If the first argument @var{hax} is an axes handle, then operate on
+## this axis rather than the current axes returned by @code{gca}.
+##
+## To query the current mode use the @code{get} function.  For example:
+## @example
+## mode = get (gca, "rotate3d");
+## @end example
+## @seealso{pan}
+## @end deftypefn
+
+function rotate3d (varargin)
+
+  if (numel (varargin) > 0 && isaxes (varargin{1}))
+    hax = varargin{1};
+    varargin(1) = [];
+  else
+    hax = gca ();
+  endif
+
+  toolkit = get (ancestor (hax, "figure"), "__graphics_toolkit__");
+  if (! strcmp (toolkit, "fltk"))
+    warning ("rotate3d: Only implemented for graphics_toolkit FLTK");
+  endif
+
+  ndims = __calc_dimensions__ (hax);
+  if (ndims == 2)
+    warning ("rotate3d: Only available for 3D plots");
+  else
+    if (numel (varargin) > 1)
+      print_usage ();
+    elseif (numel (varargin) == 0)
+      # toggle
+      m = get (hax, "pan");
+      if (strcmp (get (hax, "rotate3d"), "on"))
+        set (hax, "rotate3d", "off");
+      else
+        set (hax, "rotate3d", "on");
+      endif
+    elseif (numel (varargin) == 1)
+      set (hax, "rotate3d", varargin{1});
+    endif
+  endif
+
+endfunction
+
--- a/scripts/plot/util/saveas.m	Fri Aug 01 09:06:21 2014 -0400
+++ b/scripts/plot/util/saveas.m	Fri Aug 01 12:10:05 2014 -0400
@@ -56,7 +56,7 @@
 ## @end group
 ## @end example
 ##
-## @seealso{print, orient}
+## @seealso{print, hgsave, orient}
 ## @end deftypefn
 
 ## Author: Kai Habel
--- a/scripts/plot/util/struct2hdl.m	Fri Aug 01 09:06:21 2014 -0400
+++ b/scripts/plot/util/struct2hdl.m	Fri Aug 01 12:10:05 2014 -0400
@@ -32,7 +32,7 @@
 ## A third boolean argument @var{hilev} can be passed to specify whether
 ## the function should preserve listeners/callbacks, e.g., for legends or
 ## hggroups.  The default is false.
-## @seealso{hdl2struct, findobj}
+## @seealso{hdl2struct, hgload, findobj}
 ## @end deftypefn
 
 ## Author: pdiribarne <pdiribarne@new-host.home>
@@ -177,7 +177,7 @@
 
 function [h, sout] = createaxes (s, p, par)
   ## regular axes
-  if (strcmp (s.properties.tag, ""))
+  if (! any (strcmpi (s.properties.tag, {"colorbar", "legend"})))
     propval = {"position", s.properties.position};
     hid = {"autopos_tag", "looseinset"};
     for ii = 1:numel (hid)
@@ -297,7 +297,11 @@
   h = patch (prp);
   set (h, "parent", par);
   s.properties = rmfield (s.properties,
-                            {"faces", "vertices", "facevertexcdata"});
+                          {"faces", "vertices", "facevertexcdata"});
+  ## Also remove derived properties.  Otherwise there is a possibility for
+  ## a segfault when 'set (h, properties)' is used to restore properties
+  ## which do not match in size the ones created with from the call to patch().
+  s.properties = rmfield (s.properties, {"xdata", "ydata", "zdata", "cdata"});
   addmissingprops (h, s.properties);
   sout = s;
 endfunction
@@ -447,7 +451,7 @@
 
   elseif (isfield (fields, "bargroup"))
     ## bar plot
-    ## FIXME - here we don't have access to brothers so we first create all
+    ## FIXME: Here we don't have access to brothers so we first create all
     ## the barseries of the bargroup (but the last), then retrieve information,
     ## and rebuild the whole bargroup.
     ## The duplicate are deleted after calling "setprops"
@@ -547,8 +551,7 @@
 endfunction
 
 function setprops (s, h, p, hilev)
-  more off;
-  if (strcmpi (s.properties.tag, ""))
+  if (! any (strcmpi (s.properties.tag, {"colorbar", "legend"})))
     specs = s.children(s.special);
     if (isempty (specs))
       hdls = [];
@@ -613,8 +616,7 @@
       endif
     endif
 
-  elseif (strcmpi (s.properties.tag, "legend")
-          || strcmpi (s.properties.tag, "colorbar"))
+  else
     set (h, s.properties);
   endif
 
--- a/scripts/set/ismember.m	Fri Aug 01 09:06:21 2014 -0400
+++ b/scripts/set/ismember.m	Fri Aug 01 12:10:05 2014 -0400
@@ -118,14 +118,19 @@
       a_idx = zeros (rows (A), 1);
     else
 
-      ## FIXME: lookup does not support "rows", so we just use unique.
-      [xx, ii, jj] = unique ([A; s], "rows", "last");
-      na = rows (A);
-      jj = ii(jj(1:na));
-      tf = jj > na;
+      if (rows (s) == 1)
+        tf = all (bsxfun (@eq, A, s), 2);
+        a_idx = double (tf);
+      else
+        ## FIXME: lookup does not support "rows", so we just use unique.
+        [~, ii, jj] = unique ([A; s], "rows", "last");
+        na = rows (A);
+        jj = ii(jj(1:na));
+        tf = jj > na;
 
-      if (nargout > 1)
-        a_idx = max (0, jj - na);
+        if (nargout > 1)
+          a_idx = max (0, jj - na);
+        endif
       endif
 
     endif
@@ -214,3 +219,8 @@
 %! assert (result, [true; false; true]);
 %! assert (a_idx, [1; 0; 2]);
 
+%!test
+%! [result, a_idx] = ismember ([1:3; 5:7; 4:6; 0:2; 1:3; 2:4], [1:3], "rows");
+%! assert (result, logical ([1 0 0 0 1 0]'));
+%! assert (a_idx, [1 0 0 0 1 0]');
+
--- a/scripts/set/setdiff.m	Fri Aug 01 09:06:21 2014 -0400
+++ b/scripts/set/setdiff.m	Fri Aug 01 12:10:05 2014 -0400
@@ -81,8 +81,8 @@
       if (nargout > 1)
         i(idx(dups)) = [];
       endif
-      ## Reshape if necessary.
-      if (rows (c) != 1 && rows (b) == 1)
+      ## Reshape if necessary for Matlab compatibility.
+      if (iscolumn (c) && ! iscolumn (b))
         c = c.';
       endif
     endif
@@ -105,3 +105,16 @@
 %! assert (y, [5]);
 %! assert (y, a(i));
 
+%% Test output orientation compatibility (bug #42577)
+%!assert (setdiff ([1:5], 2), [1,3,4,5])
+%!assert (setdiff ([1:5]', 2), [1;3;4;5])
+%!assert (setdiff ([1:5], [2:3]), [1,4,5])
+%!assert (setdiff ([1:5], [2:3]'), [1,4,5])
+%!assert (setdiff ([1:5]', [2:3]), [1,4,5])
+%!assert (setdiff ([1:5]', [2:3]'), [1;4;5])
+
+%% Test input validation
+%!error setdiff ()
+%!error setdiff (1)
+%!error setdiff (1,2,3,4)
+
--- a/scripts/set/unique.m	Fri Aug 01 09:06:21 2014 -0400
+++ b/scripts/set/unique.m	Fri Aug 01 12:10:05 2014 -0400
@@ -76,7 +76,7 @@
     optrows = false;
   endif
 
-  ## FIXME -- the operations
+  ## FIXME: The operations
   ##
   ##   match = (y(1:n-1) == y(2:n));
   ##   y(idx) = [];
--- a/scripts/sparse/colperm.m	Fri Aug 01 09:06:21 2014 -0400
+++ b/scripts/sparse/colperm.m	Fri Aug 01 12:10:05 2014 -0400
@@ -20,9 +20,9 @@
 ## @deftypefn {Function File} {@var{p} =} colperm (@var{s})
 ## Return the column permutations such that the columns of
 ## @code{@var{s} (:, @var{p})} are ordered in terms of increase number
-## of non-zero elements.  If @var{s} is symmetric, then @var{p} is chosen
+## of nonzero elements.  If @var{s} is symmetric, then @var{p} is chosen
 ## such that @code{@var{s} (@var{p}, @var{p})} orders the rows and
-## columns with increasing number of non zeros elements.
+## columns with increasing number of nonzeros elements.
 ## @end deftypefn
 
 function p = colperm (s)
--- a/scripts/sparse/nonzeros.m	Fri Aug 01 09:06:21 2014 -0400
+++ b/scripts/sparse/nonzeros.m	Fri Aug 01 12:10:05 2014 -0400
@@ -18,7 +18,7 @@
 
 ## -*- texinfo -*-
 ## @deftypefn {Function File} {} nonzeros (@var{s})
-## Return a vector of the non-zero values of the sparse matrix @var{s}.
+## Return a vector of the nonzero values of the sparse matrix @var{s}.
 ## @seealso{find, nnz}
 ## @end deftypefn
 
--- a/scripts/sparse/private/__sprand_impl__.m	Fri Aug 01 09:06:21 2014 -0400
+++ b/scripts/sparse/private/__sprand_impl__.m	Fri Aug 01 12:10:05 2014 -0400
@@ -22,7 +22,8 @@
 
 ## -*- texinfo -*-
 ## @deftypefn  {Function File} {} __sprand_impl__ (@var{s}, @var{randfun})
-## @deftypefnx {Function File} {} __sprand_impl__ (@var{m}, @var{n}, @var{d}, @var{funname}, @var{randfun})
+## @deftypefnx {Function File} {} __sprand_impl__ (@var{m}, @var{n}, @var{d}, @var{fcnname}, @var{randfun})
+## @deftypefnx {Function File} {} __sprand_impl__ (@var{m}, @var{n}, @var{d}, @var{rc}, @var{fcnname}, @var{randfun})
 ## Undocumented internal function.
 ## @end deftypefn
 
@@ -31,52 +32,114 @@
 function S = __sprand_impl__ (varargin)
 
   if (nargin == 2)
-    m = varargin{1};
-    randfun = varargin{2};
+    [m, randfun] = deal (varargin{1:2});
     [i, j] = find (m);
     [nr, nc] = size (m);
     S = sparse (i, j, randfun (size (i)), nr, nc);
-    return;
-  endif
+  else
+    if (nargin == 5)
+      [m, n, d, fcnname, randfun] = deal (varargin{:});
+    else
+      [m, n, d, rc, fcnname, randfun] = deal (varargin{:});
+    endif
 
-  [m, n, d, funname, randfun] = deal (varargin{:});
+    if (! (isscalar (m) && m == fix (m) && m > 0))
+      error ("%s: M must be an integer greater than 0", fcnname);
+    endif
+    if (! (isscalar (n) && n == fix (n) && n > 0))
+      error ("%s: N must be an integer greater than 0", fcnname);
+    endif
+    if (d < 0 || d > 1)
+      error ("%s: density D must be between 0 and 1", fcnname);
+    endif
+
+    if (nargin == 5)
+      mn = m*n;
+      k = round (d*mn);
+      if (mn > sizemax ())
+        ## randperm will overflow, so use alternative methods
 
-  if (!(isscalar (m) && m == fix (m) && m > 0))
-    error ("%s: M must be an integer greater than 0", funname);
-  endif
+        idx = unique (fix (rand (1.01*k, 1) * mn)) + 1;
+
+        ## idx contains random numbers in [1,mn]
+        ## Generate 1% more random values than necessary in order to reduce the
+        ## probability that there are less than k distinct values; maybe a
+        ## better strategy could be used but I don't think it's worth the price.
 
-  if (!(isscalar (n) && n == fix (n) && n > 0))
-    error ("%s: N must be an integer greater than 0", funname);
-  endif
+        ## actual number of entries in S
+        k = min (length (idx), k);
+        j = floor ((idx(1:k) - 1) / m);
+        i = idx(1:k) - j * m;
+        j++;
+      else
+        idx = randperm (mn, k);
+        [i, j] = ind2sub ([m, n], idx);
+      endif
 
-  if (d < 0 || d > 1)
-    error ("%s: density D must be between 0 and 1", funname);
-  endif
+      S = sparse (i, j, randfun (k, 1), m, n);
+
+    elseif (nargin == 6)
+      ## Create a matrix with specified reciprocal condition number.
+
+      if (! isscalar (rc) && ! isvector (rc))
+        error ("%s: RC must be a scalar or vector", fcnname);
+      endif
 
-  mn = m*n;
-  k = round (d*mn);
-  if (mn > sizemax ())
-    ## randperm will overflow, so use alternative methods
+      ## We want to reverse singular valued decomposition A=U*S*V'.
+      ## First, first S is constructed and then U = U1*U2*..Un and
+      ## V' = V1*V2*..Vn are seen as Jacobi rotation matrices with angles and
+      ## planes of rotation randomized.  Repeatedly apply rotations until the
+      ## required density for A is achieved.
 
-    idx = unique (fix (rand (min (k*1.01, k+10), 1) * mn)) + 1;
+      if (isscalar (rc))
+        if (rc < 0 || rc > 1)
+          error ("%s: reciprocal condition number RC must be between 0 and 1", fcnname);
+        endif
+        ## Reciprocal condition number is ratio of smallest SV to largest SV
+        ## Generate singular values randomly and sort them to build S
+        ## Random singular values in range [rc, 1].
+        v = rand (1, min (m,n)) * (1 - rc) + rc;
+        v(1) = 1;
+        v(end) = rc;
+        v = sort (v, "descend");
+        S = sparse (diag (v, m, n));
+      else
+        ## Only the min (m, n) greater singular values from rc vector are used.
+        if (length (rc) > min (m,n))
+          rc = rc(1:min(m, n));
+        endif
+        S = sparse (diag (sort (rc, "descend"), m, n));
+      endif
 
-    ## idx contains random numbers in [1,mn]
-    ## generate 1% or 10 more random values than necessary in order to
-    ## reduce the probability that there are less than k distinct
-    ## values; maybe a better strategy could be used but I don't think
-    ## it's worth the price
-    
-    ## actual number of entries in S
-    k = min (length (idx), k);
-    j = floor ((idx(1:k) - 1) / m);
-    i = idx(1:k) - j * m;
-    j++;
-  else
-    idx = randperm (mn, k);
-    [i, j] = ind2sub ([m, n], idx);
+      Uinit = speye (m);
+      Vinit = speye (n);
+      k = round (d*m*n);
+      while (nnz (S) < k)
+        if (m > 1)
+          ## Construct U randomized rotation matrix
+          rot_angleu = 2 * pi * rand ();
+          cu = cos (rot_angleu); su = sin (rot_angleu);
+          rndtmp = randperm (m, 2);
+          i = rndtmp(1); j = rndtmp(2);
+          U = Uinit;
+          U(i, i) = cu; U(i, j) = -su;
+          U(j, i) = su; U(j, j) = cu;
+          S = U * S;
+        endif
+        if (n > 1)
+          ## Construct V' randomized rotation matrix
+          rot_anglev = 2 * pi * rand ();
+          cv = cos (rot_anglev); sv = sin (rot_anglev);
+          rndtmp = randperm (n, 2);
+          i = rndtmp(1); j = rndtmp(2);
+          V = Vinit;
+          V(i, i) = cv;  V(i, j) = sv;
+          V(j, i) = -sv; V(j, j) = cv;
+          S = S * V;
+        endif
+      endwhile
+    endif
   endif
 
-  S = sparse (i, j, randfun (k, 1), m, n);
-
 endfunction
 
--- a/scripts/sparse/spdiags.m	Fri Aug 01 09:06:21 2014 -0400
+++ b/scripts/sparse/spdiags.m	Fri Aug 01 12:10:05 2014 -0400
@@ -17,24 +17,25 @@
 ## <http://www.gnu.org/licenses/>.
 
 ## -*- texinfo -*-
-## @deftypefn  {Function File} {[@var{b}, @var{c}] =} spdiags (@var{A})
-## @deftypefnx {Function File} {@var{b} =} spdiags (@var{A}, @var{c})
-## @deftypefnx {Function File} {@var{b} =} spdiags (@var{v}, @var{c}, @var{A})
-## @deftypefnx {Function File} {@var{b} =} spdiags (@var{v}, @var{c}, @var{m}, @var{n})
+## @deftypefn  {Function File} {@var{B} =} spdiags (@var{A})
+## @deftypefnx {Function File} {[@var{B}, @var{d}] =} spdiags (@var{A})
+## @deftypefnx {Function File} {@var{B} =} spdiags (@var{A}, @var{d})
+## @deftypefnx {Function File} {@var{A} =} spdiags (@var{v}, @var{d}, @var{A})
+## @deftypefnx {Function File} {@var{A} =} spdiags (@var{v}, @var{d}, @var{m}, @var{n})
 ## A generalization of the function @code{diag}.  Called with a single
-## input argument, the non-zero diagonals @var{c} of @var{A} are extracted.
+## input argument, the nonzero diagonals @var{d} of @var{A} are extracted.
 ## With two arguments the diagonals to extract are given by the vector
-## @var{c}.
+## @var{d}.
 ##
 ## The other two forms of @code{spdiags} modify the input matrix by
 ## replacing the diagonals.  They use the columns of @var{v} to replace
-## the columns represented by the vector @var{c}.  If the sparse matrix
+## the diagonals represented by the vector @var{d}.  If the sparse matrix
 ## @var{A} is defined then the diagonals of this matrix are replaced.
 ## Otherwise a matrix of @var{m} by @var{n} is created with the
-## diagonals given by @var{v}.
+## diagonals given by the columns of @var{v}.
 ##
-## Negative values of @var{c} represent diagonals below the main
-## diagonal, and positive values of @var{c} diagonals above the main
+## Negative values of @var{d} represent diagonals below the main
+## diagonal, and positive values of @var{d} diagonals above the main
 ## diagonal.
 ##
 ## For example:
@@ -50,45 +51,125 @@
 ## @end group
 ## @end example
 ##
+## @seealso{diag}
 ## @end deftypefn
 
-function [A, c] = spdiags (v, c, m, n)
+function [B, d] = spdiags (v, d, m, n)
+
+  if (nargin < 1 || nargin > 4)
+    print_usage ();
+  endif
 
   if (nargin == 1 || nargin == 2)
-    ## extract nonzero diagonals of v into A,c
+    ## extract nonzero diagonals of A into B,d
     [nr, nc] = size (v);
-    [i, j, v] = find (v);
+    [i, j] = find (v);
 
     if (nargin == 1)
-      ## c contains the active diagonals
-      c = unique (j-i);
+      ## d contains the active diagonals
+      d = unique (j-i);
     endif
-    ## FIXME: we can do this without a loop if we are clever
-    offset = max (min (c, nc-nr), 0);
-    A = zeros (min (nr, nc), length (c));
-    for k = 1:length (c)
-      idx = find (j-i == c(k));
-      A(j(idx)-offset(k),k) = v(idx);
+
+    ## FIXME: Maybe this could be done faster using [i,j,v] = find (v)
+    ##        and then massaging the indices i, j.  However, some
+    ##        benchmarking has shown that diag() written in C++ makes
+    ##        the following code faster even with the for loop.
+    Brows = min (nr, nc);
+    B = zeros (Brows, length (d));
+    for k = 1:length (d)
+      dn = d(k);
+      if (dn <= -nr || dn > nc)
+        continue;
+      endif
+      dv = diag (v, dn);
+      len = rows (dv);
+      ## Put sub/super-diagonals in the right place based on matrix size (MxN)
+      if (nr >= nc)
+        if (dn > 0)
+          offset = Brows - len + 1;
+          B(offset:Brows, k) = dv;
+        else
+          B(1:len, k) = dv;
+        endif
+      else
+        if (dn < 0)
+          offset = Brows - len + 1;
+          B(offset:Brows, k) = dv;
+        else
+          B(1:len, k) = dv;
+        endif
+      endif
     endfor
+
   elseif (nargin == 3)
-    ## Replace specific diagonals c of m with v,c
+    ## Replace specific diagonals d of m with v,d
     [nr, nc] = size (m);
-    B = spdiags (m, c);
-    A = m - spdiags (B, c, nr, nc) + spdiags (v, c, nr, nc);
+    A = spdiags (m, d);
+    B = m - spdiags (A, d, nr, nc) + spdiags (v, d, nr, nc);
+
   else
-    ## Create new matrix of size mxn using v,c
+    ## Create new matrix of size mxn using v,d
     [j, i, v] = find (v);
-    offset = max (min (c(:), n-m), 0);
+    if (m >= n)
+      offset = max (min (d(:), n-m), 0);
+    else
+      offset = d(:);
+    endif
     j = j(:) + offset(i(:));
-    i = j - c(:)(i(:));
+    i = j - d(:)(i(:));
     idx = i > 0 & i <= m & j > 0 & j <= n;
-    A = sparse (i(idx), j(idx), v(idx), m, n);
+    B = sparse (i(idx), j(idx), v(idx), m, n);
+
   endif
 
 endfunction
 
 
+%!test
+%! [B,d] = spdiags (magic (3));
+%! assert (d, [-2 -1 0 1 2]');
+%! assert (B, [4 3 8 0 0
+%!             0 9 5 1 0
+%!             0 0 2 7 6]);
+%! B = spdiags (magic (3), [-2 1]);
+%! assert (B, [4 0; 0 1; 0 7]);
+
+## Test zero filling for supra- and super-diagonals
+%!test
+%! ## Case 1: M = N
+%! A = sparse (zeros (3,3));
+%! A(1,3) = 13;
+%! A(3,1) = 31;
+%! [B, d] = spdiags (A);
+%! assert (d, [-2 2]');
+%! assert (B, [31 0; 0 0; 0 13]);
+%! assert (spdiags (B, d, 3,3), A)
+
+%!test
+%! ## Case 1: M > N
+%! A = sparse (zeros (4,3));
+%! A(1,3) = 13;
+%! A(3,1) = 31;
+%! [B, d] = spdiags (A);
+%! assert (d, [-2 2]');
+%! assert (B, [31 0; 0 0; 0 13]);
+%! assert (spdiags (B, d, 4,3), A)
+
+%!test
+%! ## Case 1: M < N
+%! A = sparse (zeros (3,4));
+%! A(1,3) = 13;
+%! A(3,1) = 31;
+%! [B, d] = spdiags (A);
+%! assert (d, [-2 2]');
+%! assert (B, [0 13; 0 0; 31 0]);
+%! assert (spdiags (B, d, 3,4), A)
+
 %!assert (spdiags (zeros (1,0),1,1,1), sparse (0))
 %!assert (spdiags (zeros (0,1),1,1,1), sparse (0))
-%!assert (spdiags ([0.5 -1 0.5], 0:2, 1, 1), sparse(0.5))
+%!assert (spdiags ([0.5 -1 0.5], 0:2, 1, 1), sparse (0.5))
 
+%% Test input validation
+%!error spdiags ()
+%!error spdiags (1,2,3,4,5)
+
--- a/scripts/sparse/spfun.m	Fri Aug 01 09:06:21 2014 -0400
+++ b/scripts/sparse/spfun.m	Fri Aug 01 12:10:05 2014 -0400
@@ -18,7 +18,7 @@
 
 ## -*- texinfo -*-
 ## @deftypefn {Function File} {@var{y} =} spfun (@var{f}, @var{S})
-## Compute @code{f(@var{S})} for the non-zero values of @var{S}.
+## Compute @code{f(@var{S})} for the nonzero values of @var{S}.
 ## This results in a sparse matrix with the same structure as
 ## @var{S}.  The function @var{f} can be passed as a string, a
 ## function handle, or an inline function.
--- a/scripts/sparse/spones.m	Fri Aug 01 09:06:21 2014 -0400
+++ b/scripts/sparse/spones.m	Fri Aug 01 12:10:05 2014 -0400
@@ -18,7 +18,7 @@
 
 ## -*- texinfo -*-
 ## @deftypefn {Function File} {@var{r} =} spones (@var{S})
-## Replace the non-zero entries of @var{S} with ones.  This creates a
+## Replace the nonzero entries of @var{S} with ones.  This creates a
 ## sparse matrix with the same structure as @var{S}.
 ## @seealso{sparse, sprand, sprandn, sprandsym, spfun, spy}
 ## @end deftypefn
--- a/scripts/sparse/sprand.m	Fri Aug 01 09:06:21 2014 -0400
+++ b/scripts/sparse/sprand.m	Fri Aug 01 12:10:05 2014 -0400
@@ -21,15 +21,23 @@
 
 ## -*- texinfo -*-
 ## @deftypefn  {Function File} {} sprand (@var{m}, @var{n}, @var{d})
+## @deftypefnx {Function File} {} sprand (@var{m}, @var{n}, @var{d}, @var{rc})
 ## @deftypefnx {Function File} {} sprand (@var{s})
-## Generate a random sparse matrix.  The size of the matrix will be
-## @var{m}x@var{n}, with a density of values given by @var{d}.  @var{d} must
-## be between 0 and 1 inclusive.  Values will be uniformly distributed between
-## 0 and 1.
+## Generate a sparse matrix with uniformly distributed random values.
+##
+## The size of the matrix is @var{m}x@var{n} with a density of values @var{d}.
+## @var{d} must be between 0 and 1.  Values will be uniformly distributed on
+## the interval (0, 1).
 ##
-## If called with a single matrix argument, a random sparse matrix is
-## generated wherever the matrix @var{S} is non-zero.
-## @seealso{sprandn, sprandsym, spones, sparse}
+## If called with a single matrix argument, a sparse matrix is generated with
+## random values wherever the matrix @var{s} is nonzero.
+##
+## If called with a scalar fourth argument @var{rc}, a random sparse matrix
+## with reciprocal condition number @var{rc} is generated.  If @var{rc} is
+## a vector, then it specifies the first singular values of the generated
+## matrix (@code{length (@var{rc}) <= min (@var{m}, @var{n})}).
+##
+## @seealso{sprandn, sprandsym, rand}
 ## @end deftypefn
 
 ## Author: Paul Kienzle <pkienzle@users.sf.net>
@@ -42,12 +50,14 @@
 ## David Bateman
 ##      2004-10-20      Texinfo help and copyright message
 
-function S = sprand (m, n, d)
+function s = sprand (m, n, d, rc)
 
   if (nargin == 1 )
-    S = __sprand_impl__ (m, @rand);
+    s = __sprand_impl__ (m, @rand);
   elseif ( nargin == 3)
-    S = __sprand_impl__ (m, n, d, "sprand", @rand);
+    s = __sprand_impl__ (m, n, d, "sprand", @rand);
+  elseif (nargin == 4)
+    s = __sprand_impl__ (m, n, d, rc, "sprand", @rand);
   else
     print_usage ();
   endif
@@ -55,11 +65,25 @@
 endfunction
 
 
+%% Test 3-input calling form
 %!test
 %! s = sprand (4, 10, 0.1);
 %! assert (size (s), [4, 10]);
 %! assert (nnz (s) / numel (s), 0.1);
 
+%% Test 4-input calling form
+%!test
+%! d = rand ();
+%! s1 = sprand (100, 100, d, 0.4);
+%! rc = [5, 4, 3, 2, 1, 0.1];
+%! s2 = sprand (100, 100, d, rc);
+%! s3 = sprand (6, 4, d, rc);
+%! assert (svd (s2)'(1:length (rc)), rc, sqrt (eps)); 
+%! assert (1/cond (s1), 0.4, sqrt (eps));
+%! assert (nnz (s1) / (100*100), d, 0.02);
+%! assert (nnz (s2) / (100*100), d, 0.02); 
+%! assert (svd (s3)', [5 4 3 2], sqrt (eps));
+
 %% Test 1-input calling form
 %!test
 %! s = sprand (sparse ([1 2 3], [3 2 3], [2 2 2]));
@@ -72,16 +96,19 @@
 %!error sprand ()
 %!error sprand (1, 2)
 %!error sprand (1, 2, 3, 4)
-%!error sprand (ones (3), 3, 0.5)
-%!error sprand (3.5, 3, 0.5)
-%!error sprand (0, 3, 0.5)
-%!error sprand (3, ones (3), 0.5)
-%!error sprand (3, 3.5, 0.5)
-%!error sprand (3, 0, 0.5)
-%!error sprand (3, 3, -1)
-%!error sprand (3, 3, 2)
+%!error <M must be an integer greater than 0> sprand (ones (3), 3, 0.5)
+%!error <M must be an integer greater than 0> sprand (3.5, 3, 0.5)
+%!error <M must be an integer greater than 0> sprand (0, 3, 0.5)
+%!error <N must be an integer greater than 0> sprand (3, ones (3), 0.5)
+%!error <N must be an integer greater than 0> sprand (3, 3.5, 0.5)
+%!error <N must be an integer greater than 0> sprand (3, 0, 0.5)
+%!error <D must be between 0 and 1> sprand (3, 3, -1)
+%!error <D must be between 0 and 1> sprand (3, 3, 2)
+%!error <RC must be a scalar or vector> sprand (2, 2, 0.2, ones (3,3))
+%!error <RC must be between 0 and 1> sprand (2, 2, 0.2, -1)
+%!error <RC must be between 0 and 1> sprand (2, 2, 0.2, 2)
 
 %% Test very large, very low density matrix doesn't fail 
 %!test
-%! s = sprand(1e6,1e6,1e-7);
+%! s = sprand (1e6, 1e6, 1e-7);
 
--- a/scripts/sparse/sprandn.m	Fri Aug 01 09:06:21 2014 -0400
+++ b/scripts/sparse/sprandn.m	Fri Aug 01 12:10:05 2014 -0400
@@ -21,25 +21,35 @@
 
 ## -*- texinfo -*-
 ## @deftypefn  {Function File} {} sprandn (@var{m}, @var{n}, @var{d})
+## @deftypefnx {Function File} {} sprandn (@var{m}, @var{n}, @var{d}, @var{rc})
 ## @deftypefnx {Function File} {} sprandn (@var{s})
-## Generate a random sparse matrix.  The size of the matrix will be
-## @var{m}x@var{n}, with a density of values given by @var{d}.  @var{d} must be
-## between 0 and 1 inclusive.  Values will be normally distributed with a mean
-## of zero and a variance of 1.
+## Generate a sparse matrix with normally distributed random values.
+##
+## The size of the matrix is @var{m}x@var{n} with a density of values @var{d}.
+## @var{d} must be between 0 and 1.  Values will be normally distributed with a
+## mean of 0 and a variance of 1.
 ##
-## If called with a single matrix argument, a random sparse matrix is
-## generated wherever the matrix @var{S} is non-zero.
-## @seealso{sprand, sprandsym, spones, sparse}
+## If called with a single matrix argument, a sparse matrix is generated with
+## random values wherever the matrix @var{s} is nonzero.
+##
+## If called with a scalar fourth argument @var{rc}, a random sparse matrix
+## with reciprocal condition number @var{rc} is generated.  If @var{rc} is
+## a vector, then it specifies the first singular values of the generated
+## matrix (@code{length (@var{rc}) <= min (@var{m}, @var{n})}).
+## 
+## @seealso{sprand, sprandsym, randn}
 ## @end deftypefn
 
 ## Author: Paul Kienzle <pkienzle@users.sf.net>
 
-function S = sprandn (m, n, d)
+function s = sprandn (m, n, d, rc)
 
   if (nargin == 1 )
-    S = __sprand_impl__ (m, @randn);
+    s = __sprand_impl__ (m, @randn);
   elseif ( nargin == 3)
-    S = __sprand_impl__ (m, n, d, "sprandn", @randn);
+    s = __sprand_impl__ (m, n, d, "sprandn", @randn);
+  elseif (nargin == 4)
+    s = __sprand_impl__ (m, n, d, rc, "sprandn", @randn);
   else
     print_usage ();
   endif
@@ -47,11 +57,25 @@
 endfunction
 
 
+%% Test 3-input calling form
 %!test
 %! s = sprandn (4, 10, 0.1);
 %! assert (size (s), [4, 10]);
 %! assert (nnz (s) / numel (s), 0.1);
 
+%% Test 4-input calling form
+%!test
+%! d = rand ();
+%! s1 = sprandn (100, 100, d, 0.4);
+%! rc = [5, 4, 3, 2, 1, 0.1];
+%! s2 = sprandn (100, 100, d, rc);
+%! s3 = sprandn (6, 4, d, rc);
+%! assert (svd (s2)'(1:length (rc)), rc, sqrt (eps)); 
+%! assert (1/cond (s1), 0.4, sqrt (eps));
+%! assert (nnz (s1) / (100*100), d, 0.02); 
+%! assert (nnz (s2) / (100*100), d, 0.02); 
+%! assert (svd (s3)', [5 4 3 2], sqrt (eps));
+
 %% Test 1-input calling form
 %!test
 %! s = sprandn (sparse ([1 2 3], [3 2 3], [2 2 2]));
@@ -63,16 +87,19 @@
 %!error sprandn ()
 %!error sprandn (1, 2)
 %!error sprandn (1, 2, 3, 4)
-%!error sprandn (ones (3), 3, 0.5)
-%!error sprandn (3.5, 3, 0.5)
-%!error sprandn (0, 3, 0.5)
-%!error sprandn (3, ones (3), 0.5)
-%!error sprandn (3, 3.5, 0.5)
-%!error sprandn (3, 0, 0.5)
-%!error sprandn (3, 3, -1)
-%!error sprandn (3, 3, 2)
+%!error <M must be an integer greater than 0> sprandn (ones (3), 3, 0.5)
+%!error <M must be an integer greater than 0> sprandn (3.5, 3, 0.5)
+%!error <M must be an integer greater than 0> sprandn (0, 3, 0.5)
+%!error <N must be an integer greater than 0> sprandn (3, ones (3), 0.5)
+%!error <N must be an integer greater than 0> sprandn (3, 3.5, 0.5)
+%!error <N must be an integer greater than 0> sprandn (3, 0, 0.5)
+%!error <D must be between 0 and 1> sprandn (3, 3, -1)
+%!error <D must be between 0 and 1> sprandn (3, 3, 2)
+%!error <RC must be a scalar or vector> sprandn (2, 2, 0.2, ones (3,3))
+%!error <RC must be between 0 and 1> sprandn (2, 2, 0.2, -1)
+%!error <RC must be between 0 and 1> sprandn (2, 2, 0.2, 2)
 
 %% Test very large, very low density matrix doesn't fail 
 %!test
-%! s = sprandn(1e6,1e6,1e-7);
+%! s = sprandn (1e6,1e6,1e-7);
 
--- a/scripts/sparse/sprandsym.m	Fri Aug 01 09:06:21 2014 -0400
+++ b/scripts/sparse/sprandsym.m	Fri Aug 01 12:10:05 2014 -0400
@@ -27,7 +27,7 @@
 ## be normally distributed with a mean of zero and a variance of 1.
 ##
 ## If called with a single matrix argument, a random sparse matrix is generated
-## wherever the matrix @var{S} is non-zero in its lower triangular part.
+## wherever the matrix @var{S} is nonzero in its lower triangular part.
 ## @seealso{sprand, sprandn, spones, sparse}
 ## @end deftypefn
 
--- a/scripts/sparse/spstats.m	Fri Aug 01 09:06:21 2014 -0400
+++ b/scripts/sparse/spstats.m	Fri Aug 01 12:10:05 2014 -0400
@@ -19,10 +19,10 @@
 ## -*- texinfo -*-
 ## @deftypefn  {Function File} {[@var{count}, @var{mean}, @var{var}] =} spstats (@var{S})
 ## @deftypefnx {Function File} {[@var{count}, @var{mean}, @var{var}] =} spstats (@var{S}, @var{j})
-## Return the stats for the non-zero elements of the sparse matrix @var{S}.
-## @var{count} is the number of non-zeros in each column, @var{mean}
-## is the mean of the non-zeros in each column, and @var{var} is the
-## variance of the non-zeros in each column.
+## Return the stats for the nonzero elements of the sparse matrix @var{S}.
+## @var{count} is the number of nonzeros in each column, @var{mean}
+## is the mean of the nonzeros in each column, and @var{var} is the
+## variance of the nonzeros in each column.
 ##
 ## Called with two input arguments, if @var{S} is the data and @var{j}
 ## is the bin number for the data, compute the stats for each bin.  In
@@ -50,7 +50,7 @@
     mean = sum (S) ./ count;
   endif
   if (nargout > 2)
-    ## FIXME Variance with count = 0 or 1?
+    ## FIXME: Variance with count = 0 or 1?
     diff = S - sparse (i, j, mean (j), n, m);
     var = sum (diff .* diff) ./ (count - 1);
   endif
--- a/scripts/sparse/svds.m	Fri Aug 01 09:06:21 2014 -0400
+++ b/scripts/sparse/svds.m	Fri Aug 01 12:10:05 2014 -0400
@@ -169,7 +169,7 @@
       ## The eigenvalues returns by eigs for sigma=0 are symmetric about 0.
       ## As we are only interested in the positive eigenvalues, we have to
       ## double k and then throw out the k negative eigenvalues.
-      ## Separately, if sigma is non-zero, but smaller than the smallest
+      ## Separately, if sigma is nonzero, but smaller than the smallest
       ## singular value, ARPACK may not return k eigenvalues. However, as
       ## computation scales with k we'd like to avoid doubling k for all
       ## scalar values of sigma.
--- a/scripts/sparse/treeplot.m	Fri Aug 01 09:06:21 2014 -0400
+++ b/scripts/sparse/treeplot.m	Fri Aug 01 12:10:05 2014 -0400
@@ -156,9 +156,9 @@
   ## of most left and most right descendants).
   x_coordinate = (x_coordinate_l + x_coordinate_r) / 2;
 
-  ## FIXME -- we should probably stuff all the arguments into a cell
-  ## array and make a single call to plot here so we can avoid
-  ## setting the hold state...
+  ## FIXME: We should probably stuff all the arguments into a cell
+  ##        array and make a single call to plot here so we can avoid
+  ##        setting the hold state...
 
   hold_is_on = ishold ();
   unwind_protect
--- a/scripts/specfun/nchoosek.m	Fri Aug 01 09:06:21 2014 -0400
+++ b/scripts/specfun/nchoosek.m	Fri Aug 01 12:10:05 2014 -0400
@@ -109,7 +109,7 @@
       warning ("nchoosek", "nchoosek: possible loss of precision");
     endif
   elseif (k == 0)
-    A = [];
+    A = zeros (1,0);
   elseif (k == 1)
     A = v(:);
   elseif (k == n)
@@ -142,6 +142,7 @@
 
 %!assert (nchoosek (80,10), bincoeff (80,10))
 %!assert (nchoosek (1:5,3), [1:3;1,2,4;1,2,5;1,3,4;1,3,5;1,4,5;2:4;2,3,5;2,4,5;3:5])
+%!assert (size (nchoosek (1:5,0)), [1 0])
 
 %% Test input validation
 %!warning nchoosek (100,45);
--- a/scripts/special-matrix/gallery.m	Fri Aug 01 09:06:21 2014 -0400
+++ b/scripts/special-matrix/gallery.m	Fri Aug 01 12:10:05 2014 -0400
@@ -1214,9 +1214,9 @@
   elseif (! isnumeric (n) || ! isscalar (n) || fix (n) != n)
     error ("gallery: N must be an integer for gearmat matrix.");
   elseif (! isnumeric (i) || ! isscalar (i) || i == 0 || abs (i) <= n)
-    error ("gallery: I must be a non-zero scalar, and abs (I) <= N for gearmat matrix.");
+    error ("gallery: I must be a nonzero scalar, and abs (I) <= N for gearmat matrix.");
   elseif (! isnumeric (j) || ! isscalar (j) || i == 0 || abs (j) <= n)
-    error ("gallery: J must be a non-zero scalar, and abs (J) <= N for gearmat matrix.");
+    error ("gallery: J must be a nonzero scalar, and abs (J) <= N for gearmat matrix.");
   endif
 
   A = diag (ones (n-1, 1), -1) + diag (ones (n-1, 1), 1);
@@ -2520,7 +2520,7 @@
   T = spdiags ([[x;0] y [0;z]], -1:1, n, n);
 endfunction
 
-function t = triw (n, alpha = -1, k = -1)
+function t = triw (n, alpha = -1, k = n(end) - 1)
   ## TRIW   Upper triangular matrix discussed by Wilkinson and others.
   ##        TRIW(N, ALPHA, K) is the upper triangular matrix with ones on
   ##        the diagonal and ALPHAs on the first K >= 0 superdiagonals.
@@ -2556,8 +2556,8 @@
     error ("gallery: N must be a 1 or 2 elements vector for triw matrix.");
   elseif (! isscalar (alpha))
     error ("gallery: ALPHA must be a scalar for triw matrix.");
-  elseif (! isscalar (k) || ! isnumeric (k) || fix (k) != k)
-    error ("gallery: K must be a numeric integer for triw matrix.");
+  elseif (! isscalar (k) || ! isnumeric (k) || fix (k) != k || k < 0)
+    error ("gallery: K must be a numeric integer >= 0 for triw matrix.");
   endif
 
   m = n(1);              # Parameter n specifies dimension: m-by-n.
--- a/scripts/statistics/base/moment.m	Fri Aug 01 09:06:21 2014 -0400
+++ b/scripts/statistics/base/moment.m	Fri Aug 01 12:10:05 2014 -0400
@@ -103,6 +103,7 @@
 ##
 ## @end ifnottex
 ## @end table
+##
 ## If the optional argument @var{dim} is given, operate along this dimension.
 ##
 ## If both @var{type} and @var{dim} are given they may appear in any order.
--- a/scripts/statistics/base/prctile.m	Fri Aug 01 09:06:21 2014 -0400
+++ b/scripts/statistics/base/prctile.m	Fri Aug 01 12:10:05 2014 -0400
@@ -30,10 +30,8 @@
 ##
 ## If @var{p} is unspecified, return the quantiles for @code{[0 25 50 75 100]}.
 ## The optional argument @var{dim} determines the dimension along which
-## the percentiles are calculated.  If @var{dim} is omitted, and @var{x} is
-## a vector or matrix, it defaults to 1 (column-wise quantiles).  When
-## @var{x} is an N-D array, @var{dim} defaults to the first non-singleton
-## dimension.
+## the percentiles are calculated.  If @var{dim} is omitted it defaults to the
+## the first non-singleton dimension.
 ## @seealso{quantile}
 ## @end deftypefn
 
@@ -59,14 +57,10 @@
   endif
 
   nd = ndims (x);
+  sz = size (x);
   if (nargin < 3)
-    if (nd == 2)
-      ## If a matrix or vector, always use 1st dimension.
-      dim = 1;
-    else
-      ## If an N-d array, find the first non-singleton dimension.
-      (dim = find (sz > 1, 1)) || (dim = 1);
-    endif
+    ## Find the first non-singleton dimension.
+    (dim = find (sz > 1, 1)) || (dim = 1);
   else
     if (!(isscalar (dim) && dim == fix (dim))
         || !(1 <= dim && dim <= nd))
@@ -84,11 +78,26 @@
 
 %!test
 %! pct = 50;
+%! q = prctile (1:4, pct);
+%! qa = 2.5;
+%! assert (q, qa);
 %! q = prctile (1:4, pct, 1);
 %! qa = [1, 2, 3, 4];
 %! assert (q, qa);
 %! q = prctile (1:4, pct, 2);
-%! qa = 2.5000;
+%! qa = 2.5;
+%! assert (q, qa);
+
+%!test
+%! pct = [50 75];
+%! q = prctile (1:4, pct);
+%! qa = [2.5 3.5];
+%! assert (q, qa);
+%! q = prctile (1:4, pct, 1);
+%! qa = [1, 2, 3, 4; 1, 2, 3, 4];
+%! assert (q, qa);
+%! q = prctile (1:4, pct, 2);
+%! qa = [2.5 3.5];
 %! assert (q, qa);
 
 %!test
--- a/scripts/statistics/base/qqplot.m	Fri Aug 01 09:06:21 2014 -0400
+++ b/scripts/statistics/base/qqplot.m	Fri Aug 01 12:10:05 2014 -0400
@@ -62,7 +62,7 @@
     print_usage ();
   endif
 
-  if (!(isnumeric (x) && isvector (x)))
+  if (! (isnumeric (x) && isvector (x)))
     error ("qqplot: X must be a numeric vector");
   endif
 
@@ -97,7 +97,7 @@
   endif
 
   if (nargout == 0)
-    plot (q, s);
+    plot (q, s, "-x");
     q_label = strrep (q_label, '_inv', '\_inv');
     if (q_label(1) == '@')
       q_label = q_label(6:end);  # Strip "@(y) " from anon. function
@@ -111,4 +111,3 @@
 
 endfunction
 
-
--- a/scripts/statistics/base/quantile.m	Fri Aug 01 09:06:21 2014 -0400
+++ b/scripts/statistics/base/quantile.m	Fri Aug 01 12:10:05 2014 -0400
@@ -32,10 +32,8 @@
 ## If @var{p} is unspecified, return the quantiles for
 ## @code{[0.00 0.25 0.50 0.75 1.00]}.
 ## The optional argument @var{dim} determines the dimension along which
-## the quantiles are calculated.  If @var{dim} is omitted, and @var{x} is
-## a vector or matrix, it defaults to 1 (column-wise quantiles).  If
-## @var{x} is an N-D array, @var{dim} defaults to the first non-singleton
-## dimension.
+## the quantiles are calculated.  If @var{dim} is omitted it defaults to
+## the first non-singleton dimension.
 ##
 ## The methods available to calculate sample quantiles are the nine methods
 ## used by R (@url{http://www.r-project.org/}).  The default value is
@@ -108,7 +106,7 @@
 ## Author: Ben Abbott <bpabbott@mac.com>
 ## Description: Matlab style quantile function of a discrete/continuous distribution
 
-function q = quantile (x, p = [], dim = 1, method = 5)
+function q = quantile (x, p = [], dim, method = 5)
 
   if (nargin < 1 || nargin > 4)
     print_usage ();
@@ -126,9 +124,14 @@
     error ("quantile: P must be a numeric vector");
   endif
 
-  if (!(isscalar (dim) && dim == fix (dim))
-      || !(1 <= dim && dim <= ndims (x)))
-    error ("quantile: DIM must be an integer and a valid dimension");
+  if (nargin < 3)
+    ## Find the first non-singleton dimension.
+    (dim = find (size (x) > 1, 1)) || (dim = 1);
+  else
+    if (!(isscalar (dim) && dim == fix (dim))
+        || !(1 <= dim && dim <= ndims (x)))
+      error ("quantile: DIM must be an integer and a valid dimension");
+    endif
   endif
 
   ## Set the permutation vector.
@@ -158,6 +161,30 @@
 
 
 %!test
+%! p = 0.50;
+%! q = quantile (1:4, p);
+%! qa = 2.5;
+%! assert (q, qa);
+%! q = quantile (1:4, p, 1);
+%! qa = [1, 2, 3, 4];
+%! assert (q, qa);
+%! q = quantile (1:4, p, 2);
+%! qa = 2.5;
+%! assert (q, qa);
+
+%!test
+%! p = [0.50 0.75];
+%! q = quantile (1:4, p);
+%! qa = [2.5 3.5];
+%! assert (q, qa);
+%! q = quantile (1:4, p, 1);
+%! qa = [1, 2, 3, 4; 1, 2, 3, 4];
+%! assert (q, qa);
+%! q = quantile (1:4, p, 2);
+%! qa = [2.5 3.5];
+%! assert (q, qa);
+
+%!test
 %! p = 0.5;
 %! x = sort (rand (11));
 %! q = quantile (x, p);
--- a/scripts/statistics/distributions/empirical_pdf.m	Fri Aug 01 09:06:21 2014 -0400
+++ b/scripts/statistics/distributions/empirical_pdf.m	Fri Aug 01 12:10:05 2014 -0400
@@ -37,7 +37,16 @@
     error ("empirical_pdf: DATA must be a vector");
   endif
 
-  pdf = discrete_pdf (x, data, ones (size (data)));
+  uniq_vals = unique (data);
+  if (numel (data) != numel (uniq_vals))
+    ## Handle ties, multiple elements with same value
+    p = histc (data, uniq_vals);
+    data = uniq_vals;
+  else
+    p = ones (size (data));
+  endif
+
+  pdf = discrete_pdf (x, data, p);
 
 endfunction
 
@@ -52,6 +61,9 @@
 %!assert (empirical_pdf (single (x), v), single (y))
 %!assert (empirical_pdf (x, single (v)), single (y))
 
+%% Test distribution with ties
+%!assert (empirical_pdf (2, [1 2 3 2]), 0.5)
+
 %% Test input validation
 %!error empirical_pdf ()
 %!error empirical_pdf (1)
--- a/scripts/statistics/distributions/normrnd.m	Fri Aug 01 09:06:21 2014 -0400
+++ b/scripts/statistics/distributions/normrnd.m	Fri Aug 01 12:10:05 2014 -0400
@@ -83,7 +83,7 @@
   endif
 
   if (isscalar (mu) && isscalar (sigma))
-    if (isfinite (mu) && (sigma > 0) && (sigma < Inf))
+    if (isfinite (mu) && (sigma >= 0) && (sigma < Inf))
       rnd =  mu + sigma * randn (sz, cls);
     else
       rnd = NaN (sz, cls);
--- a/scripts/statistics/tests/cor_test.m	Fri Aug 01 09:06:21 2014 -0400
+++ b/scripts/statistics/tests/cor_test.m	Fri Aug 01 12:10:05 2014 -0400
@@ -22,7 +22,7 @@
 ## populations.
 ##
 ## The optional argument string @var{alt} describes the alternative
-## hypothesis, and can be @qcode{"!="} or @qcode{"<>"} (non-zero),
+## hypothesis, and can be @qcode{"!="} or @qcode{"<>"} (nonzero),
 ## @qcode{">"} (greater than 0), or @qcode{"<"} (less than 0).  The
 ## default is the two-sided case.
 ##
--- a/scripts/statistics/tests/hotelling_test_2.m	Fri Aug 01 09:06:21 2014 -0400
+++ b/scripts/statistics/tests/hotelling_test_2.m	Fri Aug 01 12:10:05 2014 -0400
@@ -26,7 +26,7 @@
 ## Hotelling's two-sample @math{T^2} is returned in @var{tsq}.  Under the null,
 ## @tex
 ## $$
-## {n_x+n_y-p-1) T^2 \over p(n_x+n_y-2)}
+## {(n_x+n_y-p-1) T^2 \over p(n_x+n_y-2)}
 ## $$
 ## @end tex
 ## @ifnottex
--- a/scripts/strings/validatestring.m	Fri Aug 01 09:06:21 2014 -0400
+++ b/scripts/strings/validatestring.m	Fri Aug 01 12:10:05 2014 -0400
@@ -100,22 +100,21 @@
   ## Make static part of error string that uses funcname, varname, and position
   errstr = "";
   if (! isempty (funcname))
-    errstr = sprintf ("Function: %s ", funcname);
+    errstr = [funcname ": "];
   endif
   if (! isempty (varname))
-    errstr = sprintf ("%sVariable: %s ", errstr, varname);
+    errstr = [errstr varname " "];
+  else
+    errstr = sprintf ("%s'%s' ", errstr, str);
   endif
   if (position > 0)
-    errstr = sprintf ("%sArgument position %d ", errstr, position);
-  endif
-  if (! isempty (errstr))
-    errstr(end:end+1) = ":\n";
+    errstr = sprintf ("%s(argument #%i) ", errstr, position);
   endif
 
   matches = strncmpi (str, strarray(:), length (str));
   nmatches = sum (matches);
   if (nmatches == 0)
-    error ("validatestring: %s'%s' does not match any of\n%s", errstr, str,
+    error ("%sdoes not match any of\n%s", errstr,
            sprintf ("%s, ", strarray{:})(1:end-2));
   elseif (nmatches == 1)
     str = strarray{matches};
@@ -130,8 +129,8 @@
     if (all (submatch))
       str = short_str;
     else
-      error ("validatestring: %smultiple unique matches were found for '%s':\n%s",
-             errstr, str, sprintf ("%s, ", strarray{match_idx})(1:end-2));
+      error ("%sallows multiple unique matches:\n%s",
+             errstr, sprintf ("%s, ", strarray{match_idx})(1:end-2));
     endif
   endif
 
@@ -147,10 +146,10 @@
 %!assert (validatestring ("d", strarray), "def")
 
 %!error <'xyz' does not match any> validatestring ("xyz", strarray)
-%!error <Function: DUMMY_TEST> validatestring ("xyz", strarray, "DUMMY_TEST")
-%!error <Function: DUMMY_TEST Variable: DUMMY_VAR:> validatestring ("xyz", strarray, "DUMMY_TEST", "DUMMY_VAR")
-%!error <Function: DUMMY_TEST Variable: DUMMY_VAR Argument position 5> validatestring ("xyz", strarray, "DUMMY_TEST", "DUMMY_VAR", 5)
-%!error <multiple unique matches were found for 'abc'> validatestring ("abc", strarray)
+%!error <DUMMY_TEST: 'xyz' does not> validatestring ("xyz", strarray, "DUMMY_TEST")
+%!error <DUMMY_TEST: DUMMY_VAR does> validatestring ("xyz", strarray, "DUMMY_TEST", "DUMMY_VAR")
+%!error <DUMMY_TEST: DUMMY_VAR \(argument #5\) does> validatestring ("xyz", strarray, "DUMMY_TEST", "DUMMY_VAR", 5)
+%!error <'abc' allows multiple unique matches> validatestring ("abc", strarray)
 
 %% Test input validation
 %!error validatestring ("xyz")
--- a/scripts/testfun/__run_test_suite__.m	Fri Aug 01 09:06:21 2014 -0400
+++ b/scripts/testfun/__run_test_suite__.m	Fri Aug 01 12:10:05 2014 -0400
@@ -66,7 +66,7 @@
       dsk += sk;
     endfor
     puts ("\nSummary:\n\n");
-    nfail = dn - dp;
+    nfail = dn - dp - dxf;
     printf ("  PASS    %6d\n", dp);
     printf ("  FAIL    %6d\n", nfail);
     if (dxf > 0)
@@ -116,16 +116,22 @@
 endfunction
 
 function print_test_file_name (nm)
-  filler = repmat (".", 1, 55-length (nm));
+  filler = repmat (".", 1, 60-length (nm));
   printf ("  %s %s", nm, filler);
 endfunction
 
-function print_pass_fail (n, p)
-  if (n > 0)
-    printf (" PASS %4d/%-4d", p, n);
-    nfail = n - p;
+function print_pass_fail (p, n, xf, sk)
+  if ((n + sk) > 0)
+    printf (" PASS   %4d/%-4d", p, n);
+    nfail = n - p - xf;
     if (nfail > 0)
-      printf (" FAIL %d", nfail);
+      printf ("\n%71s %3d", "FAIL ", nfail);
+    endif    
+    if (sk > 0)
+      printf ("\n%71s %3d", "SKIP ", sk);
+    endif
+    if (xf > 0)
+      printf ("\n%71s %3d", "XFAIL", xf);
     endif
   endif
   puts ("\n");
@@ -190,7 +196,7 @@
         if (has_tests (ffnm))
           print_test_file_name (nm);
           [p, n, xf, sk] = test (nm, "quiet", fid);
-          print_pass_fail (n, p);
+          print_pass_fail (p, n, xf, sk);
           files_with_tests(end+1) = ffnm;
         else
           files_with_no_tests(end+1) = ffnm;
@@ -241,7 +247,7 @@
         tmp = strrep (tmp, [topbuilddir, filesep], "");
         print_test_file_name (tmp);
         [p, n, xf, sk] = test (f, "quiet", fid);
-        print_pass_fail (n, p);
+        print_pass_fail (p, n, xf, sk);
         dp += p;
         dn += n;
         dxf += xf;
--- a/scripts/testfun/assert.m	Fri Aug 01 09:06:21 2014 -0400
+++ b/scripts/testfun/assert.m	Fri Aug 01 12:10:05 2014 -0400
@@ -162,7 +162,7 @@
           err.reason{end+1} = ["Expected struct, but observed " class(cond)];
         elseif (ndims (cond) != ndims (expected)
                 || any (size (cond) != size (expected))
-                || rows (fieldnames (cond)) != rows (fieldnames (expected)))
+                || numfields (cond) != numfields (expected))
 
           err.index{end+1} = ".";
           err.observed{end+1} = ["O(" sprintf("%dx", size(cond))(1:end-1) ")"];
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/testfun/private/compare_plot_demos.m	Fri Aug 01 12:10:05 2014 -0400
@@ -0,0 +1,119 @@
+## Copyright (C) 2012 Ben Abbott  <bpabbott@mac.com>
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn  {Function File} {} compare_plot_demos ()
+## @deftypefnx {Function File} {} compare_plot_demos ("toolkits", @{@var{toolkit1}, @var{toolkit2}, @dots{}@})
+##
+## Uses @code{dump_demos} and @code{html_compare_plot_demos} to produce an
+## html comparison of the plot demos for each of Octave's graphics toolkits.
+##
+## An m-file named @file{dump_plots.m} will be created in the current working
+## directory. This function will be used to render and save the plot demo
+## images.
+##
+## If they do not already exist, directories for each available graphics
+## toolkit are created.  Each toolkit's directory will be populated with images
+## of each plot demo in the png format.
+##
+## Finally, an html document named @file{compare_plot_demos.html} is produced.
+## This page places each toolkit's images side by side for a convenient
+## comparison of the results.
+##
+## If the property @qcode{"toolkits"} is given then compare only the listed
+## toolkits in the cell string.  The list may also include the toolkit
+## @qcode{"matlab"}.
+##
+## @end deftypefn
+
+## Author: Ben Abbott  <bpabbott@mac.com>
+
+function compare_plot_demos (varargin)
+
+  arg.toolkits = available_graphics_toolkits ();
+  arg.directories = {"plot/appearance", "plot/draw", "plot/util", "image"};
+  arg.fmt = "png";
+  arg.fcn_file = "dump_plot_demos.m";
+  arg.replace_images = false;
+
+  for n = 1:2:numel(varargin)
+    if (! ischar (varargin{n}))
+      print_usage ();
+    else
+      arg.(varargin{n}) = varargin{n+1};
+    endif
+  endfor
+
+  if (ischar (arg.toolkits))
+    arg.toolkits = {arg.toolkits};
+  elseif (! iscellstr (arg.toolkits))
+    error ('compare_plot_demos: Invalid value for "toolkits"')
+  endif
+
+  if (ischar (arg.directories))
+    arg.directories = {arg.directories};
+  elseif (! iscellstr (arg.directories))
+    error ('compare_plot_demos: Invalid value for "directory"')
+  endif
+
+  if (! ischar (arg.fmt))
+    error ('compare_plot_demos: Invalid value for "fmt"')
+  endif
+
+  ## Generate arg.fcn_file for rendering/saving the plot demo images
+  dump_demos (arg.directories, arg.fcn_file, arg.fmt);
+
+  [~, fcn_name] = fileparts (arg.fcn_file);
+
+  ## Generate the plot demo images for each toolkit
+  cwd = pwd ();
+  unwind_protect
+    addpath (pwd);
+    for n = 1:numel (arg.toolkits)
+      if (! isdir (fullfile (cwd, arg.toolkits{n})))
+        mkdir (arg.toolkits{n});
+      endif
+      cd (arg.toolkits{n});
+      if (arg.replace_images && ! isempty (dir (["*." arg.fmt])))
+        delete (["*." arg.fmt]);
+      endif
+      if (! strcmp (arg.toolkits{n}, "matlab"))
+        close all;
+        graphics_toolkit (arg.toolkits{n});
+        try
+          eval (fcn_name);
+        catch
+          printf ("Error running plot demos for ""%s"" toolkit\n", arg.toolkits{n});
+          disp (lasterror);
+        end_try_catch
+      endif
+      cd (cwd);
+    endfor
+  unwind_protect_cleanup
+    rmpath (cwd);
+  end_unwind_protect
+  if (! strcmp (arg.toolkits, "matlab"))
+    ## Generate the html comparison of the images
+    html_compare_plot_demos (arg.toolkits);
+  else
+    ## We need to run matlab manually before the html page can be created
+    printf ('\nNow run %s in Matlab.\nAfter this run html_compare_plot_demos,\n', arg.fcn_file);
+    printf ('for example html_compare_plot_demos ({"fltk", "gnuplot", "matlab"}), to create the html page.\n');
+  endif
+endfunction
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/testfun/private/dump_demos.m	Fri Aug 01 12:10:05 2014 -0400
@@ -0,0 +1,185 @@
+## Copyright (C) 2010 Søren Hauberg
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn  {Function File} {} dump_demos ()
+## @deftypefnx {Function File} {} dump_demos (@var{dirs})
+## @deftypefnx {Function File} {} dump_demos (@var{dirs}, @var{mfile})
+## @deftypefnx {Function File} {} dump_demos (@var{dirs}, @var{mfile}, @var{fmt})
+## Produce a script, with the name specified by @var{mfile}, containing
+## the demos in the directories, @var{dirs}.  The demos are assumed to produce
+## graphical output, whose renderings are saved with the specified format,
+## @var{fmt}.
+##
+## The defaults for each input are;
+##
+## @table @var
+##   @item @var{dirs}
+##   @code{@{"plot/appearance", "plot/draw", "plot/util", "image"@}}
+##   @item @var{mfile}
+##   @code{"dump.m"}
+##   @item @var{fmt}
+##   @code{"png"}
+## @end table
+##
+## For example, to produce PNG output for all demos of the functions
+## in the plot directory;
+##
+## @example
+## dump_demos plot dump.m png
+## @end example
+## @seealso{fntests, test, demo}
+## @end deftypefn
+
+## Author: Søren Hauberg  <soren@hauberg.org>
+
+function dump_demos (dirs={"plot/appearance", "plot/draw", "plot/util", "image"}, output="dump_plot_demos.m", fmt="png")
+
+  if (nargin > 3)
+    print_usage ();
+  endif
+
+  if (ischar (dirs))
+    dirs = {dirs};
+  elseif (! iscellstr (dirs))
+    error ("dump_demos: DIRS must be a cell array of strings with directory names");
+  endif
+
+  [~, funcname, ext] = fileparts (output);
+  if (isempty (ext))
+    output = [output ".m"];
+  endif
+
+  ## Create script beginning (close figures, etc.)
+  fid = fopen (output, "w");
+  fprintf (fid, "%% DO NOT EDIT!  Generated automatically by dump_demos.m\n");
+  fprintf (fid, "function %s ()\n", funcname);
+  fprintf (fid, "close all\n");
+  fprintf (fid, "more off\n");
+  fprintf (fid, "diary diary.log\n");
+
+  ## Run and print the demos in each directory
+  for i = 1:numel (dirs)
+    d = dirs{i};
+    if (! is_absolute_filename (d))
+      d = dir_in_loadpath (d);
+    endif
+    if (! exist (d, "dir"))
+      error ("dump_demos: directory %s does not exist", d);
+    endif
+    dump_all_demos (d, fid, fmt);
+  endfor
+
+  ## Stop and flush diary
+  fprintf (fid, "diary off\n");
+
+  ## Create script ending
+  fprintf (fid, "end\n\n")
+
+  ## Close script
+  fclose (fid);
+endfunction
+
+function dump_all_demos (directory, fid, fmt)
+  dirinfo = dir (fullfile (directory, "*.m"));
+  flist = {dirinfo.name};
+  ## Remove uigetdir, uigetfile, uiputfile, etc.
+  flist = flist(! strncmp (flist, "ui", 2));
+  ## Remove linkaxes, linkprops
+  flist = flist(! strncmp (flist, "link", 4));
+  ## Remove colormap
+  flist = flist(! strncmp (flist, "colormap", 8));
+  for i = 1:numel (flist)
+    fcn = flist{i};
+    fcn(end-1:end) = [];  # remove .m
+    demos = get_demos (fcn);
+    for d = 1:numel (demos)
+      idx = sprintf ("%02d", d);
+      base_fn = sprintf ("%s_%s", fcn, idx);
+      fn = sprintf ('%s.%s', base_fn, fmt);
+      fprintf (fid, "\ntry\n");
+      ## First check if the file already exists, skip demo if found
+      fprintf (fid, " if (! exist ('%s', 'file'))\n", fn);
+      ## Invoke the ancient, deprecated random seed
+      ## generators, but there is an initialization mismatch with the more modern
+      ## generators reported here (https://savannah.gnu.org/bugs/?42557).
+      fprintf (fid, "  rand ('seed', 1);\n");
+      fprintf (fid, "  tic ();\n");
+      fprintf (fid, "  %s\n\n", demos{d});
+      fprintf (fid, "  t_plot = toc ();\n");
+      fprintf (fid, "  fig = (get (0, 'currentfigure'));\n");
+      fprintf (fid, "  if (~ isempty (fig))\n");
+      fprintf (fid, "    figure (fig);\n");
+      fprintf (fid, "      fprintf ('Printing ""%s"" ... ');\n", fn);
+      fprintf (fid, "      tic ();\n");
+      fprintf (fid, "      print ('-d%s', '%s');\n", fmt, fn);
+      fprintf (fid, "      t_print = toc ();\n");
+      fprintf (fid, "      fprintf ('[%%f %%f] done\\n',t_plot, t_print);\n");
+      fprintf (fid, "  end\n");
+      # Temporary fix for cruft accumulating in figure window.
+      fprintf (fid, "  close ('all');\n");
+      fprintf (fid, " else\n");
+      fprintf (fid, "   fprintf ('File ""%s"" already exists.\\n');\n", fn);
+      fprintf (fid, " end\n");
+      fprintf (fid, "catch\n");
+      fprintf (fid, "  fprintf ('ERROR in %s: %%s\\n', lasterr ());\n", base_fn);
+      fprintf (fid, "  err_fid = fopen ('%s.err', 'w');\n", base_fn);
+      fprintf (fid, "  fprintf (err_fid, '%%s', lasterr ());\n");
+      fprintf (fid, "  fclose (err_fid);\n");
+      fprintf (fid, "end\n\n");
+    endfor
+  endfor
+  fprintf (fid, "close all\n");
+endfunction
+
+function retval = get_demos (fcn)
+  [code, idx] = test (fcn, "grabdemo");
+  num_demos = length (idx) - 1;
+  retval = cell (1, num_demos);
+  ## Now split the demos into a cell array
+  for k = 1:num_demos
+    retval{k} = oct2mat (code(idx(k):idx(k+1)-1));
+  endfor
+endfunction
+
+function code = oct2mat (code)
+  ## Simple hacks to make things Matlab compatible
+  code = strrep (code, "%!", "%%");
+  code = strrep (code, "!", "~");
+  ## Simply replacing double quotes with single quotes
+  ## causes problems with strings like 'hello "world"'
+  ## More complicated regexprep targets only full double quoted strings
+  code = regexprep (code, "^([^']*)\"(.*)\"", "$1'$2'",
+                          "lineanchors", "dotexceptnewline");
+  code = strrep (code, "#", "%");
+  ## Fix the format specs for the errorbar demos changed by the line above
+  code = strrep (code, "%r", "#r");
+  code = strrep (code, "%~", "#~");
+  endkeywords = {"endfor", "endfunction", "endif", "endwhile", "end_try_catch"};
+  for k = 1:numel (endkeywords)
+    code = strrep (code, endkeywords{k}, "end");
+  endfor
+  commentkeywords = {"unwind_protect", "end_unwind_protect"};
+  for k = 1:numel (commentkeywords)
+    code = strrep (code, commentkeywords{k}, ["%" commentkeywords{k}]);
+  endfor
+
+  ## Fix up sombrero which now has default argument in Octave
+  code = strrep (code, "sombrero ()", "sombrero (41)");
+endfunction
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/testfun/private/html_compare_plot_demos.m	Fri Aug 01 12:10:05 2014 -0400
@@ -0,0 +1,132 @@
+## Copyright (C) 2010 Ben Abbott
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn  {Function File} {} html_compare (@var{toolkits})
+## @deftypefnx {Function File} {} html_compare (@var{toolkits}, @var{name}, @var{value}, @dots{})
+##
+## Produces an html document to compare the plot demos produced by
+## @var{toolkits}.
+##
+## Valid property names, and their defaults, are:
+##
+## @table @samp
+##   @item fmt
+##   @code{"png"}
+##   @item output
+##   @code{"compare_plot_demos.html"}
+##   @item template
+##   @code{"html_plot_demos_template.html"}
+##   @item column_width
+##   @code{600}
+## @end table
+##
+## The template parameter refers to a specially formatted html file
+## which accompanies this m-file script.
+##
+## Additional toolkit description can be added to the column header
+## with a parameter named equal to the toolkit.  For example:
+##
+## @example
+## @group
+##   @code{html_compare_plot_demos ({"gnuplot", "fltk"}, "gnuplot", " 4.6 patchlevel 5")}
+## @end group
+## @end example
+##
+## @seealso{compare_plot_demos, dump_demos, demo}
+## @end deftypefn
+
+## Author: Ben Abbott  <bpabbott@mac.com>
+
+function html_compare_plot_demos (toolkits, varargin)
+
+  ## Set defaults
+  in.fmt = "png";
+  in.figfiles = {};
+  in.output= "compare_plot_demos.html";
+  in.template = "html_plot_demos_template.html";
+  in.column_width = 600;
+
+  ## Parse inputs
+  for n = 1:2:numel(varargin)
+    in.(lower(varargin{n})) = varargin{n+1};
+  endfor
+
+  ## Compile a list of all files for all toolkits
+  for t = 1:numel(toolkits)
+    filter = sprintf ("%s/*.%s", toolkits{t}, in.fmt);
+    in.figfiles = union (in.figfiles, {dir(filter).name});
+  endfor
+
+  fid = fopen (which (in.template), "r");
+  template = char (fread (fid)) .';
+  fclose (fid);
+
+  anchor = "<!-- ##ADD TABLE HERE## -->";
+  n = findstr (template, anchor);
+  header = template(1:n-1);
+  trailer = template(n+numel(anchor):end);
+
+  fid = fopen (in.output, "w");
+  unwind_protect
+    fputs (fid, header);
+    fprintf (fid, "<p><b>\nGenerated on %s by %s with GNU Octave %s</p>",
+             datestr (now (), 0), mfilename, version);
+
+    ## Create table header
+    fprintf (fid, "<table border='1'><tr>\n");
+    for t = 1:numel(toolkits)
+      ## set default
+      column_header = upper (toolkits{t});
+      if (isfield (in, toolkits{t}))
+        column_header = strcat (column_header, in.(toolkits{t}));
+      endif
+      fprintf (fid, '<th>%s <a href="%s/diary.log">diary</a></th>\n', column_header, toolkits{t});
+    endfor
+    fprintf (fid, "</tr>\n");
+
+    for m = 1:numel(in.figfiles)
+      [~, file] = fileparts (in.figfiles{m});
+      fn = strcat (file, ".", in.fmt);
+      fprintf (fid, "<tr>\n");
+      for k = toolkits
+        ffn = fullfile (k{:}, fn);
+        fprintf (fid, "  <td>%s<br>", ffn);
+        if (exist (ffn, "file"))
+          fprintf (fid, "<img src='%s' style='width: %dpx;'>", ffn, in.column_width);
+        else
+          err_fn = regexprep(ffn, ".png", ".err");
+          if (! exist (err_fn, "file"))
+            warning("File %s doesn't exist...", err_fn);
+          else
+            err_fid = fopen (err_fn);
+            msg = char (fread (err_fid))';
+            fclose (err_fid);
+            fprintf (fid, "%s", strrep (msg, "\n", "<br>"));
+          endif
+        endif
+        fprintf (fid, "</td>\n");
+      endfor
+      fprintf (fid, "</tr>\n");
+    endfor
+    fputs (fid, trailer);
+  unwind_protect_cleanup
+    fclose (fid);
+  end_unwind_protect
+
+endfunction
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/testfun/private/html_plot_demos_template.html	Fri Aug 01 12:10:05 2014 -0400
@@ -0,0 +1,62 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
+  <head>
+  <meta http-equiv="content-type" content="text/html; charset=iso-8859-1" />
+  <meta name="date" content="##DATE##"/>
+  <meta name="author" content="The Octave-Forge Community" />
+  <meta name="description" content="Octave-Forge is a collection of packages providing extra functionality for GNU Octave." />
+  <meta name="keywords" lang="en" content="Octave-Forge, Octave, extra packages" />
+  <title>Comparision of plots</title>
+
+  <link rel="stylesheet" type="text/css" href="../octave-forge.css" />
+  <script src="../fixed.js" type="text/javascript"></script>
+   <script src="../javascript.js" type="text/javascript"></script>
+  <link rel="shortcut icon" href="../favicon.ico" />
+  </head>
+  <body onload="javascript:fix_top_menu(); javascript:show_left_menu ();">
+  <div id="top-menu" class="menu">
+   <table class="menu">
+
+      <tr>
+        <td style="width: 90px;" class="menu" rowspan="2">
+          <a name="top">
+          <img src="../oct.png" alt="Octave logo" />
+          </a>
+        </td>
+        <td class="menu" style="padding-top: 0.9em;">
+          <big class="menu">Octave-Forge</big><small class="menu"> - Extra packages for GNU Octave</small>
+
+        </td>
+      </tr>
+      <tr>
+        <td class="menu">
+
+ <a href="../index.html" class="menu">Home</a> &middot;
+ <a href="../packages.php" class="menu">Packages</a> &middot;
+ <a href="../developers.html" class="menu">Developers</a> &middot;
+ <a href="../docs.html" class="menu">Documentation</a> &middot;
+ <a href="../FAQ.html" class="menu">FAQ</a> &middot;
+ <a href="../bugs.html" class="menu">Bugs</a> &middot;
+ <a href="../archive.html" class="menu">Mailing Lists</a> &middot;
+ <a href="../links.html" class="menu">Links</a> &middot;
+ <a href="http://sourceforge.net/svn/?group_id=2888" class="menu">SVN</a>
+
+        </td>
+      </tr>
+    </table>
+  </div>
+
+<div id="content">
+<!-- ##ADD TABLE HERE## -->
+</tr>
+</table>
+
+<div id="sf_logo">
+  <a href="http://sourceforge.net"><img src="http://sourceforge.net/sflogo.php?group_id=2888&amp;type=1"
+     width="88" height="31" style="border: 0;" alt="SourceForge.net Logo"/></a>
+</div>
+</div>
+</body>
+</html>
+
--- a/scripts/testfun/rundemos.m	Fri Aug 01 09:06:21 2014 -0400
+++ b/scripts/testfun/rundemos.m	Fri Aug 01 12:10:05 2014 -0400
@@ -42,7 +42,7 @@
       if (directory(end) == '/' || directory(end) == '\')
         directory(end) = [];
       endif
-      fullname = find_dir_in_path (directory);
+      fullname = dir_in_loadpath (directory);
       if (isempty (fullname))
         error ("rundemos: DIRECTORY argument must be a valid pathname");
       endif
--- a/scripts/testfun/runtests.m	Fri Aug 01 09:06:21 2014 -0400
+++ b/scripts/testfun/runtests.m	Fri Aug 01 12:10:05 2014 -0400
@@ -42,7 +42,7 @@
       if (directory(end) == '/' || directory(end) == '\')
         directory(end) = [];
       endif
-      fullname = find_dir_in_path (directory);
+      fullname = dir_in_loadpath (directory);
       if (isempty (fullname))
         error ("runtests: DIRECTORY argument must be a valid pathname");
       endif
--- a/scripts/testfun/test.m	Fri Aug 01 09:06:21 2014 -0400
+++ b/scripts/testfun/test.m	Fri Aug 01 12:10:05 2014 -0400
@@ -265,6 +265,7 @@
     ## Assume the block will succeed.
     __success = 1;
     __msg = [];
+    __isxtest = 0;
 
 ### DEMO
 
@@ -492,10 +493,17 @@
 
 ### TEST
 
-    elseif (strcmp (__type, "test") || strcmp (__type, "xtest"))
+    elseif (strcmp (__type, "test"))
       __istest = 1;
       ## Code will be evaluated below.
 
+### XTEST
+
+    elseif (strcmp (__type, "xtest"))
+      __istest = 0;
+      __isxtest = 1;
+      ## Code will be evaluated below.
+
 ### Comment block.
 
     elseif (strcmp (__block(1:1), "#"))
@@ -529,6 +537,7 @@
         if (strcmp (__type, "xtest"))
            __msg = sprintf ("%sknown failure\n%s", __signal_fail, lasterr ());
            __xfail++;
+           __success = 0;
         else
            __msg = sprintf ("%stest failed\n%s", __signal_fail, lasterr ());
            __success = 0;
@@ -558,7 +567,7 @@
         fflush (__fid);
       endif
     endif
-    if (__success == 0)
+    if (__success == 0 && !__isxtest)
       __all_success = 0;
       ## Stop after one error if not in batch mode.
       if (! __batch)
@@ -571,8 +580,8 @@
         return;
       endif
     endif
-    __tests += __istest;
-    __successes += __success * __istest;
+    __tests += (__istest || __isxtest);
+    __successes += __success * (__istest || __isxtest);
   endfor
   ## Clear any test functions created
   eval (__clear, "");
@@ -711,7 +720,7 @@
 %!demo  toeplitz ([1,2,3,4],[1,5,6])
 
 ### example from kron
-%!#error kron  # FIXME suppress these until we can handle output
+%!#error kron  # FIXME: suppress these until we can handle output
 %!#error kron(1,2,3)
 %!test assert (isempty (kron ([], rand (3, 4))))
 %!test assert (isempty (kron (rand (3, 4), [])))
--- a/scripts/time/datestr.m	Fri Aug 01 09:06:21 2014 -0400
+++ b/scripts/time/datestr.m	Fri Aug 01 12:10:05 2014 -0400
@@ -252,7 +252,8 @@
 
     df = regexprep (df, '[Ss][Ss]', "%S");
 
-    df = strrep (df, "FFF", sprintf ("%03d", 1000 * (v(i,6) - fix (v(i,6)))));
+    df = strrep (df, "FFF", sprintf ("%03d",
+                                     round (1000 * (v(i,6) - fix (v(i,6))))));
 
     df = strrep (df, 'QQ', sprintf ("Q%d", fix ((v(i,2) + 2) / 3)));
 
@@ -266,7 +267,7 @@
     tm.sec = fix (sec);
     tm.usec = fix ((sec - tm.sec) * 1e6);
     tm.wday = wday - 1;
-    ## FIXME -- Do we need YDAY and DST?  How should they be computed?
+    ## FIXME: Do we need YDAY and DST?  How should they be computed?
     ## We don't want to use "localtime (mktime (tm))" because that
     ## doesn't correctly handle dates before 1970-01-01 on some systems.
     ## tm.yday = ?;
--- a/scripts/time/datevec.m	Fri Aug 01 09:06:21 2014 -0400
+++ b/scripts/time/datevec.m	Fri Aug 01 12:10:05 2014 -0400
@@ -113,6 +113,8 @@
     p = (localtime (time ())).year + 1900 - 50;
   endif
 
+  do_resize = false;
+
   if (iscell (date))
 
     nd = numel (date);
@@ -146,6 +148,10 @@
 
   else   # datenum input
 
+    if (! iscolumn (date))
+      date_sz = size (date);
+      do_resize = true;
+    endif
     date = date(:);
 
     ## Move day 0 from midnight -0001-12-31 to midnight 0000-3-1
@@ -182,6 +188,13 @@
 
   if (nargout <= 1)
     y = [y, m, d, h, mi, s];
+  elseif (do_resize)
+    y = reshape (y, date_sz);
+    m = reshape (m, date_sz);
+    d = reshape (d, date_sz);
+    h = reshape (h, date_sz);
+    mi = reshape (mi, date_sz);
+    s = reshape (s, date_sz);
   endif
 
 endfunction
@@ -306,12 +319,23 @@
 %!assert (datevec ("03:38 PM"), [yr,1,1,15,38,0])
 %!assert (datevec ("03/13/1962"), [1962,3,13,0,0,0])
 
-%% Test millisecond format FFF
+## Test millisecond format FFF
 %!assert (datevec ("15:38:21.25", "HH:MM:SS.FFF"), [yr,1,1,15,38,21.025])
 
-# Other tests
+## Test structure of return value (bug #42334)
+%!test
+%! [~, ~, d] = datevec ([1 2; 3 4]);
+%! assert (d, [1 2; 3 4]);
+
+## Other tests
 %!assert (datenum (datevec ([-1e4:1e4])), [-1e4:1e4]');
 %!test
 %! t = linspace (-2e5, 2e5, 10993);
 %! assert (all (abs (datenum (datevec (t)) - t') < 1e-5));
 
+%% Test input validation
+%!error datevec ()
+%!error datevec (1,2,3,4)
+%!error <none of the standard formats match> datevec ("foobar")
+%!error <DATE not parsed correctly with given format> datevec ("foobar", "%d")
+
--- a/src/main.in.cc	Fri Aug 01 09:06:21 2014 -0400
+++ b/src/main.in.cc	Fri Aug 01 12:10:05 2014 -0400
@@ -603,8 +603,8 @@
 
               retval = 1;
             }
-
-          retval = octave_exec (file, new_argv);
+          else
+            retval = octave_exec (file, new_argv);
         }
       else
         {
--- a/src/mkoctfile.in.cc	Fri Aug 01 09:06:21 2014 -0400
+++ b/src/mkoctfile.in.cc	Fri Aug 01 12:10:05 2014 -0400
@@ -552,7 +552,7 @@
         }
       else
         {
-          std::cerr << "mkoctfile: unrecognized argument " << arg;
+          std::cerr << "mkoctfile: unrecognized argument " << arg << std::endl;
           return 1;
         }
 
@@ -671,8 +671,8 @@
         }
       else
         {
-          std::cerr << "mkoctfile: no way to compile Fortran file "
-                    << f << std::endl;
+          std::cerr << "mkoctfile: no way to compile Fortran file " << f
+                    << std::endl;
           return 1;
         }
     }
--- a/test/Makefile.am	Fri Aug 01 09:06:21 2014 -0400
+++ b/test/Makefile.am	Fri Aug 01 12:10:05 2014 -0400
@@ -56,6 +56,7 @@
 include bug-36025/module.mk
 include bug-38236/module.mk
 include bug-38691/module.mk
+include classdef/module.mk
 include classes/module.mk
 include class-concat/module.mk
 include ctor-vs-method/module.mk
@@ -70,6 +71,11 @@
 check: sparse.tst bc-overload-tests.stamp
 	$(top_builddir)/run-octave $(RUN_OCTAVE_OPTIONS) --norc --silent --no-history $(srcdir)/fntests.m $(srcdir)
 
+if AMCOND_HAVE_LLVM
+check-jit: sparse.tst bc-overload-tests.stamp
+	$(top_builddir)/run-octave $(RUN_OCTAVE_OPTIONS) --jit-compiler --norc --silent --no-history $(srcdir)/fntests.m $(srcdir)
+endif
+
 sparse.tst: build-sparse-tests.sh
 	$(srcdir)/build-sparse-tests.sh
 
--- a/test/build-sparse-tests.sh	Fri Aug 01 09:06:21 2014 -0400
+++ b/test/build-sparse-tests.sh	Fri Aug 01 12:10:05 2014 -0400
@@ -513,14 +513,13 @@
 # Specific tests for certain mapper functions
     cat >>$TESTS <<EOF
 
-%% These mapper functions always return a full matrix
 %!test
 %! wn2s = warning ("query", "Octave:num-to-str");
 %! warning ("off", "Octave:num-to-str");
 %! if (isreal (af))
 %!   assert (toascii (as), toascii (af));
-%!   assert (tolower (as), tolower (af));
-%!   assert (toupper (as), toupper (af));
+%!   assert (tolower (as), as);
+%!   assert (toupper (as), as);
 %! endif
 %! warning (wn2s.state, "Octave:num-to-str");
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/classdef/classdef.tst	Fri Aug 01 12:10:05 2014 -0400
@@ -0,0 +1,73 @@
+## Copyright (C) 2013 Ben Abbott
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+%%  Test script for classdef OOP.
+%%  Requires the path to contain the test classes.
+%%
+%%  Note: This script and all classes are also intended to run
+%%        in MATLAB to test compatibility.  Don't break that!
+%%
+%%  To Do:  This script tests to ensure that things done correctly work
+%%          corrrectly.  It should also check that things done incorrectly
+%%          error properly.
+%%
+%%  The classes used for the tests reside in the test/classdef with others
+%%  in the test directory.
+%%
+%%  The classes provide the ability to test most of the major features
+%%  of the classdef OOP facilities.  There are a number of classes, mostly
+%%  kind of the same, that create a hierarchy.
+
+%%  Basic classdef tests for value class
+%!shared p, q, i, amt
+%! q = foo_value_class ();
+%! p = foo_value_class (4, 4*12, 50e3);
+%! i = p.rate / (12 * 100);
+%! amt = (p.principle * i) / (1 - (1 + i)^(-p.term));
+%!assert (isempty (q.rate));
+%!assert (isempty (q.principle));
+%!assert (isempty (q.term));
+%!assert (class (p), "foo_value_class");
+%!assert (p.term, 48);
+%!assert (p.rate, 4.0);
+%!assert (p.principle, 50e3);
+%!assert (p.amount, amt, eps ())
+%!assert (amount (p), amt, eps ())
+%!xtest
+%! assert (properties (p), {'rate'; 'term'; 'principle'})
+%!xtest
+%! assert (methods (p), {'amount'; 'foo_value_class'})
+%!assert (isempty (foo_value_class().rate))
+%!error <property `rate' is not constant> foo_value_class.rate
+
+%%  Static method and Constant Property
+%!assert (foo_static_method_constant_property.radians_per_cycle, 2*pi);
+%!assert (foo_static_method_constant_property().radians_per_cycle, 2*pi);
+%!assert (foo_static_method_constant_property().pie, pi);
+%!error <property `frequency' is not constant> foo_static_method_constant_property.frequency
+%!error <method `cosine' is not static> foo_static_method_constant_property.cosine
+%!test
+%! obj = foo_static_method_constant_property;
+%! obj.frequency = 10;
+%! assert (obj.cosine (0.1), cos (2 * pi * 10 * 0.1), eps ())
+%! assert (obj.sine (0.1), sin (2 * pi * 10 * 0.1), eps ())
+
+%!test
+%! obj = foo_method_changes_property_size (3);
+%! obj = obj.move_element_to_end (2);
+%! assert (obj.element, [1 3 2])
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/classdef/foo_method_changes_property_size.m	Fri Aug 01 12:10:05 2014 -0400
@@ -0,0 +1,14 @@
+classdef foo_method_changes_property_size
+  properties
+    element;
+  end
+  methods
+    function obj = foo_method_changes_property_size (n)
+      obj.element = 1:n;
+    end
+    function obj = move_element_to_end (obj, n)
+      obj.element(end+1) = obj.element(n);
+      obj.element(n) = [];
+    end
+  end
+end
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/classdef/foo_static_method_constant_property.m	Fri Aug 01 12:10:05 2014 -0400
@@ -0,0 +1,30 @@
+classdef foo_static_method_constant_property
+  properties
+    frequency;
+  end
+  properties (Constant = true)
+    pie = pi;
+  end
+  methods
+    function obj = foo_static_method_constant_property (f)
+      if (nargin == 1)
+        obj.frequency = f;
+      elseif (nargin ~= 0)
+        error ('foo_static_method_constant_property:SyntaxError', ...
+               'foo_static_method_constant_property: Invalid syntax')
+      end
+    end
+    function res = cosine (obj, t)
+      res = cos (obj.radians_per_cycle () * obj.frequency * t);
+    end
+    function res = sine (obj, t)
+      res = sin (obj.radians_per_cycle () * obj.frequency * t);
+    end
+  end
+  methods (Static)
+    function res = radians_per_cycle ()
+      res = 2 * foo_static_method_constant_property.pie;
+    end
+  end
+end
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/classdef/foo_value_class.m	Fri Aug 01 12:10:05 2014 -0400
@@ -0,0 +1,28 @@
+classdef foo_value_class
+  properties
+    rate;
+    term;
+    principle;
+  end
+  methods
+    function obj = foo_value_class (r, t, p)
+      if (nargin == 3)
+        obj.rate = r;
+        obj.term = t;
+        obj.principle = p;
+      elseif (nargin ~= 0)
+        error ('foo_value_class:SyntaxError', ...
+               'foo_value_class: Invalid syntax')
+      end
+    end
+    function amt = amount (obj)
+      i = obj.rate / (12 * 100);
+      if (i == 0 && obj.term == 0)
+        amt = obj.principle;
+      else
+        amt = (obj.principle * i) / (1 - (1 + i)^(-obj.term));
+      end
+    end
+  end
+end
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/classdef/module.mk	Fri Aug 01 12:10:05 2014 -0400
@@ -0,0 +1,7 @@
+classdef_FCN_FILES = \
+  classdef/foo_method_changes_property_size.m \
+  classdef/foo_static_method_constant_property.m \
+  classdef/foo_value_class.m \
+  classdef/classdef.tst
+
+FCN_FILES += $(classdef_FCN_FILES)
--- a/test/fcn-handle-derived-resolution/@derived/derived.m	Fri Aug 01 09:06:21 2014 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,5 +0,0 @@
-function r = derived (n)
-  s.a = n;
-  p = parent (n);
-  r = class (s, 'derived', p);
-end
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/fcn-handle-derived-resolution/@fhdr_derived/fhdr_derived.m	Fri Aug 01 12:10:05 2014 -0400
@@ -0,0 +1,5 @@
+function r = fhdr_derived (n)
+  s.a = n;
+  p = fhdr_parent (n);
+  r = class (s, 'fhdr_derived', p);
+end
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/fcn-handle-derived-resolution/@fhdr_other/fhdr_other.m	Fri Aug 01 12:10:05 2014 -0400
@@ -0,0 +1,4 @@
+function r = fhdr_other (n)
+  s.d = fhdr_derived (n);
+  r = class (s, 'fhdr_other');
+end
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/fcn-handle-derived-resolution/@fhdr_other/getsize_arrayfun.m	Fri Aug 01 12:10:05 2014 -0400
@@ -0,0 +1,3 @@
+function r = getsize_arrayfun (x)
+  r = arrayfun (@(i) numel (x(i).d), 1:numel (x), 'uniformoutput', true);
+end
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/fcn-handle-derived-resolution/@fhdr_other/getsize_cellfun.m	Fri Aug 01 12:10:05 2014 -0400
@@ -0,0 +1,3 @@
+function r = getsize_cellfun (x)
+  r = cellfun (@numel, {x.d});
+end
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/fcn-handle-derived-resolution/@fhdr_other/getsize_loop.m	Fri Aug 01 12:10:05 2014 -0400
@@ -0,0 +1,7 @@
+function r = getsize_loop (x)
+  n = numel (x);
+  r = zeros (1, n);
+  for i = 1:n
+    r(i) = numel (x(i).d);
+  end
+end
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/fcn-handle-derived-resolution/@fhdr_parent/fhdr_parent.m	Fri Aug 01 12:10:05 2014 -0400
@@ -0,0 +1,4 @@
+function r = fhdr_parent (n)
+  s.a = rand (n, 1);
+  r = class (s, 'fhdr_parent');
+end
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/fcn-handle-derived-resolution/@fhdr_parent/numel.m	Fri Aug 01 12:10:05 2014 -0400
@@ -0,0 +1,3 @@
+function r = numel (x, varargin)
+  r = numel (x.a, varargin{:});
+end
--- a/test/fcn-handle-derived-resolution/@other/getsize_arrayfun.m	Fri Aug 01 09:06:21 2014 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,3 +0,0 @@
-function r = getsize_arrayfun (x)
-  r = arrayfun (@(i) numel (x(i).d), 1:numel (x), 'uniformoutput', true);
-end
--- a/test/fcn-handle-derived-resolution/@other/getsize_cellfun.m	Fri Aug 01 09:06:21 2014 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,3 +0,0 @@
-function r = getsize_cellfun (x)
-  r = cellfun (@numel, {x.d});
-end
--- a/test/fcn-handle-derived-resolution/@other/getsize_loop.m	Fri Aug 01 09:06:21 2014 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,7 +0,0 @@
-function r = getsize_loop (x)
-  n = numel (x);
-  r = zeros (1, n);
-  for i = 1:n
-    r(i) = numel (x(i).d);
-  end
-end
--- a/test/fcn-handle-derived-resolution/@other/other.m	Fri Aug 01 09:06:21 2014 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,4 +0,0 @@
-function r = other (n)
-  s.d = derived (n);
-  r = class (s, 'other');
-end
--- a/test/fcn-handle-derived-resolution/@parent/numel.m	Fri Aug 01 09:06:21 2014 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,3 +0,0 @@
-function r = numel (x, varargin)
-  r = numel (x.a, varargin{:});
-end
--- a/test/fcn-handle-derived-resolution/@parent/parent.m	Fri Aug 01 09:06:21 2014 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,4 +0,0 @@
-function r = parent (n)
-  s.a = rand (n, 1);
-  r = class (s, 'parent');
-end
--- a/test/fcn-handle-derived-resolution/fcn-handle-derived-resolution.tst	Fri Aug 01 09:06:21 2014 -0400
+++ b/test/fcn-handle-derived-resolution/fcn-handle-derived-resolution.tst	Fri Aug 01 12:10:05 2014 -0400
@@ -22,38 +22,46 @@
 %%  Note: This script and all classes are also intended to run
 %%        in Matlab to test compatibility.  Don't break that!
 
-%!shared
-%! clear -classes
+%% FIXME: Can't use 'clear -classes' because it also clears all functions in the
+%% namespace of test.m (bug #35881).  This is a problem only if Octave would
+%% re-use a class definition that was defined somewhere else.  Unfortunately,
+%% that is exactly the case when running 'make check' since the ctor-vs-method
+%% test also uses an @parent, @derived, and @other class.
+%% Until the bug is fixed, it suffices to make the class names unique so that
+%% there is no re-use.  Using the prefix fhdr (fcn-handle-derived-resolution)
+%% for this directory.
+%%!shared
+%%! #clear -classes
 
 %!test
-%! p = parent (7);
+%! p = fhdr_parent (7);
 %! assert (numel (p), 7)
 
 %!test
-%! d = derived (13);
+%! d = fhdr_derived (13);
 %! assert (numel (d), 13)
 
 %!test
-%! p = parent (11);
+%! p = fhdr_parent (11);
 %! f = @numel;
 %! assert (f (p), 11)
 
 %!test
-%! d = parent (21);
+%! d = fhdr_parent (21);
 %! f = @numel;
 %! assert (f (d), 21)
 
 %!test
-%! o(1) = other (13);
-%! o(2) = other (42);
+%! o(1) = fhdr_other (13);
+%! o(2) = fhdr_other (42);
 %! assert (getsize_loop (o), [13, 42])
 
 %!test
-%! o(1) = other (13);
-%! o(2) = other (42);
+%! o(1) = fhdr_other (13);
+%! o(2) = fhdr_other (42);
 %! assert (getsize_cellfun (o), [13, 42])
 
 %!test
-%! o(1) = other (13);
-%! o(2) = other (42);
+%! o(1) = fhdr_other (13);
+%! o(2) = fhdr_other (42);
 %! assert (getsize_arrayfun (o), [13, 42])
--- a/test/fcn-handle-derived-resolution/module.mk	Fri Aug 01 09:06:21 2014 -0400
+++ b/test/fcn-handle-derived-resolution/module.mk	Fri Aug 01 12:10:05 2014 -0400
@@ -1,11 +1,11 @@
 fcn_handle_derived_resolution_FCN_FILES = \
-  fcn-handle-derived-resolution/@derived/derived.m \
-  fcn-handle-derived-resolution/@other/getsize_arrayfun.m \
-  fcn-handle-derived-resolution/@other/getsize_cellfun.m \
-  fcn-handle-derived-resolution/@other/getsize_loop.m \
-  fcn-handle-derived-resolution/@other/other.m \
-  fcn-handle-derived-resolution/@parent/numel.m \
-  fcn-handle-derived-resolution/@parent/parent.m \
+  fcn-handle-derived-resolution/@fhdr_derived/fhdr_derived.m \
+  fcn-handle-derived-resolution/@fhdr_other/getsize_arrayfun.m \
+  fcn-handle-derived-resolution/@fhdr_other/getsize_cellfun.m \
+  fcn-handle-derived-resolution/@fhdr_other/getsize_loop.m \
+  fcn-handle-derived-resolution/@fhdr_other/fhdr_other.m \
+  fcn-handle-derived-resolution/@fhdr_parent/numel.m \
+  fcn-handle-derived-resolution/@fhdr_parent/fhdr_parent.m \
   fcn-handle-derived-resolution/fcn-handle-derived-resolution.tst
 
 FCN_FILES += $(fcn_handle_derived_resolution_FCN_FILES)
--- a/test/jit.tst	Fri Aug 01 09:06:21 2014 -0400
+++ b/test/jit.tst	Fri Aug 01 12:10:05 2014 -0400
@@ -26,8 +26,8 @@
 %! __old_jit_startcnt__ = jit_startcnt (1000);
 
 ## Test some simple cases that compile.
-
 %!testif HAVE_LLVM
+%! jit_failure_count (0)
 %! for i=1:1e6
 %!   if (i < 5)
 %!     break;
@@ -36,8 +36,10 @@
 %!   endif
 %! endfor
 %! assert (i, 1);
+%! assert (jit_failure_count, 0);
 
 %!testif HAVE_LLVM
+%! jit_failure_count (0)
 %! while (1)
 %!   if (1)
 %!     break;
@@ -45,33 +47,133 @@
 %!     break;
 %!   endif
 %! endwhile
+%! assert (jit_failure_count, 0);
+
+%!testif HAVE_LLVM
+%! jit_failure_count (0)
+%! do
+%!   break;
+%! until (0)
+%! assert (jit_failure_count, 0);
 
 %!testif HAVE_LLVM
+%! jit_failure_count (0)
+%! do
+%!   if (1)
+%!     break;
+%!   end;
+%! until (0)
+%! assert (jit_failure_count, 0);
+
+%!testif HAVE_LLVM
+%! jit_failure_count (0)
+%! i=1;
+%! do
+%!   continue;
+%!   i=i+1;
+%! until (1)
+%! assert (i, 1);
+%! assert (jit_failure_count, 0);
+
+%!testif HAVE_LLVM
+%! jit_failure_count (0)
 %! for i=1:1e6
 %!   if (i == 100)
 %!     break;
 %!   endif
 %! endfor
 %! assert (i, 100);
+%! assert (jit_failure_count, 0);
 
 ## Also test parfor keyword
 %!testif HAVE_LLVM
+%! jit_failure_count (0)
 %! parfor i=1:1e6
 %!   if (i == 100)
 %!     break;
 %!   endif
 %! endparfor
 %! assert (i, 100);
+%! assert (jit_failure_count, 0);
+## Test some switch statements
+%!testif HAVE_LLVM
+%! jit_failure_count (0)
+%! do
+%!   switch (1)
+%!   end;
+%! until(1)
+%! assert (jit_failure_count, 0);
+
+%!testif HAVE_LLVM
+%! jit_failure_count (0)
+%! do
+%!   switch (1)
+%!   case 1
+%!     break;
+%!   end;
+%! until(1)
+%! assert (jit_failure_count, 0);
+
+%!testif HAVE_LLVM
+%! jit_failure_count (0)
+%! do
+%!   switch (1)
+%!   otherwise
+%!     break;
+%!   end;
+%! until(1)
+%! assert (jit_failure_count, 0);
 
 %!testif HAVE_LLVM
+%! jit_failure_count (0)
+%! do
+%!   switch (1)
+%!   case 1
+%!     break;
+%!   otherwise
+%!     break;
+%!   end;
+%! until(1)
+%! assert (jit_failure_count, 0);
+
+%!testif HAVE_LLVM
+%! jit_failure_count (0)
+%! i=0;
+%! a=0;
+%! b=0;
+%! do
+%!   i=i+1;
+%!   switch (i)
+%!   case 1
+%!     continue;
+%!   case 2
+%!     b=1;
+%!     continue;
+%!   case 4
+%!     break;
+%!   otherwise
+%!     a=a+5;
+%!   end;
+%!   a=a+1;
+%! until(0);
+%! assert (i, 4);
+%! assert (a, 6);
+%! assert (b, 1);
+%! assert (jit_failure_count, 0);
+
+## Some more complex calculations
+%!testif HAVE_LLVM
+%! jit_failure_count (0)
 %! inc = 1e-5;
 %! result = 0;
 %! for ii = 0:inc:1
 %!   result = result + inc * (1/3 * ii * ii);
 %! endfor
 %! assert (abs (result - 1/9) < 1e-5);
+%! assert (jit_failure_count, 0);
 
 %!testif HAVE_LLVM
+%! jit_failure_count (0)
 %! inc = 1e-5;
 %! result = 0;
 %! for ii = 0:inc:1
@@ -79,8 +181,10 @@
 %!   result = result + inc * (1/3 * ii ^ 2);
 %! endfor
 %! assert (abs (result - 1/9) < 1e-5);
+%! assert (jit_failure_count, 0);
 
 %!testif HAVE_LLVM
+%! jit_failure_count (0)
 %! temp = 1+1i;
 %! nan = NaN;
 %! while (1)
@@ -89,8 +193,10 @@
 %!   break;
 %! endwhile
 %! assert (imag (temp), 0);
+%! assert (jit_failure_count, 0);
 
 %!testif HAVE_LLVM
+%! jit_failure_count (0)
 %! temp = 1+1i;
 %! nan = NaN+1i;
 %! while (1)
@@ -100,24 +206,30 @@
 %!   break;
 %! endwhile
 %! assert (imag (temp), 0);
+%! assert (jit_failure_count, 0);
 
 %!testif HAVE_LLVM
+%! jit_failure_count (0)
 %! temp = 1+1i;
 %! while (1)
 %!   temp = temp * 5;
 %!   break;
 %! endwhile
 %! assert (temp, 5+5i);
+%! assert (jit_failure_count, 0);
 
 %!testif HAVE_LLVM
+%! jit_failure_count (0)
 %! nr = 1001;
 %! mat = zeros (1, nr);
 %! for i = 1:nr
 %!   mat(i) = i;
 %! endfor
 %! assert (mat == 1:nr);
+%! assert (jit_failure_count, 0);
 
 %!testif HAVE_LLVM
+%! jit_failure_count (0)
 %! nr = 1001;
 %! mat = 1:nr;
 %! mat(end) = 0; # force mat to a matrix
@@ -126,8 +238,10 @@
 %!   total = mat(i) + total;
 %! endfor
 %! assert (sum (mat) == total);
+%! assert (jit_failure_count, 0);
 
 %!testif HAVE_LLVM
+%! jit_failure_count (0)
 %! nr = 1001;
 %! mat = [3 1 5];
 %! try
@@ -141,6 +255,7 @@
 %! catch
 %! end_try_catch
 %! assert (result == 500);
+%! assert (jit_failure_count, 0);
 
 %!function result = gen_test (n)
 %!  result = double (rand (1, n) > .01);
@@ -176,18 +291,23 @@
 %!endfunction
 
 %!testif HAVE_LLVM
+%! jit_failure_count (0)
 %! test_set = gen_test (10000);
 %! assert (all (vectorized (test_set, 3) == loopy (test_set, 3)));
+%! assert (jit_failure_count, 0);
 
 %!testif HAVE_LLVM
+%! jit_failure_count (0)
 %! niter = 1001;
 %! i = 0;
 %! while (i < niter)
 %!   i = i + 1;
 %! endwhile
 %! assert (i == niter);
+%! assert (jit_failure_count, 0);
 
 %!testif HAVE_LLVM
+%! jit_failure_count (0)
 %! niter = 1001;
 %! result = 0;
 %! m = [5 10];
@@ -195,8 +315,10 @@
 %!   result = result + m(end);
 %! endfor
 %! assert (result == m(end) * niter);
+%! assert (jit_failure_count, 0);
 
 %!testif HAVE_LLVM
+%! jit_failure_count (0)
 %! ndim = 100;
 %! result = 0;
 %! m = zeros (ndim);
@@ -209,8 +331,10 @@
 %!   i = i + 1;
 %! endwhile
 %! assert (result == sum (sum (m)));
+%! assert (jit_failure_count, 0);
 
 %!testif HAVE_LLVM
+%! jit_failure_count (0)
 %! ndim = 100;
 %! m = zeros (ndim);
 %! i = 1;
@@ -223,8 +347,10 @@
 %! m2 = zeros (ndim);
 %! m2(:) = 1:(ndim^2);
 %! assert (all (m == m2));
+%! assert (jit_failure_count, 0);
 
 %!testif HAVE_LLVM
+%! jit_failure_count (0)
 %! ndim = 2;
 %! m = zeros (ndim, ndim, ndim, ndim);
 %! result = 0;
@@ -244,6 +370,7 @@
 %! expected = ones (ndim, ndim, ndim, ndim);
 %! assert (all (m == expected));
 %! assert (result == sum (expected (:)));
+%! assert (jit_failure_count, 0);
 
 %!function test_divide ()
 %! state = warning ("query", "Octave:divide-by-zero").state;
@@ -259,21 +386,26 @@
 %!endfunction
 
 %!testif HAVE_LLVM
+%! jit_failure_count (0)
 %! lasterr ("");
 %! try
 %!   test_divide ();
 %! end_try_catch
 %! assert (strcmp (lasterr (), "division by zero"));
+%! assert (jit_failure_count, 0);
 
 %!testif HAVE_LLVM
+%! jit_failure_count (0)
 %! while (1)
 %!   a = 0;
 %!   result = a / 1;
 %!   break;
 %! endwhile
 %! assert (result, 0);
+%! assert (jit_failure_count, 0);
 
 %!testif HAVE_LLVM
+%! jit_failure_count (0)
 %! m = zeros (2, 1001);
 %! for i=1:1001
 %!   m(end, i) = i;
@@ -283,38 +415,49 @@
 %! m2(1, :) = fliplr (1:1001);
 %! m2(2, :) = 1:1001;
 %! assert (m, m2);
+%! assert (jit_failure_count, 0);
 
 %!testif HAVE_LLVM
+%! jit_failure_count (0)
 %! m = [1 2 3];
 %! for i=1:1001
 %!   m = sin (m);
 %!   break;
 %! endfor
 %! assert (m == sin ([1  2 3]));
+%! assert (jit_failure_count, 0);
 
 %!testif HAVE_LLVM
+%! jit_failure_count (0)
 %! i = 0;
 %! while i < 10
 %!   i += 1;
 %! endwhile
 %! assert (i == 10);
+%! assert (jit_failure_count, 0);
 
 %!testif HAVE_LLVM
+%! jit_failure_count (0)
 %! i = 0;
 %! while i < 10
 %!   a = ++i;
 %! endwhile
 %! assert (i == 10);
 %! assert (a == 10);
+%! assert (jit_failure_count, 0);
+
 %!testif HAVE_LLVM
+%! jit_failure_count (0)
 %! i = 0;
 %! while i < 10
 %!   a = i++;
 %! endwhile
 %! assert (i == 10);
 %! assert (a == 9);
+%! assert (jit_failure_count, 0);
 
 %!testif HAVE_LLVM
+%! jit_failure_count (0)
 %! num = 2;
 %! a = zeros (1, num);
 %! i = 1;
@@ -323,6 +466,7 @@
 %!   ++i;
 %! endwhile
 %! assert (a, ones (1, num));
+%! assert (jit_failure_count, 0);
 
 %!function test_compute_idom ()
 %! while (li <= length (l1) && si <= length (s1))
@@ -337,11 +481,13 @@
 %! endwhile
 
 %!testif HAVE_LLVM
+%! jit_failure_count (0)
 %! lasterr ("");
 %! try
 %!   test_compute_idom ();
 %! end_try_catch
 %! assert (! isempty (lasterr ()));
+%! assert (jit_failure_count, 1);
 
 %!function x = test_overload (a)
 %!  while (1)
@@ -351,8 +497,10 @@
 %!endfunction
 
 %!testif HAVE_LLVM
+%! jit_failure_count (0)
 %! assert (test_overload (1), 1);
 %! assert (test_overload ([1 2]), [1 2]);
+%! assert (jit_failure_count, 0);
 
 %!function a = bubble (a = [3 2 1])
 %!  swapped = 1;
@@ -371,9 +519,12 @@
 %!endfunction
 
 %!testif HAVE_LLVM
+%! jit_failure_count (0)
 %! assert (bubble (), [1 2 3]);
+%! assert (jit_failure_count, 0);
 
 %!testif HAVE_LLVM
+%! jit_failure_count (0)
 %! a = 0;
 %! b = 1;
 %! for i=1:1e3
@@ -383,8 +534,10 @@
 %! endfor
 %! assert (a, 2000);
 %! assert (b, 1);
+%! assert (jit_failure_count, 0);
 
 %!testif HAVE_LLVM
+%! jit_failure_count (0)
 %! a = [1+1i 1+2i];
 %! b = 0;
 %! while (1)
@@ -392,6 +545,7 @@
 %!   break;
 %! endwhile
 %! assert (b, a(1));
+%! assert (jit_failure_count, 0);
 
 %!function test_undef ()
 %!  for i=1:1e7
@@ -400,26 +554,32 @@
 %!endfunction
 
 %!testif HAVE_LLVM
+%! jit_failure_count (0)
 %! lasterr ("");
 %! try
 %!   test_undef ();
 %! end_try_catch
 %! assert (strncmp (lasterr (), "'XXX' undefined near", 20));
+%! assert (jit_failure_count, 1);
 
 %!shared id
 %! id = @(x) x;
 
 %!testif HAVE_LLVM
+%! jit_failure_count (0)
 %! assert (id (1), 1);
 %! assert (id (1+1i), 1+1i);
 %! assert (id (1, 2), 1);
+%! assert (jit_failure_count, 0);
 
 %!testif HAVE_LLVM
+%! jit_failure_count (0)
 %! lasterr ("");
 %! try
 %!   id ();
 %! end_try_catch
 %! assert (strncmp (lasterr (), "'x' undefined near", 18));
+%! assert (jit_failure_count, 0);
 
 ## Restore JIT settings
 %!testif HAVE_LLVM
--- a/test/null-assign.tst	Fri Aug 01 09:06:21 2014 -0400
+++ b/test/null-assign.tst	Fri Aug 01 12:10:05 2014 -0400
@@ -61,3 +61,49 @@
 %!test
 %! a = ones (3); b = []; fail ("subsasgn (a, substruct ('()', {':',1:2}), b)", ".")
 
+%!test
+%! classes = {@int8, @int16, @int32, @int64, ...
+%!   @uint8, @uint16, @uint32, @uint64, ...
+%!   @single, @double, @logical};
+%! for i = 1:numel (classes)
+%!   cls = classes{i};
+%!   x = cls ([1, 2, 3]);
+%!   cls_nm = class (x);
+%!   x(2) = [];
+%!   assert (x, cls ([1, 3]));
+%!   assert (class (x), cls_nm);
+%!   x(2) = [];
+%!   assert (x, cls (1));
+%!   assert (class (x), cls_nm);
+%!   x(1) = [];
+%!   assert (x, cls (zeros (1, 0)));
+%!   assert (class (x), cls_nm);
+%! endfor
+%! for i = 1:numel (classes)
+%!   cls = classes{i};
+%!   x = cls ([1, 2, 3]);
+%!   cls_nm = class (x);
+%!   x(2) = '';
+%!   assert (x, cls ([1, 3]));
+%!   assert (class (x), cls_nm);
+%!   x(2) = '';
+%!   assert (x, cls (1));
+%!   assert (class (x), cls_nm);
+%!   x(1) = '';
+%!   assert (x, cls (zeros (1, 0)));
+%!   assert (class (x), cls_nm);
+%! endfor
+%! for i = 1:numel (classes)
+%!   cls = classes{i};
+%!   x = cls ([1, 2, 3]);
+%!   cls_nm = class (x);
+%!   x(2) = "";
+%!   assert (x, cls ([1, 3]));
+%!   assert (class (x), cls_nm);
+%!   x(2) = "";
+%!   assert (x, cls (1));
+%!   assert (class (x), cls_nm);
+%!   x(1) = "";
+%!   assert (x, cls (zeros (1, 0)));
+%!   assert (class (x), cls_nm);
+%! endfor