changeset 19696:c728ae4d1790

maint: Periodic merge of stable to default.
author Rik <rik@octave.org>
date Fri, 06 Feb 2015 08:31:49 -0800
parents 40e846a96908 (diff) 6e2729924601 (current diff)
children dfea01b3425f
files scripts/sparse/eigs.m
diffstat 1313 files changed, 75849 insertions(+), 27999 deletions(-) [+]
line wrap: on
line diff
--- a/Makefile.am	Fri Feb 06 08:31:09 2015 -0800
+++ b/Makefile.am	Fri Feb 06 08:31:49 2015 -0800
@@ -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 Feb 06 08:31:09 2015 -0800
+++ b/NEWS	Fri Feb 06 08:31:49 2015 -0800
@@ -1,1520 +1,264 @@
-Summary of important user-visible changes for version 3.8:
+Summary of important user-visible changes for version 4.0:
 ---------------------------------------------------------
 
-  ** 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.  But
-     because it is not quite as polished as we would like, we have
-     decided to wait until the 4.0.x release series before making the
-     GUI the default interface (until then, you can use the --force-gui
-     option to start the GUI).
+ ** A new syntax for object oriented programming termed classdef has been
+    introduced.  See the manual for more extensive documentation of the
+    classdef interface.
 
-     Given the length of time and the number of bug fixes and
-     improvements since the last major release Octave, we also decided
-     against delaying the release of all these new improvements any
-     longer just to perfect the GUI.  So please enjoy the 3.8 release of
-     Octave and the preview of the new GUI.  We believe it is working
-     reasonably well, but we also know that there are some obvious rough
-     spots and many things that could be improved.
+    New keywords:
 
-     WE NEED YOUR HELP.  There are many ways that you can help us fix
-     the remaining problems, complete the GUI, and improve the overall
-     user experience for both novices and experts alike:
-
-       * If you are a skilled software developer, you can help by
-         contributing your time to help with Octave's development.  See
-         http://octave.org/get-involved.html for more information.
+      classdef      endclassdef
+      enumeration   endenumeration
+      events        endevents
+      methods       endmethods
+      properties    endproperties
 
-       * If Octave does not work properly, you are encouraged
-         report the problems you find.  See http://octave.org/bugs.html
-         for more information about how to report problems.
+ ** New audio functions and classes:
 
-       * Whether you are a user or developer, you can help to fund the
-         project.  Octave development takes a lot of time and expertise.
-         Your contributions help to ensure that Octave will continue to
-         improve.  See http://octave.org/donate.html for more details.
+      audiodevinfo  audioread
+      audioinfo     audiorecorder
+      audioplayer   audiowrite
 
-    We hope you find Octave to be useful.  Please help us make it even
-    better for the future!
+ ** Other new classes in Octave 4.0:
 
- ** Octave now uses OpenGL graphics by default with FLTK widgets.  If
-    OpenGL libraries or FLTK widgets are not available when Octave is
-    built, gnuplot is used.  You may also choose to use gnuplot for
-    graphics by executing the command
-
-      graphics_toolkit ("gnuplot")
+      audioplayer    inputParser
+      audiorecorder
 
-    Adding this command to your ~/.octaverc file will set the default
-    for each session.
+ ** Optional stricter Matlab compatibility for ranges, diagonal matrices,
+    and permutation matrices.
 
- ** Printing or saving figures with OpenGL graphics requires the
-    gl2ps library which is no longer distributed with Octave.  The
-    software is widely available in most package managers.  If a
-    pre-compiled package does not exist for your system, you can find
-    the current sources at http://www.geuz.org/gl2ps/.
+    Octave has internal optimizations which use space-efficient storage
+    for the three data types above.  Three new functions have been added
+    which control whether the optimizations are used (default), or whether
+    the data types are stored as full matrices.
 
- ** Octave now supports nested functions with scoping rules that are
-    compatible with Matlab.  A nested function is one declared and defined
-    within the body of another function.  The nested function is only
-    accessible from within the enclosing function which makes it one
-    method for making private functions whose names do not conflict with those
-    in the global namespace (See also subfunctions and private functions).
-    In addition, variables in the enclosing function are visible within the
-    nested function.  This makes it possible to have a pseudo-global variable
-    which can be seen by a group of functions, but which is not visible in
-    the global namespace.
+    disable_range   disable_diagonal_matrix   disable_permutation_matrix
+
+    All three optimizations are disabled if Octave is started with the
+    --braindead command line option.
 
-    Example:
-    function outerfunc (...)
-      ...
-      function nested1 (...)
-        ...
-        function nested2 (...)
-           ...
-        endfunction
-      endfunction
+ ** For compatibility with Matlab, the "backtrace" warning option is now
+    enabled by default.
 
-      function nested3 (...)
-        ...
-      endfunction
-    endfunction
+ ** The preference
 
- ** Line continuations inside character strings have changed.
+      do_braindead_shortcircuit_evaluation
 
-    The sequence '...' is no longer recognized as a line continuation
-    inside a character string.  A backslash '\' followed by a newline
-    character is no longer recognized as a line continuation inside
-    single-quoted character strings.  Inside double-quoted character
-    strings, a backslash followed by a newline character is still
-    recognized as a line continuation, but the backslash character must
-    be followed *immediately* by the newline character.  No whitespace or
-    end-of-line comment may appear between them.
+    is now enabled by default.
+
+ ** The preference
 
- ** Backslash as a continuation marker outside of double-quoted strings
-    is now deprecated.
+      allow_noninteger_range_as_index
 
-    Using '\' as a continuation marker outside of double quoted strings
-    is now deprecated and will be removed from a future version of
-    Octave.  When that is done, the behavior of
-
-      (a \
-       b)
-
-    will be consistent with other binary operators.
+    is now enabled by default and the warning ID
 
- ** Redundant terminal comma accepted by parser
-
-    A redundant terminal comma is now accepted in matrix
-    definitions which allows writing code such as
+      Octave:noninteger-range-as-index
 
-    [a,...
-     b,...
-     c,...
-    ] = deal (1,2,3)
+    is now set to "on" by default instead of "error" by default and "on"
+    for --traditional.
 
- ** Octave now has limited support for named exceptions
-
-    The following syntax is now accepted:
+ ** polyeig now returns a row vector of eigenvalues rather than a matrix
+    with the eigenvalues on the diagonal.  This change was made for Matlab
+    compatibility.
 
-      try
-        statements
-      catch exception-id
-        statements
-      end
-
-    The exception-id is a structure with the fields "message" and
-    "identifier".  For example
+ ** Interpolation function changes for Matlab compatibility
 
-      try
-        error ("Octave:error-id", "error message");
-      catch myerr
-        printf ("identifier: %s\n", myerr.identifier);
-        printf ("message:    %s\n", myerr.message);
-      end_try_catch
-
-    When classdef-style classes are added to Octave, the exception-id
-    will become an MException object.
+    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.  The methods 'next' and 'previous' have been added to
+    interp1 for compatibility.
 
- ** Warning states may now be set temporarily, until the end of the
-    current function, using the syntax
-
-      warning STATE ID "local"
-
-    in which STATE may be "on", "off", or "error".  Changes to warning
-    states that are set locally affect the current function and all
-    functions called from the current scope.  The previous warning state
-    is restored on return from the current function.  The "local"
-    option is ignored if used in the top-level workspace.
-
- ** Warning IDs renamed:
+ ** The delaunay function has been extended to accept 3-D inputs for
+    Matlab compatibility.  The delaunay function no longer plots the
+    triangulation if no output argument is requested, instead, the
+    triangulation is always returned.  The delaunay3 function which
+    handles 3-D inputs has been deprecated in favor of delaunay.
 
-    Octave:array-as-scalar => Octave:array-to-scalar
-    Octave:array-as-vector => Octave:array-to-vector
-
- ** 'emptymatch', 'noemptymatch' options added to regular expressions.
-
-    With this addition Octave now accepts the entire set of Matlab options
-    for regular expressions.  'noemptymatch' is the default, but 'emptymatch'
-    has certain uses where you need to match an assertion rather than actual
-    characters.  For example,
-
-    regexprep ('World', '^', 'Hello ', 'emptymatch')
-      => Hello World
+ ** The trigonometric functions asin and acos return different phase values
+    from previous versions of Octave when the input is outside the principal
+    branch ([-1, 1]).  If the real portion of the input is greater than 1 then
+    the limit from below is taken.  If the real portion is less than 1 then the
+    limit from above is taken.  This criteria is consistent with several other
+    numerical analysis software packages.
 
-    where the pattern is actually the assertion '^' or start-of-line.
-
- ** For compatibility with Matlab, the regexp, regexpi, and regexprep
-    functions now process backslash escape sequences in single-quoted pattern
-    strings.  In addition, the regexprep function now processes backslash
-    escapes in single-quoted replacement strings.  For example,
+ ** strfind changes when using empty pattern ("") for Matlab compatibility
 
-    regexprep (str, '\t', '\n')
-
-    would search the variable str for a TAB character (escape sequence \t)
-    and replace it with a NEWLINE (escape sequence \n).  Previously the
-    expression would have searched for a literal '\' followed by 't' and
-    replaced the two characters with the sequence '\', 'n'.
+    strfind now returns an empty array when the pattern itself is empty.
+    In previous versions of Octave, strfind matched at every character
+    location when the pattern was empty.
 
- ** A TeX parser has been implemented for the FLTK toolkit and is the default
-    for any text object including titles and axis labels.  The TeX parser is
-    supported only for display on a monitor, not for printing.
-
-    A quick summary of features:
+      NEW
+      strfind ("abc", "") => []
+      OLD
+      strfind ("abc", "") => [1, 2, 3, 4]
 
-    Code         Feature     Example             Comment
-    -----------------------------------------------------------------
-    _            subscript   H_2O                formula for water
-    ^            exponent    y=x^2               formula for parabola
-    \char        symbol      \beta               Greek symbol beta
-    \fontname    font        \fontname{Arial}    set Arial font
-    \fontsize    fontsize    \fontsize{16}       set fontsize 16
-    \color[rgb]  fontcolor   \color[rgb]{1 0 1}  set magenta color
-    \bf          bold        \bfBold Text        bold font
-    \it          italic      \itItalic Text      italic font
-    \sl          slanted     \slOblique Text     slanted font
-    \rm          normal      \bfBold\rmNormal    normal font
-    {}           group       {\bf Bold}Normal    group objects
-                             e^{i*\pi} = -1      group objects
+ ** 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 m-files in the plot directory have been overhauled.
-
-    The plot functions now produce output that is nearly visually compatible
-    with Matlab.  Plot performance has also increased, dramatically for some
-    functions such as comet and waitbar.  Finally, the documentation for most
-    functions has been updated so it should be clearer both how to use a
-    function and when a function is appropriate.
-
- ** The m-files in the image directory have been overhauled.
+      * 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').
 
-    The principal benefit is that Octave will now no longer automatically
-    convert images stored with integers to doubles.  Storing images as uint8
-    or uint16 requires only 1/8 or 1/4 the memory of an image stored using
-    doubles.  For certain operations, such as fft2, the image must still be
-    converted to double in order to work.
+      * round(x) != x or the value is outside the range allowed by the
+        integer format specifier.
 
-    Other changes include fixes to the way indexed images are read from a
-    colormap depending on the image class (integer images have a -1 offset to
-    the colormap row number).
-
- ** The imread and imwrite functions have been completely rewritten.
+    There is still one difference:  Matlab switches to '%e' and Octave
+    is currently switching to '%g'.
 
-    The main changes relate to the alpha channel, support for reading and
-    writing of floating point images, implemented writing of indexed images,
-    and appending images to multipage image files.
-
-    The issues that may arise due to backwards incompatibility are:
-
-      * imwrite no longer interprets a length of 2 or 4 in the third dimension
-        as grayscale or RGB with alpha channel (a length of 4 will be saved
-        as a CMYK image).  Alpha channel must be passed as separate argument.
+ ** The archive family of functions (bzip2, gzip, zip, tar) and their
+    unpacking routines (bunzip2, gunzip, unzip, untar, unpack) have
+    been recoded.  Excepting unpack, the default is now to place files
+    in the same directory as the archive (on unpack) or as the original
+    files (on archiving).
 
-      * imread will always return the colormap indexes when reading an indexed
-        image, even if the colormap is not requested as output.
-
-      * transparency values are now inverted from previous Octave versions
-        (0 is for completely transparent instead of completely opaque).
-
-    In addition, the function imformats has been implemented to expand
-    reading and writing of images of different formats through imread
-    and imwrite.
+ ** 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 colormap function now provides new options--"list", "register",
-    and "unregister"--to list all available colormap functions, and to
-    add or remove a function name from the list of known colormap
-    functions.  Packages that implement extra colormaps should use these
-    commands with PKG_ADD and PKG_DEL statements.
-
- ** strsplit has been modified to be compatible with Matlab.  There
-    are two instances where backward compatibility is broken.
-
-    (1) Delimiters are now string vectors, not scalars.
+ ** The patch graphic object has been overhauled.  It now produces visual
+    results equivalent to Matlab even for esoteric combinations of
+    faces/vertices/cdata.
 
-    Octave's legacy behavior
+ ** The polar() plot function now draws a circular theta axis and
+    radial rho axis rather than using a rectangular x/y axis.
 
-      strsplit ("1 2, 3", ", ")
-      ans =
-      {
-       [1,1] = 1
-       [1,2] = 2
-       [1,3] =
-       [1,4] = 3
-      }
-
-    Matlab compatible behavior
+ ** 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.
 
-      strsplit ("1 2, 3", ", ")
-      ans =
-      {
-       [1,1] = 1 2
-       [1,2] = 3
-      }
-
-    (2) By default, Matlab treats consecutive delimiters as a single
-    delimiter.  By default, Octave's legacy behavior was to return an
-    empty string for the part between the delmiters.
+ ** isprime has been extended to operate on negative and complex inputs.
 
-    Where legacy behavior is desired, the call to strsplit() may be
-    replaced by ostrsplit(), which is Octave's original implementation of
-    strsplit().
+ ** xor has been extended to accept more than two arguments in which case
+    it performs cumulative XOR reduction.
 
- ** The datevec function has been extended for better Matlab compatibility.
-    It now accepts string inputs in the following numerical formats: 12, 21,
-    22, 26, 29, 31.  This is undocumented, but verifiable, Matlab behavior.
-    In addition, the default for formats which do not specify a date is
-    January 1st of the current year.  The previous default was the current day,
-    month, and year.  This may produce changes in existing scripts.
+ ** The following functions now support N-dimensional arrays:
 
- ** The error function and its derivatives has been extended to accept complex
-    arguments.  The following functions now accept complex inputs:
-
-    erf  erfc  erfcx
-
-    In addition two new error functions erfi (imaginary error function) and
-    dawson (scaled imaginary error function) have been added.
+      fliplr   flipud   rot90
 
- ** The glpk function has been modified to reflect changes in the GLPK
-    library.  The "round" and "itcnt" options have been removed.  The
-    "relax" option has been replaced by the "rtest" option.  The numeric
-    values of error codes and of some options have also changed.
+ ** The new warning ID "Octave:data-file-in-path" replaces the three
+    previous separate warning IDs "Octave:fopen-file-in-path",
+    "Octave:load-file-in-path", and "Octave:md5sum-file-in-path".
 
- ** The kurtosis function has changed definition to be compatible with
-    Matlab.  It now returns the base kurtosis instead of the "excess kurtosis".
-    The old behavior can be had by changing scripts to normalize with -3.
-
-               "excess kurtosis" = kurtosis (x) - 3
-
- ** The moment function has changed definition to be compatible with
-    Matlab.  It now returns the central moment instead of the raw moment.
-    The old behavior can be had by passing the type argument "r" for raw.
+ ** Other new functions added in 4.0:
 
- ** The default name of the Octave crash dump file is now
-    "octave-workspace" instead of "octave-core".  The exact name can
-    always be customized with the octave_core_file_name function.
-
- ** A citation command has been added to display information on how to
-    cite Octave and packages in publications.  The package system will
-    look for and install CITATION files from packages.
-
- ** The java package from Octave Forge is now part of core Octave.  The
-    following new functions are available for interacting with Java
-    directly from Octave:
-
-      debug_java     java_matrix_autoconversion
-      isjava         java_set
-      java2mat       java_unsigned_autoconversion
-      javaArray      javaaddpath
-      javaMethod     javaclasspath
-      javaObject     javamem
-      java_get       javarmpath
-                     usejava
+      bandwidth
+      cubehelix
+      dir_in_loadpath
+      flip
+      frame2im
+      hgload
+      hgsave
+      ichol
+      ilu
+      im2frame
+      isbanded
+      isdiag
+      istril
+      istriu
+      javachk
+      linkaxes
+      lscov
+      numfields
+      qmr
+      rotate
+      sylvester
+      unsetenv
+      validateattributes
+      zoom
 
-    In addition, the following functions that use the Java interface
-    are now available (provided that Octave is compiled with support for
-    Java enabled):
-
-      helpdlg    listdlg   questdlg
-      inputdlg   msgbox    warndlg
-
- ** Other new functions added in 3.8.0:
+ ** inline() scheduled for eventual deprecation by Matlab
 
-      atan2d                     erfi             lines
-      base64_decode              expint           linsolve
-      base64_encode              findfigs         missing_component_hook
-      betaincinv                 flintmax         polyeig
-      built_in_docstrings_file   fminsearch       prefdir
-      cmpermute                  gallery          preferences
-      cmunique                   gco              readline_re_read_init_file
-      colorcube                  hdl2struct       readline_read_init_file
-      copyobj                    history_save     rgbplot
-      dawson                     imformats        save_default_options
-      dblist                     importdata       shrinkfaces
-      desktop                    isaxes           splinefit
-      doc_cache_create           iscolormap       stemleaf
-      ellipj                     isequaln         strjoin
-      ellipke                    jit_debug        struct2hdl
-      erfcinv                    jit_enable       tetramesh
-                                 jit_startcnt     waterfall
+    Functions created through the use of inline are scheduled for deprecation
+    by Matlab.  When this occurs Octave will continue to support inline
+    functions for an indeterminate amount of time before also removing support.
+    All new code should use anonymous functions in place of inline functions.
 
  ** Deprecated functions.
 
-    The following functions were deprecated in Octave 3.4 and have been
-    removed from Octave 3.8.
+    The following functions have been deprecated in Octave 4.0 and will
+    be removed from Octave 4.4 (or whatever version is the second major
+    release after 4.0):
 
-      autocor    dispatch              is_global    setstr
-      autocov    fstat                 krylovb      strerror
-      betai      gammai                perror       values
-      cellidx    glpkmex               replot
-      cquad      is_duplicate_entry    saveimage
+      Function             | Replacement
+      ---------------------|------------------
+      bicubic              | interp2
+      delaunay3            | delaunay
+      dump_prefs           | individual preference get/set routines
+      find_dir_in_path     | dir_in_loadpath
+      finite               | isfinite
+      fmod                 | rem
+      fnmatch              | glob or regexp
+      loadaudio            | audioread
+      luinc                | ilu or ichol
+      nfields              | numfields
+      octave_tmp_file_name | tempname
+      playaudio            | audioplayer
+      saveaudio            | audiowrite
+      syl                  | sylvester
+      usage                | print_usage
 
-    The following functions have been deprecated in Octave 3.8 and will
-    be removed from Octave 3.12 (or whatever version is the second major
+      allow_noninteger_range_as_index
+      do_braindead_shortcircuit_evaluation
+      setaudio
+
+ ** The following functions were deprecated in Octave 3.8 and will be
+    removed from Octave 4.2 (or whatever version is the second major
     release after 3.8):
 
-      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
+      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 have been deprecated in Octave 3.8 and will
-    be removed from Octave 3.12 (or whatever version is the second major
-    release after 3.8):
+ ** The following functions were deprecated in Octave 3.6 and have been
+    removed from Octave 4.0.
+
+      cut                polyderiv
+      cor                shell_cmd
+      corrcoef           studentize
+      __error_text__     sylvester_matrix
+      error_text
+
+ ** The following keywords were deprecated in Octave 3.8 and have been
+    removed from Octave 4.0
 
       static
 
-    The following configuration variables have been deprecated in Octave
-    3.8 and will be removed from Octave 3.12 (or whatever version is the
-    second major release after 3.8):
+ ** The following configuration variables were deprecated in Octave 3.8
+    and have been removed from Octave 4.0
 
       CC_VERSION  (now GCC_VERSION)
       CXX_VERSION (now GXX_VERSION)
 
-    The internal class <Octave_map> has been deprecated in Octave 3.8 and will
-    be removed from Octave 3.12 (or whatever version is the second major
-    release after 3.8).  Replacement classes are <octave_map> (struct array)
-    or <octave_scalar_map> for a single structure.
-
-Summary of important user-visible changes for version 3.6:
----------------------------------------------------------
-
- ** The PCRE library is now required to build Octave.  If a pre-compiled
-    package does not exist for your system, you can find PCRE sources
-    at http://www.pcre.org
-
- ** The ARPACK library is no longer distributed with Octave.
-    If you need the eigs or svds functions you must provide an
-    external ARPACK through a package manager or by compiling it
-    yourself.  If a pre-compiled package does not exist for your system,
-    you can find the current ARPACK sources at
-    http://forge.scilab.org/index.php/p/arpack-ng
-
- ** Many of Octave's binary operators (.*, .^, +, -, ...) now perform
-    automatic broadcasting for array operations which allows you to use
-    operator notation instead of calling bsxfun or expanding arrays (and
-    unnecessarily wasting memory) with repmat or similar idioms.  For
-    example, to scale the columns of a matrix by the elements of a row
-    vector, you may now write
-
-      rv .* M
-
-    In this expression, the number of elements of rv must match the
-    number of columns of M.  The following operators are affected:
-
-      plus      +  .+
-      minus     -  .-
-      times     .*
-      rdivide   ./
-      ldivide   .\
-      power     .^  .**
-      lt        <
-      le        <=
-      eq        ==
-      gt        >
-      ge        >=
-      ne        !=  ~=
-      and       &
-      or        |
-      atan2
-      hypot
-      max
-      min
-      mod
-      rem
-      xor
-
-    additionally, since the A op= B assignment operators are equivalent
-    to A = A op B, the following operators are also affected:
-
-      +=  -=  .+=  .-=  .*=  ./=  .\=  .^=  .**=  &=  |=
-
-    See the "Broadcasting" section in the new "Vectorization and Faster
-    Code Execution" chapter of the manual for more details.
-
- ** Octave now features a profiler, thanks to the work of Daniel Kraft
-    under the Google Summer of Code mentorship program.  The manual has
-    been updated to reflect this addition.  The new user-visible
-    functions are profile, profshow, and profexplore.
-
- ** Overhaul of statistical distribution functions
-
-    Functions now return "single" outputs for inputs of class "single".
+ ** The internal function atan2 of the sparse matrix class has been deprecated
+    in Octave 4.0 and will be removed from Octave 4.4 (or whatever version is
+    the second major release after 4.0).  Use the Fatan2 function with sparse
+    inputs as a replacement.
 
-    75% reduction in memory usage through use of logical indexing.
-
-    Random sample functions now use the same syntax as rand and accept
-    a comma separated list of dimensions or a dimension vector.
-
-    Functions have been made Matlab-compatible with regard to special
-    cases (probability on boundaries, probabilities for values outside
-    distribution, etc.).  This may cause subtle changes to existing
-    scripts.
-
-    negative binomial function has been extended to real, non-integer
-    inputs.  The discrete_inv function now returns v(1) for 0 instead of
-    NaN.  The nbincdf function has been recoded to use a closed form
-    solution with betainc.
-
- ** strread, textscan, and textread have been completely revamped.
-
-    They now support nearly all Matlab functionality including:
-
-      * Matlab-compatible whitespace and delimiter defaults
-
-      * Matlab-compatible options: 'whitespace', treatasempty', format
-        string repeat count, user-specified comment style, uneven-length
-        output arrays, %n and %u conversion specifiers (provisionally)
-
- ** All .m string functions have been modified for better performance or
-    greater Matlab compatibility.  Performance gains of 15X-30X have
-    been demonstrated.  Operations on cell array of strings no longer pay
-    quite as high a penalty as those on 2-D character arrays.
-
-      deblank:  Now requires character or cellstr input.
-
-      strtrim:  Now requires character or cellstr input.
-                No longer trims nulls ("\0") from string for Matlab
-                compatibility.
-
-      strmatch: Follows documentation precisely and ignores trailing spaces
-                in pattern and in string.  Note that this is documented
-                Matlab behavior but the implementation apparently does
-                not always follow it.
-
-      substr:   Now possible to specify a negative LEN option which
-                extracts to within LEN of the end of the string.
-
-      strtok:   Now accepts cellstr input.
-
-      base2dec, bin2dec, hex2dec:
-                Now accept cellstr inputs.
-
-      dec2base, dec2bin, dec2hex:
-                Now accept cellstr inputs.
-
-      index, rindex:
-                Now accept 2-D character array input.
-
-      strsplit: Now accepts 2-D character array input.
-
- ** Geometry functions derived from Qhull (convhull, delaunay, voronoi)
-    have been revamped.  The options passed to the underlying qhull
-    command have been changed for better results or for Matlab
-    compatibility.
-
-      convhull: Default options are "Qt" for 2D, 3D, 4D inputs
-                Default options are "Qt Qx" for 5D and higher
-
-      delaunay: Default options are "Qt Qbb Qc Qz" for 2D and 3D inputs
-                Default options are "Qt Qbb Qc Qx" for 4D and higher
-
-      voronoi:  No default arguments
+ ** The internal class <Octave_map> was deprecated in Octave 3.8 and has
+    been removed from Octave 4.0.  Replacement classes are
+    <octave_map> (struct array) or <octave_scalar_map> for a single structure.
 
- ** Date/Time functions updated.  Millisecond support with FFF format
-    string now supported.
-
-    datestr: Numerical formats 21, 22, 29 changed to match Matlab.
-             Now accepts cellstr input.
-
- ** The following warning IDs have been removed:
-
-      Octave:associativity-change
-      Octave:complex-cmp-ops
-      Octave:empty-list-elements
-      Octave:fortran-indexing
-      Octave:precedence-change
-
- ** The warning ID Octave:string-concat has been renamed to
-    Octave:mixed-string-concat.
-
- ** Octave now includes the following Matlab-compatible preference
-    functions:
-
-      addpref  getpref  ispref  rmpref  setpref
-
- ** The following Matlab-compatible handle graphics functions have been
-    added:
-
-      guidata         uipanel        uitoolbar
-      guihandles      uipushtool     uiwait
-      uicontextmenu   uiresume       waitfor
-      uicontrol       uitoggletool
-
-    The uiXXX functions above are experimental.
-
-    Except for uiwait and uiresume, the uiXXX functions are not
-    supported with the FLTK+OpenGL graphics toolkit.
-
-    The gnuplot graphics toolkit does not support any of the uiXXX
-    functions nor the waitfor function.
-
- ** New keyword parfor (parallel for loop) is now recognized as a valid
-    keyword.  Implementation, however, is still mapped to an ordinary
-    for loop.
-
- ** Other new functions added in 3.6.0:
-
-      bicg                       nthargout                   usejava
-      is_dq_string               narginchk                   waitbar
-      is_sq_string               python                      zscore
-      is_function_handle         register_graphics_toolkit
-      loaded_graphics_toolkits   recycle
-
- ** Deprecated functions.
-
-    The following functions were deprecated in Octave 3.2 and have been
-    removed from Octave 3.6.
-
-      create_set          spcholinv    splu
-      dmult               spcumprod    spmax
-      iscommand           spcumsum     spmin
-      israwcommand        spdet        spprod
-      lchol               spdiag       spqr
-      loadimage           spfind       spsum
-      mark_as_command     sphcat       spsumsq
-      mark_as_rawcommand  spinv        spvcat
-      spatan2             spkron       str2mat
-      spchol              splchol      unmark_command
-      spchol2inv          split        unmark_rawcommand
-
-    The following functions have been deprecated in Octave 3.6 and will
-    be removed from Octave 3.10 (or whatever version is the second major
-    release after 3.6):
+ ** The warning ID Octave:singular-matrix-div has been replaced by
+    Octave:nearly-singular-matrix and Octave:singular-matrix.
 
-      cut                is_duplicate_entry
-      cor                polyderiv
-      corrcoef           shell_cmd
-      __error_text__     studentize
-      error_text         sylvester_matrix
-
- ** The following functions have been modified for Matlab compatibility:
-
-      randperm
-
-Summary of important user-visible changes for version 3.4.3:
------------------------------------------------------------
-
- ** Octave 3.4.3 is a bug fixing release.
-
-Summary of important user-visible changes for version 3.4.2:
------------------------------------------------------------
-
- ** Octave 3.4.2 fixes some minor installation problems that affected
-    version 3.4.1.
-
-Summary of important user-visible changes for version 3.4.1:
------------------------------------------------------------
-
- ** Octave 3.4.1 is primarily a bug fixing release.
-
- ** IMPORTANT note about binary incompatibility in this release:
-
-    Binary compatibility for all 3.4.x releases was originally planned,
-    but this is impossible for the 3.4.1 release due to a bug in the way
-    shared libraries were built in Octave 3.4.0.  Because of this bug,
-    .oct files built for Octave 3.4.0 must be recompiled before they
-    will work with Octave 3.4.1.
+ ** The configure option --enable-octave-allocator has been removed.
+    The internal class <octave_allocator> declared in oct-alloc.h has
+    been removed.  The header remains, but is deprecated.  The macros to
+    access the class (DECLARE_OCTAVE_ALLOCATOR, DEFINE_OCTAVE_ALLOCATOR,
+    and DEFINE_OCTAVE_ALLOCATOR2) are now unconditionally defined to be
+    empty.
 
-    Given that there would be binary incompatibilities with shared
-    libraries going from Octave 3.4.0 to 3.4.1, the following
-    incompatible changes were also made in this release:
-
-      * The Perl Compatible Regular Expression (PCRE) library is now
-        required to build Octave.
-
-      * Octave's libraries and .oct files are now installed in
-        subdirectories of $libdir instead of $libexecdir.
-
-    Any future Octave 3.4.x release versions should remain binary
-    compatible with Octave 3.4.1 as proper library versioning is now
-    being used as recommended by the libtool manual.
-
- ** The following functions have been deprecated in Octave 3.4.1 and will
-    be removed from Octave 3.8 (or whatever version is the second major
-    release after 3.4):
-
-      cquad  is_duplicate_entry  perror  strerror
-
- ** The following functions are new in 3.4.1:
-
-      colstyle  gmres  iscolumn  isrow  mgorth  nproc  rectangle
-
- ** The get_forge_pkg function is now private.
-
- ** The rectangle_lw, rectangle_sw, triangle_lw, and triangle_sw
-    functions are now private.
-
- ** The logistic_regression_derivatives and logistic_regression_likelihood
-    functions are now private.
-
- ** ChangeLog files in the Octave sources are no longer maintained
-    by hand.  Instead, there is a single ChangeLog file generated from
-    the Mercurial version control commit messages.  Older ChangeLog
-    information can be found in the etc/OLD-ChangeLogs directory in the
-    source distribution.
-
-Summary of important user-visible changes for version 3.4:
 ---------------------------------------------------------
 
- ** BLAS and LAPACK libraries are now required to build Octave.  The
-    subset of the reference BLAS and LAPACK libraries has been removed
-    from the Octave sources.
-
- ** The ARPACK library is now distributed with Octave so it no longer
-    needs to be available as an external dependency when building
-    Octave.
-
- ** The `lookup' function was extended to be more useful for
-    general-purpose binary searching.  Using this improvement, the
-    ismember function was rewritten for significantly better
-    performance.
-
- ** Real, integer and logical matrices, when used in indexing, will now
-    cache the internal index_vector value (zero-based indices) when
-    successfully used as indices, eliminating the conversion penalty for
-    subsequent indexing by the same matrix.  In particular, this means it
-    is no longer needed to avoid repeated indexing by logical arrays
-    using find for performance reasons.
-
- ** Logical matrices are now treated more efficiently when used as
-    indices.  Octave will keep the index as a logical mask unless the
-    ratio of true elements is small enough, using a specialized
-    code.  Previously, all logical matrices were always first converted
-    to index vectors.  This results in savings in both memory and
-    computing time.
-
- ** The `sub2ind' and `ind2sub' functions were reimplemented as compiled
-    functions for better performance.  These functions are now faster,
-    can deliver more economized results for ranges, and can reuse the
-    index cache mechanism described in previous paragraph.
-
- ** The built-in function equivalents to associative operators (`plus',
-    `times', `mtimes', `and', and `or') have been extended to accept
-    multiple arguments.  This is especially useful for summing
-    (multiplying, etc.) lists of objects (of possibly distinct types):
-
-      matrix_sum = plus (matrix_list{:});
-
- ** An FTP object type based on libcurl has been implemented.  These
-    objects allow ftp connections, downloads and uploads to be
-    managed.  For example,
-
-      fp = ftp ("ftp.octave.org);
-      cd (fp, "gnu/octave");
-      mget (fp, "octave-3.2.3.tar.bz2");
-      close (fp);
-
- ** The default behavior of `assert (observed, expected)' has been
-    relaxed to employ less strict checking that does not require the
-    internals of the values to match.  This avoids previously valid
-    tests from breaking due to new internal classes introduced in future
-    Octave versions.
-
-    For instance, all of these assertions were true in Octave 3.0.x
-    but false in 3.2.x due to new optimizations and improvements:
-
-      assert (2*linspace (1, 5, 5), 2*(1:5))
-      assert (zeros (0, 0), [])
-      assert (2*ones (1, 5), (2) (ones (1,5)))
-
- ** The behavior of library functions `ismatrix', `issquare', and
-    `issymmetric' has been changed for better consistency.
-
-    * The `ismatrix' function now returns true for all numeric,
-      logical and character 2-D or N-D matrices.  Previously, `ismatrix'
-      returned false if the first or second dimension was zero.
-      Hence, `ismatrix ([])' was false,
-      while `ismatrix (zeros (1,2,0))' was true.
-
-    * The `issquare' function now returns a logical scalar, and is
-      equivalent to the expression
-
-        ismatrix (x) && ndims (x) == 2 && rows (x) == columns (x)
-
-      The dimension is no longer returned.  As a result, `issquare ([])'
-      now yields true.
-
-    * The `issymmetric' function now checks for symmetry instead of
-      Hermitianness.  For the latter, ishermitian was created.  Also,
-      logical scalar is returned rather than the dimension, so
-      `issymmetric ([])' is now true.
-
- ** Function handles are now aware of overloaded functions.  If a
-    function is overloaded, the handle determines at the time of its
-    reference which function to call.  A non-overloaded version does not
-    need to exist.
-
- ** Overloading functions for built-in classes (double, int8, cell,
-    etc.) is now compatible with Matlab.
-
- ** Function handles can now be compared with the == and != operators,
-    as well as the `isequal' function.
-
- ** Performance of concatenation (using []) and the functions `cat',
-    `horzcat', and `vertcat' has been improved for multidimensional
-    arrays.
-
- ** The operation-assignment operators +=, -=, *= and /= now behave more
-    efficiently in certain cases.  For instance, if M is a matrix and S a
-    scalar, then the statement
-
-      M += S;
-
-    will operate on M's data in-place if it is not shared by another
-    variable, usually increasing both time and memory efficiency.
-
-    Only selected common combinations are affected, namely:
-
-      matrix += matrix
-      matrix -= matrix
-      matrix .*= matrix
-      matrix ./= matrix
-
-      matrix += scalar
-      matrix -= scalar
-      matrix *= scalar
-      matrix /= scalar
-
-      logical matrix |= logical matrix
-      logical matrix &= logical matrix
-
-    where matrix and scalar belong to the same class.  The left-hand
-    side must be a simple variable reference.
-
-    Moreover, when unary operators occur in expressions, Octave will
-    also try to do the operation in-place if it's argument is a
-    temporary expression.
-
- ** The effect of comparison operators (<, >, <=, and >=) applied to
-    complex numbers has changed to be consistent with the strict
-    ordering defined by the `max', `min', and `sort' functions.  More
-    specifically, complex numbers are compared by lexicographical
-    comparison of the pairs `[abs(z), arg(z)]'.  Previously, only real
-    parts were compared; this can be trivially achieved by converting
-    the operands to real values with the `real' function.
-
- ** The automatic simplification of complex computation results has
-    changed.  Octave will now simplify any complex number with a zero
-    imaginary part or any complex matrix with all elements having zero
-    imaginary part to a real value.  Previously, this was done only for
-    positive zeros.  Note that the behavior of the complex function is
-    unchanged and it still produces a complex value even if the
-    imaginary part is zero.
-
- ** As a side effect of code refactoring in liboctave, the binary
-    logical operations are now more easily amenable to compiler
-    optimizations and are thus significantly faster.
-
- ** Octave now allows user-defined `subsasgn' methods to optimize out
-    redundant copies.  For more information, see the manual.
-
- ** More efficient matrix division handling.  Octave is now able to
-    handle the expressions
-
-      M' \ V
-      M.' \ V
-      V / M
-
-    (M is a matrix and V is a vector) more efficiently in certain cases.
-    In particular, if M is triangular, all three expressions will be
-    handled by a single call to xTRTRS (from LAPACK), with appropriate
-    flags.  Previously, all three expressions required a physical
-    transpose of M.
-
- ** More efficient handling of certain mixed real-complex matrix
-    operations.  For instance, if RM is a real matrix and CM a complex
-    matrix,
-
-      RM * CM
-
-    can now be evaluated either as
-
-      complex (RM * real (CM), RM * imag (CM))
-
-    or as
-
-      complex (RM) * CM,
-
-    depending on the dimensions.  The first form requires more
-    temporaries and copying, but halves the FLOP count, which normally
-    brings better performance if RM has enough rows.  Previously, the
-    second form was always used.
-
-    Matrix division is similarly affected.
-
- ** More efficient handling of triangular matrix factors returned from
-    factorizations.  The functions for computing QR, LU and Cholesky
-    factorizations will now automatically return the triangular matrix
-    factors with proper internal matrix_type set, so that it won't need
-    to be computed when the matrix is used for division.
-
- ** The built-in `sum' function now handles the non-native summation
-    (i.e., double precision sum of single or integer inputs) more
-    efficiently, avoiding a temporary conversion of the whole input
-    array to doubles.  Further, `sum' can now accept an extra option
-    argument, using a compensated summation algorithm rather than a
-    straightforward sum, which significantly improves precision if lots
-    of cancellation occurs in the summation.
-
- ** The built-in `bsxfun' function now uses optimized code for certain
-    cases where built-in operator handles are passed in.  Namely, the
-    optimizations concern the operators `plus', `minus', `times',
-    `ldivide', `rdivide', `power', `and', `or' (for logical arrays),
-    the relational operators `eq', `ne', `lt', `le', `gt', `ge', and the
-    functions `min' and `max'.  Optimizations only apply when both
-    operands are of the same built-in class.  Mixed real/complex and
-    single/double operations will first convert both operands to a
-    common type.
-
- ** The `strfind' and `strrep' functions now have compiled
-    implementations, facilitating significantly more efficient searching
-    and replacing in strings, especially with longer patterns.  The code
-    of `strcat' has been vectorized and is now much more efficient when
-    many strings are concatenated.  The `strcmpi' and `strncmpi'
-    functions are now built-in functions, providing better performance.
-
- ** 'str2double' now has a compiled implementation and the API conforms
-    to Matlab.  The additional Octave-specific features of returning a
-    boolean matrix indicating which elements were successfully converted
-    has been removed.
-
- ** Matlab-style ignoring input and output function arguments using
-    tilde (~) is now supported.  Ignored output arguments may be
-    detected from a function using the built-in function `isargout'.
-    For more details, consult the manual.
-
- ** The list datatype, deprecated since the introduction of cells, has
-    been removed.
-
- ** The accumarray function has been optimized and is now significantly
-    faster in certain important cases.
-
- ** The behavior of isreal and isnumeric functions was changed to be more
-    Matlab-compatible.
-
- ** The integer math & conversion warnings (Octave:int-convert-nan,
-    Octave:int-convert-non-int-val, Octave:int-convert-overflow,
-    Octave:int-math-overflow) have been removed.
-
- ** rem and mod are now built-in functions.  They also handle integer
-    types efficiently using integer arithmetic.
-
- ** Sparse indexing and indexed assignment has been mostly rewritten.
-    Since Octave uses compressed column storage for sparse matrices,
-    major attention is devoted to operations manipulating whole columns.
-    Such operations are now significantly faster, as well as some other
-    important cases.
-
-    Further, it is now possible to pre-allocate a sparse matrix and
-    subsequently fill it by assignments, provided they meet certain
-    conditions.  For more information, consult the `spalloc' function,
-    which is no longer a mere dummy.  Consequently, nzmax and nnz are no
-    longer always equal in Octave.  Octave may also produce a matrix
-    with nnz < nzmax as a result of other operations, so you should
-    consistently use nnz unless you really want to use nzmax (i.e., the
-    space allocated for nonzero elements).
-
-    Sparse concatenation is also affected, and concatenating sparse
-    matrices, especially larger collections, is now significantly more
-    efficient.  This applies to both the [] operator and the
-    cat/vertcat/horzcat functions.
-
- ** It is now possible to optionally employ the xGESDD LAPACK drivers
-    for computing the singular value decomposition using svd, instead
-    of the default xGESVD, using the configuration pseudo-variable
-    svd_driver.  The xGESDD driver can be up to 6x times faster when
-    singular vectors are requested, but is reported to be somewhat less
-    robust on highly ill-conditioned matrices.
-
- ** Configuration pseudo-variables, such as page_screen_output or
-    confirm_recursive_rmdir (or the above mentioned svd_driver), now
-    accept a "local" option as second argument, requesting the change
-    to be undone when the current function returns:
-
-    function [status, msg] = rm_rf (dir)
-      confirm_recursive_rmdir (false, "local");
-      [status, msg] = rmdir (dir, "s");
-      ...
-    endfunction
-
-    Upon return, confirm_recursive_rmdir will be restored to the value
-    it had on entry to the function, even if there were subsequent
-    changes to the variable in function rm_rf or any of the functions
-    it calls.
-
- ** pkg now accepts a -forge option for downloading and installing
-    packages from Octave Forge automatically.  For example,
-
-      pkg install -forge general
-
-    will automatically download the latest release of the general
-    package and attempt to install it.  No automatic resolving of
-    dependencies is provided.  Further,
-
-      pkg list -forge
-
-    can be used to list all available packages.
-
- ** The internal data representation of structs has been completely
-    rewritten to make certain optimizations feasible.  The field data
-    can now be shared between structs with equal keys but different
-    dimensions or values, making operations that preserve the fields
-    faster.  Economized storage is now used for scalar structs (just
-    like most other scalars), making their usage more
-    memory-efficient.  Certain array-like operations on structs
-    (concatenation, uniform cellfun, num2cell) have gained a
-    significant speed-up.  Additionally, the octave_scalar_map class
-    now provides a simpler interface to work with scalar structs within
-    a C++ DLD function.
-
- ** Two new formats are available for displaying numbers:
-
-      format short eng
-      format long eng
-
-    Both display numbers in engineering notation, i.e., mantissa +
-    exponent where the exponent is a multiple of 3.
-
- ** The following functions are new in Octave 3.4:
-      accumdim    erfcx        nfields      pqpnonneg  uigetdir
-      bitpack     fileread     nth_element  quadcc     uigetfile
-      bitunpack   fminbnd      onCleanup    randi      uiputfile
-      blkmm       fskipl       pbaspect     repelems   uimenu
-      cbrt        ifelse       pie3         reset      whitebg
-      curl        ishermitian  powerset     rsf2csf
-      chop        isindex      ppder        saveas
-      daspect     luupdate     ppint        strread
-      divergence  merge        ppjumps      textread
-
- ** Using the image function to view images with external programs such
-    as display, xv, and xloadimage is no longer supported.  The
-    image_viewer function has also been removed.
-
- ** The behavior of struct assignments to non-struct values has been
-    changed.  Previously, it was possible to overwrite an arbitrary
-    value:
-
-      a = 1;
-      a.x = 2;
-
-    This is no longer possible unless a is an empty matrix or cell
-    array.
-
- ** The dlmread function has been extended to allow specifying a custom
-    value for empty fields.
-
- ** The dlmread and dlmwrite functions have been modified to accept
-    file IDs (as returned by fopen) in addition to file names.
-
- ** Octave can now optimize away the interpreter overhead of an
-    anonymous function handle, if the function simply calls another
-    function or handle with some of its parameters bound to certain
-    values.  Example:
-
-      f = @(x) sum (x, 1);
-
-    When f is called, the call is forwarded to @sum with the constant 1
-    appended, and the anonymous function call does not occur on the
-    call stack.
-
- ** For compatibility with Matlab, mu2lin (x) is now equivalent to
-    mu2lin (x, 0).
-
- ** The new function `history_control' may be used to control the way
-    command lines are added to the history list when Octave is using
-    readline for command-line editing.  For example
-
-      history_control ("ignoredups")
-
-    tells Octave to avoid adding duplicate lines to the history list.
-
- ** Octave now uses the gnulib library for improved portability and to
-    avoid bugs in operating system functions.
-
- ** Deprecated functions.
-
-    The following functions were deprecated in Octave 3.0 and have been
-    removed from Octave 3.4.
-
-      beta_cdf         geometric_pdf        pascal_pdf
-      beta_inv         geometric_rnd        pascal_rnd
-      beta_pdf         hypergeometric_cdf   poisson_cdf
-      beta_rnd         hypergeometric_inv   poisson_inv
-      binomial_cdf     hypergeometric_pdf   poisson_pdf
-      binomial_inv     hypergeometric_rnd   poisson_rnd
-      binomial_pdf     intersection         polyinteg
-      binomial_rnd     is_bool              setstr
-      chisquare_cdf    is_complex           struct_contains
-      chisquare_inv    is_list              struct_elements
-      chisquare_pdf    is_matrix            t_cdf
-      chisquare_rnd    is_scalar            t_inv
-      clearplot        is_square            t_pdf
-      clg              is_stream            t_rnd
-      com2str          is_struct            uniform_cdf
-      exponential_cdf  is_symmetric         uniform_inv
-      exponential_inv  is_vector            uniform_pdf
-      exponential_pdf  isstr                uniform_rnd
-      exponential_rnd  lognormal_cdf        weibcdf
-      f_cdf            lognormal_inv        weibinv
-      f_inv            lognormal_pdf        weibpdf
-      f_pdf            lognormal_rnd        weibrnd
-      f_rnd            meshdom              weibull_cdf
-      gamma_cdf        normal_cdf           weibull_inv
-      gamma_inv        normal_inv           weibull_pdf
-      gamma_pdf        normal_pdf           weibull_rnd
-      gamma_rnd        normal_rnd           wiener_rnd
-      geometric_cdf    pascal_cdf
-      geometric_inv    pascal_inv
-
-    The following functions were deprecated in Octave 3.2 and will
-    be removed from Octave 3.6 (or whatever version is the second major
-    release after 3.2):
-
-      create_set          spcholinv    splu
-      dmult               spcumprod    spmax
-      iscommand           spcumsum     spmin
-      israwcommand        spdet        spprod
-      lchol               spdiag       spqr
-      loadimage           spfind       spsum
-      mark_as_command     sphcat       spsumsq
-      mark_as_rawcommand  spinv        spvcat
-      spatan2             spkron       str2mat
-      spchol              splchol      unmark_command
-      spchol2inv          split        unmark_rawcommand
-
-    The following functions have been deprecated in Octave 3.4 and will
-    be removed from Octave 3.8 (or whatever version is the second major
-    release after 3.4):
-
-      autocor  cellidx   gammai     is_global  replot     values
-      autocov  dispatch  glpkmex    krylovb    saveimage
-      betai    fstat     intwarning perror     strerror
-
-Summary of important user-visible changes for version 3.2:
----------------------------------------------------------
-
- ** Compatibility with Matlab graphics has been improved.
-
-    The hggroup object and associated listener callback functions have
-    been added allowing the inclusion of group objects.  Data sources
-    have been added to these group objects such that
-
-           x = 0:0.1:10;
-           y = sin (x);
-           plot (x, y, "ydatasource", "y");
-           for i = 1 : 100
-             pause(0.1)
-             y = sin (x + 0.1 * i);
-             refreshdata ();
-           endfor
-
-    works as expected.  This capability has be used to introduce
-    stem-series, bar-series, etc., objects for better Matlab
-    compatibility.
-
- ** New graphics functions:
-
-      addlistener                  ezcontour   gcbo         refresh
-      addproperty                  ezcontourf  ginput       refreshdata
-      allchild                     ezmesh      gtext        specular
-      available_graphics_toolkits  ezmeshc     intwarning   surfl
-      graphics_toolkit             ezplot      ishghandle   trisurf
-      cla                          ezplot3     isocolors    waitforbuttonpress
-      clabel                       ezpolar     isonormals
-      comet                        ezsurf      isosurface
-      dellistener                  findall     linkprop
-      diffuse                      gcbf        plotmatrix
-
- ** New experimental OpenGL/FLTK based plotting system.
-
-    An experimental plotting system based on OpenGL and the FLTK
-    toolkit is now part of Octave.  This graphics toolkit is disabled by
-    default.  You can switch to using it with the command
-
-        graphics_toolkit ("fltk")
-
-    for all future figures or for a particular figure with the command
-
-        graphics_toolkit (h, "fltk")
-
-    where "h" is a valid figure handle.
-
- ** Functions providing direct access to gnuplot have been removed.
-
-    The functions __gnuplot_plot__, __gnuplot_set__, __gnuplot_raw__,
-     __gnuplot_show__, __gnuplot_replot__, __gnuplot_splot__,
-     __gnuplot_save_data__ and __gnuplot_send_inline_data__ have been
-     removed from Octave.  These function were incompatible with the
-     high level graphics handle code.
-
- ** The Control, Finance and Quaternion functions have been removed.
-
-    These functions are now available as separate packages from
-
-      http://octave.sourceforge.net/packages.html
-
-    and can be reinstalled using the Octave package manager (see
-    the pkg function).
-
- ** Specific sparse matrix functions removed.
-
-    The following functions, which handled only sparse matrices have
-    been removed.  Instead of calling these functions directly, you
-    should use the corresponding function without the "sp" prefix.
-
-      spatan2     spcumsum  spkron   spprod
-      spchol      spdet     splchol  spqr
-      spchol2inv  spdiag    splu     spsum
-      spcholinv   spfind    spmax    spsumsqk
-      spcumprod   spinv     spmin
-
- ** Improvements to the debugger.
-
-    The interactive debugging features have been improved.  Stopping
-    on statements with dbstop should work correctly now.  Stepping
-    into and over functions, and stepping one statement at a time
-    (with dbstep) now works.  Moving up and down the call stack with
-    dbup and dbdown now works.  The dbstack function is now available
-    to print the current function call stack.  The new dbquit function
-    is available to exit the debugging mode.
-
- ** Improved traceback error messages.
-
-    Traceback error messages are much more concise and easier to
-    understand.  They now display information about the function call
-    stack instead of the stack of all statements that were active at
-    the point of the error.
-
- ** Object Oriented Programming.
-
-    Octave now includes OOP features and the user can create their own
-    class objects and overloaded functions and operators.  For
-    example, all methods of a class called "myclass" will be found in
-    a directory "@myclass" on the users path.  The class specific
-    versions of functions and operators take precedence over the
-    generic versions of these functions.
-
-    New functions related to OOP include
-
-      class  inferiorto  isobject  loadobj  methods  superiorto
-
-    See the Octave manual for more details.
-
- ** Parsing of Command-style Functions.
-
-    Octave now parses command-style functions without needing to first
-    declare them with "mark_as_command".  The rules for recognizing a
-    command-style function calls are
-
-      * A command must appear as the first word in a statement,
-        followed by a space.
-
-      * The first character after the space must not be '=' or '('
-
-      * The next token after the space must not look like a binary
-        operator.
-
-    These rules should be mostly compatible with the way Matlab parses
-    command-style function calls and allow users to define commands in
-    .m files without having to mark them as commands.
-
-    Note that previous versions of Octave allowed expressions like
-
-      x = load -text foo.dat
-
-    but an expression like this will now generate a parse error.  In
-    order to assign the value returned by a function to a variable,
-    you must use the normal function call syntax:
-
-      x = load ("-text", "foo.dat");
-
- ** Block comments.
-
-    Commented code can be between matching "#{" and "#}" or "%{" and
-    "%}" markers, even if the commented code spans several line.  This
-    allows blocks code to be commented, without needing to comment
-    each line.  For example,
-
-    function [s, t] = func (x, y)
-      s = 2 * x;
-    #{
-      s *= y;
-      t = y + x;
-    #}
-    endfunction
-
-    the lines "s *= y;" and "t = y + x" will not be executed.
-
- ** If any subfunction in a file ends with "end" or "endfunction", then
-    they all must end that way.  Previously, Octave accepted
-
-      function main ()
-        ...
-      # no endfunction here.
-      function sub ()
-        ...
-      endfunction
-
-    but this is no longer allowed.
-
- ** Special treatment in the parser of expressions like "a' * b".
-
-    In these cases the transpose is no longer explicitly formed and
-    BLAS libraries are called with the transpose flagged,
-    significantly improving performance for these kinds of
-    operations.
-
- ** Single Precision data type.
-
-    Octave now includes a single precision data type.  Single
-    precision variables can be created with the "single" command, or
-    from functions like ones, eye, etc.  For example,
-
-      single (1)
-      ones (2, 2, "single")
-      zeros (2, 2, "single")
-      eye (2, 2, "single")
-      Inf (2, 2, "single")
-      NaN (2, 2, "single")
-      NA (2, 2, "single")
-
-    all create single precision variables.  For compatibility with
-    Matlab, mixed double/single precision operators and functions
-    return single precision types.
-
-    As a consequence of this addition to Octave the internal
-    representation of the double precision NA value has changed, and
-    so users that make use of data generated by Octave with R or
-    visa-versa are warned that compatibility might not be assured.
-
- ** Improved array indexing.
-
-    The underlying code used for indexing of arrays has been
-    completely rewritten and indexing is now significantly faster.
-
- ** Improved memory management.
-
-    Octave will now attempt to share data in some cases where previously
-    a copy would be made, such as certain array slicing operations or
-    conversions between cells, structs and cs-lists.  This usually reduces
-    both time and memory consumption.
-    Also, Octave will now attempt to detect and optimize usage of a vector
-    as a stack, when elements are being repeatedly inserted at/removed from
-    the end of the vector.
-
- ** Improved performance for reduction operations.
-
-    The performance of the sum, prod, sumsq, cumsum, cumprod, any, all,
-    max and min functions has been significantly improved.
-
- ** Sorting and searching.
-
-    The performance of sort has been improved, especially when sorting
-    indices are requested.  An efficient built-in issorted
-    implementation was added.  The sortrows function now uses a more
-    efficient algorithm, especially in the homogeneous case.  The lookup
-    function is now a built-in function performing a binary search,
-    optimized for long runs of close elements.  Lookup also works with
-    cell arrays of strings.
-
- ** Range arithmetics
-
-    For some operations on ranges, Octave will attempt to keep the
-    result as a range.  These include negation, adding a scalar,
-    subtracting a scalar, and multiplying by a scalar.  Ranges with zero
-    increment are allowed and can be constructed using the built-in
-    function `ones'.
-
- ** Various performance improvements.
-
-    Performance of a number of other built-in operations and functions
-    was improved, including:
-
-    * logical operations
-    * comparison operators
-    * element-wise power
-    * accumarray
-    * cellfun
-    * isnan
-    * isinf
-    * isfinite
-    * nchoosek
-    * repmat
-    * strcmp
-
- ** 64-bit integer arithmetic.
-
-    Arithmetic with 64-bit integers (int64 and uint64 types) is fully
-    supported, with saturation semantics like the other integer types.
-    Performance of most integer arithmetic operations has been
-    improved by using integer arithmetic directly.  Previously, Octave
-    performed integer math with saturation semantics by converting the
-    operands to double precision, performing the operation, and then
-    converting the result back to an integer value, truncating if
-    necessary.
-
- ** Diagonal and permutation matrices.
-
-    The interpreter can now treat diagonal and permutation matrices as
-    special objects that store only the non-zero elements, rather than
-    general full matrices.  Therefore, it is now possible to construct
-    and use these matrices in linear algebra without suffering a
-    performance penalty due to storing large numbers of zero elements.
-
- ** Improvements to fsolve.
-
-    The fsolve function now accepts an option structure argument (see
-    also the optimset function).  The INFO values returned from fsolve
-    have changed to be compatible with Matlab's fsolve function.
-    Additionally, fsolve is now able to solve overdetermined systems,
-    complex-differentiable complex systems, systems with a sparse
-    jacobian and can work in single precision if given single precision
-    inputs.  It can also be called recursively.
-
- ** Improvements to the norm function.
-
-    The norm function is now able to compute row or column norms of a
-    matrix in a single call, as well as general matrix p-norms.
-
- ** New functions for computing some eigenvalues or singular values.
-
-    The eigs and svds functions have been included in Octave.  These
-    functions require the ARPACK library (now distributed under a
-    GPL-compatible license).
-
- ** New QR and Cholesky factorization updating functions.
-
-      choldelete  cholshift   qrdelete  qrshift
-      cholinsert  cholupdate  qrinsert  qrupdate
-
- ** New quadrature functions.
-
-      dblquad  quadgk  quadv  triplequad
-
- ** New functions for reading and writing images.
-
-    The imwrite and imread functions have been included in Octave.
-    These functions require the GraphicsMagick library.  The new
-    function imfinfo provides information about an image file (size,
-    type, colors, etc.)
-
- ** The input_event_hook function has been replaced by the pair of
-    functions add_input_event_hook and remove_input_event_hook so that
-    more than one hook function may be installed at a time.
-
- ** Other miscellaneous new functions.
-
-      addtodate          hypot                       reallog
-      bicgstab           idivide                     realpow
-      cellslices         info                        realsqrt
-      cgs                interp1q                    rectint
-      command_line_path  isdebugmode                 regexptranslate
-      contrast           isfloat                     restoredefaultpath
-      convn              isstrprop                   roundb
-      cummin             log1p                       rundemos
-      cummax             lsqnonneg                   runlength
-      datetick           matlabroot                  saveobj
-      display            namelengthmax               spaugment
-      expm1              nargoutchk                  strchr
-      filemarker         pathdef                     strvcat
-      fstat              perl                        subspace
-      full               prctile                     symvar
-      fzero              quantile                    treelayout
-      genvarname         re_read_readline_init_file  validatestring
-      histc
-
- ** Changes to strcat.
-
-    The strcat function is now compatible with Matlab's strcat
-    function, which removes trailing whitespace when concatenating
-    character strings.  For example
-
-      strcat ('foo ', 'bar')
-      ==> 'foobar'
-
-    The new function cstrcat provides the previous behavior of
-    Octave's strcat.
-
- ** Improvements to the help functions.
-
-    The help system has been mostly re-implemented in .m files to make
-    it easier to modify.  Performance of the lookfor function has been
-    greatly improved by caching the help text from all functions that
-    are distributed with Octave.  The pkg function has been modified
-    to generate cache files for external packages when they are
-    installed.
-
- ** Deprecated functions.
-
-    The following functions were deprecated in Octave 3.0 and will be
-    removed from Octave 3.4 (or whatever version is the second major
-    release after 3.0):
-
-      beta_cdf         geometric_pdf       pascal_pdf
-      beta_inv         geometric_rnd       pascal_rnd
-      beta_pdf         hypergeometric_cdf  poisson_cdf
-      beta_rnd         hypergeometric_inv  poisson_inv
-      binomial_cdf     hypergeometric_pdf  poisson_pdf
-      binomial_inv     hypergeometric_rnd  poisson_rnd
-      binomial_pdf     intersection        polyinteg
-      binomial_rnd     is_bool             setstr
-      chisquare_cdf    is_complex          struct_contains
-      chisquare_inv    is_list             struct_elements
-      chisquare_pdf    is_matrix           t_cdf
-      chisquare_rnd    is_scalar           t_inv
-      clearplot        is_square           t_pdf
-      clg              is_stream           t_rnd
-      com2str          is_struct           uniform_cdf
-      exponential_cdf  is_symmetric        uniform_inv
-      exponential_inv  is_vector           uniform_pdf
-      exponential_pdf  isstr               uniform_rnd
-      exponential_rnd  lognormal_cdf       weibcdf
-      f_cdf            lognormal_inv       weibinv
-      f_inv            lognormal_pdf       weibpdf
-      f_pdf            lognormal_rnd       weibrnd
-      f_rnd            meshdom             weibull_cdf
-      gamma_cdf        normal_cdf          weibull_inv
-      gamma_inv        normal_inv          weibull_pdf
-      gamma_pdf        normal_pdf          weibull_rnd
-      gamma_rnd        normal_rnd          wiener_rnd
-      geometric_cdf    pascal_cdf
-      geometric_inv    pascal_inv
-
-    The following functions are now deprecated in Octave 3.2 and will
-    be removed from Octave 3.6 (or whatever version is the second major
-    release after 3.2):
-
-      create_set          spcholinv  spmax
-      dmult               spcumprod  spmin
-      iscommand           spcumsum   spprod
-      israwcommand        spdet      spqr
-      lchol               spdiag     spsum
-      loadimage           spfind     spsumsq
-      mark_as_command     spinv      str2mat
-      mark_as_rawcommand  spkron     unmark_command
-      spatan2             splchol    unmark_rawcommand
-      spchol              split
-      spchol2inv          splu
-
 See NEWS.3 for old news.
--- a/README	Fri Feb 06 08:31:09 2015 -0800
+++ b/README	Fri Feb 06 08:31:49 2015 -0800
@@ -49,9 +49,9 @@
 features of GNU Make that are not present in other versions of make.
 GNU Make is very portable and easy to install.
 
-See the notes in the files INSTALL and the system-specific README files
-in the etc directory of the Octave source distribution for more specific
-installation instructions.
+See the notes in the files INSTALL.OCTAVE and the system-specific README
+files in the etc directory of the Octave source distribution for more
+specific installation instructions.
 
 Bugs and Patches
 ----------------
--- a/bootstrap.conf	Fri Feb 06 08:31:09 2015 -0800
+++ b/bootstrap.conf	Fri Feb 06 08:31:49 2015 -0800
@@ -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
@@ -91,6 +93,7 @@
   sys_stat
   sys_time
   sys_times
+  tempname
   time
   times
   tmpfile
@@ -99,6 +102,7 @@
   uname
   unistd
   unlink
+  unsetenv
   vasprintf
 "
 
@@ -188,19 +192,3 @@
   (cd libinterp/dldfcn; ./config-module.sh)
 }
 
-bootstrap_epilogue ()
-{
-  ## G77 is obsolete, but it is still the first option in the autoconf
-  ## Fortran macros.  We should avoid it, because mixing old versions of
-  ## g77 with modern gcc and g++ causes trouble.  The following will
-  ## make it harder (but not impossible) for users to make this mistake.
-  ##
-  ## FIXME -- we should really work to fix autoconf so that it prefers
-  ## gfortran over g77 even when searching for a Fortran 77 compiler.
-
-  echo "replacing all occurrences of g77 with gfortran in configure script..."
-
-  sed 's/g77/gfortran/g' configure > configure.t
-  mv configure.t configure
-  chmod 755 configure
-}
--- a/build-aux/common.mk	Fri Feb 06 08:31:09 2015 -0800
+++ b/build-aux/common.mk	Fri Feb 06 08:31:49 2015 -0800
@@ -91,7 +91,6 @@
 
 # Fortran compiler flags.
 
-FC = @FC@
 F77 = @F77@
 AM_FFLAGS = @FFLAGS@
 FPICFLAG = @FPICFLAG@
@@ -108,14 +107,11 @@
 # 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@
 WARN_CFLAGS = @WARN_CFLAGS@
 AM_CFLAGS = $(XTRA_CFLAGS)
-ALL_CPPFLAGS = $(CPPFLAGS) $(HDF5_CPPFLAGS) $(Z_CPPFLAGS) $(LLVM_CPPFLAGS)
 
 BUILD_CC = @BUILD_CC@
 BUILD_CFLAGS = @BUILD_CFLAGS@
@@ -132,8 +128,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@
@@ -319,11 +313,6 @@
 USE_64_BIT_IDX_T = @USE_64_BIT_IDX_T@
 OCTAVE_IDX_TYPE = @OCTAVE_IDX_TYPE@
 
-TEXINFO_COLAMD = @TEXINFO_COLAMD@
-TEXINFO_CHOLMOD = @TEXINFO_CHOLMOD@
-TEXINFO_UMFPACK = @TEXINFO_UMFPACK@
-TEXINFO_QHULL = @TEXINFO_QHULL@
-
 # The arguments passed to configure.
 config_opts = @config_opts@
 
@@ -449,6 +438,9 @@
 localapioctfiledir = @localapioctfiledir@
 localveroctfiledir = @localveroctfiledir@
 
+# Where Octave will search for example data files shipped with distribution.
+octdatadir = @octdatadir@
+
 # Where Octave will search to find image files.
 imagedir = @imagedir@
 
@@ -519,7 +511,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}\"|" \
@@ -557,7 +548,6 @@
   -e "s|%OCTAVE_CONF_F77%|\"${F77}\"|" \
   -e "s|%OCTAVE_CONF_F77_FLOAT_STORE_FLAG%|\"${F77_FLOAT_STORE_FLAG}\"|" \
   -e "s|%OCTAVE_CONF_F77_INTEGER_8_FLAG%|\"${F77_INTEGER_8_FLAG}\"|" \
-  -e "s|%OCTAVE_CONF_FC%|\"${FC}\"|" \
   -e "s|%OCTAVE_CONF_FFLAGS%|\"${FFLAGS}\"|" \
   -e "s|%OCTAVE_CONF_FFTW3_CPPFLAGS%|\"${FFTW3_CPPFLAGS}\"|" \
   -e "s|%OCTAVE_CONF_FFTW3_LDFLAGS%|\"${FFTW3_LDFLAGS}\"|" \
@@ -694,6 +684,7 @@
   -e "s|%OCTAVE_MAN1DIR%|\"${man1dir}\"|" \
   -e "s|%OCTAVE_MAN1EXT%|\"${man1ext}\"|" \
   -e "s|%OCTAVE_MANDIR%|\"${mandir}\"|" \
+  -e "s|%OCTAVE_OCTDATADIR%|\"${octdatadir}\"|" \
   -e "s|%OCTAVE_OCTFILEDIR%|\"${octfiledir}\"|" \
   -e "s|%OCTAVE_OCTETCDIR%|\"${octetcdir}\"|" \
   -e "s|%OCTAVE_OCTINCLUDEDIR%|\"${octincludedir}\"|" \
--- a/configure.ac	Fri Feb 06 08:31:09 2015 -0800
+++ b/configure.ac	Fri Feb 06 08:31:49 2015 -0800
@@ -19,21 +19,21 @@
 ### <http://www.gnu.org/licenses/>.
 
 AC_PREREQ([2.62])
-AC_INIT([GNU Octave], [3.8.2], [http://octave.org/bugs.html], [octave])
+AC_INIT([GNU Octave], [3.9.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=8
-OCTAVE_PATCH_VERSION=2
+OCTAVE_MINOR_VERSION=9
+OCTAVE_PATCH_VERSION=0+
 
 dnl PACKAGE_VERSION is set by the AC_INIT VERSION arg
 OCTAVE_VERSION="$PACKAGE_VERSION"
 
-OCTAVE_COPYRIGHT="Copyright (C) 2014 John W. Eaton and others."
-
-OCTAVE_RELEASE_DATE="2014-08-06"
+OCTAVE_COPYRIGHT="Copyright (C) 2013 John W. Eaton and others."
+
+OCTAVE_RELEASE_DATE="2014-07-01"
 
 ## The "API version" is used as a way of checking that interfaces in the
 ## liboctave and libinterp libraries haven't changed in a backwardly
@@ -113,6 +113,7 @@
 OCTAVE_SET_DEFAULT([octtestsdir], '$(octetcdir)/tests')
 OCTAVE_SET_DEFAULT([texi_macros_file], '$(octetcdir)/macros.texi')
 OCTAVE_SET_DEFAULT([imagedir], '$(datadir)/octave/$(version)/imagelib')
+OCTAVE_SET_DEFAULT([octdatadir], '$(datadir)/octave/$(version)/data')
 OCTAVE_SET_DEFAULT([man1dir], '$(mandir)/man1')
 OCTAVE_SET_DEFAULT([man1ext], '.1')
 OCTAVE_SET_DEFAULT([infofile], '$(infodir)/octave.info')
@@ -231,28 +232,15 @@
   AC_DEFINE(BOUNDS_CHECKING, 1, [Define to 1 to use internal bounds checking.])
 fi
 
-### Use Octave's built-in memory allocator rather than straightforward malloc.
-### Disabled by default.
-
-USE_OCTAVE_ALLOCATOR=no
-AC_ARG_ENABLE([octave-allocator],
-  [AS_HELP_STRING([--enable-octave-allocator],
-    [use the obsolete octave_allocator class for many of Octave's objects (mostly octave_value types).  You probably do NOT want to enable this feature.])],
-  [if test "$enableval" = yes; then USE_OCTAVE_ALLOCATOR=yes; fi], [])
-if test $USE_OCTAVE_ALLOCATOR = yes; then
-  AC_DEFINE(USE_OCTAVE_ALLOCATOR, 1,
-    [Define to 1 to use octave_allocator class.])
-fi
-
 ### Use atomic operations for internal reference counting.  This is required
-### for thread-safe behavior but incurs a significant slowdown, and is thus
-### disabled by default.
-
-USE_ATOMIC_REFCOUNT=no
+### for thread-safe behavior (Qt Handles) but incurs a significant slowdown.
+### Enabled by default until a higher performing solution can be found.
+
+USE_ATOMIC_REFCOUNT=yes
 AC_ARG_ENABLE([atomic-refcount],
-  [AS_HELP_STRING([--enable-atomic-refcount],
-    [use atomic operations for internal reference counting.  This is required for thread-safe behavior but does not by itself make Octave internals thread safe.])],
-  [if test "$enableval" = yes; then USE_ATOMIC_REFCOUNT=yes; fi], [])
+  [AS_HELP_STRING([--disable-atomic-refcount],
+    [Do not use atomic operations for internal reference counting.  This option is required for thread-safe behavior as used in the GUI's Qt plotting toolkit.  Performance for CLI-only builds is improved by disabling this feature.])],
+  [if test "$enableval" = no; then USE_ATOMIC_REFCOUNT=no; fi], [])
 if test $USE_ATOMIC_REFCOUNT = yes; then
   AC_DEFINE(USE_ATOMIC_REFCOUNT, 1,
     [Define to 1 to use atomic operations for reference counting.])
@@ -315,24 +303,6 @@
 AC_PROG_CXX
 AC_PROG_CXXCPP
 
-### Check version number when using g++.
-
-GXX_VERSION=
-if test "$GXX" = yes; then
-  gxx_version=`$CXX -v 2>&1 | $GREP "^.*g.. version" | \
-    $SED -e 's/^.*g.. version *//' -e 's/cygnus-//' -e 's/egcs-//' -e 's/ .*//'`
-
-  AX_COMPARE_VERSION([$gxx_version], [lt], [3.5],
-    [AC_MSG_ERROR([g++ version $gxx_version will probably fail to compile Octave])])
-
-  GXX_VERSION=$gxx_version
-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,12 +349,8 @@
 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.
+### Check version number when using g++ .
+### It might be different from the gcc version number.
 
 GXX_VERSION=
 if test "$GXX" = yes; then
@@ -392,7 +358,7 @@
   gxx_version=`$CXX -v 2>&1 | $GREP "^.*g.. version" | \
     $SED -e 's/^.*g.. version *//' -e 's/cygnus-//' -e 's/egcs-//' -e 's/ .*//'`
 
-  AX_COMPARE_VERSION([$gxx_version], [lt], [3],
+  AX_COMPARE_VERSION([$gxx_version], [lt], [4.1],
     [warn_gxx_version="g++ version $gxx_version is likely to cause problems"
      OCTAVE_CONFIGURE_WARNING([warn_gxx_version])])
 
@@ -613,8 +579,17 @@
   FFLAGS="-O"
 fi
 
-## the F77 variable, if set, overrides AC_PROG_F77 automatically
-AC_PROG_F77
+## Prefer gfortran, but the user's F77 environment variable will override.
+AC_PROG_F77([gfortran])
+if test -z "$F77"; then
+  ## No gfortran found, search for any other installed compiler.
+  AC_PROG_F77
+fi
+if test "$F77" = g77; then
+  AC_MSG_ERROR([g77 is not a supported Fortran compiler.  Select another compiler by setting the environment variable F77 and re-running configure.])
+fi
+
+## Determine calling conventions for Fortran compiler
 AC_F77_LIBRARY_LDFLAGS
 AC_F77_DUMMY_MAIN
 AC_F77_WRAPPERS
@@ -710,10 +685,6 @@
 fi
 AC_SUBST(F77_INTEGER_8_FLAG)
 
-## FIXME: Is this really used?  Makefile seems to use $F77 for compiler
-FC=$F77
-AC_SUBST(FC)
-
 OCTAVE_F77_FLAG([-ffloat-store], [
   AC_MSG_RESULT([setting F77_FLOAT_STORE_FLAG to -ffloat-store])
   F77_FLOAT_STORE_FLAG=-ffloat-store
@@ -723,15 +694,14 @@
 ### Check for the Qhull library
 
 OCTAVE_CHECK_LIB(qhull, QHull,
-  [Qhull library not found -- this will result in loss of functionality of some geometry functions.],
+  [Qhull library not found.  This will result in loss of functionality of some geometry functions.],
   [libqhull/libqhull.h qhull/libqhull.h libqhull.h qhull/qhull.h qhull.h],
   [qh_qhull], [], [],
   [warn_qhull=
   OCTAVE_CHECK_QHULL_VERSION
   OCTAVE_CHECK_LIB_QHULL_OK(
-    [TEXINFO_QHULL="@set HAVE_QHULL"
-    AC_DEFINE(HAVE_QHULL, 1, [Define to 1 if Qhull is available.])],
-    [warn_qhull="Qhull library found, but does not seem to work properly -- this will result in loss of functionality of some geometry functions.  Please try recompiling the library with -fno-strict-aliasing."])])
+    [AC_DEFINE(HAVE_QHULL, 1, [Define to 1 if Qhull is available.])],
+    [warn_qhull="Qhull library found, but does not seem to work properly.  This will result in loss of functionality of some geometry functions.  Please try recompiling the library with -fno-strict-aliasing."])])
 
 ### Check for PCRE regex library.
 
@@ -865,9 +835,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 +869,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.
 
@@ -907,7 +882,6 @@
   [hdf5.h], [H5Gget_num_objs], [], [],
   [warn_hdf5=
    OCTAVE_CHECK_HDF5_HAS_VER_16_API
-   TEXINFO_HDF5="@set HAVE_HDF5"
    AC_DEFINE(HAVE_HDF5, 1,
      [Define to 1 if HDF5 is available and newer than version 1.6.])
    if test $have_msvc = yes; then
@@ -974,8 +948,7 @@
   [glpk/glpk.h glpk.h], [glp_simplex], [], [],
   [warn_glpk=
    OCTAVE_CHECK_LIB_GLPK_OK(
-    [TEXINFO_GLPK="@set HAVE_GLPK"
-    AC_DEFINE(HAVE_GLPK, 1, [Define to 1 if GLPK is available.])],
+    [AC_DEFINE(HAVE_GLPK, 1, [Define to 1 if GLPK is available.])],
     [warn_glpk="GLPK library found, but does not seem to work properly -- disabling glpk function"])])
 LIBS="$save_LIBS"
 CPPFLAGS="$save_CPPFLAGS"
@@ -1009,6 +982,76 @@
 LIBS="$save_LIBS"
 CPPFLAGS="$save_CPPFLAGS"
 
+### Check for sndfile
+
+warn_sndfile="sndfile library fails tests.  The audioinfo, audioread and audiowrite functions for reading and writing audio files will not be fully functional."
+
+check_sndfile=no
+AC_ARG_WITH([sndfile],
+  [AS_HELP_STRING([--without-sndfile],
+    [don't use sndfile library, disable audio file I/O])],
+  [if test x"$withval" = x"no"; then
+     warn_sndfile="--without-sndfile specified.  The audioinfo, audioread and audiowrite functions for reading and writing audio files will not be fully functional."
+   else
+     check_sndfile=yes
+   fi],
+  [check_sndfile=yes])
+
+if test $check_sndfile = yes; then
+  PKG_CHECK_EXISTS([sndfile], [
+    SNDFILE_CPPFLAGS=`$PKG_CONFIG --cflags-only-I sndfile`
+    SNDFILE_LDFLAGS=`$PKG_CONFIG --libs-only-L sndfile`
+    SNDFILE_LIBS=`$PKG_CONFIG --libs-only-l sndfile`
+    warn_sndfile=
+  ])
+fi
+
+if test -z "$warn_sndfile"; then
+  AC_DEFINE(HAVE_SNDFILE, 1, [Define to 1 if sndfile is available.])
+else
+  SNDFILE_CPPFLAGS=
+  SNDFILE_LDFLAGS=
+  SNDFILE_LIBS=
+fi
+AC_SUBST(SNDFILE_CPPFLAGS)
+AC_SUBST(SNDFILE_LDFLAGS)
+AC_SUBST(SNDFILE_LIBS)
+
+### Check for PortAudio
+
+warn_portaudio="PortAudio library fails tests.  The audioplayer, audiorecorder classes and audiodevinfo function for audio playback and recording will not be fully functional."
+
+check_portaudio=no
+AC_ARG_WITH([portaudio],
+  [AS_HELP_STRING([--without-portaudio],
+    [don't use PortAudio library, disable audio playback and recording])],
+  [if test x"$withval" = x"no"; then
+     warn_portaudio="--without-portaudio specified.  The audioplayer, audiorecorder classes and audiodevinfo function for audio playback and recording will not be fully functional."
+   else
+     check_portaudio=yes
+   fi],
+  [check_portaudio=yes])
+
+if test $check_portaudio = yes; then
+  PKG_CHECK_EXISTS([portaudio-2.0 >= 19], [
+    PORTAUDIO_CPPFLAGS=`$PKG_CONFIG --cflags-only-I portaudio-2.0`
+    PORTAUDIO_LDFLAGS=`$PKG_CONFIG --libs-only-L portaudio-2.0`
+    PORTAUDIO_LIBS=`$PKG_CONFIG --libs-only-l portaudio-2.0`
+    warn_portaudio=
+  ])
+fi
+
+if test -z "$warn_portaudio"; then
+  AC_DEFINE(HAVE_PORTAUDIO, 1, [Define to 1 if PortAudio is available.])
+else
+  PORTAUDIO_CPPFLAGS=
+  PORTAUDIO_LDFLAGS=
+  PORTAUDIO_LIBS=
+fi
+AC_SUBST(PORTAUDIO_CPPFLAGS)
+AC_SUBST(PORTAUDIO_LDFLAGS)
+AC_SUBST(PORTAUDIO_LIBS)
+
 ### Check for either of Graphics/ImageMagick++ libraries
 
 AC_ARG_WITH([magick],
@@ -1200,76 +1243,91 @@
 
   ## Check for FLTK (www.fltk.org) library
 
-  AC_ARG_WITH([fltk-prefix], [
-    AS_HELP_STRING([--with-fltk-prefix=PFX],
-      [prefix where FLTK is installed (optional)])],
-    [fltk_prefix="$withval"],
-    [fltk_prefix=""])
-
-  AC_ARG_WITH([fltk-exec-prefix], [
-    AS_HELP_STRING([--with-fltk-exec-prefix=PFX],
-      [exec prefix where FLTK is installed (optional)])],
-    [fltk_exec_prefix="$withval"],
-    [fltk_exec_prefix=""])
-
-  if test x"$fltk_exec_prefix" != x""; then
-    fltk_args="$fltk_args --exec-prefix=$fltk_exec_prefix"
-    if test "x${FLTK_CONFIG+set}" != xset ; then
-      FLTK_CONFIG="$fltk_exec_prefix/bin/fltk-config"
+  check_fltk=no
+  AC_ARG_WITH([fltk],
+    [AS_HELP_STRING([--without-fltk],
+      [don't use FLTK libraries, disable native graphics])],
+    [if test x"$withval" = x"no"; then
+       native_graphics=no
+       warn_fltk="--without-fltk specified.  Native graphics will be disabled."
+       OCTAVE_CONFIGURE_WARNING([warn_fltk])
+     else
+       check_fltk=yes
+     fi],
+    [check_fltk=yes])
+
+  if test $check_fltk = yes; then
+    AC_ARG_WITH([fltk-prefix],
+      [AS_HELP_STRING([--with-fltk-prefix=PFX],
+        [prefix where FLTK is installed (optional)])],
+      [fltk_prefix="$withval"],
+      [fltk_prefix=""])
+
+    AC_ARG_WITH([fltk-exec-prefix],
+      [AS_HELP_STRING([--with-fltk-exec-prefix=PFX],
+        [exec prefix where FLTK is installed (optional)])],
+      [fltk_exec_prefix="$withval"],
+      [fltk_exec_prefix=""])
+
+    if test x"$fltk_exec_prefix" != x""; then
+      fltk_args="$fltk_args --exec-prefix=$fltk_exec_prefix"
+      if test "x${FLTK_CONFIG+set}" != xset ; then
+        FLTK_CONFIG="$fltk_exec_prefix/bin/fltk-config"
+      fi
     fi
-  fi
-
-  if test x"$fltk_prefix" != x""; then
-    fltk_args="$fltk_args --prefix=$fltk_prefix"
-    if test x${FLTK_CONFIG+set} != xset ; then
-      FLTK_CONFIG="$fltk_prefix/bin/fltk-config"
+
+    if test x"$fltk_prefix" != x""; then
+      fltk_args="$fltk_args --prefix=$fltk_prefix"
+      if test x${FLTK_CONFIG+set} != xset ; then
+        FLTK_CONFIG="$fltk_prefix/bin/fltk-config"
+      fi
     fi
-  fi
-
-  AC_PATH_PROG([FLTK_CONFIG], [fltk-config], [no])
-
-  warn_fltk_config=""
-  warn_fltk_opengl=""
-
-  if test "$FLTK_CONFIG" = no; then
-    native_graphics=no
-    warn_fltk_config="FLTK config script not found.  Native graphics will be disabled."
-    OCTAVE_CONFIGURE_WARNING([warn_fltk_config])
-  else
-    FLTK_CFLAGS=`$FLTK_CONFIG $fltkconf_args --use-gl --cflags`
-    FLTK_LDFLAGS=`$FLTK_CONFIG $fltkconf_args --use-gl --ldflags`
-
-    case $host_os in
-      mingw*)
-        FLTK_LDFLAGS=`echo $FLTK_LDFLAGS | $SED -e 's/-mwindows//g'`
-      ;;
-    esac
-
-    AC_CACHE_CHECK([for OpenGL support in FLTK],
-      [octave_cv_fltk_opengl_support],
-      [save_CFLAGS="$CFLAGS"
-      CFLAGS="$CFLAGS $FLTK_CFLAGS"
-      AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
-        #include <FL/gl.h>
-        ]], [[
-        int nothing = 0;
-        ]])],
-        octave_cv_fltk_opengl_support=no,
-        octave_cv_fltk_opengl_support=yes)
-      CFLAGS="$save_CFLAGS"
-      ])
-    if test $octave_cv_fltk_opengl_support = no; then
-      warn_fltk_opengl="FLTK does not have OpenGL support.  Native graphics will be disabled."
+
+    AC_PATH_PROG([FLTK_CONFIG], [fltk-config], [no])
+
+    warn_fltk_config=""
+    warn_fltk_opengl=""
+
+    if test "$FLTK_CONFIG" = no; then
+      native_graphics=no
+      warn_fltk_config="FLTK config script not found.  Native graphics will be disabled."
+      OCTAVE_CONFIGURE_WARNING([warn_fltk_config])
     else
-      AC_DEFINE(HAVE_FLTK, 1, [Define to 1 if FLTK is available.])
-    fi
-
-    if test -z "$warn_fltk_opengl"; then
-      GRAPHICS_CFLAGS="$FLTK_CFLAGS"
-      GRAPHICS_LIBS="$FLTK_LDFLAGS"
-    else
-      native_graphics=no
-      OCTAVE_CONFIGURE_WARNING([warn_fltk_opengl])
+      FLTK_CFLAGS=`$FLTK_CONFIG $fltkconf_args --use-gl --cflags`
+      FLTK_LDFLAGS=`$FLTK_CONFIG $fltkconf_args --use-gl --ldflags`
+
+      case $host_os in
+        mingw*)
+          FLTK_LDFLAGS=`echo $FLTK_LDFLAGS | $SED -e 's/-mwindows//g'`
+        ;;
+      esac
+
+      AC_CACHE_CHECK([for OpenGL support in FLTK],
+        [octave_cv_fltk_opengl_support],
+        [save_CFLAGS="$CFLAGS"
+        CFLAGS="$CFLAGS $FLTK_CFLAGS"
+        AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
+          #include <FL/gl.h>
+          ]], [[
+          int nothing = 0;
+          ]])],
+          octave_cv_fltk_opengl_support=no,
+          octave_cv_fltk_opengl_support=yes)
+        CFLAGS="$save_CFLAGS"
+        ])
+      if test $octave_cv_fltk_opengl_support = no; then
+        warn_fltk_opengl="FLTK does not have OpenGL support.  Native graphics will be disabled."
+      else
+        AC_DEFINE(HAVE_FLTK, 1, [Define to 1 if FLTK is available.])
+      fi
+
+      if test -z "$warn_fltk_opengl"; then
+        GRAPHICS_CFLAGS="$FLTK_CFLAGS"
+        GRAPHICS_LIBS="$FLTK_LDFLAGS"
+      else
+        native_graphics=no
+        OCTAVE_CONFIGURE_WARNING([warn_fltk_opengl])
+      fi
     fi
   fi
 fi
@@ -2183,7 +2241,7 @@
 dnl These checks define/undefine HAVE_FUNCNAME in config.h.
 dnl Code tests HAVE_FUNCNAME and either uses function or provides workaround.
 dnl Use multiple AC_CHECKs to avoid line continuations '\' in list
-AC_CHECK_FUNCS([canonicalize_file_name ctermid dup2])
+AC_CHECK_FUNCS([ctermid dup2])
 AC_CHECK_FUNCS([endgrent endpwent execvp expm1 expm1f fork])
 AC_CHECK_FUNCS([getegid geteuid getgid getgrent getgrgid getgrnam])
 AC_CHECK_FUNCS([getpgrp getpid getppid getpwent getpwuid getuid])
@@ -2192,7 +2250,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])
 
@@ -2228,6 +2286,7 @@
 OCTAVE_CHECK_FUNC_CMATH(isnan)
 OCTAVE_CHECK_FUNC_CMATH(isinf)
 OCTAVE_CHECK_FUNC_CMATH(isfinite)
+OCTAVE_CHECK_FUNC_CMATH(signbit)
 
 ## Check for Inf and NaN functions
 
@@ -2714,27 +2773,38 @@
   [AS_HELP_STRING([--disable-gui], [don't build the GUI])],
   [if test "$enableval" = no; then build_gui=no; fi], [])
 
+if test -z "$OPENGL_LIBS"; then
+  build_gui=no
+  if test $check_opengl = yes; then
+    warn_gui="OpenGL libs (GL and GLU) not found -- disabling GUI"
+  else
+    warn_gui="--without-opengl was specified -- disabling GUI"
+  fi
+  OCTAVE_CONFIGURE_WARNING([warn_gui])
+fi
+
 if test $build_gui = yes; then
 
   warn_gui=""
   ## Check for Qt libraries
-  PKG_CHECK_MODULES(QT, [QtCore, QtGui, QtNetwork],
+  QT_MODULES="QtCore QtGui QtNetwork QtOpenGL"
+  PKG_CHECK_MODULES(QT, [$QT_MODULES],
     [],
     [warn_gui="Qt libraries not found -- disabling GUI"
      build_gui=no])
 
   if test $build_gui = yes; then
     ## Retrieve Qt compilation and linker flags
-    QT_CPPFLAGS="`$PKG_CONFIG --cflags-only-I QtCore QtGui QtNetwork`"
-    QT_LDFLAGS="`$PKG_CONFIG --libs-only-L QtCore QtGui QtNetwork`"
-    QT_LIBS="`$PKG_CONFIG --libs-only-l QtCore QtGui QtNetwork`"
+    QT_CPPFLAGS="`$PKG_CONFIG --cflags-only-I $QT_MODULES`"
+    QT_LDFLAGS="`$PKG_CONFIG --libs-only-L $QT_MODULES`"
+    QT_LIBS="`$PKG_CONFIG --libs-only-l $QT_MODULES`"
 
     case $host_os in
       *darwin*)
         ## Qt might be installed in framework
         if test -z "$QT_LIBS"; then
-          QT_LDFLAGS="`$PKG_CONFIG --libs-only-other QtCore QtGui QtNetwork | tr ' ' '\n' | $GREP -e '-F' | uniq | tr '\n' ' '`"
-          QT_LIBS="`$PKG_CONFIG --libs-only-other QtCore QtGui QtNetwork | tr ' ' '\n' | $GREP -v -e '-F' | uniq | tr '\n' ' '`"
+          QT_LDFLAGS="`$PKG_CONFIG --libs-only-other $QT_MODULES | tr ' ' '\n' | $GREP -e '-F' | uniq | tr '\n' ' '`"
+          QT_LIBS="`$PKG_CONFIG --libs-only-other $QT_MODULES | tr ' ' '\n' | $GREP -v -e '-F' | uniq | tr '\n' ' '`"
           ## Enabling link_all_deps works around libtool's imperfect handling
           ## of the -F flag
           AM_CONDITIONAL([AMCOND_LINK_ALL_DEPS],
@@ -2776,6 +2846,8 @@
     OCTAVE_CHECK_QFONT_MONOSPACE
     OCTAVE_CHECK_QFONT_FORCE_INTEGER_METRICS
     OCTAVE_CHECK_FUNC_SETPLACEHOLDERTEXT
+    OCTAVE_CHECK_FUNC_QTABWIDGET_SETMOVABLE
+    OCTAVE_CHECK_FUNC_QSCI_FINDSELECTION
   fi
 
   if test $build_gui = yes; then
@@ -2849,7 +2921,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)
@@ -2885,11 +2958,12 @@
   doc/refcard/Makefile
   etc/icons/Makefile
   examples/Makefile
+  examples/code/Makefile
+  examples/data/Makefile
   libgnu/Makefile
   libgui/Makefile
   libinterp/Makefile
   liboctave/Makefile
-  liboctave/cruft/Makefile
   liboctave/cruft/mkf77def
   scripts/Makefile
   src/Makefile
@@ -2971,6 +3045,9 @@
   OPENGL libraries:            $OPENGL_LIBS
   PCRE CPPFLAGS:               $PCRE_CPPFLAGS
   PCRE libraries:              $PCRE_LIBS
+  PortAudio CPPFLAGS:          $PORTAUDIO_CPPFLAGS
+  PortAudio LDFLAGS:           $PORTAUDIO_LDFLAGS
+  PortAudio libraries:         $PORTAUDIO_LIBS
   PTHREAD flags:               $PTHREAD_CFLAGS
   PTHREAD libraries:           $PTHREAD_LIBS
   QHULL CPPFLAGS:              $QHULL_CPPFLAGS
@@ -2983,6 +3060,9 @@
   Qt LDFLAGS:                  $QT_LDFLAGS
   Qt libraries:                $QT_LIBS
   READLINE libraries:          $READLINE_LIBS
+  Sndfile CPPFLAGS:            $SNDFILE_CPPFLAGS
+  Sndfile LDFLAGS:             $SNDFILE_LDFLAGS
+  Sndfile libraries:           $SNDFILE_LIBS
   TERM libraries:              $TERM_LIBS
   UMFPACK CPPFLAGS:            $UMFPACK_CPPFLAGS
   UMFPACK LDFLAGS:             $UMFPACK_LDFLAGS
@@ -3000,12 +3080,12 @@
   JIT compiler for loops:             $build_jit
   Build Java interface:               $build_java
   Do internal array bounds checking:  $BOUNDS_CHECKING
-  Use octave_allocator:               $USE_OCTAVE_ALLOCATOR
   Build static libraries:             $STATIC_LIBS
   Build shared libraries:             $SHARED_LIBS
   Dynamic Linking:                    $ENABLE_DYNAMIC_LINKING $DL_API_MSG
   Include support for GNU readline:   $USE_READLINE
   64-bit array dims and indexing:     $USE_64_BIT_IDX_T
+  Experimental SMP multithreading:    $USE_OPENMP
 ])
 
 warn_msg_printed=false
@@ -3085,20 +3165,13 @@
   warn_msg_printed=true
 fi
 
-if test $USE_ATOMIC_REFCOUNT = yes; then
+if test $USE_ATOMIC_REFCOUNT = no; then
   AC_MSG_WARN([])
-  AC_MSG_WARN([Using atomic reference counting.])
+  AC_MSG_WARN([atomic reference counting disabled.])
   AC_MSG_WARN([This feature allows access to Octave data safely from])
-  AC_MSG_WARN([another thread, for instance from a GUI.  However this])
-  AC_MSG_WARN([results in a small performance penalty in the Octave])
-  AC_MSG_WARN([interpreter.])
+  AC_MSG_WARN([another thread, and is required when using the GUI's Qt toolkit])
+  AC_MSG_WARN([for plotting.])
   AC_MSG_WARN([])
-  if test $USE_OCTAVE_ALLOCATOR = yes; then
-    AC_MSG_WARN([Thread-safe behavior is not guaranteed unless you also])
-    AC_MSG_WARN([disable the use of the octave_allocator class.])
-    AC_MSG_WARN([])
-  fi
-  warn_msg_printed=true
 fi
 
 if $warn_msg_printed; then
--- a/doc/interpreter/Makefile.am	Fri Feb 06 08:31:09 2015 -0800
+++ b/doc/interpreter/Makefile.am	Fri Feb 06 08:31:49 2015 -0800
@@ -40,43 +40,43 @@
 ## They are dependencies for the documentation.
 ## They must not be distributed from this directory.
 EXAMPLE_FILES = \
-  $(top_srcdir)/examples/@FIRfilter/FIRfilter.m \
-  $(top_srcdir)/examples/@FIRfilter/FIRfilter_aggregation.m \
-  $(top_srcdir)/examples/@FIRfilter/display.m \
-  $(top_srcdir)/examples/@FIRfilter/subsasgn.m \
-  $(top_srcdir)/examples/@FIRfilter/subsref.m \
-  $(top_srcdir)/examples/@polynomial/display.m \
-  $(top_srcdir)/examples/@polynomial/double.m \
-  $(top_srcdir)/examples/@polynomial/end.m \
-  $(top_srcdir)/examples/@polynomial/get.m \
-  $(top_srcdir)/examples/@polynomial/mtimes.m \
-  $(top_srcdir)/examples/@polynomial/plot.m \
-  $(top_srcdir)/examples/@polynomial/polynomial.m \
-  $(top_srcdir)/examples/@polynomial/polynomial_superiorto.m \
-  $(top_srcdir)/examples/@polynomial/polyval.m \
-  $(top_srcdir)/examples/@polynomial/set.m \
-  $(top_srcdir)/examples/@polynomial/subsref.m \
-  $(top_srcdir)/examples/addtwomatrices.cc \
-  $(top_srcdir)/examples/celldemo.cc \
-  $(top_srcdir)/examples/embedded.cc \
-  $(top_srcdir)/examples/fortrandemo.cc \
-  $(top_srcdir)/examples/fortransub.f \
-  $(top_srcdir)/examples/funcdemo.cc \
-  $(top_srcdir)/examples/globaldemo.cc \
-  $(top_srcdir)/examples/helloworld.cc \
-  $(top_srcdir)/examples/mycell.c \
-  $(top_srcdir)/examples/myfeval.c \
-  $(top_srcdir)/examples/myfunc.c \
-  $(top_srcdir)/examples/myhello.c \
-  $(top_srcdir)/examples/mypow2.c \
-  $(top_srcdir)/examples/mysparse.c \
-  $(top_srcdir)/examples/mystring.c \
-  $(top_srcdir)/examples/mystruct.c \
-  $(top_srcdir)/examples/paramdemo.cc \
-  $(top_srcdir)/examples/standalone.cc \
-  $(top_srcdir)/examples/stringdemo.cc \
-  $(top_srcdir)/examples/structdemo.cc \
-  $(top_srcdir)/examples/unwinddemo.cc
+  $(top_srcdir)/examples/code/@FIRfilter/FIRfilter.m \
+  $(top_srcdir)/examples/code/@FIRfilter/FIRfilter_aggregation.m \
+  $(top_srcdir)/examples/code/@FIRfilter/display.m \
+  $(top_srcdir)/examples/code/@FIRfilter/subsasgn.m \
+  $(top_srcdir)/examples/code/@FIRfilter/subsref.m \
+  $(top_srcdir)/examples/code/@polynomial/display.m \
+  $(top_srcdir)/examples/code/@polynomial/double.m \
+  $(top_srcdir)/examples/code/@polynomial/end.m \
+  $(top_srcdir)/examples/code/@polynomial/get.m \
+  $(top_srcdir)/examples/code/@polynomial/mtimes.m \
+  $(top_srcdir)/examples/code/@polynomial/plot.m \
+  $(top_srcdir)/examples/code/@polynomial/polynomial.m \
+  $(top_srcdir)/examples/code/@polynomial/polynomial_superiorto.m \
+  $(top_srcdir)/examples/code/@polynomial/polyval.m \
+  $(top_srcdir)/examples/code/@polynomial/set.m \
+  $(top_srcdir)/examples/code/@polynomial/subsref.m \
+  $(top_srcdir)/examples/code/addtwomatrices.cc \
+  $(top_srcdir)/examples/code/celldemo.cc \
+  $(top_srcdir)/examples/code/embedded.cc \
+  $(top_srcdir)/examples/code/fortrandemo.cc \
+  $(top_srcdir)/examples/code/fortransub.f \
+  $(top_srcdir)/examples/code/funcdemo.cc \
+  $(top_srcdir)/examples/code/globaldemo.cc \
+  $(top_srcdir)/examples/code/helloworld.cc \
+  $(top_srcdir)/examples/code/mycell.c \
+  $(top_srcdir)/examples/code/myfeval.c \
+  $(top_srcdir)/examples/code/myfunc.c \
+  $(top_srcdir)/examples/code/myhello.c \
+  $(top_srcdir)/examples/code/mypow2.c \
+  $(top_srcdir)/examples/code/mysparse.c \
+  $(top_srcdir)/examples/code/mystring.c \
+  $(top_srcdir)/examples/code/mystruct.c \
+  $(top_srcdir)/examples/code/paramdemo.cc \
+  $(top_srcdir)/examples/code/standalone.cc \
+  $(top_srcdir)/examples/code/stringdemo.cc \
+  $(top_srcdir)/examples/code/structdemo.cc \
+  $(top_srcdir)/examples/code/unwinddemo.cc
 
 
 include images.mk
@@ -170,8 +170,11 @@
 
 TXI_SRC = $(MUNGED_TEXI_SRC:.texi=.txi)
 
+include graphics_properties.mk
+
 BUILT_TEXINFOS = \
   contributors.texi \
+  $(GRAPH_PROP_TEXI_SRC) \
   $(MUNGED_TEXI_SRC)
 
 info_TEXINFOS = octave.texi
@@ -271,6 +274,8 @@
   contributors.in \
   doc-cache \
   find-docstring-files.sh \
+  genpropdoc.m \
+  graphics_properties.mk \
   images \
   images.awk \
   images.mk \
--- a/doc/interpreter/audio.txi	Fri Feb 06 08:31:09 2015 -0800
+++ b/doc/interpreter/audio.txi	Fri Feb 06 08:31:49 2015 -0800
@@ -21,6 +21,135 @@
 @node Audio Processing
 @chapter Audio Processing
 
+@menu
+* Audio File Utilities::
+* Audio Device Information::
+* Audio Player::
+* Audio Recorder::
+* Audio Data Processing::
+@end menu
+
+@node Audio File Utilities
+@section Audio File Utilities
+
+The following functions allow you to read, write and retrieve
+information about audio files.  Various formats are supported including
+wav, flac and ogg vorbis.
+
+@DOCSTRING(audioinfo)
+
+@DOCSTRING(audioread)
+
+@DOCSTRING(audiowrite)
+
+@node Audio Device Information
+@section Audio Device Information
+
+@DOCSTRING(audiodevinfo)
+
+@node Audio Player
+@section Audio Player
+
+The following methods are used to create and use audioplayer
+objects.  These objects can be used to play back audio data stored in
+Octave matrices and arrays.  The audioplayer object supports playback
+from various devices available to the system, blocking and non-blocking
+playback, convenient pausing and resuming and much more.
+
+@DOCSTRING(@audioplayer/audioplayer)
+
+@menu
+* Playback::
+* Player Properties::
+@end menu
+
+@node Playback
+@subsection Playback
+
+The following methods are used to control player playback.
+
+@DOCSTRING(@audioplayer/play)
+
+@DOCSTRING(@audioplayer/playblocking)
+
+@DOCSTRING(@audioplayer/pause)
+
+@DOCSTRING(@audioplayer/resume)
+
+@DOCSTRING(@audioplayer/stop)
+
+@DOCSTRING(@audioplayer/isplaying)
+
+@node Player Properties
+@subsection Properties
+
+The remaining couple of methods are used to get and set various
+properties of the audioplayer object.
+
+@DOCSTRING(@audioplayer/get)
+
+@DOCSTRING(@audioplayer/set)
+
+@node Audio Recorder
+@section Audio Recorder
+
+The following methods are used to create and use audiorecorder
+objects.  These objects can be used to record audio data from various
+devices available to the system.  You can use convenient methods to
+retrieve that data or audioplayer objects created from that
+data.  Methods for blocking and non-blocking recording, pausing and
+resuming recording and much more is available.
+
+@DOCSTRING(@audiorecorder/audiorecorder)
+
+@menu
+* Recording::
+* Data Retrieval::
+* Recorder Properties::
+@end menu
+
+@node Recording
+@subsection Recording
+
+The following methods control the recording process.
+
+@DOCSTRING(@audiorecorder/record)
+
+@DOCSTRING(@audiorecorder/recordblocking)
+
+@DOCSTRING(@audiorecorder/pause)
+
+@DOCSTRING(@audiorecorder/resume)
+
+@DOCSTRING(@audiorecorder/stop)
+
+@DOCSTRING(@audiorecorder/isrecording)
+
+@node Data Retrieval
+@subsection Data Retrieval
+
+The following methods allow you to retrieve recorded audio data in
+various ways.
+
+@DOCSTRING(@audiorecorder/getaudiodata)
+
+@DOCSTRING(@audiorecorder/getplayer)
+
+@DOCSTRING(@audiorecorder/play)
+
+@node Recorder Properties
+@subsection Properties
+
+The remaining two methods allow you to read or alter the properties of
+audiorecorder objects.
+
+@DOCSTRING(@audiorecorder/get)
+
+@DOCSTRING(@audiorecorder/set)
+
+@node Audio Data Processing
+@section Audio Data Processing
+
 Octave provides a few functions for dealing with audio data.  An audio
 `sample' is a single output value from an A/D converter, i.e., a small
 integer number (usually 8 or 16 bits), and audio data is just a series
@@ -32,8 +161,8 @@
 There are many different formats for representing such data.  Currently,
 only the two most popular, @emph{linear encoding} and @emph{mu-law
 encoding}, are supported by Octave.  There is an excellent FAQ on audio
-formats by Guido van Rossum @email{guido@@cwi.nl} which can be found at any
-FAQ ftp site, in particular in the directory
+formats by @nospell{Guido van Rossum} @email{guido@@cwi.nl} which can be
+found at any FAQ ftp site, in particular in the directory
 @file{/pub/usenet/news.answers/audio-fmts} of the archive site
 @code{rtfm.mit.edu}.
 
@@ -47,24 +176,8 @@
 
 @DOCSTRING(mu2lin)
 
-@DOCSTRING(loadaudio)
-
-@DOCSTRING(saveaudio)
-
-The following functions for audio I/O require special A/D hardware and
-operating system support.  It is assumed that audio data in linear
-encoding can be played and recorded by reading from and writing to
-@file{/dev/dsp}, and that similarly @file{/dev/audio} is used for mu-law
-encoding.  These file names are system-dependent.  Improvements so that
-these functions will work without modification on a wide variety of
-hardware are welcome.
-
-@DOCSTRING(playaudio)
-
 @DOCSTRING(record)
 
-@DOCSTRING(setaudio)
-
 @DOCSTRING(wavread)
 
 @DOCSTRING(wavwrite)
--- a/doc/interpreter/basics.txi	Fri Feb 06 08:31:09 2015 -0800
+++ b/doc/interpreter/basics.txi	Fri Feb 06 08:31:49 2015 -0800
@@ -244,16 +244,18 @@
 @group
 PS1                             = ">> "
 PS2                             = ""
-allow_noninteger_range_as_index = true
 beep_on_error                   = true
 confirm_recursive_rmdir         = false
 crash_dumps_octave_core         = false
-save_default_options            = "-mat-binary"
-do_braindead_shortcircuit_evaluation = true
+disable_diagonal_matrix         = true
+disable_permutation_matrix      = true
+disable_range                   = true
 fixed_point_format              = true
 history_timestamp_format_string = "%%-- %D %I:%M %p --%%"
 page_screen_output              = false
 print_empty_dimensions          = false
+save_default_options            = "-mat-binary"
+struct_levels_to_print          = 0
 @end group
 @end example
 
@@ -266,6 +268,7 @@
 Octave:fopen-file-in-path
 Octave:function-name-clash
 Octave:load-file-in-path
+Octave:possible-matlab-short-circuit-operator
 @end group
 @end example
 
@@ -377,15 +380,19 @@
 invoke Octave with the @option{--verbose} option but without the
 @option{--silent} option.
 
-The @code{dump_prefs} function is useful for determining what customizations
-to Octave are possible and which are in effect.
-
-@DOCSTRING(dump_prefs)
-
 @node Quitting Octave
 @section Quitting Octave
 @cindex exiting octave
 @cindex quitting octave
+@cindex finish.m
+@cindex site exiting file
+
+Shutdown is initiated with the @code{exit} or @code{quit} commands (they are
+equivalent).  Similar to startup, Octave has a shutdown process that can be
+customized by user script files.  During shutdown Octave will search for the
+script file @file{finish.m} in the function load path.  Commands to save all
+workspace variables or cleanup temporary files may be placed there.  Additional
+functions to execute on shutdown may be registered with @code{atexit}.
 
 @DOCSTRING(quit)
 
--- a/doc/interpreter/container.txi	Fri Feb 06 08:31:09 2015 -0800
+++ b/doc/interpreter/container.txi	Fri Feb 06 08:31:49 2015 -0800
@@ -507,7 +507,7 @@
 
 Other functions that can manipulate the fields of a structure are given below.
 
-@DOCSTRING(nfields)
+@DOCSTRING(numfields)
 
 @DOCSTRING(fieldnames)
 
@@ -891,8 +891,8 @@
 Strings}), @code{strcmp}, @code{strncmp}, @code{strcmpi},
 @code{strncmpi} (@pxref{Comparing Strings}), @code{str2double},
 @code{deblank}, @code{strtrim}, @code{strtrunc}, @code{strfind},
-@code{strmatch}, , @code{regexp}, @code{regexpi} (@pxref{Manipulating
-Strings}) and @code{str2double} (@pxref{String Conversions}).
+@code{regexp}, @code{regexpi} (@pxref{Manipulating Strings}) and
+@code{str2double} (@pxref{String Conversions}).
 
 The function @code{iscellstr} can be used to test if an object is a
 cell array of strings.
--- a/doc/interpreter/contrib.txi	Fri Feb 06 08:31:09 2015 -0800
+++ b/doc/interpreter/contrib.txi	Fri Feb 06 08:31:49 2015 -0800
@@ -198,6 +198,7 @@
 comment header (use appropriate year, name and comment marks):
 
 @example
+@group
 ## Copyright (C) 1996-2013 John W. Eaton <jwe@@octave.org>
 ##
 ## This file is part of Octave.
@@ -215,6 +216,7 @@
 ## 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/>.
+@end group
 @end example
 
 Always include commit messages in changesets.  After making your source
@@ -284,8 +286,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 Feb 06 08:31:09 2015 -0800
+++ b/doc/interpreter/contributors.in	Fri Feb 06 08:31:49 2015 -0800
@@ -1,8 +1,11 @@
 Ben Abbott
+Drew Abbot
 Andy Adler
 Adam H. Aitkenhead
 Giles Anderson
 Joel Andersson
+Lachlan Andrew
+Pedro Angelo
 Muthiah Annamalai
 Markus Appel
 Branden Archer
@@ -15,6 +18,7 @@
 Heinz Bauschke
 Julien Bect
 Roman Belov
+Markus Bergholz
 Karl Berry
 David Billinghurst
 Don Bindner
@@ -69,9 +73,11 @@
 Peter Ekberg
 Rolf Fabian
 Gunnar Farnebäck
+Massimiliano Fasi
 Stephen Fegan
 Ramon Garcia Fernandez
 Torsten Finke
+Colin Foster
 Jose Daniel Munoz Frias
 Brad Froehle
 Castor Fu
@@ -79,6 +85,7 @@
 Walter Gautschi
 Klaus Gebhardt
 Driss Ghaddab
+Eugenio Gianniti
 Nicolo Giorgetti
 Arun Giridhar
 Michael D. Godfrey
@@ -87,6 +94,7 @@
 Tomislav Goles
 Keith Goodman
 Brian Gough
+Michael C. Grant
 Steffen Groot
 Etienne Grossmann
 David Grundberg
@@ -118,6 +126,7 @@
 John Hunt
 Teemu Ikonen
 Alan W. Irwin
+Allan Jacobs
 Geoff Jacobsen
 Mats Jansson
 Cai Jianming
@@ -187,6 +196,7 @@
 Júlio Hoffimann Mendes
 Ed Meyer
 Thorsten Meyer
+Stefan Miereis
 Petr Mikulik
 Mike Miller
 Stefan Monnier
@@ -209,12 +219,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
@@ -225,6 +237,7 @@
 Elias Pipping
 Robert Platt
 Hans Ekkehard Plesser
+Sergey Plotnikov
 Tom Poage
 Orion Poplawski
 Ondrej Popp
@@ -232,6 +245,8 @@
 Francesco Potortì
 Konstantinos Poulios
 Jarno Rajahalme
+Eduardo Ramos
+Pooja Rao
 James B. Rawlings
 Eric S. Raymond
 Balint Reczey
@@ -257,6 +272,7 @@
 Toni Saarela
 Juhani Saastamoinen
 Radek Salac
+Mike Sander
 Ben Sapp
 Aleksej Saushev
 Alois Schlögl
@@ -264,6 +280,7 @@
 Julian Schnidder
 Nicol N. Schraudolph
 Sebastian Schubert
+Lasse Schuirmann
 Ludwig Schwardt
 Thomas L. Scofield
 Daniel J. Sebald
@@ -280,6 +297,7 @@
 Joerg Specht
 Quentin H. Spencer
 Christoph Spiel
+David Spies
 Richard Stallman
 Russell Standish
 Brett Stewart
@@ -323,6 +341,7 @@
 Martin Weiser
 Michael Weitzel
 David Wells
+Joachim Wiesemann
 Fook Fah Yap
 Sean Young
 Michael Zeising
--- a/doc/interpreter/diagperm.txi	Fri Feb 06 08:31:09 2015 -0800
+++ b/doc/interpreter/diagperm.txi	Fri Feb 06 08:31:49 2015 -0800
@@ -59,7 +59,26 @@
 Octave provides special treatment of real and complex rectangular diagonal
 matrices, as well as permutation matrices.  They are stored as special objects,
 using efficient storage and algorithms, facilitating writing both readable and
-efficient matrix algebra expressions in the Octave language.
+efficient matrix algebra expressions in the Octave language.  The special
+treatment may be disabled by using the functions @dfn{disable_diagonal_matrix}
+and @dfn{disable_permutation_matrix}.
+
+@DOCSTRING(disable_diagonal_matrix)
+
+@DOCSTRING(disable_permutation_matrix)
+
+The space savings are significant as demonstrated by the following code.
+
+@example
+@group
+x = diag (rand (10, 1));
+xf = full (x);
+sizeof (x)
+@result{} 80
+sizeof (xf)
+@result{} 800
+@end group
+@end example
 
 @menu
 * Creating Diagonal Matrices::
@@ -462,7 +481,8 @@
 
 @noindent
 Finally, here's how to solve a linear system @code{A*x = b}
-with Tikhonov regularization (ridge regression) using SVD (a skeleton only):
+with @nospell{Tikhonov} regularization (ridge regression) using SVD (a skeleton
+only):
 
 @example
 @group
@@ -489,21 +509,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/diffeq.txi	Fri Feb 06 08:31:09 2015 -0800
+++ b/doc/interpreter/diffeq.txi	Fri Feb 06 08:31:49 2015 -0800
@@ -54,7 +54,7 @@
 @end ifnottex
 
 @noindent
-using Hindmarsh's ODE solver @sc{lsode}.
+using @nospell{Hindmarsh's} ODE solver @sc{lsode}.
 
 
 
@@ -106,9 +106,10 @@
 @end group
 @end example
 
-See Alan C. Hindmarsh, @cite{ODEPACK, A Systematized Collection of ODE
-Solvers}, in Scientific Computing, R. S. Stepleman, editor, (1983) for
-more information about the inner workings of @code{lsode}.
+See @nospell{Alan C. Hindmarsh},
+@cite{ODEPACK, A Systematized Collection of ODE Solvers},
+in Scientific Computing, @nospell{R. S. Stepleman}, editor, (1983)
+for more information about the inner workings of @code{lsode}.
 
 An m-file for the differential equation used above is included with the
 Octave distribution in the examples directory under the name
@@ -139,8 +140,8 @@
 @ifnottex
 @math{x-dot}
 @end ifnottex
-is the derivative of @math{x}.  The equation is solved using Petzold's
-DAE solver @sc{daspk}.
+is the derivative of @math{x}.  The equation is solved using
+@nospell{Petzold's} DAE solver @sc{daspk}.
 
 @DOCSTRING(daspk)
 
@@ -158,6 +159,6 @@
 
 @DOCSTRING(dasrt_options)
 
-See K. E. Brenan, et al., @cite{Numerical Solution of Initial-Value
+See @nospell{K. E. Brenan}, et al., @cite{Numerical Solution of Initial-Value
 Problems in Differential-Algebraic Equations}, North-Holland (1989) for
 more information about the implementation of @sc{dassl}.
--- a/doc/interpreter/doccheck/aspell-octave.en.pws	Fri Feb 06 08:31:09 2015 -0800
+++ b/doc/interpreter/doccheck/aspell-octave.en.pws	Fri Feb 06 08:31:49 2015 -0800
@@ -1,5 +1,4 @@
 personal_ws-1.1 en 1
-Abramowitz
 accumarray
 Acknowledgements
 acknowledgements
@@ -7,11 +6,9 @@
 adams
 Affero
 afterwards
-Ahalt
 aifm
 AIX
 al
-Alamos
 aleph
 alnum
 alphanum
@@ -28,11 +25,13 @@
 ARMA
 arpack
 ascii
-Ashok
 ast
 async
 atan
 Attr
+audiodevinfo
+audioplayer
+audiorecorder
 AutoCAD
 Autoconf
 autocorrelations
@@ -52,10 +51,10 @@
 backend
 Backends
 backends
+backtrace
 bartlett
 BaseValue
 basevalue
-Bateman
 BDF
 bdf
 betacdf
@@ -64,8 +63,9 @@
 betapdf
 betarnd
 BFGS
+BICG
+BiConjugate
 bigtriangledown
-Bilbert
 bincoeff
 binocdf
 binoinv
@@ -90,9 +90,7 @@
 brackety
 braindead
 breakpoint
-Brenan
 broadcastable
-Brockwell
 BSX
 builtin
 builtins
@@ -120,7 +118,6 @@
 changelogs
 changeset
 changesets
-Chaves
 chdir
 Chebyshev
 chisq
@@ -136,7 +133,6 @@
 circum
 classpath
 classpaths
-Clenshaw
 CLI
 clim
 climmode
@@ -168,7 +164,6 @@
 conformant
 cong
 const
-constuctors
 contextless
 contourc
 convhull
@@ -181,8 +176,11 @@
 CPLEX
 CreateFcn
 CRLF
+Crout
+crout
 csymamd
 ctranspose
+Ctrl
 CTRL
 CTS
 cummax
@@ -194,7 +192,6 @@
 CurrentFigure
 CurrentObject
 currentpoint
-Cuthill
 cxsparse
 Cygwin
 DAE
@@ -222,10 +219,10 @@
 delim
 deltaX
 demi
-Demmel
 DeskJet
 det
 diag
+diagcomp
 diamondsuit
 dir
 disp
@@ -234,7 +231,7 @@
 displayrange
 dMatrix
 dmperm
-Dobkin
+docstring
 docstrings
 dOmega
 doNotSpecify
@@ -244,11 +241,9 @@
 downarrow
 downdate
 dpi
-Driebeck
+droptol
 dt
 Dt
-Dulmage
-Durbin
 dx
 dy
 EastOutside
@@ -259,9 +254,7 @@
 eigenvector
 eigenvectors
 eigs
-Ekerdt
 elementwise
-Elfers
 elseif
 emacs
 emptyvalue
@@ -270,7 +263,6 @@
 Endian
 endif
 endofline
-Engle's
 eof
 EOF
 EOLs
@@ -290,7 +282,6 @@
 errordlg
 ErrorHandler
 ESC
-Esmond
 et
 etree
 etreeplot
@@ -314,16 +305,18 @@
 fftpack
 FFTs
 fftw
-Fiedler
 fieldname
 fieldnames
 filename
 filenames
+filepaths
 Filesystem
+filetype
 FinDiffType
 finv
 FIRfilter
 FIXME
+flac
 FlashPix
 FLTK
 fltk
@@ -333,7 +326,6 @@
 forall
 foregroundcolor
 formfeed
-Forsythe
 Fortran
 fpdf
 fprintf
@@ -353,7 +345,6 @@
 gaminv
 gampdf
 gamrnd
-Gautschi
 gca
 gcbo
 GCC
@@ -378,15 +369,15 @@
 globbing
 glpk
 GLS
+GMRES
 gnulib
 gnuplot
 Gnuplot
 gnuplot's
-Golub
-Gonnet
 goto
 Goto
 gotos
+gperf
 GPL
 GPLK
 gplot
@@ -396,7 +387,6 @@
 GraphicsMagick
 Graymap
 grayscale
-Graz
 griddata
 gswin
 GUIs
@@ -404,16 +394,13 @@
 gz
 gzip
 gzipped
-Hackbusch
 Hadamard
-Haddad
 HandleVisibility
 Hankel
 hanning
 Hanning
 hardcode
 hardcoding
-Hauberg
 HDF
 hdf
 headerlines
@@ -427,11 +414,7 @@
 hggroups
 hh
 HH
-Higham
-Hindmarsh
-Hindmarsh's
 histc
-Hodel
 holomorphic
 Horner's
 horzcat
@@ -440,15 +423,14 @@
 Hotelling's
 HSV
 html
-Hudak
-Huhdanpaa
 hygecdf
 hygeinv
 hygepdf
 hygernd
-Hyndman
 Hypergeometric
 hypergeometric
+ichol
+ict
 IEC
 ieee
 IEEE
@@ -457,10 +439,11 @@
 ifftn
 ignorecase
 ij
+ilu
+ilutp
 Im
 imag
 ImageMagick
-Imenu
 Indices
 indices
 infty
@@ -478,6 +461,7 @@
 interpolant
 Interpolants
 interquartile
+inuse
 inv
 involutory
 ipermute
@@ -499,14 +483,13 @@
 javaaddpath
 javamem
 jbig
+JDK
 JIT
 jpeg
 JPEG
 jpg
 jvm
 JVM's
-Kac
-Kahan
 kendall
 keybindings
 keypress
@@ -514,10 +497,8 @@
 Kolmogorov
 kolmogorov
 Konrod
-Krishnamurthy
 kron
 kruskal
-Kruskal
 Krylov
 kurtosis
 LabelSpacing
@@ -525,9 +506,7 @@
 Lanzcos
 lapack
 laplace
-Larimore
 LaserJet
-Lauchli
 lceil
 ldiv
 ldivide
@@ -538,10 +517,7 @@
 leftarrow
 Leftrightarrow
 leftrightarrow
-Lehmer
-Lehoucq
 leq
-Levinson
 LF
 lfloor
 li
@@ -563,12 +539,12 @@
 ListSize
 ListString
 literalspacing
-Liu
 LLVM
 LM
 lm
 loadpath
 Lobatto
+logfile
 logit
 logncdf
 logninv
@@ -578,8 +554,6 @@
 lookup
 Lookup
 lookups
-Los
-Lotkin
 Lovato
 lpx
 lr
@@ -595,7 +569,6 @@
 lz
 lzma
 lzw
-Magnus
 Mahalanobis
 makefile
 makefiles
@@ -607,19 +580,15 @@
 markerfacecolor
 markersize
 markerstyle
-Marsaglia
-Maschhoff
 matchcase
 matlab
-Matsumoto
 MaxFunEvals
 maxima
 MaxIntervalCount
 MaxIter
 mcnemar
-McNemar's
+mdl
 meansq
-Mendelsohn
 menubars
 Mersenne
 meshgrid
@@ -630,7 +599,7 @@
 Metafont
 mex
 mget
-Michelsen
+michol
 Microsystems
 MinGW
 minima
@@ -639,7 +608,6 @@
 minval
 MIP
 miscompiled
-Misra
 mkdir
 mkoctfile
 mldivide
@@ -649,8 +617,6 @@
 mmmm
 mmmyy
 mmmyyyy
-Moler
-Montanet
 mpoles
 mpower
 mput
@@ -678,29 +644,32 @@
 nbininv
 nbinpdf
 nbinrnd
+ncols
 nd
 ndgrid
+ndims
 ne
-Nelder
 neq
-Neudecker
 Neumann
 NeXT
 NextPlot
 nfev
 nfft
-Ng
 ni
-Nishimura
 NLP
 nnls
 nnz
 nocompute
 nodither
+nofill
 nolabel
 noncommercially
 nonconformant
+nondecreasing
+nonincreasing
+nonnan
 nonsmooth
+nonsparse
 nonzeros
 NOP
 noperm
@@ -713,26 +682,31 @@
 noscal
 noshare
 notin
+nrows
 nthargout
 NTSC
 ntsc
+numel
 Numpy
 nzmax
 oct
 octaverc
 ODEPACK
+Ogg
+ogg
 OKString
 OLS
 onCleanup
 online
 OpenGL
+OpenJDK
 oplus
-Oppenheim
 Ord
 oregonator
 Orthogonalize
 oslash
 otimes
+outerposition
 OutputFcn
 outputfcn
 overridable
@@ -743,7 +717,6 @@
 paperunits
 PaperUnits
 parseparams
-Parter
 pbm
 PBM
 PBMplus
@@ -762,7 +735,6 @@
 pentadiagonal
 periodogram
 perp
-Petzold's
 PGF
 pgm
 PGMRES
@@ -787,10 +759,10 @@
 POSIX
 postorder
 PostScript
-Pothen
 powerset
 pre
 preconditioner
+preconditioners
 premultiplied
 Prepend
 prepended
@@ -799,6 +771,7 @@
 priori
 Profiler
 profiler
+programmatically
 prolate
 PromptString
 propto
@@ -832,20 +805,17 @@
 qz
 QZ
 radices
-Rajamanickam
 randn
 randperm
 rangle
 ranlib
 ras
-Rawlings
 rceil
 rdivide
 Readline
 readline
 RECT
 recursing
-Redheffer
 reentrant
 regex
 regressor
@@ -880,15 +850,11 @@
 rnd
 roffset
 Rosser
-Rossum
 rpath
 RPMs
 runtime
 sa
-Saad
-Sandia
 SAS
-Schafer
 schar
 Schur
 SCO
@@ -899,7 +865,6 @@
 SelectionMode
 semidefinite
 Sep
-Shampine
 shiftdim
 si
 signum
@@ -912,10 +877,10 @@
 simplematrix
 simplices
 sinetone
+slx
 sm
 smirnov
 Smirnov
-Sorensen
 SouthOutside
 sp
 spadesuit
@@ -943,16 +908,13 @@
 sqrtm
 sr
 ss
-Stadlober
 stairstep
-Stallman
 startup
 Startup
 statinfo
+stdin
 stdnormal
 stdout
-Stegun
-Stepleman
 stepsize
 STFT
 STL
@@ -967,6 +929,7 @@
 struct
 structs
 subarrays
+subdiagonals
 subdirectories
 subdirectory
 subexpressions
@@ -998,8 +961,10 @@
 SuiteSparse
 sumsq
 SunOS
+superdiagonal
+superdiagonals
 superiorto
-supradiagonal
+superscripting
 supset
 supseteq
 SV
@@ -1015,7 +980,7 @@
 symamd
 symbfact
 symrcm
-Szego
+Syntaxes
 tcdf
 Tcv
 terminal's
@@ -1029,12 +994,9 @@
 th
 ths
 tif
-Tikhonov
 TikZ
 Timestamp
 tinv
-Tisseur
-Tisseur's
 tmp
 Toeplitz
 tokenExtents
@@ -1058,7 +1020,6 @@
 trnd
 truecolor
 TrueColor
-Tsang
 Tukey
 tuples
 Tx
@@ -1127,14 +1088,15 @@
 versa
 vertcat
 vertices
-Villadsen
+Vorbis
+vorbis
 voronoi
 Voronoi
 waitbar
 waitbars
 wallis
 warndlg
-Wathen
+wav
 WAV
 WayPoints
 wblcdf
@@ -1155,17 +1117,16 @@
 wildcard
 Wildcards
 wildcards
-Wilks
 windowbuttondownfcn
 windowbuttonmotionfcn
 windowbuttonupfcn
 windowstyle
-WinRand
 WIPO
 wireframe
 wp
 wspace
 xb
+xboxes
 xc
 xcorr
 xdata
@@ -1180,17 +1141,21 @@
 xl
 xmax
 xmin
+xon
 xPBTRF
 xPOTRF
 xPTSV
 xtest
+xtests
 xTRTRS
 xu
 xwd
 xy
+xyboxes
 xyerrorbar
 xyerrorbars
 xyz
+yboxes
 yc
 ydata
 yerrorbar
@@ -1204,7 +1169,6 @@
 YYYY
 yyyymmdd
 yyyymmddTHHMMSS
-Zechner
 Ziggurat
 zlib
 zlim
--- a/doc/interpreter/emacs.txi	Fri Feb 06 08:31:09 2015 -0800
+++ b/doc/interpreter/emacs.txi	Fri Feb 06 08:31:49 2015 -0800
@@ -351,8 +351,8 @@
 @code{font-lock-function-name-face}.
 @end itemize
 
-There is also rudimentary support for Imenu (currently, function names
-can be indexed).
+There is also rudimentary support for @nospell{Imenu} (currently, function
+names can be indexed).
 
 @cindex TAGS
 @cindex Emacs TAGS files
--- a/doc/interpreter/errors.txi	Fri Feb 06 08:31:09 2015 -0800
+++ b/doc/interpreter/errors.txi	Fri Feb 06 08:31:49 2015 -0800
@@ -126,8 +126,6 @@
 
 @DOCSTRING(print_usage)
 
-@DOCSTRING(usage)
-
 @DOCSTRING(beep)
 
 @DOCSTRING(beep_on_error)
@@ -285,7 +283,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/expr.txi	Fri Feb 06 08:31:09 2015 -0800
+++ b/doc/interpreter/expr.txi	Fri Feb 06 08:31:49 2015 -0800
@@ -1009,10 +1009,10 @@
 
 @sc{matlab} has special behavior that allows the operators @samp{&} and
 @samp{|} to short-circuit when used in the truth expression for @code{if} and
-@code{while} statements.  The Octave parser may be instructed to behave in the
-same manner, but its use is strongly discouraged.
-
-@DOCSTRING(do_braindead_shortcircuit_evaluation)
+@code{while} statements.  Octave also behaves the same way by default,
+though the use of the @samp{&} and @samp{|} operators in this way is
+strongly discouraged.  Instead, you should use the @samp{&&} and @samp{||}
+operators that always have short-circuit behavior.
 
 Finally, the ternary operator (?:) is not supported in Octave.  If
 short-circuiting is not important, it can be replaced by the @code{ifelse}
@@ -1243,8 +1243,10 @@
 is evaluated as
 
 @example
+@group
 @var{temp} = @var{expr2}
 @var{expr1} = (@var{expr1}) @var{op} @var{temp}
+@end group
 @end example
 
 @noindent
--- a/doc/interpreter/external.txi	Fri Feb 06 08:31:09 2015 -0800
+++ b/doc/interpreter/external.txi	Fri Feb 06 08:31:49 2015 -0800
@@ -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 Feb 06 08:31:09 2015 -0800
+++ b/doc/interpreter/func.txi	Fri Feb 06 08:31:49 2015 -0800
@@ -393,15 +393,27 @@
 which stops the function execution and prints a message about the correct
 way to call the function whenever the number of inputs is wrong.
 
-For compatibility with @sc{matlab}, @code{nargchk}, @code{narginchk} and
-@code{nargoutchk} are available which provide similar error checking.
-
-@DOCSTRING(nargchk)
+For compatibility with @sc{matlab}, @code{narginchk} and @code{nargoutchk} are
+available which provide similar error checking.
 
 @DOCSTRING(narginchk)
 
 @DOCSTRING(nargoutchk)
 
+Besides the number of arguments, inputs can be checked for various properties.
+@code{validatestring} is used for string arguments and
+@code{validateattributes} for numeric arguments.
+
+@DOCSTRING(validatestring)
+
+@DOCSTRING(validateattributes)
+
+If none of the preceding functions is sufficient there is also the class
+@code{inputParser} which can perform extremely complex input checking for
+functions.
+
+@DOCSTRING(inputParser)
+
 @anchor{XREFvarargin} @anchor{XREFvarargout}
 @node Variable-length Argument Lists
 @section Variable-length Argument Lists
@@ -800,7 +812,7 @@
 
 @DOCSTRING(command_line_path)
 
-@DOCSTRING(find_dir_in_path)
+@DOCSTRING(dir_in_loadpath)
 
 @node Subfunctions
 @subsection Subfunctions
@@ -1124,7 +1136,7 @@
 which contains the current function.
 
 @item Class constructor
-A function that constuctors a user class as defined in chapter
+A function that constructs a user class as defined in chapter
 @ref{Object Oriented Programming}.
 
 @item Class method
@@ -1377,6 +1389,34 @@
 are passed to @code{betainc} are inherited from the current
 environment.
 
+Note that for performance reasons it is better to use handles to existing
+Octave functions, rather than to define anonymous functions which wrap an
+existing function.  The integration of @code{sin (x)} is 5X faster if the code
+is written as
+
+@example
+quad (@@sin, 0, pi)
+@end example
+
+@noindent
+rather than using the anonymous function @code{@@(x) sin (x)}.  There are many
+operators which have functional equivalents that may be better choices than an
+anonymous function.  Instead of writing
+
+@example
+f = @@(x, y) x + y
+@end example
+
+@noindent
+this should be coded as
+
+@example
+f = @@plus
+@end example
+
+@xref{Operator Overloading}, for a list of operators which also have a
+functional form.
+
 @node Inline Functions
 @subsection Inline Functions
 
@@ -1392,6 +1432,11 @@
 After this it is possible to evaluate @math{f} at any @math{x} by
 writing @code{f(x)}.
 
+@strong{Caution}: @sc{matlab} has begun the process of deprecating inline
+functions.  At some point in the future support will be dropped and eventually
+Octave will follow @sc{matlab} and also remove inline functions.  Use anonymous
+functions in all new code.
+
 @DOCSTRING(inline)
 
 @DOCSTRING(argnames)
@@ -1486,7 +1531,7 @@
 @item general
 Miscellaneous matrix manipulations, like @code{flipud}, @code{rot90},
 and @code{triu}, as well as other basic functions, like
-@code{ismatrix}, @code{nargchk}, etc.
+@code{ismatrix}, @code{narginchk}, etc.
 
 @item geometry
 Functions related to Delaunay triangulation.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/interpreter/genpropdoc.m	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,1305 @@
+## Copyright (C) 2014 Pantxo Diribarne
+##
+## This program is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or
+## (at your option) any later version.
+##
+## This program is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+## GNU General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with this program.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {@var{retval} =} genpropdoc (@var{OBJNAME}, @var{FILENAME})
+##
+## Print FILENAME texinfo source file associated to OBJNAME objects.
+## This function is meant to be run for generating octave
+## documentation (see doc/interpreter/graphics_properties.mk).
+##
+## All the hard coded documentation is written in getdoc
+## function.  See the comments in getdoc bellow for instruction on how
+## to document a graphics property.
+##
+## @seealso{}
+## @end deftypefn
+
+function genpropdoc (objname, fname)
+  objnames = {"root", "figure", "axes", "line", ...
+              "text", "image", "patch", "surface"};
+
+  ## Base properties
+  base = getstructure ("base");
+
+  ## Object properties
+  if (any (strcmp (objname, objnames)))
+    obj = getstructure (objname, base);
+  else
+    error ("genpropdoc: unknown object %s", objname);
+  endif
+
+  ## Docstring
+  str = printdoc (objname, obj);
+
+  fid = fopen (fname,  "w+");
+  if (fid < 0)
+    error ("genpropdoc: couldn't open %s.", fname);
+  endif
+
+  fprintf (fid, str);
+  fclose (fid);
+endfunction
+
+function s = getdoc (objname, field, base)
+  ## Properties are represented by a struct with fields :
+  ##
+  ## -"doc": string to be printed verbatim after being expanded
+  ##   through expand_doc function.  Special keywords are:
+  ##   "__objname__" further replaced by the current object name;
+  ##   "__prop__"  further replaced by the current property name;
+  ##   "__modemsg__"  further replaced by a message explaining that
+  ##   the propmode will be toggled to "manual".
+  ##   You may also cross reference properties using the label format
+  ##   OBJNAMEPROPERTY, e.g, "@xref{XREFaxescolor, , axes color
+  ##   property}."
+  ##
+  ## -"valid": string that describes valid values for the
+  ##   current property.  Use "packopt" function to join options with
+  ##   " | " separator and "markdef" to mark default among valid
+  ##   values between curly braces.
+  ##   If not provided, valid values for radio properties are
+  ##   automatically retrieved using set function.
+  ##
+  ## -"default": string.  If not provided the default value is
+  ##   automatically retrieved using get function.
+  ##
+  ## -"printdefault": a boolean (def. true) that specifies whether the
+  ## default value should be printed.  It is useful for properties
+  ## like root "screendepth" that default to screen dependant values.
+
+  packopt = @(c) strjoin (c, ' | ');
+  markdef = @(s) ["@{" s "@}"];
+
+  ## Some generic templates:
+  valid_color = "colorspec";
+  valid_handle = "graphics handle";
+  valid_string = "string";
+  valid_fcn = packopt ({"string", "function handle"});
+  valid_cellstring = packopt ({"string", "cell array of strings"});
+  valid_2elvec = "two elements vector";
+  valid_3elvec = "three elements vector";
+  valid_4elvec = "four elements vector";
+  valid_vecmat = packopt ({"vector", "matrix"});
+  valid_scalmat = packopt ({"scalar", "matrix"});
+
+  doc_notimpl =  "%s is not yet implemented for __objname__ \
+objects.  __prop__ is unused.";
+  doc_unused =  "__prop__ is unused.";
+
+
+  ## Initialize structure
+  if (isfield (base, field))
+    s = base.(field);
+  else
+    s = struct ("valid", "", "default", "", "doc", "", ...
+                "printdefault", true);
+  endif
+
+  ## Base properties: write generic documentation as it will, by
+  ## default, be included in the list of each graphics object.
+  ## If a given graphics object interprets the property differently
+  ## than most others, the doc will have to be rewritten for this object.
+  if (strcmp (objname, "base"))
+    switch field
+      case "beingdeleted"
+      case "busyaction"
+      case "buttondownfcn"
+        s.valid = valid_fcn;
+      case "children"
+        s.doc = "Graphics handles of the __objname__'s children.";
+        s.valid = "vector of graphics handles";
+
+      case "clipping"
+        s.doc = "If __prop__ is @qcode{\"on\"}, the __objname__ is \
+clipped in its parent axes limits.";
+
+      case "createfcn"
+        s.doc = "Callback functions to be executed right after \
+the __objname__ has been created.  Those functions have to be set by \
+default using e.g.  @code{set (0, \"default__objname__createfcn\", \
+'disp (\"__objname__ created!\")') }.";
+        s.valid = valid_fcn;
+
+      case "deletefcn"
+        s.doc = "Callback functions to be executed right before \
+the __objname__ is deleted.";
+        s.valid = valid_fcn;
+
+      case "handlevisibility"
+        s.doc = "If __prop__ is @qcode{\"off\"}, the __objname__'s \
+handle is not visible into its parent's children list.";
+
+      case "hittest"
+      case "interruptible"
+      case "parent"
+        s.doc = "Handle of the parent graphics object.";
+        s.valid = valid_handle;
+
+      case "selected"
+      case "selectionhighlight"
+      case "tag"
+        s.valid = valid_string;
+
+      case "type"
+        s.doc = "Class name of the graphics object.  __prop__ is \
+always @qcode{\"__objname__\"}";
+        s.valid = valid_string;
+        s.printdefault = false;
+
+      case "uicontextmenu"
+      case "userdata"
+      case "visible"
+        s.doc = "If __prop__ is @qcode{\"off\"}, the __objname__ is \
+not rendered on screen.";
+    endswitch
+
+  ## Root properties:
+  elseif (strcmp (objname, "root"))
+    switch field
+      ## Overridden shared properties
+      case {"beingdeleted", "busyaction", "buttondownfcn", ...
+            "clipping", "createfcn", "deletefcn", "handlevisibility", ...
+            "hittest", "interruptible", "selected", ...
+            "selectionhighlight", "uicontextmenu", "visible"}
+        s.doc = doc_unused;
+
+      case "parent"
+        s.doc = "Root figure has no parent graphics object.  __prop__ \
+is always empty.";
+
+      ## Specific properties
+      case "callbackobject"
+        s.valid = valid_handle;
+
+      case "commandwindowsize"
+      case "currentfigure"
+        s.doc = "Graphics handle of the current figure.";
+        s.valid = valid_handle;
+
+      case "diary"
+        s.doc = "If __prop__ is @qcode{\"on\"}, the octave \
+command window session is saved to file.  @xref{XREFrootdiaryfile, , \
+diaryfile property}.";
+        s.valid = valid_string;
+
+      case "diaryfile"
+        s.doc = "The name of the diary file.  \
+@xref{XREFdiary, , diary function}.";
+        s.valid = valid_string;
+
+      case "echo"
+        s.doc = "Control whether octave displays commands executed \
+from scripts.  @xref{XREFecho, , echo function}.";
+
+      case "errormessage"
+        s.doc = "The last error message octave raised.  \
+@xref{XREFlasterr, , lasterr function}.";
+        s.valid = valid_string;
+
+      case "fixedwidthfontname"
+        s.valid = valid_string;
+
+      case "format"
+        s.doc = "This property is a wrapper around @code{format} \
+function.  @xref{XREFformat, , format function}.";
+
+      case "formatspacing"
+        s.doc = "This property is a wrapper around @code{format} \
+function.  @xref{XREFformat, , format function}.";
+
+      case "language"
+        s.valid = valid_string;
+
+      case "monitorpositions"
+        s.valid = valid_4elvec;
+
+      case "pointerlocation"
+        s.valid = valid_2elvec;
+
+      case "pointerwindow"
+        s.valid = valid_handle;
+
+      case "recursionlimit"
+        s.doc = "The maximum number of times a function can be \
+called recursively.  @xref{XREFmax_recursion_depth, , \
+max_recursion_depth function}.";
+        s.valid = "double";
+
+      case "screendepth"
+        s.valid = "double";
+        s.printdefault = false;
+
+      case "screenpixelsperinch"
+        s.valid = "double";
+        s.printdefault = false;
+
+      case "screensize"
+        s.valid = valid_4elvec;
+        s.printdefault = false;
+
+      case "showhiddenhandles"
+        s.doc = "If __prop__ is @qcode{\"on\"}, all graphics objects \
+handle are visible in their parents' children list, regardless of \
+the value of their @code{handlevisibility} property.";
+
+      case "units"
+    endswitch
+
+  ## Figure properties
+  elseif (strcmp (objname, "figure"))
+    switch field
+      ## Overridden shared properties
+      case "clipping"
+        s.doc = doc_unused;
+
+      ## Specific properties
+      case "alphamap"
+        s.doc = sprintf (doc_notimpl, "Transparency");
+      case "closerequestfcn"
+        s.valid = valid_fcn;
+
+      case "color"
+        s.doc = "Color of the figure background.  @xref{Colors, , \
+colorspec}.";
+        s.valid = valid_color;
+
+      case "colormap"
+        s.doc = "A matrix containing the RGB color map for \
+the current axes.";
+        s.valid = "N-by-3 matrix";
+
+      case "currentaxes"
+        s.doc = "Handle to the graphics object of the current axes.";
+        s.valid = valid_handle;
+
+      case "currentcharacter"
+        s.doc = doc_unused;
+
+      case "currentobject"
+        s.valid = valid_handle;
+
+      case "currentpoint"
+        s.doc = "A 1-by-2 matrix which holds the coordinates of \
+the point over which the mouse pointer was when a mouse event \
+occurred.  The x and y coordinates are in units defined by the \
+figures @qcode{\"units\"} property and their origin is the lower \
+left corner of the plotting area.\
+\n\nEvents which set @qcode{\"currentpoint\"} are\n\
+@table @asis\n\
+@item A mouse button was pressed\n\
+always\n\
+@item A mouse button was released\n\
+only if the figures callback @qcode{\"windowbuttonupfcn\"} is defined\n\
+@item The pointer was moved while pressing mouse button (drag)\n\
+ only if the figures callback @qcode{\"windowbuttonmotionfcn\"} is \
+defined \n\
+@end table";
+        s.valid = valid_2elvec;
+
+      case "dockcontrols"
+        s.doc = doc_unused;
+
+      case "doublebuffer"
+      case "filename"
+      case "integerhandle"
+      case "inverthardcopy"
+      case "keypressfcn"
+        s.valid = valid_fcn;
+
+      case "keyreleasefcn"
+        s.doc = "With @code{keypressfcn}, the keyboard callback \
+functions.  These callback functions get called when a key is \
+pressed/released respectively.  The functions are called with two \
+input arguments.  The first argument holds the handle of the calling \
+figure.  The second argument holds the event structure which has the \
+following members:\n\
+@table @code\n\
+@item Character:\n\
+The ASCII value of the key\n\
+@item Key:\n\
+lowercase value of the key\n\
+@item Modifier:\n\
+A cell array containing strings representing the modifiers pressed \
+with the key.\n\
+@end table";
+        s.valid = valid_fcn;
+
+      case "menubar"
+      case "mincolormap"
+      case "name"
+        s.doc = "Name to be displayed in the figure title bar.  If \
+__prop__ is empty, the title of the figure is \"figure\" followed \
+by the figure handle value.";
+        s.valid = valid_string;
+
+      case "nextplot"
+      case "numbertitle"
+      case "outerposition"
+        s.valid = valid_4elvec;
+
+      case "paperorientation"
+      case "paperposition"
+        s.doc = "Vector @qcode{[x0 y0 width height]} defining the \
+position of the figure (in @code{paperunits} units) in the printed \
+page.  __modemsg__.";
+        s.valid = valid_4elvec;
+
+      case "paperpositionmode"
+        s.doc = "If __prop__ is set to @qcode{\"auto\"}, the \
+@qcode{\"paperposition\"} property is automatically computed: the \
+printed figure will have the same size as on-screen figure and will \
+be centered in the output page.";
+      case "papersize"
+        s.doc = "Vector @qcode{[width height]} defining the size of the \
+printing paper.  Setting this property forces the @code{papertype} \
+property to be set to @qcode{\"<custom>\"}.";
+        s.valid = valid_2elvec;
+
+      case "papertype"
+        s.doc = "Name of the paper to be used for printed output.  \
+Setting __prop__ also changes @code{papersize} accordingly.";
+
+      case "paperunits"
+        s.doc = "The unit used to compute the @code{paperposition} \
+property.";
+
+      case "pointer"
+      case "pointershapecdata"
+        s.doc = doc_unused;
+
+      case "pointershapehotspot"
+        s.doc = doc_unused;
+
+      case "position"
+        s.valid = valid_4elvec;
+
+      case "renderer"
+      case "renderermode"
+      case "resize"
+      case "resizefcn"
+        s.valid = valid_fcn;
+
+      case "selectiontype"
+      case "toolbar"
+      case "units"
+        s.doc = "The unit used to compute the @code{position} and \
+@code{outerposition} properties.";
+      case "windowbuttondownfcn"
+        s.doc = "@xref{XREFfigurewindowbuttonupfcn, , \
+windowbuttonupfcn property}.";
+        s.valid = valid_fcn;
+
+      case "windowbuttonmotionfcn"
+        s.doc = "@xref{XREFfigurewindowbuttonupfcn, , \
+windowbuttonupfcn property}.";
+        s.valid = valid_fcn;
+
+      case "windowbuttonupfcn"
+        s.doc = "With @code{windowbuttondownfcn} and \
+@code{windowbuttonmotionfcn}, the mouse callback functions.  These \
+callback functions get called when the mouse button is pressed, \
+dragged, and released respectively.  When these callback functions \
+are called, the @code{currentpoint} property holds the current \
+coordinates of the cursor.";
+        s.valid = valid_fcn;
+
+      case "windowkeypressfcn"
+        s.valid = valid_fcn;
+
+      case "windowkeyreleasefcn"
+        s.valid = valid_fcn;
+
+      case "windowscrollwheelfcn"
+        s.valid = valid_fcn;
+
+      case "windowstyle"
+      case "wvisual"
+      case "wvisualmode"
+      case "xdisplay"
+      case "xvisual"
+      case "xvisualmode"
+      case "__graphics_toolkit__"
+        s.doc = "The graphics toolkit that is used to render the \
+figure.  @xref{XREFavailable_graphics_toolkits, , \
+available_graphics_toolkits function}.";
+    endswitch
+
+  ## Axes properties
+  elseif (strcmp (objname, "axes"))
+    switch field
+      ## Overridden shared properties
+      case "clipping"
+        s.doc = doc_unused;
+
+      ## Specific properties
+      case "activepositionproperty"
+      case "alim"
+        s.doc = sprintf (doc_notimpl, "Transparency");
+      case "alimmode"
+      case "ambientlightcolor"
+        s.doc = sprintf (doc_notimpl, "Light");
+      case "box"
+        s.doc = "Control wether the axes has a surrounding box.";
+
+      case "cameraposition"
+        s.valid = valid_3elvec;
+
+      case "camerapositionmode"
+      case "cameratarget"
+        s.valid = valid_3elvec;
+
+      case "cameratargetmode"
+      case "cameraupvector"
+        s.valid = valid_3elvec;
+
+      case "cameraupvectormode"
+      case "cameraviewangle"
+        s.valid = "scalar";
+
+      case "cameraviewanglemode"
+      case "clim"
+        s.valid = valid_2elvec;
+        s.doc = "Define the limits for the color axis of image \
+children.  __modemsg__.  @xref{XREFpcolor, , pcolor function}.";
+
+      case "climmode"
+      case "color"
+        s.doc = "Color of the axes background.  @xref{Colors, , \
+colorspec}.";
+        s.valid = valid_color;
+
+      case "colororder"
+        s.doc = "RGB values to be used by plot function for \
+automatic line coloring.";
+        s.valid = "N-by-3 RGB matrix";
+
+      case "currentpoint"
+        s.doc = "Matrix @qcode{[xf, yf, zf; xb, yb, zb]} which holds \
+the coordinates of the point over which the mouse pointer was when \
+the mouse button was pressed in axes data units.  If a mouse \
+callback function is defined, @code{currentpoint} holds the \
+pointer coordinates at the time the mouse button was pressed.  For \
+3D plots, the first row of the returned matrix specifies the point \
+nearest to the current camera position and the second rows the \
+furthest point.  The two points forms a line which is perpendicular \
+to the screen.";
+        s.valid = "2-by-3 matrix";
+
+      case "dataaspectratio"
+        s.doc = "Specify the relative height and width of the data \
+displayed in the axes.  Setting @code{dataaspectratio} to @samp{[1, \
+2]} causes the length of one unit as displayed on the y-axis to be \
+the same as the length of 2 units on the x-axis.  __modemsg__.";
+        s.valid = valid_3elvec;
+
+      case "dataaspectratiomode"
+      case "drawmode"
+      case "fontangle"
+      case "fontname"
+        s.doc = "Name of the font to be used for axes annotations.";
+        s.valid = valid_string;
+
+      case "fontsize"
+        s.doc = "Size of the font to be used for axes annotations.  \
+@xref{XREFaxesfontunits, , fontunits property}.";
+        s.valid = "scalar";
+
+      case "fontunits"
+        s.doc = "Unit used to interpret @code{fontsize} property.";
+
+      case "fontweight"
+      case "gridlinestyle"
+      case "interpreter"
+      case "layer"
+      case "linestyleorder"
+      case "linewidth"
+      case "minorgridlinestyle"
+      case "nextplot"
+      case "outerposition"
+        s.doc = "Specify the position of the plot, including titles, \
+axes and legend.  The four elements of the vector are the \
+coordinates of the lower left corner and width and height of the \
+plot, in units normalized to the width and height of the plot \
+window.  For example, @qcode{[0.2, 0.3, 0.4, 0.5]} sets the lower \
+left corner of the axes at @math{(0.2, 0.3)} and the width and \
+height to be 0.4 and 0.5 respectively.  @xref{XREFaxesposition, , position property}.";
+        s.valid = valid_4elvec;
+
+      case "plotboxaspectratio"
+      case "plotboxaspectratiomode"
+      case "position"
+        s.doc = "Specify the position of the plot, excluding titles, \
+axes and legend.  The four elements of the vector are the \
+coordinates of the lower left corner and width and height of the \
+plot, in units normalized to the width and height of the plot \
+window.  For example, @qcode{[0.2, 0.3, 0.4, 0.5]} sets the lower \
+left corner of the axes at @math{(0.2, 0.3)} and the width and \
+height to be 0.4 and 0.5 respectively.  @xref{XREFaxesouterposition, , \
+outerposition property}.";
+        s.valid = valid_4elvec;
+
+      case "projection"
+      case "tickdir"
+      case "tickdirmode"
+      case "ticklength"
+      case "tightinset"
+      case "title"
+        s.doc = "Graphics handle of the title text object.";
+        s.valid = valid_handle;
+
+      case "units"
+      case "view"
+        s.doc = "Specify the view point for three-dimensional plots";
+        s.valid = valid_2elvec;
+
+      case "xaxislocation"
+      case "xcolor"
+        s.doc = "Color of the x-axis.  @xref{Colors, , colorspec}.";
+        s.valid = packopt ({markdef(valid_color), ...
+                            "@qcode{\"none\"}"});
+
+      case "xdir"
+      case "xgrid"
+        s.doc = "Control wether major x grid lines are displayed.";
+
+      case "xlabel"
+        s.doc = "Graphics handle of the x label text object.";
+        s.valid = valid_handle;
+
+      case "xlim"
+        s.doc = "Specify the limits for x-axis.  __modemsg__.  \
+@xref{XREFxlim, , xlim function}.";
+        s.valid = valid_2elvec;
+
+      case "xlimmode"
+      case "xminorgrid"
+        s.doc = "Control wether minor x grid lines are displayed.";
+
+      case "xminortick"
+      case "xscale"
+      case "xtick"
+        s.doc = "Position of x tick marks.  __modemsg__.";
+        s.valid = "vector";
+
+      case "xticklabel"
+        s.doc = "Labels of x tick marks.  __modemsg__.";
+        s.valid = valid_cellstring;
+
+      case "xticklabelmode"
+      case "xtickmode"
+      case "yaxislocation"
+      case "ycolor"
+        s.doc = "Color of the y-axis.  @xref{Colors, , colorspec}.";
+        s.valid = packopt ({markdef(valid_color), ...
+                            "@qcode{\"none\"}"});
+
+      case "ydir"
+      case "ygrid"
+        s.doc = "Control wether major y grid lines are displayed.";
+
+      case "ylabel"
+        s.doc = "Graphics handle of the y label text object.";
+        s.valid = valid_handle;
+
+      case "ylim"
+        s.doc = "Specify the limits for y-axis.  __modemsg__.  \
+@xref{XREFylim, , ylim function}.";
+        s.valid = valid_2elvec;
+
+      case "ylimmode"
+      case "yminorgrid"
+        s.doc = "Control wether minor y grid lines are displayed.";
+
+      case "yminortick"
+      case "yscale"
+      case "ytick"
+        s.doc = "Position of y tick marks.  __modemsg__.";
+        s.valid = "vector";
+
+      case "yticklabel"
+        s.doc = "Labels of y tick marks.  __modemsg__.";
+        s.valid = valid_cellstring;
+
+      case "yticklabelmode"
+      case "ytickmode"
+      case "zcolor"
+        s.doc = "Color of the z-axis.  @xref{Colors, , colorspec}.";
+        s.valid = packopt ({markdef(valid_color), ...
+                            "@qcode{\"none\"}"});
+
+      case "zdir"
+      case "zgrid"
+        s.doc = "Control wether major z grid lines are displayed.";
+
+      case "zlabel"
+        s.doc = "Graphics handle of the z label text object.";
+        s.valid = valid_handle;
+
+      case "zlim"
+        s.doc = "Specify the limits for z-axis.  __modemsg__.  \
+@xref{XREFzlim, , zlim function}.";
+        s.valid = valid_2elvec;
+
+      case "zlimmode"
+      case "zminorgrid"
+        s.doc = "Control wether minor z grid lines are displayed.";
+
+      case "zminortick"
+      case "zscale"
+      case "ztick"
+        s.doc = "Position of z tick marks.  __modemsg__.";
+        s.valid = "vector";
+
+      case "zticklabel"
+        s.doc = "Labels of z tick marks.  __modemsg__.";
+        s.valid = valid_cellstring;
+
+      case "zticklabelmode"
+      case "ztickmode"
+    endswitch
+
+  ## Line properties
+  elseif (strcmp (objname, "line"))
+    switch field
+      ## Overridden shared properties
+      case "children"
+        s.doc = doc_unused;
+
+      ## Specific properties
+      case "color"
+        s.doc = "Color of the line object.  @xref{Colors, , \
+colorspec}.";
+        s.valid = valid_color;
+
+      case "displayname"
+        s.doc = "The text of the legend entry corresponding to this \
+line.";
+        s.valid = valid_cellstring;
+
+      case "erasemode"
+        s.doc = doc_unused;
+
+      case "interpreter"
+      case "linestyle"
+        s.doc = "@xref{Line Styles}.";
+
+      case "linewidth"
+        s.doc = "Width in points of the line object.";
+
+      case "marker"
+        s.doc = "The shape of the marker to be used.  @xref{Marker \
+Styles}.";
+
+      case "markeredgecolor"
+        s.doc = "Color of the edge of the markers.  If set \
+@qcode{\"auto\"}, the markers edges have the same color as the line.  If \
+set @qcode{\"none\"}, the markers edges are not displayed.  This property \
+can also be set to any color.  @xref{Colors, , colorspec}.";
+
+      case "markerfacecolor"
+        s.doc = "Color of the face of the markers.  If set \
+@qcode{\"auto\"}, the markers faces have the same color as the line.  If \
+set @qcode{\"none\"}, the markers faces are not displayed.  This property \
+can also be set to any color.  @xref{Colors, , colorspec}.";
+
+      case "markersize"
+        s.doc = "Size of the markers  in points.";
+        s.valid = "scalar";
+
+      case "xdata"
+        s.doc = "Vector of x data to be plotted.";
+        s.valid = "vector";
+
+      case "xdatasource"
+        s.valid = valid_string;
+        s.doc = "Name of the vector in the current base workspace \
+that should be used as x data.";
+
+      case "ydata"
+        s.doc = "Vector of y data to be plotted.";
+        s.valid = "vector";
+
+      case "ydatasource"
+        s.valid = valid_string;
+        s.doc = "Name of the vector in the current base workspace \
+that should be used as y data.";
+
+      case "zdata"
+        s.doc = "Vector of z data to be plotted.";
+        s.valid = "vector";
+
+      case "zdatasource"
+        s.valid = valid_string;
+        s.doc = "Name of the vector in the current base workspace \
+that should be used as z data.";
+
+    endswitch
+
+  ## Text properties
+  elseif (strcmp (objname, "text"))
+    switch field
+      ## Overridden shared properties
+      case "children"
+        s.doc = doc_unused;
+
+      ## Specific properties
+      case "backgroundcolor"
+        s.doc = sprintf (doc_notimpl, "Background area");
+        s.valid = valid_color;
+
+      case "color"
+        s.doc = "Color of the text.  @xref{Colors, ,colorspec}.  ";
+        s.valid = valid_color;
+
+      case "displayname"
+      case "edgecolor"
+        s.doc = sprintf (doc_notimpl, "Background area");
+        s.valid = valid_color;
+
+      case "editing"
+      case "erasemode"
+        s.doc = doc_unused;
+
+      case "extent"
+      case "fontangle"
+        s.doc = "Flag whether the font is italic or normal.  \
+@code{fontangle} is currently unused.";
+
+      case "fontname"
+        s.doc = "The font used for the text.";
+        s.valid = valid_string;
+
+      case "fontsize"
+        s.doc = "The font size of the text.";
+        s.valid = "scalar";
+
+      case "fontunits"
+        s.doc = "The units used to interpret @code{fontsize} \
+property.";
+
+      case "fontweight"
+        s.doc = "Flag whether the font is bold, etc.";
+
+      case "horizontalalignment"
+      case "interpreter"
+      case "linestyle"
+        s.doc = sprintf (doc_notimpl, "Background area");
+
+      case "linewidth"
+        s.doc = sprintf (doc_notimpl, "Background area");
+        s.valid = "scalar";
+
+      case "margin"
+        s.doc = sprintf (doc_notimpl, "Background area");
+        s.valid = "scalar";
+
+      case "position"
+        s.doc = "Vector @qcode{[X0 Y0 Z0]} where X0, Y0 and Z0 \
+indicate the position of the text anchor as defined by \
+@code{verticalalignment} and @code{horizontalalignment}.";
+        s.valid = valid_4elvec;
+
+      case "rotation"
+        s.doc = "The angle of rotation for the displayed text, \
+measured in degrees.";
+        s.valid = "scalar";
+
+      case "string"
+        s.doc = "The text object string content.";
+        s.valid = valid_string;
+
+      case "units"
+      case "verticalalignment"
+    endswitch
+
+  ## Image properties
+  elseif (strcmp (objname, "image"))
+    switch field
+      ## Overridden shared properties
+      case "children"
+        s.doc = doc_unused;
+
+      ## Specific properties
+      case "alphadata"
+        s.doc = sprintf (doc_notimpl, "Transparency");
+        s.valid = valid_scalmat;
+
+      case "alphadatamapping"
+        s.doc = sprintf (doc_notimpl, "Transparency");
+
+      case "cdata"
+        s.valid = "matrix";
+
+      case "cdatamapping"
+      case "displayname"
+        s.doc = "The text of the legend entry corresponding to this \
+image.";
+        s.valid = valid_cellstring;
+
+      case "erasemode"
+        s.doc = doc_unused;
+
+      case "xdata"
+        s.doc = "Two element vector @qcode{[xmin xmax]} specifying the x \
+coordinates of the first and last columns of the image.  \
+\n\nSetting @code{xdata} empty matrix makes octave automatically \
+affect it the value @qcode{[1 columns(image)]}.";
+        s.valid = valid_2elvec;
+
+      case "ydata"
+        s.doc = "Vector @qcode{[ymin ymax]} specifying the y \
+coordinates of the first and last columns of the image.  \
+\n\nSetting @code{ydata} empty matrix makes octave automatically \
+affect it the value @qcode{[1 rows(image)]}.";
+        s.valid = valid_2elvec;
+
+    endswitch
+
+  ## Surface properties
+  elseif (strcmp (objname, "surface"))
+    switch field
+      ## Overridden shared properties
+      case "children"
+        s.doc = doc_unused;
+
+      ## Specific properties
+      case "alphadata"
+        s.doc = sprintf (doc_notimpl, "Transparency");
+        s.valid = valid_scalmat;
+
+      case "alphadatamapping"
+        s.doc = sprintf (doc_notimpl, "Transparency");
+
+      case "ambientstrength"
+        s.doc = sprintf (doc_notimpl, "Light");
+
+      case "backfacelighting"
+        s.doc = sprintf (doc_notimpl, "Light");
+
+      case "cdata"
+        s.valid = "matrix";
+
+      case "cdatamapping"
+      case "cdatasource"
+      case "diffusestrength"
+        s.doc = sprintf (doc_notimpl, "Light");
+
+      case "displayname"
+        s.doc = "The text of the legend entry corresponding to this \
+surface.";
+
+      case "edgealpha"
+        s.doc = sprintf (doc_notimpl, "Transparency");
+        s.valid = "scalar";
+
+      case "edgecolor"
+      case "edgelighting"
+        s.doc = sprintf (doc_notimpl, "Light");
+
+      case "erasemode"
+        s.doc = doc_unused;
+      case "facealpha"
+        s.doc = sprintf (doc_notimpl, "Transparency");
+        s.valid = valid_scalmat;
+
+      case "facecolor"
+      case "facelighting"
+        s.doc = sprintf (doc_notimpl, "Light");
+
+      case "interpreter"
+      case "linestyle"
+        s.doc = "@xref{Line Styles}.";
+
+      case "linewidth"
+        s.doc = "@xref{XREFlinelinewidth, , line linewidth \
+property}.";
+
+      case "marker"
+        s.doc = "@xref{Marker Styles}.";
+
+      case "markeredgecolor"
+        s.doc = "@xref{XREFlinemarkeredgecolor, , line \
+markeredgecolor property}.";
+
+      case "markerfacecolor"
+        s.doc = "@xref{XREFlinemarkerfacecolor, , line \
+markerfacecolor property}.";
+
+      case "markersize"
+        s.doc = "@xref{XREFlinemarkersize, , line \
+markersize property}.";
+        s.valid = "scalar";
+
+      case "meshstyle"
+      case "normalmode"
+      case "specularcolorreflectance"
+        s.doc = sprintf (doc_notimpl, "Light");
+
+      case "specularexponent"
+        s.doc = sprintf (doc_notimpl, "Light");
+
+      case "specularstrength"
+        s.doc = sprintf (doc_notimpl, "Light");
+
+      case "vertexnormals"
+      case "xdata"
+        s.valid = "matrix";
+
+      case "xdatasource"
+      case "ydata"
+        s.valid = "matrix";
+
+      case "ydatasource"
+      case "zdata"
+        s.valid = "matrix";
+
+      case "zdatasource"
+    endswitch
+
+  ## Patch properties
+  elseif (strcmp (objname, "patch"))
+    switch field
+      ## Overridden shared properties
+      case "children"
+        s.doc = doc_unused;
+
+      ## Specific properties
+      case "alphadatamapping"
+        s.doc = sprintf (doc_notimpl, "Transparency");
+
+      case "ambientstrength"
+        s.doc = sprintf (doc_notimpl, "Light");
+        s.valid = "scalar";
+
+      case "backfacelighting"
+        s.doc = sprintf (doc_notimpl, "Light");
+
+      case "cdata"
+        s.doc = "Data defining the patch object color.\n\
+Patch color can be defined for faces or for vertices.  \n\n\
+If @code{cdata} is a scalar index into the current colormap or a RGB \
+triplet, it defines the color of all faces.  \n\n\
+If @code{cdata} is a N-by-1 vector of indices or a N-by-3 (RGB) \
+matrix, it defines the color of each one of the N faces.\n\n\
+If @code{cdata} is a N-by-M or a N-by-M-by-3 (RGB) \
+matrix, it defines the color all vertices.";
+        s.valid = valid_scalmat;
+
+      case "diffusestrength"
+        s.doc = sprintf (doc_notimpl, "Light");
+        s.valid = "scalar";
+
+      case "displayname"
+        s.doc = "The text of the legend entry corresponding to this \
+patch.";
+      case "edgealpha"
+        s.doc = sprintf (doc_notimpl, "Transparency");
+        s.valid = valid_scalmat;
+
+      case "edgecolor"
+      case "edgelighting"
+        s.doc = sprintf (doc_notimpl, "Light");
+
+      case "erasemode"
+        s.doc = doc_unused;
+
+      case "facealpha"
+        s.doc = sprintf (doc_notimpl, "Transparency");
+        s.valid = valid_scalmat;
+
+      case "facecolor"
+        ## Don't provide a default value, and mark colorspec with
+        ## braces, this forces the default rgb triplet to be displayed
+        s.valid = packopt ({markdef(valid_color), ...
+                            "@qcode{\"flat\"}", ...
+                            "@qcode{\"none\"}", ...
+                            "@qcode{\"interp\"}"});
+
+      case "facelighting"
+        s.doc = sprintf (doc_notimpl, "Light");
+
+      case "faces"
+      case "xdata"
+        s.valid = valid_vecmat;
+
+      case "facevertexalphadata"
+        s.doc = sprintf (doc_notimpl, "Transparency");
+        s.valid = valid_scalmat;
+
+      case "facevertexcdata"
+      case "interpreter"
+        s.doc = doc_unused;
+
+      case "linestyle"
+      case "linewidth"
+      case "marker"
+        s.doc = "@xref{XREFlinemarker, , line marker property}.";
+
+      case "markeredgecolor"
+        s.doc = "@xref{XREFlinemarkeredgecolor, , line \
+markeredgecolor property}.";
+
+      case "markerfacecolor"
+        s.doc = "@xref{XREFlinemarkerfacecolor, , line \
+markerfacecolor property}.";
+
+      case "markersize"
+        s.doc = "@xref{XREFlinemarkersize, , line \
+markersize property}.";
+        s.valid = "scalar";
+
+      case "normalmode"
+      case "specularcolorreflectance"
+        s.doc = sprintf (doc_notimpl, "Light");
+        s.valid = "scalar";
+
+      case "specularexponent"
+        s.doc = sprintf (doc_notimpl, "Light");
+        s.valid = "scalar";
+
+      case "specularstrength"
+        s.doc = sprintf (doc_notimpl, "Light");
+        s.valid = "scalar";
+
+      case "vertexnormals"
+      case "vertices"
+        s.valid = valid_vecmat;
+
+      case "xdata"
+        s.valid = valid_vecmat;
+
+      case "ydata"
+        s.valid = valid_vecmat;
+
+      case "zdata"
+        s.valid = valid_vecmat;
+
+    endswitch
+  endif
+
+  ## Replace keywords
+  if (! isempty (s.doc) && ! strcmp (objname, "base"))
+    s.doc = expand_doc (s.doc, field, objname);
+  endif
+
+endfunction
+
+function strout = expand_doc (strin, field, objname)
+  strout = strrep (strin, "__objname__", objname);
+  strout = strrep (strout, "__prop__", ["@code{" field "}"]);
+
+  modemsg = "Setting @code{%s} also forces the @code{%smode} \
+property to be set to @qcode{\"manual\"}";
+  modemsg = sprintf (modemsg, field, field);
+  strout = strrep (strout, "__modemsg__", modemsg);
+endfunction
+
+function s = getstructure (objname, base = [])
+  hf = [];
+  if (! strcmp (objname, "root"))
+    ## Use an improbable figure number to avoid ishandle to return
+    ## true for 1
+    hf = figure (2265465, "visible", "off");
+  endif
+
+  ## Build a default object to extract its properties list and default
+  ## values.
+  if (strcmp (objname, "base"))
+    ## Base properties are extracted from hggroup that only have 2
+    ## additional regular (non-hidden) properties, "displayname" and
+    ## "erasemode".
+    h = hggroup ();
+  elseif (strcmp (objname, "root"))
+    h = 0;
+  elseif (strcmp (objname, "figure"))
+    h = hf;
+  else
+    eval (["h = " objname " ();"]);
+  endif
+
+  gprop = get (h);
+  sprop = set (h);
+
+  fields = fieldnames (gprop);
+  nf = numel (fields);
+  args = cell (2*nf, 1);
+  for ii = 1:nf
+    field = fields{ii};
+
+    ## Get hard coded documentation
+    val = getdoc (objname, field, base);
+
+    ## Extract the default values that are not hard coded in getdoc
+    if (isempty (val.default) && val.printdefault)
+      val.default = getdefault (h, objname, field);
+    endif
+
+    val.isreadonly = ! isfield (sprop, field);
+
+    ## Extract the valid values that are not hard coded in getdoc
+    if (! val.isreadonly && isempty (val.valid))
+      val.valid = sprop.(field);
+      if (! isempty (val.valid) &&
+          iscellstr (val.valid))
+        ## Add double quotes around string radio properties
+        val.valid = cellfun (@(s) ["@qcode{\"" s "\"}"], val.valid,
+                             "uniformoutput", false);
+        val.valid = strjoin (val.valid, ' | ');
+      endif
+    endif
+
+    args{2*(ii-1)+1} = field;
+    args{2*ii} = val;
+  endfor
+
+  ## Build struct and remove unused fields in base properties
+  s = struct (args{:});
+
+  if (strcmp (objname, "base"))
+    s = rmfield (s, {"displayname", "erasemode"});
+  endif
+
+  if (isfigure (hf))
+    close (hf)
+  endif
+endfunction
+
+function def = getdefault (h, objname, field)
+  ## This function is meant to be run without initialization file so
+  ## that the properties we get are the default.
+  def = get (h, field);
+
+  ## Don't print default values for graphics handles
+  if (isscalar (def) && def != 0 && ishandle (def))
+    def = "";
+  else
+    if (ischar (def))
+      def = ["@qcode{\"" def "\"}"];
+    else
+      if ((isvector (def) && numel (def) < 5) ||
+          isempty (def))
+        ## Use disp to print the default value for short vectors and
+        ## empty values
+        str = disp (def);
+        str(end) = [];          # remove linefeed
+        str = strtrim (str);    # remove leading space
+
+        ## Add [] around vector values
+        if (ismatrix (def) && numel (def) > 1)
+          str = ["[" str "]"];
+          ## Add ";" between columns vector values
+          if (rows (def) != 1)
+            str = strrep (str, "\n", "; ");
+          endif
+        endif
+
+        ## Replace texinfo reserved characters
+        def = strrep (str, "{", "@{");
+        def = strrep (def, "}", "@}");
+        def = strrep (def, "@", "@@");
+
+        def = ["@code{" def "}"];
+      else
+        args = arrayfun (@(x) num2str (x), size (def),
+                         "uniformoutput", false);
+        def = [strjoin(args, "-by-") " " class(def)];
+      endif
+    endif
+  endif
+endfunction
+
+function str = printdoc (objname, obj)
+  ## Sort fields so that they appear in alphabetic order in the manual
+  fields = sort (fieldnames (obj));
+  nf = numel (fields);
+
+  ## File header and begining of properties table
+  str = [warn_autogen() "\n\n@table @asis"];
+
+
+  for ii = 1:nf
+    field = fields{ii};
+    str = sprintf ("%s\n\n", str);
+
+    ## @anchor: cross reference using XREFobjnamefield label
+    ## Concept index: call info from octave with
+    ## 'doc ("objname field")'
+    str = sprintf ("%s@anchor{XREF%s%s}\n@cindex %s %s\n",
+                   str, objname, field, objname, field);
+
+    ## Item
+    str = sprintf ("%s@item @code{%s}", str, field);
+
+    ## Mark item read-only if needed
+    if (obj.(field).isreadonly)
+      str = sprintf ("%s (read-only):", str);
+    else
+      str = sprintf ("%s:", str);
+    endif
+
+    ## Print valid and default values
+    tmp = print_options (obj.(field).valid,
+                         obj.(field).default);
+    if (! isempty (tmp))
+      str = sprintf ("%s %s\n", str, tmp);
+    else
+      str = sprintf ("%s\n", str);
+    endif
+
+    ## Print documentation
+    str = sprintf ("%s%s\n", str, obj.(field).doc);
+  endfor
+
+  ## End of properties table
+  str = sprintf ("%s\n@end table", str);
+endfunction
+
+function str = warn_autogen ()
+  str = "@c DO NOT EDIT!  Generated automatically by genpropdoc.m.\n\
+\n\
+@c Copyright (C) 2014 Pantxo Diribarne\n\
+@c\n\
+@c This file is part of Octave.\n\
+@c\n\
+@c Octave is free software; you can redistribute it and/or modify it\n\
+@c under the terms of the GNU General Public License as published by the\n\
+@c Free Software Foundation; either version 3 of the License, or (at\n\
+@c your option) any later version.\n\
+@c\n\
+@c Octave is distributed in the hope that it will be useful, but WITHOUT\n\
+@c ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n\
+@c FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\n\
+@c for more details.\n\
+@c\n\
+@c You should have received a copy of the GNU General Public License\n\
+@c along with Octave; see the file COPYING.  If not, see\n\
+@c <http://www.gnu.org/licenses/>.";
+endfunction
+
+function str = print_options (val, default)
+  str = "";
+  if (! isempty (val))
+    tmp = strrep (val, default, ["@{" default "@}"]);
+    if (length (tmp) == length (val) && ! isempty (default))
+      str = [tmp ", def. " default];
+    else
+      str = tmp;
+    endif
+  elseif (! isempty (default))
+    str = ["def. " default];
+  endif
+endfunction
--- a/doc/interpreter/geometry.txi	Fri Feb 06 08:31:09 2015 -0800
+++ b/doc/interpreter/geometry.txi	Fri Feb 06 08:31:49 2015 -0800
@@ -20,7 +20,7 @@
 @chapter Geometry
 
 Much of the geometry code in Octave is based on the Qhull
-library@footnote{Barber, C.B., Dobkin, D.P., and Huhdanpaa, H.T.,
+library@footnote{@nospell{Barber, C.B., Dobkin, D.P., and Huhdanpaa, H.T.},
 @cite{The Quickhull Algorithm for Convex Hulls}, ACM Trans. on Mathematical
 Software, 22(4):469--483, Dec 1996, @url{http://www.qhull.org}}.
 Some of the documentation for Qhull, particularly for the options that
@@ -50,15 +50,11 @@
 
 @DOCSTRING(delaunay)
 
-The 3- and N-dimensional extension of the Delaunay triangulation are
-given by @code{delaunay3} and @code{delaunayn} respectively.
-@code{delaunay3} returns a set of tetrahedra that satisfy the
+For 3-D inputs @code{delaunay} returns a set of tetrahedra that satisfy the
 Delaunay circum-circle criteria.  Similarly, @code{delaunayn} returns the
 N-dimensional simplex satisfying the Delaunay circum-circle criteria.
 The N-dimensional extension of a triangulation is called a tessellation.
 
-@DOCSTRING(delaunay3)
-
 @DOCSTRING(delaunayn)
 
 An example of a Delaunay triangulation of a set of points is
@@ -417,12 +413,10 @@
 An important use of the Delaunay tessellation is that it can be used to
 interpolate from scattered data to an arbitrary set of points.  To do
 this the N-simplex of the known set of points is calculated with
-@code{delaunay}, @code{delaunay3} or @code{delaunayn}.  Then the
-simplices in to which the desired points are found are
-identified.  Finally the vertices of the simplices are used to
-interpolate to the desired points.  The functions that perform this
-interpolation are @code{griddata}, @code{griddata3} and
-@code{griddatan}.
+@code{delaunay} or @code{delaunayn}.  Then the simplices in to which the
+desired points are found are identified.  Finally the vertices of the simplices
+are used to interpolate to the desired points.  The functions that perform this
+interpolation are @code{griddata}, @code{griddata3} and @code{griddatan}.
 
 @DOCSTRING(griddata)
 
@@ -444,8 +438,7 @@
 @end example
 
 @noindent
-that interpolates from a random scattering of points, to a uniform
-grid.
+that interpolates from a random scattering of points, to a uniform grid.
 @ifnotinfo
 The output of the above can be seen in @ref{fig:griddata}.
 
--- a/doc/interpreter/grammar.txi	Fri Feb 06 08:31:09 2015 -0800
+++ b/doc/interpreter/grammar.txi	Fri Feb 06 08:31:49 2015 -0800
@@ -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
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/interpreter/graphics_properties.mk	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,34 @@
+GRAPH_PROP_TEXI_SRC= \
+  plot-axesproperties.texi \
+  plot-figureproperties.texi \
+  plot-imageproperties.texi \
+  plot-lineproperties.texi \
+  plot-patchproperties.texi \
+  plot-rootproperties.texi \
+  plot-surfaceproperties.texi \
+  plot-textproperties.texi
+
+
+plot-axesproperties.texi: genpropdoc.m
+	$(top_builddir)/run-octave -f -q -H -p $(srcdir) --eval "genpropdoc ('axes', '$@');" || { rm -f $@; exit 1; }
+
+plot-figureproperties.texi: genpropdoc.m
+	$(top_builddir)/run-octave -f -q -H -p $(srcdir) --eval "genpropdoc ('figure', '$@');" || { rm -f $@; exit 1; }
+
+plot-imageproperties.texi: genpropdoc.m
+	$(top_builddir)/run-octave -f -q -H -p $(srcdir) --eval "genpropdoc ('image', '$@');" || { rm -f $@; exit 1; }
+
+plot-lineproperties.texi: genpropdoc.m
+	$(top_builddir)/run-octave -f -q -H -p $(srcdir) --eval "genpropdoc ('line', '$@');" || { rm -f $@; exit 1; }
+
+plot-patchproperties.texi: genpropdoc.m
+	$(top_builddir)/run-octave -f -q -H -p $(srcdir) --eval "genpropdoc ('patch', '$@');" || { rm -f $@; exit 1; }
+
+plot-rootproperties.texi: genpropdoc.m
+	$(top_builddir)/run-octave -f -q -H -p $(srcdir) --eval "genpropdoc ('root', '$@');" || { rm -f $@; exit 1; }
+
+plot-surfaceproperties.texi: genpropdoc.m
+	$(top_builddir)/run-octave -f -q -H -p $(srcdir) --eval "genpropdoc ('surface', '$@');" || { rm -f $@; exit 1; }
+
+plot-textproperties.texi: genpropdoc.m
+	$(top_builddir)/run-octave -f -q -H -p $(srcdir) --eval "genpropdoc ('text', '$@');" || { rm -f $@; exit 1; }
--- a/doc/interpreter/gui.txi	Fri Feb 06 08:31:09 2015 -0800
+++ b/doc/interpreter/gui.txi	Fri Feb 06 08:31:49 2015 -0800
@@ -66,7 +66,7 @@
 
 These functions do not implement a GUI element but are useful when developing
 programs that do.  @strong{Warning:} The functions @code{uiwait},
-@code{uiresume}, and @code{waitfor} are only available for the FLTK tooolkit.
+@code{uiresume}, and @code{waitfor} are only available for the FLTK toolkit.
 
 @DOCSTRING(desktop)
 
--- a/doc/interpreter/image.txi	Fri Feb 06 08:31:09 2015 -0800
+++ b/doc/interpreter/image.txi	Fri Feb 06 08:31:49 2015 -0800
@@ -164,6 +164,8 @@
 
 @DOCSTRING(copper)
 
+@DOCSTRING(cubehelix)
+
 @DOCSTRING(flag)
 
 @DOCSTRING(gray)
--- a/doc/interpreter/install.txi	Fri Feb 06 08:31:09 2015 -0800
+++ b/doc/interpreter/install.txi	Fri Feb 06 08:31:49 2015 -0800
@@ -288,8 +288,7 @@
 @item Qhull
 Computational geometry library (@url{http://www.qhull.org}).  Qhull is
 required to provide the functions @code{convhull}, @code{convhulln},
-@code{delaunay}, @code{delaunay3}, @code{delaunayn}, @code{voronoi}, and
-@code{voronoin}.
+@code{delaunay}, @code{delaunayn}, @code{voronoi}, and @code{voronoin}.
 
 @item QRUPDATE
 QR factorization updating library
@@ -744,6 +743,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
@@ -856,7 +856,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
@@ -1036,3 +1036,4 @@
 @env{FFLAGS} is set to @qcode{"-O"}.
 
 @end itemize
+
--- a/doc/interpreter/interp.txi	Fri Feb 06 08:31:09 2015 -0800
+++ b/doc/interpreter/interp.txi	Fri Feb 06 08:31:49 2015 -0800
@@ -176,7 +176,3 @@
 @end float
 @end ifnotinfo
 
-In additional the support function @code{bicubic} that underlies the
-cubic interpolation of @code{interp2} function can be called directly.
-
-@DOCSTRING(bicubic)
--- a/doc/interpreter/intro.txi	Fri Feb 06 08:31:09 2015 -0800
+++ b/doc/interpreter/intro.txi	Fri Feb 06 08:31:49 2015 -0800
@@ -334,9 +334,10 @@
 
 @noindent
 The function @code{lsode} uses the Livermore Solver for Ordinary
-Differential Equations, described in A. C. Hindmarsh, @cite{ODEPACK, a
-Systematized Collection of ODE Solvers}, in: Scientific Computing, R. S.
-Stepleman et al. (Eds.), North-Holland, Amsterdam, 1983, pages 55--64.
+Differential Equations, described in @nospell{A. C. Hindmarsh},
+@cite{ODEPACK, a Systematized Collection of ODE Solvers}, in: Scientific
+Computing, @nospell{R. S. Stepleman} et al. (Eds.), North-Holland, Amsterdam,
+1983, pages 55--64.
 
 @subsection Producing Graphical Output
 
--- a/doc/interpreter/io.txi	Fri Feb 06 08:31:09 2015 -0800
+++ b/doc/interpreter/io.txi	Fri Feb 06 08:31:49 2015 -0800
@@ -616,10 +616,26 @@
 @end table
 
 If the syntax of a conversion specification is invalid, unpredictable
-things will happen, so don't do this.  If there aren't enough function
-arguments provided to supply values for all the conversion
-specifications in the template string, or if the arguments are not of
-the correct types, the results are unpredictable.  If you supply more
+things will happen, so don't do this.  In particular, @sc{matlab} allows
+a bare percentage sign @samp{%} with no subsequent conversion character.
+Octave will emit an error and stop if it sees such code.  When the string
+variable to be processed cannot be guaranteed to be free of potential format
+codes it is better to use the two argument form of any of the @code{printf}
+functions and set the format string to @code{%s}.  Alternatively, for code
+which is not required to be backwards-compatible with @sc{matlab} the
+Octave function @code{puts} or @code{disp} can be used.
+
+@example
+@group
+printf (strvar);        # Unsafe if strvar contains format codes
+printf ("%s", strvar);  # Safe
+puts (strvar);          # Safe
+@end group
+@end example
+
+If there aren't enough function arguments provided to supply values for all
+the conversion specifications in the template string, or if the arguments are
+not of the correct types, the results are unpredictable.  If you supply more
 arguments than conversion specifications, the extra argument values are
 simply ignored; this is sometimes useful.
 
@@ -1006,7 +1022,11 @@
 
 @DOCSTRING(tmpfile)
 
-@DOCSTRING(tmpnam)
+@DOCSTRING(tempname)
+
+@DOCSTRING(tempdir)
+
+@DOCSTRING(P_tmpdir)
 
 @node EOF and Errors
 @subsection End of File and Errors
--- a/doc/interpreter/java.txi	Fri Feb 06 08:31:09 2015 -0800
+++ b/doc/interpreter/java.txi	Fri Feb 06 08:31:49 2015 -0800
@@ -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 Feb 06 08:31:09 2015 -0800
+++ b/doc/interpreter/linalg.txi	Fri Feb 06 08:31:49 2015 -0800
@@ -21,18 +21,18 @@
 @cindex linear algebra
 
 This chapter documents the linear algebra functions provided in Octave.
-Reference material for many of these functions may be found in Golub and
-Van Loan, @cite{Matrix Computations, 2nd Ed.}, Johns Hopkins, 1989, and
-in the @cite{@sc{lapack} Users' Guide}, SIAM, 1992. The
-@cite{@sc{lapack} Users' Guide} is available at:
+Reference material for many of these functions may be found in
+@nospell{Golub and Van Loan}, @cite{Matrix Computations, 2nd Ed.},
+Johns Hopkins, 1989, and in the @cite{@sc{lapack} Users' Guide}, SIAM, 1992.
+The @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)
@@ -199,7 +201,7 @@
 
 @DOCSTRING(blkmm)
 
-@DOCSTRING(syl)
+@DOCSTRING(sylvester)
 
 @node Specialized Solvers
 @section Specialized Solvers
@@ -212,3 +214,4 @@
 @DOCSTRING(cgs)
 
 @DOCSTRING(gmres)
+
--- a/doc/interpreter/matrix.txi	Fri Feb 06 08:31:09 2015 -0800
+++ b/doc/interpreter/matrix.txi	Fri Feb 06 08:31:49 2015 -0800
@@ -90,7 +90,7 @@
 
 @DOCSTRING(flipud)
 
-@DOCSTRING(flipdim)
+@DOCSTRING(flip)
 
 @DOCSTRING(rot90)
 
--- a/doc/interpreter/mk_doc_cache.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/doc/interpreter/mk_doc_cache.m	Fri Feb 06 08:31:49 2015 -0800
@@ -133,5 +133,5 @@
 
 cache(:,k:end) = [];    # delete unused pre-allocated entries
 
-save_header_format_string (["# doc-cache created by Octave " OCTAVE_VERSION ", %a %b %d %H:%M:%S %Y %Z"]);
+save_header_format_string (["# doc-cache created by Octave " OCTAVE_VERSION]);
 save ("-text", output_file, "cache");
--- a/doc/interpreter/munge-texi.pl	Fri Feb 06 08:31:09 2015 -0800
+++ b/doc/interpreter/munge-texi.pl	Fri Feb 06 08:31:49 2015 -0800
@@ -68,7 +68,7 @@
   }
   if (/^\s*\@EXAMPLEFILE\((\S+)\)/)
   {
-    $fname = "$top_srcdir/examples/$1";
+    $fname = "$top_srcdir/examples/code/$1";
     print '@verbatim',"\n";
     open (EXAMPFH, $fname) or die "unable to open example file $fname\n";
     while (<EXAMPFH>)
--- a/doc/interpreter/numbers.txi	Fri Feb 06 08:31:09 2015 -0800
+++ b/doc/interpreter/numbers.txi	Fri Feb 06 08:31:49 2015 -0800
@@ -311,11 +311,11 @@
 @subsection Empty Matrices
 
 A matrix may have one or both dimensions zero, and operations on empty
-matrices are handled as described by Carl @nospell{de} Boor in @cite{An Empty
-Exercise}, SIGNUM, Volume 25, pages 2-6, 1990 and C. N. Nett and W. M.
-Haddad, in @cite{A System-Theoretic Appropriate Realization of the Empty
-Matrix Concept}, IEEE Transactions on Automatic Control, Volume 38,
-Number 5, May 1993.
+matrices are handled as described by @nospell{Carl de Boor} in
+@cite{An Empty Exercise}, SIGNUM, Volume 25, pages 2-6, 1990 and
+@nospell{C. N. Nett and W. M. Haddad}, in
+@cite{A System-Theoretic Appropriate Realization of the Empty Matrix Concept},
+IEEE Transactions on Automatic Control, Volume 38, Number 5, May 1993.
 @tex
 Briefly, given a scalar $s$, an $m\times n$ matrix $M_{m\times n}$,
 and an $m\times n$ empty matrix $[\,]_{m\times n}$ (with either one or
@@ -396,7 +396,7 @@
 defines the set of values @samp{[ 1, 4 ]}.
 
 Although a range constant specifies a row vector, Octave does @emph{not}
-convert range constants to vectors unless it is necessary to do so.
+normally convert range constants to vectors unless it is necessary to do so.
 This allows you to write a constant like @samp{1 : 10000} without using
 80,000 bytes of storage on a typical 32-bit workstation.
 
@@ -420,6 +420,11 @@
 defines @var{y} to be of type @code{matrix} and occupies 88 bytes of
 memory.
 
+This space saving optimization may be disabled using the function
+@dfn{disable_range}.
+
+@DOCSTRING(disable_range)
+
 Note that the upper (or lower, if the increment is negative) bound on
 the range is not always included in the set of values, and that ranges
 defined by floating point values can produce surprising results because
@@ -811,6 +816,8 @@
 
 @DOCSTRING(isnumeric)
 
+@DOCSTRING(islogical)
+
 @DOCSTRING(isfloat)
 
 @DOCSTRING(isreal)
@@ -835,7 +842,13 @@
 
 @DOCSTRING(isdefinite)
 
-@DOCSTRING(islogical)
+@DOCSTRING(isbanded)
+
+@DOCSTRING(isdiag)
+
+@DOCSTRING(istril)
+
+@DOCSTRING(istriu)
 
 @DOCSTRING(isprime)
 
--- a/doc/interpreter/octave_logo.eps	Fri Feb 06 08:31:09 2015 -0800
+++ b/doc/interpreter/octave_logo.eps	Fri Feb 06 08:31:49 2015 -0800
@@ -69,9 +69,9 @@
 %%EndPageSetup
 q
 1 0.498039 0.164706 rg
-16.258 153.068 m 61.023 153.068 l 67.812 153.068 73.277 147.599 73.277 
-140.81 c 73.277 96.048 l 73.277 89.259 67.812 83.791 61.023 83.791 c 
-16.258 83.791 l 9.469 83.791 4.004 89.259 4.004 96.048 c 4.004 140.81 l 
+16.258 153.068 m 61.023 153.068 l 67.812 153.068 73.277 147.599 73.277
+140.81 c 73.277 96.048 l 73.277 89.259 67.812 83.791 61.023 83.791 c
+16.258 83.791 l 9.469 83.791 4.004 89.259 4.004 96.048 c 4.004 140.81 l
 4.004 147.599 9.469 153.068 16.258 153.068 c h
 16.258 153.068 m f
 0.831373 0.333333 0 rg
@@ -80,9 +80,9 @@
 0 j
 [] 0.0 d
 4 M q 1 0 0 -1 0 230.399994 cm
-16.258 77.332 m 61.023 77.332 l 67.812 77.332 73.277 82.801 73.277 
-89.59 c 73.277 134.352 l 73.277 141.141 67.812 146.609 61.023 146.609 c 
-16.258 146.609 l 9.469 146.609 4.004 141.141 4.004 134.352 c 4.004 
+16.258 77.332 m 61.023 77.332 l 67.812 77.332 73.277 82.801 73.277
+89.59 c 73.277 134.352 l 73.277 141.141 67.812 146.609 61.023 146.609 c
+16.258 146.609 l 9.469 146.609 4.004 141.141 4.004 134.352 c 4.004
 89.59 l 4.004 82.801 9.469 77.332 16.258 77.332 c h
 16.258 77.332 m S Q
 Q q
--- a/doc/interpreter/optim.txi	Fri Feb 06 08:31:09 2015 -0800
+++ b/doc/interpreter/optim.txi	Fri Feb 06 08:31:49 2015 -0800
@@ -139,6 +139,8 @@
 
 @DOCSTRING(lsqnonneg)
 
+@DOCSTRING(lscov)
+
 @DOCSTRING(optimset)
 
 @DOCSTRING(optimget)
--- a/doc/interpreter/plot.txi	Fri Feb 06 08:31:09 2015 -0800
+++ b/doc/interpreter/plot.txi	Fri Feb 06 08:31:49 2015 -0800
@@ -63,6 +63,7 @@
 * Plot Annotations::
 * Multiple Plots on One Page::
 * Multiple Plot Windows::
+* Manipulation of Plot Objects::
 * Manipulation of Plot Windows::
 * Use of the @code{interpreter} Property::
 * Printing and Saving Plots::
@@ -232,10 +233,16 @@
 
 @DOCSTRING(area)
 
+@DOCSTRING(fill)
+
 @DOCSTRING(comet)
 
 @DOCSTRING(comet3)
 
+@DOCSTRING(frame2im)
+
+@DOCSTRING(im2frame)
+
 @node Axis Configuration
 @subsubsection Axis Configuration
 
@@ -530,6 +537,18 @@
 
 @DOCSTRING(figure)
 
+@node Manipulation of Plot Objects
+@subsection Manipulation of Plot Objects
+@cindex plotting, object manipulation
+
+@DOCSTRING(pan)
+
+@DOCSTRING(rotate)
+
+@DOCSTRING(rotate3d)
+
+@DOCSTRING(zoom)
+
 @node Manipulation of Plot Windows
 @subsection Manipulation of Plot Windows
 @cindex plotting, window manipulation
@@ -541,7 +560,7 @@
 @DOCSTRING(drawnow)
 
 Only figures that are modified will be updated.  The @code{refresh}
-function can also be used to force an update of the current figure, even if
+function can also be used to cause an update of the current figure, even if
 it is not modified.
 
 @DOCSTRING(refresh)
@@ -950,6 +969,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
 
@@ -994,45 +1024,46 @@
 @anchor{XREFgraphics structures}
 
 The graphics functions use pointers, which are of class graphics_handle, in
-order to address the data structures which control graphical displays.  A
-graphics handle may point any one of a number of different object types.  The
-objects are the graphics data structures.  The types of objects are:
-@code{figure}, @code{axes}, @code{line}, @code{text}, @code{patch},
-@code{surface}, @code{text} and @code{image}.
-
-Each of these objects has a function by the same name. and, each of these
-functions returns a graphics handle pointing to an object of corresponding
+order to address the data structures which control visual display.  A
+graphics handle may point to any one of a number of different base object
+types and these objects are the graphics data structures themselves.  The
+primitive graphic object types are: @code{figure}, @code{axes}, @code{line},
+@code{text}, @code{patch}, @code{surface}, @code{text}, and @code{image}.
+
+Each of these objects has a function by the same name, and, each of these
+functions returns a graphics handle pointing to an object of the corresponding
 type.  In addition there are several functions which operate on properties of
-the graphics objects and which return handles: the functions @code{ plot} and
-@code{plot3} return a handle pointing to an object of type line, the function
-@code{subplot} returns a handle pointing to an object of type axes, the
-function @code{fill} returns a handle pointing to an object of type patch, the
-functions @code{area}, @code{bar}, @code{barh}, @code{contour},
+the graphics objects and which also return handles: the functions @code{plot}
+and @code{plot3} return a handle pointing to an object of type line, the
+function @code{subplot} returns a handle pointing to an object of type axes,
+the function @code{fill} returns a handle pointing to an object of type patch,
+the functions @code{area}, @code{bar}, @code{barh}, @code{contour},
 @code{contourf}, @code{contour3}, @code{surf}, @code{mesh}, @code{surfc},
 @code{meshc}, @code{errorbar}, @code{quiver}, @code{quiver3}, @code{scatter},
 @code{scatter3}, @code{stair}, @code{stem}, @code{stem3} each return a handle
-as documented in @ref{XREFdatasources,,Data Sources}.
-
+to a complex data structure as documented in
+@ref{XREFdatasources,,Data Sources}.
 
 The graphics objects are arranged in a hierarchy:
 
-1. The root is at 0.  i.e., @code{get (0)} returns the properties of the root
-   object.
+1. The root is at 0.  In other words, @code{get (0)} returns the properties of
+the root object.
 
 2. Below the root are @code{figure} objects.
 
-3. Below the @code{figure} objects are @code{axes}.
-
-4. Below the @code{axes} objects are
-@code{line}, @code{text}, @code{patch},
+3. Below the @code{figure} objects are @code{axes} objects.
+
+4. Below the @code{axes} objects are @code{line}, @code{text}, @code{patch},
 @code{surface}, and @code{image} objects.
 
 Graphics handles may be distinguished from function handles
 (@pxref{Function Handles}) by means of the function @code{ishandle}.
 @code{ishandle} returns true if its argument is a handle of a graphics object.
-In addition, the figure object may be tested using @code{isfigure}.
-@code{isfigure} returns true only if its argument is a handle of a figure.  The
-@code{whos} function can be used to show the object type of each currently
+In addition, a figure or axes object may be tested using @code{isfigure} or
+@code{isaxes} respectively.  The test functions return true only if the
+argument is both a handle and of the correct type (figure or axes).
+
+The @code{whos} function can be used to show the object type of each currently
 defined graphics handle.  (Note: this is not true today, but it is, I hope,
 considered an error in whos.  It may be better to have whos just show
 graphics_handle as the class, and provide a new function which, given a
@@ -1159,9 +1190,20 @@
 @subsubsection Creating Graphics Objects
 @cindex creating graphics objects
 
-You can create axes, line, patch, and surface objects directly using the
-@code{axes}, @code{line}, @code{patch}, @code{fill}, and @code{surface}
-functions.  These objects become children of the current axes object.
+You can create any graphics object primitive by calling the function of the
+same name as the object; In other words, @code{figure}, @code{axes},
+@code{line}, @code{text}, @code{image}, @code{patch}, and @code{surface}
+functions.  These fundamental graphic objects automatically become children
+of the current axes object as if @code{hold on} was in place.  Seperately, axes
+will automatically become children of the current figure object and figures
+will become children of the root object 0.
+
+If this auto-joining feature is not desired then it is important to call
+@code{newplot} first to prepare a new figure and axes for plotting.
+Alternatively, the easier way is to call a high-level graphics routine which
+will both create the plot and then populate it with low-level graphics objects.
+Instead of calling @code{line}, use @code{plot}.  Or use @code{surf} instead of
+@code{surface}.  Or use @code{fill} instead of @code{patch}.
 
 @DOCSTRING(axes)
 
@@ -1169,8 +1211,6 @@
 
 @DOCSTRING(patch)
 
-@DOCSTRING(fill)
-
 @DOCSTRING(surface)
 
 @subsubsection Handle Functions
@@ -1246,18 +1286,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)
 
@@ -1310,9 +1353,17 @@
 * Surface Properties::
 @end menu
 
-In this Section the object properties are discussed in detail, starting
-with the root figure properties and continuing through the graphics object
-hierarchy.
+In this Section the graphics object properties are discussed in detail, starting
+with the root figure properties and continuing through the objects
+hierarchy.  The documentation about a specific graphics object can be displayed
+using @code{doc} function, e.g., @code{doc ("axes properties")} will show
+@ref{Axes Properties}.
+
+The allowed values for radio (string) properties can be retrieved
+programmatically or displayed using the one or
+two arguments call to @code{set} function.  @xref{XREFset, , set}.
+
+In the following documentation, default values are enclosed in @{ @}.
 
 @node Root Figure Properties
 @subsubsection Root Figure Properties
@@ -1320,72 +1371,8 @@
 
 The @code{root figure} properties are:
 
-@table @code
-@item __modified__
---- Values: @qcode{"on"}, @qcode{"off"}
-
-@item __myhandle__
-
-@item beingdeleted
---- Values: @qcode{"on"}, @qcode{"off"}
-
-@item busyaction
-
-@item buttondownfcn
-
-@item callbackobject
-
-@item children
-
-@item clipping
- --- Values: @qcode{"on"}, @qcode{"off"}
-
-@item createfcn
-
-@item currentfigure
-
-@item deletefcn
-
-@item handlevisibility
---- Values: @qcode{"on"}, @qcode{"off"}
-
-@item hittest
---- Values: @qcode{"on"}, @qcode{"off"}
-
-@item interruptible
---- Values: @qcode{"on"}, @qcode{"off"}
-
-@item parent
-
-@item screendepth
-
-@item screenpixelsperinch
-
-@item screensize
-
-@item selected
-
-@item selectionhighlight
-
-@item screendepth
-
-@item screenpixelsperinch
-
-@item showhiddenhandles
---- Values: @qcode{"on"}, @qcode{"off"}
-
-@item tag
-
-@item type
-
-@item uicontextmenu
-
-@item units
-
-@item userdata
-
-@item visible
-@end table
+@include plot-rootproperties.texi
+
 
 @node Figure Properties
 @subsubsection Figure Properties
@@ -1393,201 +1380,8 @@
 
 The @code{figure} properties are:
 
-@table @code
-@item __graphics_toolkit__
---- The graphics toolkit currently in use.
-
-@item __enhanced__
-
-@item __modified__
-
-@item __myhandle__
-
-@item __plot_stream__
-
-@item alphamap
-
-@item beingdeleted
---- Values: @qcode{"on"}, @qcode{"off"}
-
-@item busyaction
-
-@item buttondownfcn
-
-@item children
-Handle to children.
-
-@item clipping
---- Values: @qcode{"on"}, @qcode{"off"}
-
-@item closerequestfcn
---- Handle of function to call on close.
-
-@item color
-
-@item colormap
-An N-by-3 matrix containing the color map for the current axes.
-
-@item paperorientation
-
-@item createfcn
-
-@item currentaxes
-Handle to graphics object of current axes.
-
-@item currentcharacter
-
-@item currentobject
-
-@item currentpoint
-Holds the coordinates of the point over which the mouse pointer was when
-the mouse button was pressed.  If a mouse callback function is defined,
-@qcode{"currentpoint"} holds the coordinates of the point over which the
-mouse pointer is when the function gets called.
-
-@item deletefcn
-
-@item dockcontrols
---- Values: @qcode{"on"}, @qcode{"off"}
-
-@item doublebuffer
---- Values: @qcode{"on"}, @qcode{"off"}
-
-@item filename
-
-@item handlevisibility
---- Values: @qcode{"on"}, @qcode{"off"}
-
-@item hittest
-
-@item integerhandle
-
-@item interruptible
---- Values: @qcode{"on"}, @qcode{"off"}
-
-@item inverthardcopy
-
-@item keypressfcn
-see @qcode{"keypressfcn"}
-
-@item keyreleasefcn
-With @qcode{"keypressfcn"}, the keyboard callback functions.  These
-callback functions get called when a key is pressed/released
-respectively.  The functions are called with two input arguments.  The
-first argument holds the handle of the calling figure.  The second
-argument holds the event structure which has the following members:
-
-@table @code
-@item Character
-The ASCII value of the key
-
-@item Key
-lowercase value of the key
-
-@item Modifier
-A cell array containing strings representing the modifiers pressed with
-the key.  Possible values are @qcode{"shift"}, @qcode{"alt"}, and
-@qcode{"control"}.
-@end table
-
-@item menubar
-
-@item mincolormap
-
-@item name
-
-@item nextplot
-May be one of
-
-@table @asis
-@item @qcode{"new"}
-
-@item @qcode{"add"}
-
-@item @qcode{"replace"}
-
-@item @qcode{"replacechildren"}
-@end table
-
-@item numbertitle
-
-@item paperorientation
-Indicates the orientation for printing.  Either @qcode{"landscape"} or
-@qcode{"portrait"}.
-
-@item paperposition
-
-@item paperpositionmode
-
-@item papersize
-
-@item papertype
-
-@item paperunits
-
-@item pointer
-
-@item pointershapecdata
-
-@item pointershapehotspot
-
-@item position
-
-@item renderer
-
-@item renderermode
-
-@item resize
-
-@item resizefcn
-
-@item selected
-
-@item selectionhighlight
---- Values: @qcode{"on"}, @qcode{"off"}
-
-@item selectiontype
-
-@item tag
-
-@item toolbar
-
-@item type
-
-@item units
-
-@item userdata
-
-@item visible
-Either @qcode{"on"} or @qcode{"off"} to toggle display of the figure.
-
-@item windowbuttondownfcn
-See @qcode{"windowbuttonupfcn"}
-
-@item windowbuttonmotionfcn
-See @qcode{"windowbuttonupfcn"}
-
-@item windowbuttonupfcn
-With @qcode{"windowbuttondownfcn"} and @qcode{"windowbuttonmotionfcn"},
-the mouse callback functions.  These callback functions get called when
-the mouse button is pressed, dragged, and released respectively.  When
-these callback functions are called, the @qcode{"currentpoint"} property
-holds the current coordinates of the cursor.
-
-@item windowscrollwheelfcn
-
-@item windowstyle
-
-@item wvisual
-
-@item wvisualmode
-
-@item xdisplay
-
-@item xvisual
-
-@item xvisualmode
-@end table
+@include plot-figureproperties.texi
+
 
 @node Axes Properties
 @subsubsection Axes Properties
@@ -1595,324 +1389,8 @@
 
 The @code{axes} properties are:
 
-@table @code
-@item __modified__
-
-@item __myhandle__
-
-@item activepositionproperty
-
-@item alim
-
-@item alimmode
-
-@item ambientlightcolor
-
-@item beingdeleted
-
-@item box
-Box surrounding axes.
---- Values: @qcode{"on"}, @qcode{"off"}
-
-@item busyaction
-
-@item buttondownfcn
-
-@item cameraposition
-
-@item camerapositionmode
-
-@item cameratarget
-
-@item cameratargetmode
-
-@item cameraupvector
-
-@item cameraupvectormode
-
-@item cameraviewangle
-
-@item cameraviewanglemode
-
-@item children
-
-@item clim
-Two-element vector defining the limits for the c axis of
-an image.  See @code{pcolor} property.
-Setting this property also forces the corresponding mode
-property to be set to @qcode{"manual"}.
-
-@item climmode
-Either @qcode{"manual"} or @qcode{"auto"}.
-
-@item clipping
-
-@item color
-
-@item colororder
-
-@item createfcn
-
-@item currentpoint
-Holds the coordinates of the point over which the mouse pointer was when
-the mouse button was pressed.  If a mouse callback function is defined,
-@qcode{"currentpoint"} holds the coordinates of the point over which the
-mouse pointer is when the function gets called.
-
-@item dataaspectratio
-A two-element vector specifying the relative height and width of the
-data displayed in the axes.  Setting @code{dataaspectratio} to @samp{1,
-2]} causes the length of one unit as displayed on the y-axis to be the
-same as the length of 2 units on the x-axis.  Setting
-@code{dataaspectratio} also forces the @code{dataaspectratiomode}
-property to be set to @qcode{"manual"}.
-
-@item dataaspectratiomode
-Either @qcode{"manual"} or @qcode{"auto"}.
-
-@item deletefcn
-
-@item drawmode
-
-@item fontangle
-
-@item fontname
-
-@item fontsize
-
-@item fontunits
-
-@item fontweight
-
-@item gridlinestyle
-
-@item handlevisibility
-
-@item hittest
-
-@item interpreter
-
-@item interruptible
-
-@item layer
-
-@item linestyleorder
-
-@item linewidth
-
-@item minorgridlinestyle
-
-@item nextplot
-May be one of
-
-@table @asis
-@item @qcode{"add"}
-
-@item @qcode{"replace"}
-
-@item @qcode{"replacechildren"}
-@end table
-
-@item outerposition
-A vector specifying the position of the plot, including titles, axes and
-legend.  The four elements of the vector are the coordinates of the
-lower left corner and width and height of the plot, in units normalized
-to the width and height of the plot window.  For example, @code{[0.2,
-0.3, 0.4, 0.5]} sets the lower left corner of the axes at @math{(0.2,
-0.3)} and the width and height to be 0.4 and 0.5 respectively.  See also
-the @code{position} property.
-
-@item parent
-
-@item plotboxaspectratio
-
-@item plotboxaspectratiomode
-
-@item position
-A vector specifying the position of the plot, excluding titles, axes and
-legend.  The four elements of the vector are the coordinates of the
-lower left corner and width and height of the plot, in units normalized
-to the width and height of the plot window.  For example, @code{[0.2,
-0.3, 0.4, 0.5]} sets the lower left corner of the axes at @math{(0.2,
-0.3)} and the width and height to be 0.4 and 0.5 respectively.  See also
-the @code{outerposition} property.
-
-@item projection
-
-@item selected
-
-@item selectionhighlight
-
-@item tag
-
-@item tickdir
-
-@item tickdirmode
-
-@item ticklength
-
-@item tightinset
-
-@item title
-Index of text object for the axes title.
-
-@item type
-
-@item uicontextmenu
-
-@item units
-
-@item userdata
-
-@item view
-A three element vector specifying the view point for three-dimensional plots.
-
-@item visible
-Either @qcode{"on"} or @qcode{"off"} to toggle display of the axes.
-
-@item x_normrendertransform
-
-@item x_projectiontransform
-
-@item x_rendertransform
-
-@item x_viewporttransform
-
-@item x_viewtransform
-
-@item xaxislocation
-Either @qcode{"top"} or @qcode{"bottom"}.
-
-@item xcolor
-
-@item xdir
-Either @qcode{"forward"} or @qcode{"reverse"}.
-
-@item xgrid
-Either @qcode{"on"} or @qcode{"off"} to toggle display of grid lines.
-
-@item xlabel
-Indices to text objects for the axes labels.
-
-@item xlim
-Two-element vector defining the limits for the x-axis.
-Setting this property also forces the corresponding mode
-property to be set to @qcode{"manual"}.
-
-@item xlimmode
-Either @qcode{"manual"} or @qcode{"auto"}.
-
-@item xminorgrid
-Either @qcode{"on"} or @qcode{"off"} to toggle display of minor grid lines.
-
-@item xminortick
-
-@item xscale
-Either @qcode{"linear"} or @qcode{"log"}.
-
-@item xtick
-Set position of tick marks.
-Setting this property also forces the corresponding mode
-property to be set to @qcode{"manual"}.
-
-@item xticklabel
-Setting this property also forces the corresponding mode
-property to be set to @qcode{"manual"}.
-
-@item xticklabelmode
-Either @qcode{"manual"} or @qcode{"auto"}.
-
-@item xtickmode
-Either @qcode{"manual"} or @qcode{"auto"}.
-
-@item yaxislocation
-Either @qcode{"left"} or @qcode{"right"}
-
-@item ycolor
-
-@item ydir
-Either @qcode{"forward"} or @qcode{"reverse"}.
-
-@item ygrid
-Either @qcode{"on"} or @qcode{"off"} to toggle display of grid lines.
-
-@item ylabel
-Indices to text objects for the axes labels.
-
-@item ylim
-Two-element vectors defining the limits for the x, y, and z axes and the
-Setting one of these properties also forces the corresponding mode
-property to be set to @qcode{"manual"}.
-
-@item ylimmode
-Either @qcode{"manual"} or @qcode{"auto"}.
-
-@item yminorgrid
-Either @qcode{"on"} or @qcode{"off"} to toggle display of minor grid lines.
-
-@item yminortick
-
-@item yscale
-Either @qcode{"linear"} or @qcode{"log"}.
-
-@item ytick
-Set position of tick marks.
-Setting this property also forces the corresponding mode
-property to be set to @qcode{"manual"}.
-
-@item yticklabel
-Setting this property also forces the corresponding mode
-property to be set to @qcode{"manual"}.
-
-@item yticklabelmode
-Either @qcode{"manual"} or @qcode{"auto"}.
-
-@item ytickmode
-Either @qcode{"manual"} or @qcode{"auto"}.
-
-@item zcolor
-
-@item zdir
-Either @qcode{"forward"} or @qcode{"reverse"}.
-
-@item zgrid
-Either @qcode{"on"} or @qcode{"off"} to toggle display of grid lines.
-
-@item zlabel
-Indices to text objects for the axes labels.
-
-@item zlim
-Two-element vector defining the limits for z-axis.
-Setting this property also forces the corresponding mode
-property to be set to @qcode{"manual"}.
-
-@item zlimmode
-Either @qcode{"manual"} or @qcode{"auto"}.
-
-@item zminorgrid
-Either @qcode{"on"} or @qcode{"off"} to toggle display of minor grid lines.
-
-@item zminortick
-
-@item zscale
-Either @qcode{"linear"} or @qcode{"log"}.
-
-@item ztick
-Set position of tick marks.
-Setting this property also forces the corresponding mode
-property to be set to @qcode{"manual"}.
-
-@item zticklabel
-Setting this property also forces the corresponding mode
-property to be set to @qcode{"manual"}.
-
-@item zticklabelmode
-Either @qcode{"manual"} or @qcode{"auto"}.
-
-@item ztickmode
-Either @qcode{"manual"} or @qcode{"auto"}.
-
-@end table
+@include plot-axesproperties.texi
+
 
 @node Line Properties
 @subsubsection Line Properties
@@ -1920,111 +1398,8 @@
 
 The @code{line} properties are:
 
-@table @code
-@item __modified__
-
-@item __myhandle__
-
-@item beingdeleted
-
-@item busyaction
-
-@item buttondownfcn
-
-@item children
-
-@item clipping
-
-@item color
-The RGB color of the line, or a color name.  @xref{Colors}.
-
-@item createfcn
-
-@item deletefcn
-
-@item displayname
-The text of the legend entry corresponding to this line.
-
-@item erasemode
-
-@item handlevisibility
-
-@item hittest
-
-@item interpreter
-
-@item interruptible
-
-@item ldata
-The lower errorbar in the y direction to be plotted.
-
-@item  linestyle
-@itemx linewidth
-@xref{Line Styles}.
-
-@item linewidth
-
-@item marker
-
-@item markeredgecolor
-
-@item markerfacecolor
-
-@item markersize
-@xref{Marker Styles}.
-
-@item parent
-
-@item selected
-
-@item selectionhighlight
-
-@item tag
-
-@item type
-
-@item udata
-The upper errorbar in the y direction to be plotted.
-
-@item uicontextmenu
-
-@item userdata
-
-@item visible
-
-@item xdata
-The data to be plotted.
-
-@item xdatasource
-
-@item xldata
-The lower errorbar to be plotted.
-
-@item xlim
-
-@item xliminclude
-
-@item xudata
-The upper errorbar to be plotted.
-
-@item ydata
-The data to be plotted.
-
-@item ydatasource
-
-@item ylim
-
-@item yliminclude
-
-@item zdata
-The data to be plotted.
-
-@item zdatasource
-
-@item zlim
-
-@item zliminclude
-@end table
+@include plot-lineproperties.texi
+
 
 @node Text Properties
 @subsubsection Text Properties
@@ -2032,117 +1407,8 @@
 
 The @code{text} properties are:
 
-@table @code
-@item __modified__
-
-@item __myhandle__
-
-@item backgroundcolor
-
-@item beingdeleted
-
-@item busyaction
-
-@item buttondownfcn
-
-@item children
-
-@item clipping
-
-@item color
-The color of the text.  @xref{Colors}.
-
-@item createfcn
-
-@item deletefcn
-
-@item displayname
-The text of the legend entry corresponding to this line.
-
-@item edgecolor
-
-@item editing
-
-@item erasemode
-
-@item fontangle
-Flag whether the font is italic or normal.  Valid values are @qcode{"normal"},
-@qcode{"italic"}, and @qcode{"oblique"}.
-
-@item fontname
-The font used for the text.
-
-@item fontsize
-The size of the font, in points to use.
-
-@item fontunits
-
-@item fontweight
-Flag whether the font is bold, etc.  Valid values are @qcode{"normal"},
-@qcode{"bold"}, @qcode{"demi"}, or @qcode{"light"}.
-
-@item handlevisibility
-
-@item hittest
-
-@item horizontalalignment
-May be @qcode{"left"}, @qcode{"center"}, or @qcode{"right"}.
-
-@item interpreter
-Determines how the text is rendered.  Valid values are @qcode{"none"},
-@qcode{"tex"}, or @qcode{"latex"}.
-
-@item interruptible
-
-@item linestyle
-
-@item linewidth
-
-@item margin
-
-@item parent
-
-@item position
-The coordinates of the text object.
-
-@item rotation
-The angle of rotation for the displayed text, measured in degrees.
-
-@item selected
-
-@item selectionhighlight
-
-@item string
-The character string contained by the text object.
-
-@item tag
-
-@item type
-
-@item uicontextmenu
-
-@item units
-May be @qcode{"normalized"} or @qcode{"graph"}.
-
-@item userdata
-
-@item verticalalignment
-
-@item visible
-
-@item xlim
-
-@item xliminclude
-
-@item ylim
-
-@item yliminclude
-
-@item zlim
-
-@item zliminclude
-
-@end table
+@include plot-textproperties.texi
+
 
 @node Image Properties
 @subsubsection Image Properties
@@ -2150,76 +1416,8 @@
 
 The @code{image} properties are:
 
-@table @code
-@item __modified__
-
-@item __myhandle__
-
-@item beingdeleted
-
-@item busyaction
-
-@item buttondownfcn
-
-@item cdata
-The data for the image.  Each pixel of the image corresponds to an
-element of @code{cdata}.  The value of an element of @code{cdata}
-specifies the row-index into the colormap of the axes object containing
-the image.  The color value found in the color map for the given index
-determines the color of the pixel.
-
-@item cdatamapping
-
-@item children
-
-@item clim
-
-@item climinclude
-
-@item clipping
-
-@item createfcn
-
-@item deletefcn
-
-@item handlevisibility
-
-@item hittest
-
-@item interruptible
-
-@item parent
-
-@item selected
-
-@item selectionhighlight
-
-@item tag
-
-@item type
-
-@item uicontextmenu
-
-@item userdata
-
-@item visible
-
-@item xdata
-Two-element vector specifying the range of the x-coordinates for
-the image.
-
-@item xlim
-
-@item xliminclude
-
-@item ydata
-Two-element vector specifying the range of the y-coordinates for
-the image.
-
-@item ylim
-
-@item yliminclude
-@end table
+@include plot-imageproperties.texi
+
 
 @node Patch Properties
 @subsubsection Patch Properties
@@ -2227,148 +1425,8 @@
 
 The @code{patch} properties are:
 
-@table @code
-@item __modified__
-
-@item __myhandle__
-
-@item alim
-
-@item aliminclude
-
-@item alphadatamapping
-
-@item ambientstrength
-
-@item backfacelighting
-
-@item beingdeleted
-
-@item busyaction
-
-@item buttondownfcn
-
-@item cdata
-Data defining the patch object.
-
-@item cdatamapping
-
-@item children
-
-@item clim
-
-@item climinclude
-
-@item clipping
-
-@item createfcn
-
-@item deletefcn
-
-@item diffusestrength
-
-@item displayname
-The text of the legend entry corresponding to this line.
-
-@item edgealpha
-
-@item edgecolor
-The color of the line defining the patch.  @xref{Colors}.
-
-@item edgelighting
-
-@item erasemode
-
-@item facealpha
-A number in the range [0, 1] indicating the transparency of the patch.
-
-@item facecolor
-The fill color of the patch.  @xref{Colors}.
-
-@item facelighting
-
-@item faces
-
-@item facevertexalphadata
-
-@item facevertexcdata
-
-@item handlevisibility
-
-@item hittest
-
-@item interpreter
-
-@item interruptible
-
-@item linestyle
-@xref{Line Styles}.
-
-@item linewidth
-@xref{Line Styles}.
-
-@item marker
-@xref{Marker Styles}.
-
-@item markeredgecolor
-@xref{Marker Styles}.
-
-@item markerfacecolor
-@xref{Marker Styles}.
-
-@item markersize
-@xref{Marker Styles}.
-
-@item normalmode
-
-@item parent
-
-@item selected
-
-@item selectionhighlight
-
-@item specularcolorreflectance
-
-@item specularexponent
-
-@item specularstrength
-
-@item tag
-
-@item type
-
-@item uicontextmenu
-
-@item userdata
-
-@item vertexnormals
-
-@item vertices
-
-@item visible
-
-@item xdata
-Data defining the patch object.
-
-@item xlim
-
-@item xliminclude
-
-@item ydata
-Data defining the patch object.
-
-@item ylim
-
-@item yliminclude
-
-@item zdata
-Data defining the patch object.
-
-@item zlim
-
-@item zliminclude
-
-@end table
+@include plot-patchproperties.texi
+
 
 @node Surface Properties
 @subsubsection Surface Properties
@@ -2376,144 +1434,8 @@
 
 The @code{surface} properties are:
 
-@table @code
-@item __modified__
-
-@item __myhandle__
-
-@item alim
-
-@item aliminclude
-
-@item alphadata
-
-@item alphadatamapping
-
-@item ambientstrength
-
-@item backfacelighting
-
-@item beingdeleted
-
-@item busyaction
-
-@item buttondownfcn
-
-@item cdata
-
-@item cdatamapping
-
-@item cdatasource
-
-@item children
-
-@item clim
-
-@item climinclude
-
-@item clipping
-
-@item createfcn
-
-@item deletefcn
-
-@item diffusestrength
-
-@item displayname
-The text of the legend entry corresponding to this surface.
-
-@item edgealpha
-
-@item edgecolor
-
-@item edgelighting
-
-@item erasemode
-
-@item facealpha
-
-@item facecolor
-
-@item facelighting
-
-@item handlevisibility
-
-@item hittest
-
-@item interpreter
-
-@item interruptible
-
-@item linestyle
-
-@item linewidth
-
-@item marker
-
-@item markeredgecolor
-
-@item markerfacecolor
-
-@item markersize
-
-@item meshstyle
-
-@item normalmode
-
-@item parent
-
-@item selected
-
-@item selectionhighlight
-
-@item specularcolorreflectance
-
-@item specularexponent
-
-@item specularstrength
-
-@item tag
-
-@item type
-
-@item uicontextmenu
-
-@item userdata
-
-@item vertexnormals
-
-@item visible
-
-@item xdata
-The data determining the surface.  The @code{xdata} and @code{ydata}
-elements are vectors and @code{zdata} must be a matrix.
-
-@item xdatasource
-
-@item xlim
-
-@item xliminclude
-
-@item ydata
-The data determining the surface.  The @code{xdata} and @code{ydata}
-elements are vectors and @code{zdata} must be a matrix.
-
-@item ydatasource
-
-@item ylim
-
-@item yliminclude
-
-@item zdata
-The data determining the surface.  The @code{xdata} and @code{ydata}
-elements are vectors and @code{zdata} must be a matrix.
-
-@item zdatasource
-
-@item zlim
-
-@item zliminclude
-@end table
+@include plot-surfaceproperties.texi
+
 
 @node Searching Properties
 @subsection Searching Properties
@@ -2652,17 +1574,25 @@
 @item linestyle
 May be one of
 
-@table @code
-@item "-"
+@table @asis
+@item @qcode{"-"}
 Solid line.  [default]
 
-@item "--"
+@c Special handling required to avoid '--' becoming single en-dash in Info
+@ifnottex
+
+@item @verb{|"--"|}
+@end ifnottex
+@iftex
+
+@item @code{"--"}
+@end iftex
 Dashed line.
 
-@item ":"
+@item @qcode{":"}
 Dotted line.
 
-@item "-."
+@item @qcode{"-."}
 A dash-dot line.
 
 @item @qcode{"none"}
@@ -2875,6 +1805,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/preface.txi	Fri Feb 06 08:31:09 2015 -0800
+++ b/doc/interpreter/preface.txi	Fri Feb 06 08:31:49 2015 -0800
@@ -24,8 +24,8 @@
 
 Octave was originally intended to be companion software for an
 undergraduate-level textbook on chemical reactor design being written by
-James B. Rawlings of the University of Wisconsin-Madison and John
-G. Ekerdt of the University of Texas.
+@nospell{James B. Rawlings} of the University of Wisconsin-Madison and
+@nospell{John G. Ekerdt} of the University of Texas.
 
 Clearly, Octave is now much more than just another `courseware' package
 with limited utility beyond the classroom.  Although our initial goals
@@ -90,8 +90,8 @@
 @nospell{DE-FG02-04ER25635}.
 
 @item
-Ashok Krishnamurthy, David Hudak, Juan Carlos Chaves, and Stanley
-C. Ahalt of the Ohio Supercomputer Center.
+@nospell{Ashok Krishnamurthy, David Hudak, Juan Carlos Chaves}, and
+@nospell{Stanley C. Ahalt} of the Ohio Supercomputer Center.
 
 @item
 The National Science Foundation, through grant numbers CTS-0105360,
@@ -102,7 +102,7 @@
 Consortium (@url{http://www.che.utexas.edu/twmcc, TWMCC}).
 
 @item
-The Paul A. Elfers Endowed Chair in Chemical Engineering at the
+The @nospell{Paul A. Elfers} Endowed Chair in Chemical Engineering at the
 University of Wisconsin-Madison.
 
 @item
@@ -133,15 +133,16 @@
 Noel Bell, Senior Engineer, Texaco Chemical Company, Austin Texas.
 
 @item
-John A. Turner, Group Leader, Continuum Dynamics @nospell{(CCS-2)}, Los Alamos
-National Laboratory, for registering the @url{octave.org} domain name.
+John A. Turner, Group Leader, Continuum Dynamics @nospell{(CCS-2)},
+@nospell{Los Alamos} National Laboratory, for registering the
+@url{octave.org} domain name.
 
 @item
-James B. Rawlings, Professor, University of Wisconsin-Madison,
+@nospell{James B. Rawlings}, Professor, University of Wisconsin-Madison,
 Department of Chemical and Biological Engineering.
 
 @item
-Richard Stallman, for writing GNU.
+@nospell{Richard Stallman}, for writing GNU.
 @end itemize
 
 This project would not have been possible without the GNU software used
--- a/doc/interpreter/quad.txi	Fri Feb 06 08:31:09 2015 -0800
+++ b/doc/interpreter/quad.txi	Fri Feb 06 08:31:49 2015 -0800
@@ -55,7 +55,7 @@
 Numerical integration using an adaptive Gauss-Konrod rule.
 
 @item quadcc
-Numerical integration using adaptive Clenshaw-Curtis rules.
+Numerical integration using adaptive @nospell{Clenshaw-Curtis} rules.
 
 @item trapz, cumtrapz
 Numerical integration of data using the trapezoidal method.
--- a/doc/interpreter/set.txi	Fri Feb 06 08:31:09 2015 -0800
+++ b/doc/interpreter/set.txi	Fri Feb 06 08:31:49 2015 -0800
@@ -19,9 +19,12 @@
 @node Sets
 @chapter Sets
 
-Octave has a limited number of functions for managing sets of data, where a
-set is defined as a collection of unique elements.  In Octave a set is
-represented as a vector of numbers.
+Octave has a number of functions for managing sets of data.  A set is defined
+as a collection of unique elements and is typically represented by a vector of
+numbers sorted in ascending order.  Any vector or matrix can be converted to a
+set by removing duplicates through the use of the @code{unique} function.
+However, it isn't necessary to explicitly create a set as all of the functions
+which operate on sets will convert their input to a set before proceeding.
 
 @DOCSTRING(unique)
 
@@ -32,28 +35,34 @@
 @node Set Operations
 @section Set Operations
 
-Octave supports the basic set operations.  That is, Octave can compute
-the union, intersection, and difference of two sets.
-Octave also supports the @emph{Exclusive Or} set operation, and
-membership determination.  The functions for set operations all work in
-pretty much the same way.  As an example, assume that @code{x} and
-@code{y} contains two sets, then
+Octave supports several basic set operations.  Octave can compute the union,
+intersection, and difference of two sets.  Octave also supports the
+@emph{Exclusive Or} set operation.
+
+The functions for set operations all work in the same way by accepting two
+input sets and returning a third set.  As an example, assume that @code{a} and
+@code{b} contains two sets, then
 
 @example
-union (x, y)
+union (a, b)
 @end example
 
 @noindent
 computes the union of the two sets.
 
-@DOCSTRING(ismember)
+Finally, determining whether elements belong to a set can be done with the
+@code{ismember} function.  Because sets are ordered this operation is very
+efficient and is of order O(log2(n)) which is preferable to the @code{find}
+function which is of order O(n).
+
+@DOCSTRING(intersect)
 
 @DOCSTRING(union)
 
-@DOCSTRING(intersect)
-
 @DOCSTRING(setdiff)
 
 @DOCSTRING(setxor)
 
+@DOCSTRING(ismember)
+
 @DOCSTRING(powerset)
--- a/doc/interpreter/sparse.txi	Fri Feb 06 08:31:09 2015 -0800
+++ b/doc/interpreter/sparse.txi	Fri Feb 06 08:31:49 2015 -0800
@@ -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.
@@ -75,13 +75,13 @@
 of the methods have in common is that they attempt to reduce the complexity
 and storage given a priori knowledge of the particular class of problems
 that will be solved.  A good summary of the available techniques for storing
-sparse matrix is given by Saad @footnote{Y. Saad "SPARSKIT: A basic toolkit
-for sparse matrix computation", 1994,
+sparse matrix is given by @nospell{Saad} @footnote{Y. Saad "SPARSKIT: A basic
+toolkit for sparse matrix computation", 1994,
 @url{http://www-users.cs.umn.edu/~saad/software/SPARSKIT/paper.ps}}.
 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.
@@ -485,11 +485,11 @@
   @dfn{dmperm}, @dfn{symamd}, @dfn{randperm}, @dfn{symrcm}
 
 @item Linear algebra:
-  @dfn{condest}, @dfn{eigs}, @dfn{matrix_type}, @dfn{normest}, @dfn{sprank},
-  @dfn{spaugment}, @dfn{svds}
+  @dfn{condest}, @dfn{eigs}, @dfn{matrix_type},
+  @dfn{normest}, @dfn{sprank}, @dfn{spaugment}, @dfn{svds}
 
 @item Iterative techniques:
-  @dfn{luinc}, @dfn{pcg}, @dfn{pcr}
+  @dfn{ichol}, @dfn{ilu}, @dfn{pcg}, @dfn{pcr}
 @c @dfn{bicg}, @dfn{bicgstab}, @dfn{cholinc}, @dfn{cgs}, @dfn{gmres},
 @c @dfn{lsqr}, @dfn{minres}, @dfn{qmr}, @dfn{symmlq}
 
@@ -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,17 +793,17 @@
 
 @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)}).
 
-The QR@tie{}solver factorizes the problem with a Dulmage-Mendelsohn
+The QR@tie{}solver factorizes the problem with a @nospell{Dulmage-Mendelsohn}
 decomposition, to separate the problem into blocks that can be treated
 as over-determined, multiple well determined blocks, and a final
 over-determined block.  For matrices with blocks of strongly connected
@@ -860,7 +860,7 @@
 The left division @code{\} and right division @code{/} operators,
 discussed in the previous section, use direct solvers to resolve a
 linear equation of the form @code{@var{x} = @var{A} \ @var{b}} or
-@code{@var{x} = @var{b} / @var{A}}.  Octave equally includes a number of
+@code{@var{x} = @var{b} / @var{A}}.  Octave also includes a number of
 functions to solve sparse linear equations using iterative techniques.
 
 @DOCSTRING(pcg)
@@ -873,7 +873,9 @@
 @var{A} \ @var{b}} is solved instead.  Typical pre-conditioning matrices
 are partial factorizations of the original matrix.
 
-@DOCSTRING(luinc)
+@DOCSTRING(ichol)
+
+@DOCSTRING(ilu)
 
 @node Real Life Example
 @section Real Life Example using Sparse Matrices
@@ -997,7 +999,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 Feb 06 08:31:09 2015 -0800
+++ b/doc/interpreter/stmt.txi	Fri Feb 06 08:31:49 2015 -0800
@@ -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/strings.txi	Fri Feb 06 08:31:09 2015 -0800
+++ b/doc/interpreter/strings.txi	Fri Feb 06 08:31:49 2015 -0800
@@ -401,8 +401,6 @@
 
 @DOCSTRING(strncmpi)
 
-@DOCSTRING(validatestring)
-
 @node Manipulating Strings
 @section Manipulating Strings
 
@@ -442,8 +440,6 @@
 
 @DOCSTRING(strjoin)
 
-@DOCSTRING(strmatch)
-
 @DOCSTRING(strtok)
 
 @DOCSTRING(strsplit)
--- a/doc/interpreter/system.txi	Fri Feb 06 08:31:09 2015 -0800
+++ b/doc/interpreter/system.txi	Fri Feb 06 08:31:49 2015 -0800
@@ -202,8 +202,6 @@
 
 @DOCSTRING(glob)
 
-@DOCSTRING(fnmatch)
-
 @DOCSTRING(file_in_path)
 
 @DOCSTRING(filesep)
@@ -224,12 +222,6 @@
 
 @DOCSTRING(is_rooted_relative_filename)
 
-@DOCSTRING(P_tmpdir)
-
-@DOCSTRING(tempdir)
-
-@DOCSTRING(tempname)
-
 @DOCSTRING(recycle)
 
 @node File Archiving Utilities
@@ -332,6 +324,8 @@
 
 @DOCSTRING(dos)
 
+@DOCSTRING(open)
+
 @DOCSTRING(perl)
 
 @DOCSTRING(python)
@@ -408,7 +402,9 @@
 
 @DOCSTRING(getenv)
 
-@DOCSTRING(putenv)
+@DOCSTRING(setenv)
+
+@DOCSTRING(unsetenv)
 
 @node Current Working Directory
 @section Current Working Directory
@@ -517,6 +513,8 @@
 
 @DOCSTRING(isdeployed)
 
+@DOCSTRING(isstudent)
+
 @DOCSTRING(OCTAVE_HOME)
 
 @DOCSTRING(matlabroot)
--- a/doc/interpreter/testfun.txi	Fri Feb 06 08:31:09 2015 -0800
+++ b/doc/interpreter/testfun.txi	Fri Feb 06 08:31:49 2015 -0800
@@ -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/tips.txi	Fri Feb 06 08:31:09 2015 -0800
+++ b/doc/interpreter/tips.txi	Fri Feb 06 08:31:49 2015 -0800
@@ -500,7 +500,8 @@
 @@deftypefn  @{Function File@} @{@@var@{c@} =@} nchoosek (@@var@{n@}, @@var@{k@})
 @@deftypefnx @{Function File@} @{@@var@{c@} =@} nchoosek (@@var@{set@}, @@var@{k@})
 
-Compute the binomial coefficient or all combinations of a set of items.
+Compute the binomial coefficient of @@var@{n@} or list all possible
+combinations of a @@var@{set@} of items.
 
 If @@var@{n@} is a scalar then calculate the binomial coefficient
 of @@var@{n@} and @@var@{k@} which is defined as
@@ -554,10 +555,10 @@
 @@end group
 @@end example
 
-@@code@{nchoosek@} works only for non-negative, integer arguments.  Use
-@@code@{bincoeff@} for non-integer and negative scalar arguments, or for
-computing many binomial coefficients at once with vector inputs
-for @@var@{n@} or @@var@{k@}.
+Programming Note: When calculating the binomial coefficient @@code@{nchoosek@}
+works only for non-negative, integer arguments.  Use @@code@{bincoeff@} for
+non-integer and negative scalar arguments, or for computing many binomial
+coefficients at once with vector inputs for @@var@{n@} or @@var@{k@}.
 
 @@seealso@{bincoeff, perms@}
 @@end deftypefn
@@ -566,7 +567,7 @@
 @noindent
 which demonstrates most of the concepts discussed above.
 @iftex
-This documentation string renders as
+This documentation string renders in Info format as
 @c Note: use the actual output of info below, rather than try and
 @c reproduce it here to prevent it looking different from how it would
 @c appear with info.
@@ -574,8 +575,8 @@
 @example
  -- Function File: C = nchoosek (N, K)
  -- Function File: C = nchoosek (SET, K)
-     Compute the binomial coefficient or all combinations of a set of
-     items.
+     Compute the binomial coefficient of N or list all possible
+     combinations of a SET of items.
 
      If N is a scalar then calculate the binomial coefficient of N and
      K which is defined as
@@ -608,32 +609,31 @@
                  1   3
                  2   3
 
+     Programming Note: When calculating the binomial coefficient
      `nchoosek' works only for non-negative, integer arguments.  Use
      `bincoeff' for non-integer and negative scalar arguments, or for
      computing many binomial coefficients at once with vector inputs
      for N or K.
 
-     See also: bincoeff, perms
+     See also: bincoeff, perms.
 @end example
 @noindent
-using info, whereas in a printed documentation using @TeX{} it will
-appear as
+whereas in printed documentation using @TeX{} it will appear as
 
 @deftypefn  {Function File} {@var{c} =} nchoosek (@var{n}, @var{k})
 @deftypefnx {Function File} {@var{c} =} nchoosek (@var{set}, @var{k})
 
-Compute the binomial coefficient or all combinations of a set of items.
+Compute the binomial coefficient of @var{n} or list all possible
+combinations of a @var{set} of items.
 
 If @var{n} is a scalar then calculate the binomial coefficient
 of @var{n} and @var{k} which is defined as
-
 @tex
 $$
  {n \choose k} = {n (n-1) (n-2) \cdots (n-k+1) \over k!}
                = {n! \over k! (n-k)!}
 $$
 @end tex
-
 @noindent
 This is the number of combinations of @var{n} items taken in groups of
 size @var{k}.
@@ -665,10 +665,10 @@
 @end group
 @end example
 
-@code{nchoosek} works only for non-negative, integer arguments.  Use
-@code{bincoeff} for non-integer and negative scalar arguments, or for
-computing many binomial coefficients at once with vector inputs for @var{n}
-or @var{k}.
+Programming Note: When calculating the binomial coefficient @code{nchoosek}
+works only for non-negative, integer arguments.  Use @code{bincoeff} for
+non-integer and negative scalar arguments, or for computing many binomial
+coefficients at once with vector inputs for @var{n} or @var{k}.
 
 @seealso{bincoeff, perms}
 @end deftypefn
--- a/doc/interpreter/var.txi	Fri Feb 06 08:31:09 2015 -0800
+++ b/doc/interpreter/var.txi	Fri Feb 06 08:31:49 2015 -0800
@@ -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 Feb 06 08:31:09 2015 -0800
+++ b/doc/interpreter/vectorize.txi	Fri Feb 06 08:31:49 2015 -0800
@@ -496,6 +496,15 @@
 
 @DOCSTRING(structfun)
 
+Consistent with earlier advice, seek to use Octave built-in functions whenever
+possible for the best performance.  This advice applies especially to the four
+functions above.  For example, when adding two arrays together
+element-by-element one could use a handle to the built-in addition function
+@code{@@plus} or define an anonymous function @code{@@(x,y) x + y}.  But, the
+anonymous function is 60% slower than the first method.
+@xref{Operator Overloading}, for a list of basic functions which might be used
+in place of anonymous ones.
+
 @node Accumulation
 @section Accumulation
 
@@ -697,7 +706,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 +722,4 @@
 a column vector.  This is a common vectorization trick.
 
 @end itemize
+
--- a/doc/refcard/refcard.tex	Fri Feb 06 08:31:09 2015 -0800
+++ b/doc/refcard/refcard.tex	Fri Feb 06 08:31:49 2015 -0800
@@ -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/etc/NEWS.3	Fri Feb 06 08:31:09 2015 -0800
+++ b/etc/NEWS.3	Fri Feb 06 08:31:49 2015 -0800
@@ -1,3 +1,1523 @@
+Summary of important user-visible changes for version 3.8:
+---------------------------------------------------------
+
+  ** 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.  But
+     because it is not quite as polished as we would like, we have
+     decided to wait until the 4.0.x release series before making the
+     GUI the default interface (until then, you can use the --force-gui
+     option to start the GUI).
+
+     Given the length of time and the number of bug fixes and
+     improvements since the last major release Octave, we also decided
+     against delaying the release of all these new improvements any
+     longer just to perfect the GUI.  So please enjoy the 3.8 release of
+     Octave and the preview of the new GUI.  We believe it is working
+     reasonably well, but we also know that there are some obvious rough
+     spots and many things that could be improved.
+
+     WE NEED YOUR HELP.  There are many ways that you can help us fix
+     the remaining problems, complete the GUI, and improve the overall
+     user experience for both novices and experts alike:
+
+       * If you are a skilled software developer, you can help by
+         contributing your time to help with Octave's development.  See
+         http://octave.org/get-involved.html for more information.
+
+       * If Octave does not work properly, you are encouraged
+         report the problems you find.  See http://octave.org/bugs.html
+         for more information about how to report problems.
+
+       * Whether you are a user or developer, you can help to fund the
+         project.  Octave development takes a lot of time and expertise.
+         Your contributions help to ensure that Octave will continue to
+         improve.  See http://octave.org/donate.html for more details.
+
+    We hope you find Octave to be useful.  Please help us make it even
+    better for the future!
+
+ ** Octave now uses OpenGL graphics by default with FLTK widgets.  If
+    OpenGL libraries or FLTK widgets are not available when Octave is
+    built, gnuplot is used.  You may also choose to use gnuplot for
+    graphics by executing the command
+
+      graphics_toolkit ("gnuplot")
+
+    Adding this command to your ~/.octaverc file will set the default
+    for each session.
+
+ ** Printing or saving figures with OpenGL graphics requires the
+    gl2ps library which is no longer distributed with Octave.  The
+    software is widely available in most package managers.  If a
+    pre-compiled package does not exist for your system, you can find
+    the current sources at http://www.geuz.org/gl2ps/.
+
+ ** Octave now supports nested functions with scoping rules that are
+    compatible with Matlab.  A nested function is one declared and defined
+    within the body of another function.  The nested function is only
+    accessible from within the enclosing function which makes it one
+    method for making private functions whose names do not conflict with those
+    in the global namespace (See also subfunctions and private functions).
+    In addition, variables in the enclosing function are visible within the
+    nested function.  This makes it possible to have a pseudo-global variable
+    which can be seen by a group of functions, but which is not visible in
+    the global namespace.
+
+    Example:
+    function outerfunc (...)
+      ...
+      function nested1 (...)
+        ...
+        function nested2 (...)
+           ...
+        endfunction
+      endfunction
+
+      function nested3 (...)
+        ...
+      endfunction
+    endfunction
+
+ ** Line continuations inside character strings have changed.
+
+    The sequence '...' is no longer recognized as a line continuation
+    inside a character string.  A backslash '\' followed by a newline
+    character is no longer recognized as a line continuation inside
+    single-quoted character strings.  Inside double-quoted character
+    strings, a backslash followed by a newline character is still
+    recognized as a line continuation, but the backslash character must
+    be followed *immediately* by the newline character.  No whitespace or
+    end-of-line comment may appear between them.
+
+ ** Backslash as a continuation marker outside of double-quoted strings
+    is now deprecated.
+
+    Using '\' as a continuation marker outside of double quoted strings
+    is now deprecated and will be removed from a future version of
+    Octave.  When that is done, the behavior of
+
+      (a \
+       b)
+
+    will be consistent with other binary operators.
+
+ ** Redundant terminal comma accepted by parser
+
+    A redundant terminal comma is now accepted in matrix
+    definitions which allows writing code such as
+
+    [a,...
+     b,...
+     c,...
+    ] = deal (1,2,3)
+
+ ** Octave now has limited support for named exceptions
+
+    The following syntax is now accepted:
+
+      try
+        statements
+      catch exception-id
+        statements
+      end
+
+    The exception-id is a structure with the fields "message" and
+    "identifier".  For example
+
+      try
+        error ("Octave:error-id", "error message");
+      catch myerr
+        printf ("identifier: %s\n", myerr.identifier);
+        printf ("message:    %s\n", myerr.message);
+      end_try_catch
+
+    When classdef-style classes are added to Octave, the exception-id
+    will become an MException object.
+
+ ** Warning states may now be set temporarily, until the end of the
+    current function, using the syntax
+
+      warning STATE ID "local"
+
+    in which STATE may be "on", "off", or "error".  Changes to warning
+    states that are set locally affect the current function and all
+    functions called from the current scope.  The previous warning state
+    is restored on return from the current function.  The "local"
+    option is ignored if used in the top-level workspace.
+
+ ** Warning IDs renamed:
+
+    Octave:array-as-scalar => Octave:array-to-scalar
+    Octave:array-as-vector => Octave:array-to-vector
+
+ ** 'emptymatch', 'noemptymatch' options added to regular expressions.
+
+    With this addition Octave now accepts the entire set of Matlab options
+    for regular expressions.  'noemptymatch' is the default, but 'emptymatch'
+    has certain uses where you need to match an assertion rather than actual
+    characters.  For example,
+
+    regexprep ('World', '^', 'Hello ', 'emptymatch')
+      => Hello World
+
+    where the pattern is actually the assertion '^' or start-of-line.
+
+ ** For compatibility with Matlab, the regexp, regexpi, and regexprep
+    functions now process backslash escape sequences in single-quoted pattern
+    strings.  In addition, the regexprep function now processes backslash
+    escapes in single-quoted replacement strings.  For example,
+
+    regexprep (str, '\t', '\n')
+
+    would search the variable str for a TAB character (escape sequence \t)
+    and replace it with a NEWLINE (escape sequence \n).  Previously the
+    expression would have searched for a literal '\' followed by 't' and
+    replaced the two characters with the sequence '\', 'n'.
+
+ ** A TeX parser has been implemented for the FLTK toolkit and is the default
+    for any text object including titles and axis labels.  The TeX parser is
+    supported only for display on a monitor, not for printing.
+
+    A quick summary of features:
+
+    Code         Feature     Example             Comment
+    -----------------------------------------------------------------
+    _            subscript   H_2O                formula for water
+    ^            exponent    y=x^2               formula for parabola
+    \char        symbol      \beta               Greek symbol beta
+    \fontname    font        \fontname{Arial}    set Arial font
+    \fontsize    fontsize    \fontsize{16}       set fontsize 16
+    \color[rgb]  fontcolor   \color[rgb]{1 0 1}  set magenta color
+    \bf          bold        \bfBold Text        bold font
+    \it          italic      \itItalic Text      italic font
+    \sl          slanted     \slOblique Text     slanted font
+    \rm          normal      \bfBold\rmNormal    normal font
+    {}           group       {\bf Bold}Normal    group objects
+                             e^{i*\pi} = -1      group objects
+
+ ** The m-files in the plot directory have been overhauled.
+
+    The plot functions now produce output that is nearly visually compatible
+    with Matlab.  Plot performance has also increased, dramatically for some
+    functions such as comet and waitbar.  Finally, the documentation for most
+    functions has been updated so it should be clearer both how to use a
+    function and when a function is appropriate.
+
+ ** The m-files in the image directory have been overhauled.
+
+    The principal benefit is that Octave will now no longer automatically
+    convert images stored with integers to doubles.  Storing images as uint8
+    or uint16 requires only 1/8 or 1/4 the memory of an image stored using
+    doubles.  For certain operations, such as fft2, the image must still be
+    converted to double in order to work.
+
+    Other changes include fixes to the way indexed images are read from a
+    colormap depending on the image class (integer images have a -1 offset to
+    the colormap row number).
+
+ ** The imread and imwrite functions have been completely rewritten.
+
+    The main changes relate to the alpha channel, support for reading and
+    writing of floating point images, implemented writing of indexed images,
+    and appending images to multipage image files.
+
+    The issues that may arise due to backwards incompatibility are:
+
+      * imwrite no longer interprets a length of 2 or 4 in the third dimension
+        as grayscale or RGB with alpha channel (a length of 4 will be saved
+        as a CMYK image).  Alpha channel must be passed as separate argument.
+
+      * imread will always return the colormap indexes when reading an indexed
+        image, even if the colormap is not requested as output.
+
+      * transparency values are now inverted from previous Octave versions
+        (0 is for completely transparent instead of completely opaque).
+
+    In addition, the function imformats has been implemented to expand
+    reading and writing of images of different formats through imread
+    and imwrite.
+
+ ** The colormap function now provides new options--"list", "register",
+    and "unregister"--to list all available colormap functions, and to
+    add or remove a function name from the list of known colormap
+    functions.  Packages that implement extra colormaps should use these
+    commands with PKG_ADD and PKG_DEL statements.
+
+ ** strsplit has been modified to be compatible with Matlab.  There
+    are two instances where backward compatibility is broken.
+
+    (1) Delimiters are now string vectors, not scalars.
+
+    Octave's legacy behavior
+
+      strsplit ("1 2, 3", ", ")
+      ans =
+      {
+       [1,1] = 1
+       [1,2] = 2
+       [1,3] =
+       [1,4] = 3
+      }
+
+    Matlab compatible behavior
+
+      strsplit ("1 2, 3", ", ")
+      ans =
+      {
+       [1,1] = 1 2
+       [1,2] = 3
+      }
+
+    (2) By default, Matlab treats consecutive delimiters as a single
+    delimiter.  By default, Octave's legacy behavior was to return an
+    empty string for the part between the delmiters.
+
+    Where legacy behavior is desired, the call to strsplit() may be
+    replaced by ostrsplit(), which is Octave's original implementation of
+    strsplit().
+
+ ** The datevec function has been extended for better Matlab compatibility.
+    It now accepts string inputs in the following numerical formats: 12, 21,
+    22, 26, 29, 31.  This is undocumented, but verifiable, Matlab behavior.
+    In addition, the default for formats which do not specify a date is
+    January 1st of the current year.  The previous default was the current day,
+    month, and year.  This may produce changes in existing scripts.
+
+ ** The error function and its derivatives has been extended to accept complex
+    arguments.  The following functions now accept complex inputs:
+
+    erf  erfc  erfcx
+
+    In addition two new error functions erfi (imaginary error function) and
+    dawson (scaled imaginary error function) have been added.
+
+ ** The glpk function has been modified to reflect changes in the GLPK
+    library.  The "round" and "itcnt" options have been removed.  The
+    "relax" option has been replaced by the "rtest" option.  The numeric
+    values of error codes and of some options have also changed.
+
+ ** The kurtosis function has changed definition to be compatible with
+    Matlab.  It now returns the base kurtosis instead of the "excess kurtosis".
+    The old behavior can be had by changing scripts to normalize with -3.
+
+               "excess kurtosis" = kurtosis (x) - 3
+
+ ** The moment function has changed definition to be compatible with
+    Matlab.  It now returns the central moment instead of the raw moment.
+    The old behavior can be had by passing the type argument "r" for raw.
+
+ ** The default name of the Octave crash dump file is now
+    "octave-workspace" instead of "octave-core".  The exact name can
+    always be customized with the octave_core_file_name function.
+
+ ** A citation command has been added to display information on how to
+    cite Octave and packages in publications.  The package system will
+    look for and install CITATION files from packages.
+
+ ** The java package from Octave Forge is now part of core Octave.  The
+    following new functions are available for interacting with Java
+    directly from Octave:
+
+      debug_java     java_matrix_autoconversion
+      isjava         java_unsigned_autoconversion
+      java2mat       javaaddpath
+      javaArray      javaclasspath
+      javaMethod     javamem
+      javaObject     javarmpath
+                     usejava
+
+    In addition, the following functions that use the Java interface
+    are now available (provided that Octave is compiled with support for
+    Java enabled):
+
+      helpdlg    listdlg   questdlg
+      inputdlg   msgbox    warndlg
+
+ ** Other new functions added in 3.8.0:
+
+      atan2d                     erfi             lines
+      base64_decode              expint           linsolve
+      base64_encode              findfigs         missing_component_hook
+      betaincinv                 flintmax         polyeig
+      built_in_docstrings_file   fminsearch       prefdir
+      cmpermute                  gallery          preferences
+      cmunique                   gco              readline_re_read_init_file
+      colorcube                  hdl2struct       readline_read_init_file
+      copyobj                    history_save     rgbplot
+      dawson                     imformats        save_default_options
+      dblist                     importdata       shrinkfaces
+      desktop                    isaxes           splinefit
+      doc_cache_create           iscolormap       stemleaf
+      ellipj                     isequaln         strjoin
+      ellipke                    jit_debug        struct2hdl
+      erfcinv                    jit_enable       tetramesh
+                                 jit_startcnt     waterfall
+
+ ** Deprecated functions.
+
+    The following functions were deprecated in Octave 3.4 and have been
+    removed from Octave 3.8.
+
+      autocor    dispatch              is_global    setstr
+      autocov    fstat                 krylovb      strerror
+      betai      gammai                perror       values
+      cellidx    glpkmex               replot
+      cquad      is_duplicate_entry    saveimage
+
+    The following functions have been deprecated in Octave 3.8 and will
+    be removed from Octave 3.12 (or whatever version is the second major
+    release after 3.8):
+
+      default_save_options    java_new
+      gen_doc_cache           java_set
+      interp1q                java_unsigned_conversion
+      isequalwithequalnans    javafields
+      java_convert_matrix     javamethods
+      java_debug              re_read_readline_init_file
+      java_get                read_readline_init_file
+      java_invoke             saving_history
+
+
+    The following keywords have been deprecated in Octave 3.8 and will
+    be removed from Octave 3.12 (or whatever version is the second major
+    release after 3.8):
+
+      static
+
+    The following configuration variables have been deprecated in Octave
+    3.8 and will be removed from Octave 3.12 (or whatever version is the
+    second major release after 3.8):
+
+      CC_VERSION  (now GCC_VERSION)
+      CXX_VERSION (now GXX_VERSION)
+
+    The internal class <Octave_map> has been deprecated in Octave 3.8 and will
+    be removed from Octave 3.12 (or whatever version is the second major
+    release after 3.8).  Replacement classes are <octave_map> (struct array)
+    or <octave_scalar_map> for a single structure.
+
+Summary of important user-visible changes for version 3.6:
+---------------------------------------------------------
+
+ ** The PCRE library is now required to build Octave.  If a pre-compiled
+    package does not exist for your system, you can find PCRE sources
+    at http://www.pcre.org
+
+ ** The ARPACK library is no longer distributed with Octave.
+    If you need the eigs or svds functions you must provide an
+    external ARPACK through a package manager or by compiling it
+    yourself.  If a pre-compiled package does not exist for your system,
+    you can find the current ARPACK sources at
+    http://forge.scilab.org/index.php/p/arpack-ng
+
+ ** Many of Octave's binary operators (.*, .^, +, -, ...) now perform
+    automatic broadcasting for array operations which allows you to use
+    operator notation instead of calling bsxfun or expanding arrays (and
+    unnecessarily wasting memory) with repmat or similar idioms.  For
+    example, to scale the columns of a matrix by the elements of a row
+    vector, you may now write
+
+      rv .* M
+
+    In this expression, the number of elements of rv must match the
+    number of columns of M.  The following operators are affected:
+
+      plus      +  .+
+      minus     -  .-
+      times     .*
+      rdivide   ./
+      ldivide   .\
+      power     .^  .**
+      lt        <
+      le        <=
+      eq        ==
+      gt        >
+      ge        >=
+      ne        !=  ~=
+      and       &
+      or        |
+      atan2
+      hypot
+      max
+      min
+      mod
+      rem
+      xor
+
+    additionally, since the A op= B assignment operators are equivalent
+    to A = A op B, the following operators are also affected:
+
+      +=  -=  .+=  .-=  .*=  ./=  .\=  .^=  .**=  &=  |=
+
+    See the "Broadcasting" section in the new "Vectorization and Faster
+    Code Execution" chapter of the manual for more details.
+
+ ** Octave now features a profiler, thanks to the work of Daniel Kraft
+    under the Google Summer of Code mentorship program.  The manual has
+    been updated to reflect this addition.  The new user-visible
+    functions are profile, profshow, and profexplore.
+
+ ** Overhaul of statistical distribution functions
+
+    Functions now return "single" outputs for inputs of class "single".
+
+    75% reduction in memory usage through use of logical indexing.
+
+    Random sample functions now use the same syntax as rand and accept
+    a comma separated list of dimensions or a dimension vector.
+
+    Functions have been made Matlab-compatible with regard to special
+    cases (probability on boundaries, probabilities for values outside
+    distribution, etc.).  This may cause subtle changes to existing
+    scripts.
+
+    negative binomial function has been extended to real, non-integer
+    inputs.  The discrete_inv function now returns v(1) for 0 instead of
+    NaN.  The nbincdf function has been recoded to use a closed form
+    solution with betainc.
+
+ ** strread, textscan, and textread have been completely revamped.
+
+    They now support nearly all Matlab functionality including:
+
+      * Matlab-compatible whitespace and delimiter defaults
+
+      * Matlab-compatible options: 'whitespace', treatasempty', format
+        string repeat count, user-specified comment style, uneven-length
+        output arrays, %n and %u conversion specifiers (provisionally)
+
+ ** All .m string functions have been modified for better performance or
+    greater Matlab compatibility.  Performance gains of 15X-30X have
+    been demonstrated.  Operations on cell array of strings no longer pay
+    quite as high a penalty as those on 2-D character arrays.
+
+      deblank:  Now requires character or cellstr input.
+
+      strtrim:  Now requires character or cellstr input.
+                No longer trims nulls ("\0") from string for Matlab
+                compatibility.
+
+      strmatch: Follows documentation precisely and ignores trailing spaces
+                in pattern and in string.  Note that this is documented
+                Matlab behavior but the implementation apparently does
+                not always follow it.
+
+      substr:   Now possible to specify a negative LEN option which
+                extracts to within LEN of the end of the string.
+
+      strtok:   Now accepts cellstr input.
+
+      base2dec, bin2dec, hex2dec:
+                Now accept cellstr inputs.
+
+      dec2base, dec2bin, dec2hex:
+                Now accept cellstr inputs.
+
+      index, rindex:
+                Now accept 2-D character array input.
+
+      strsplit: Now accepts 2-D character array input.
+
+ ** Geometry functions derived from Qhull (convhull, delaunay, voronoi)
+    have been revamped.  The options passed to the underlying qhull
+    command have been changed for better results or for Matlab
+    compatibility.
+
+      convhull: Default options are "Qt" for 2D, 3D, 4D inputs
+                Default options are "Qt Qx" for 5D and higher
+
+      delaunay: Default options are "Qt Qbb Qc Qz" for 2D and 3D inputs
+                Default options are "Qt Qbb Qc Qx" for 4D and higher
+
+      voronoi:  No default arguments
+
+ ** Date/Time functions updated.  Millisecond support with FFF format
+    string now supported.
+
+    datestr: Numerical formats 21, 22, 29 changed to match Matlab.
+             Now accepts cellstr input.
+
+ ** The following warning IDs have been removed:
+
+      Octave:associativity-change
+      Octave:complex-cmp-ops
+      Octave:empty-list-elements
+      Octave:fortran-indexing
+      Octave:precedence-change
+
+ ** The warning ID Octave:string-concat has been renamed to
+    Octave:mixed-string-concat.
+
+ ** Octave now includes the following Matlab-compatible preference
+    functions:
+
+      addpref  getpref  ispref  rmpref  setpref
+
+ ** The following Matlab-compatible handle graphics functions have been
+    added:
+
+      guidata         uipanel        uitoolbar
+      guihandles      uipushtool     uiwait
+      uicontextmenu   uiresume       waitfor
+      uicontrol       uitoggletool
+
+    The uiXXX functions above are experimental.
+
+    Except for uiwait and uiresume, the uiXXX functions are not
+    supported with the FLTK+OpenGL graphics toolkit.
+
+    The gnuplot graphics toolkit does not support any of the uiXXX
+    functions nor the waitfor function.
+
+ ** New keyword parfor (parallel for loop) is now recognized as a valid
+    keyword.  Implementation, however, is still mapped to an ordinary
+    for loop.
+
+ ** Other new functions added in 3.6.0:
+
+      bicg                       nthargout                   usejava
+      is_dq_string               narginchk                   waitbar
+      is_sq_string               python                      zscore
+      is_function_handle         register_graphics_toolkit
+      loaded_graphics_toolkits   recycle
+
+ ** Deprecated functions.
+
+    The following functions were deprecated in Octave 3.2 and have been
+    removed from Octave 3.6.
+
+      create_set          spcholinv    splu
+      dmult               spcumprod    spmax
+      iscommand           spcumsum     spmin
+      israwcommand        spdet        spprod
+      lchol               spdiag       spqr
+      loadimage           spfind       spsum
+      mark_as_command     sphcat       spsumsq
+      mark_as_rawcommand  spinv        spvcat
+      spatan2             spkron       str2mat
+      spchol              splchol      unmark_command
+      spchol2inv          split        unmark_rawcommand
+
+    The following functions have been deprecated in Octave 3.6 and will
+    be removed from Octave 3.10 (or whatever version is the second major
+    release after 3.6):
+
+      cut                polyderiv
+      cor                shell_cmd
+      corrcoef           studentize
+      __error_text__     sylvester_matrix
+      error_text
+
+ ** The following functions have been modified for Matlab compatibility:
+
+      randperm
+
+Summary of important user-visible changes for version 3.4.3:
+-----------------------------------------------------------
+
+ ** Octave 3.4.3 is a bug fixing release.
+
+Summary of important user-visible changes for version 3.4.2:
+-----------------------------------------------------------
+
+ ** Octave 3.4.2 fixes some minor installation problems that affected
+    version 3.4.1.
+
+Summary of important user-visible changes for version 3.4.1:
+-----------------------------------------------------------
+
+ ** Octave 3.4.1 is primarily a bug fixing release.
+
+ ** IMPORTANT note about binary incompatibility in this release:
+
+    Binary compatibility for all 3.4.x releases was originally planned,
+    but this is impossible for the 3.4.1 release due to a bug in the way
+    shared libraries were built in Octave 3.4.0.  Because of this bug,
+    .oct files built for Octave 3.4.0 must be recompiled before they
+    will work with Octave 3.4.1.
+
+    Given that there would be binary incompatibilities with shared
+    libraries going from Octave 3.4.0 to 3.4.1, the following
+    incompatible changes were also made in this release:
+
+      * The Perl Compatible Regular Expression (PCRE) library is now
+        required to build Octave.
+
+      * Octave's libraries and .oct files are now installed in
+        subdirectories of $libdir instead of $libexecdir.
+
+    Any future Octave 3.4.x release versions should remain binary
+    compatible with Octave 3.4.1 as proper library versioning is now
+    being used as recommended by the libtool manual.
+
+ ** The following functions have been deprecated in Octave 3.4.1 and will
+    be removed from Octave 3.8 (or whatever version is the second major
+    release after 3.4):
+
+      cquad  is_duplicate_entry  perror  strerror
+
+ ** The following functions are new in 3.4.1:
+
+      colstyle  gmres  iscolumn  isrow  mgorth  nproc  rectangle
+
+ ** The get_forge_pkg function is now private.
+
+ ** The rectangle_lw, rectangle_sw, triangle_lw, and triangle_sw
+    functions are now private.
+
+ ** The logistic_regression_derivatives and logistic_regression_likelihood
+    functions are now private.
+
+ ** ChangeLog files in the Octave sources are no longer maintained
+    by hand.  Instead, there is a single ChangeLog file generated from
+    the Mercurial version control commit messages.  Older ChangeLog
+    information can be found in the etc/OLD-ChangeLogs directory in the
+    source distribution.
+
+Summary of important user-visible changes for version 3.4:
+---------------------------------------------------------
+
+ ** BLAS and LAPACK libraries are now required to build Octave.  The
+    subset of the reference BLAS and LAPACK libraries has been removed
+    from the Octave sources.
+
+ ** The ARPACK library is now distributed with Octave so it no longer
+    needs to be available as an external dependency when building
+    Octave.
+
+ ** The `lookup' function was extended to be more useful for
+    general-purpose binary searching.  Using this improvement, the
+    ismember function was rewritten for significantly better
+    performance.
+
+ ** Real, integer and logical matrices, when used in indexing, will now
+    cache the internal index_vector value (zero-based indices) when
+    successfully used as indices, eliminating the conversion penalty for
+    subsequent indexing by the same matrix.  In particular, this means it
+    is no longer needed to avoid repeated indexing by logical arrays
+    using find for performance reasons.
+
+ ** Logical matrices are now treated more efficiently when used as
+    indices.  Octave will keep the index as a logical mask unless the
+    ratio of true elements is small enough, using a specialized
+    code.  Previously, all logical matrices were always first converted
+    to index vectors.  This results in savings in both memory and
+    computing time.
+
+ ** The `sub2ind' and `ind2sub' functions were reimplemented as compiled
+    functions for better performance.  These functions are now faster,
+    can deliver more economized results for ranges, and can reuse the
+    index cache mechanism described in previous paragraph.
+
+ ** The built-in function equivalents to associative operators (`plus',
+    `times', `mtimes', `and', and `or') have been extended to accept
+    multiple arguments.  This is especially useful for summing
+    (multiplying, etc.) lists of objects (of possibly distinct types):
+
+      matrix_sum = plus (matrix_list{:});
+
+ ** An FTP object type based on libcurl has been implemented.  These
+    objects allow ftp connections, downloads and uploads to be
+    managed.  For example,
+
+      fp = ftp ("ftp.octave.org);
+      cd (fp, "gnu/octave");
+      mget (fp, "octave-3.2.3.tar.bz2");
+      close (fp);
+
+ ** The default behavior of `assert (observed, expected)' has been
+    relaxed to employ less strict checking that does not require the
+    internals of the values to match.  This avoids previously valid
+    tests from breaking due to new internal classes introduced in future
+    Octave versions.
+
+    For instance, all of these assertions were true in Octave 3.0.x
+    but false in 3.2.x due to new optimizations and improvements:
+
+      assert (2*linspace (1, 5, 5), 2*(1:5))
+      assert (zeros (0, 0), [])
+      assert (2*ones (1, 5), (2) (ones (1,5)))
+
+ ** The behavior of library functions `ismatrix', `issquare', and
+    `issymmetric' has been changed for better consistency.
+
+    * The `ismatrix' function now returns true for all numeric,
+      logical and character 2-D or N-D matrices.  Previously, `ismatrix'
+      returned false if the first or second dimension was zero.
+      Hence, `ismatrix ([])' was false,
+      while `ismatrix (zeros (1,2,0))' was true.
+
+    * The `issquare' function now returns a logical scalar, and is
+      equivalent to the expression
+
+        ismatrix (x) && ndims (x) == 2 && rows (x) == columns (x)
+
+      The dimension is no longer returned.  As a result, `issquare ([])'
+      now yields true.
+
+    * The `issymmetric' function now checks for symmetry instead of
+      Hermitianness.  For the latter, ishermitian was created.  Also,
+      logical scalar is returned rather than the dimension, so
+      `issymmetric ([])' is now true.
+
+ ** Function handles are now aware of overloaded functions.  If a
+    function is overloaded, the handle determines at the time of its
+    reference which function to call.  A non-overloaded version does not
+    need to exist.
+
+ ** Overloading functions for built-in classes (double, int8, cell,
+    etc.) is now compatible with Matlab.
+
+ ** Function handles can now be compared with the == and != operators,
+    as well as the `isequal' function.
+
+ ** Performance of concatenation (using []) and the functions `cat',
+    `horzcat', and `vertcat' has been improved for multidimensional
+    arrays.
+
+ ** The operation-assignment operators +=, -=, *= and /= now behave more
+    efficiently in certain cases.  For instance, if M is a matrix and S a
+    scalar, then the statement
+
+      M += S;
+
+    will operate on M's data in-place if it is not shared by another
+    variable, usually increasing both time and memory efficiency.
+
+    Only selected common combinations are affected, namely:
+
+      matrix += matrix
+      matrix -= matrix
+      matrix .*= matrix
+      matrix ./= matrix
+
+      matrix += scalar
+      matrix -= scalar
+      matrix *= scalar
+      matrix /= scalar
+
+      logical matrix |= logical matrix
+      logical matrix &= logical matrix
+
+    where matrix and scalar belong to the same class.  The left-hand
+    side must be a simple variable reference.
+
+    Moreover, when unary operators occur in expressions, Octave will
+    also try to do the operation in-place if it's argument is a
+    temporary expression.
+
+ ** The effect of comparison operators (<, >, <=, and >=) applied to
+    complex numbers has changed to be consistent with the strict
+    ordering defined by the `max', `min', and `sort' functions.  More
+    specifically, complex numbers are compared by lexicographical
+    comparison of the pairs `[abs(z), arg(z)]'.  Previously, only real
+    parts were compared; this can be trivially achieved by converting
+    the operands to real values with the `real' function.
+
+ ** The automatic simplification of complex computation results has
+    changed.  Octave will now simplify any complex number with a zero
+    imaginary part or any complex matrix with all elements having zero
+    imaginary part to a real value.  Previously, this was done only for
+    positive zeros.  Note that the behavior of the complex function is
+    unchanged and it still produces a complex value even if the
+    imaginary part is zero.
+
+ ** As a side effect of code refactoring in liboctave, the binary
+    logical operations are now more easily amenable to compiler
+    optimizations and are thus significantly faster.
+
+ ** Octave now allows user-defined `subsasgn' methods to optimize out
+    redundant copies.  For more information, see the manual.
+
+ ** More efficient matrix division handling.  Octave is now able to
+    handle the expressions
+
+      M' \ V
+      M.' \ V
+      V / M
+
+    (M is a matrix and V is a vector) more efficiently in certain cases.
+    In particular, if M is triangular, all three expressions will be
+    handled by a single call to xTRTRS (from LAPACK), with appropriate
+    flags.  Previously, all three expressions required a physical
+    transpose of M.
+
+ ** More efficient handling of certain mixed real-complex matrix
+    operations.  For instance, if RM is a real matrix and CM a complex
+    matrix,
+
+      RM * CM
+
+    can now be evaluated either as
+
+      complex (RM * real (CM), RM * imag (CM))
+
+    or as
+
+      complex (RM) * CM,
+
+    depending on the dimensions.  The first form requires more
+    temporaries and copying, but halves the FLOP count, which normally
+    brings better performance if RM has enough rows.  Previously, the
+    second form was always used.
+
+    Matrix division is similarly affected.
+
+ ** More efficient handling of triangular matrix factors returned from
+    factorizations.  The functions for computing QR, LU and Cholesky
+    factorizations will now automatically return the triangular matrix
+    factors with proper internal matrix_type set, so that it won't need
+    to be computed when the matrix is used for division.
+
+ ** The built-in `sum' function now handles the non-native summation
+    (i.e., double precision sum of single or integer inputs) more
+    efficiently, avoiding a temporary conversion of the whole input
+    array to doubles.  Further, `sum' can now accept an extra option
+    argument, using a compensated summation algorithm rather than a
+    straightforward sum, which significantly improves precision if lots
+    of cancellation occurs in the summation.
+
+ ** The built-in `bsxfun' function now uses optimized code for certain
+    cases where built-in operator handles are passed in.  Namely, the
+    optimizations concern the operators `plus', `minus', `times',
+    `ldivide', `rdivide', `power', `and', `or' (for logical arrays),
+    the relational operators `eq', `ne', `lt', `le', `gt', `ge', and the
+    functions `min' and `max'.  Optimizations only apply when both
+    operands are of the same built-in class.  Mixed real/complex and
+    single/double operations will first convert both operands to a
+    common type.
+
+ ** The `strfind' and `strrep' functions now have compiled
+    implementations, facilitating significantly more efficient searching
+    and replacing in strings, especially with longer patterns.  The code
+    of `strcat' has been vectorized and is now much more efficient when
+    many strings are concatenated.  The `strcmpi' and `strncmpi'
+    functions are now built-in functions, providing better performance.
+
+ ** 'str2double' now has a compiled implementation and the API conforms
+    to Matlab.  The additional Octave-specific features of returning a
+    boolean matrix indicating which elements were successfully converted
+    has been removed.
+
+ ** Matlab-style ignoring input and output function arguments using
+    tilde (~) is now supported.  Ignored output arguments may be
+    detected from a function using the built-in function `isargout'.
+    For more details, consult the manual.
+
+ ** The list datatype, deprecated since the introduction of cells, has
+    been removed.
+
+ ** The accumarray function has been optimized and is now significantly
+    faster in certain important cases.
+
+ ** The behavior of isreal and isnumeric functions was changed to be more
+    Matlab-compatible.
+
+ ** The integer math & conversion warnings (Octave:int-convert-nan,
+    Octave:int-convert-non-int-val, Octave:int-convert-overflow,
+    Octave:int-math-overflow) have been removed.
+
+ ** rem and mod are now built-in functions.  They also handle integer
+    types efficiently using integer arithmetic.
+
+ ** Sparse indexing and indexed assignment has been mostly rewritten.
+    Since Octave uses compressed column storage for sparse matrices,
+    major attention is devoted to operations manipulating whole columns.
+    Such operations are now significantly faster, as well as some other
+    important cases.
+
+    Further, it is now possible to pre-allocate a sparse matrix and
+    subsequently fill it by assignments, provided they meet certain
+    conditions.  For more information, consult the `spalloc' function,
+    which is no longer a mere dummy.  Consequently, nzmax and nnz are no
+    longer always equal in Octave.  Octave may also produce a matrix
+    with nnz < nzmax as a result of other operations, so you should
+    consistently use nnz unless you really want to use nzmax (i.e., the
+    space allocated for nonzero elements).
+
+    Sparse concatenation is also affected, and concatenating sparse
+    matrices, especially larger collections, is now significantly more
+    efficient.  This applies to both the [] operator and the
+    cat/vertcat/horzcat functions.
+
+ ** It is now possible to optionally employ the xGESDD LAPACK drivers
+    for computing the singular value decomposition using svd, instead
+    of the default xGESVD, using the configuration pseudo-variable
+    svd_driver.  The xGESDD driver can be up to 6x times faster when
+    singular vectors are requested, but is reported to be somewhat less
+    robust on highly ill-conditioned matrices.
+
+ ** Configuration pseudo-variables, such as page_screen_output or
+    confirm_recursive_rmdir (or the above mentioned svd_driver), now
+    accept a "local" option as second argument, requesting the change
+    to be undone when the current function returns:
+
+    function [status, msg] = rm_rf (dir)
+      confirm_recursive_rmdir (false, "local");
+      [status, msg] = rmdir (dir, "s");
+      ...
+    endfunction
+
+    Upon return, confirm_recursive_rmdir will be restored to the value
+    it had on entry to the function, even if there were subsequent
+    changes to the variable in function rm_rf or any of the functions
+    it calls.
+
+ ** pkg now accepts a -forge option for downloading and installing
+    packages from Octave Forge automatically.  For example,
+
+      pkg install -forge general
+
+    will automatically download the latest release of the general
+    package and attempt to install it.  No automatic resolving of
+    dependencies is provided.  Further,
+
+      pkg list -forge
+
+    can be used to list all available packages.
+
+ ** The internal data representation of structs has been completely
+    rewritten to make certain optimizations feasible.  The field data
+    can now be shared between structs with equal keys but different
+    dimensions or values, making operations that preserve the fields
+    faster.  Economized storage is now used for scalar structs (just
+    like most other scalars), making their usage more
+    memory-efficient.  Certain array-like operations on structs
+    (concatenation, uniform cellfun, num2cell) have gained a
+    significant speed-up.  Additionally, the octave_scalar_map class
+    now provides a simpler interface to work with scalar structs within
+    a C++ DLD function.
+
+ ** Two new formats are available for displaying numbers:
+
+      format short eng
+      format long eng
+
+    Both display numbers in engineering notation, i.e., mantissa +
+    exponent where the exponent is a multiple of 3.
+
+ ** The following functions are new in Octave 3.4:
+      accumdim    erfcx        nfields      pqpnonneg  uigetdir
+      bitpack     fileread     nth_element  quadcc     uigetfile
+      bitunpack   fminbnd      onCleanup    randi      uiputfile
+      blkmm       fskipl       pbaspect     repelems   uimenu
+      cbrt        ifelse       pie3         reset      whitebg
+      curl        ishermitian  powerset     rsf2csf
+      chop        isindex      ppder        saveas
+      daspect     luupdate     ppint        strread
+      divergence  merge        ppjumps      textread
+
+ ** Using the image function to view images with external programs such
+    as display, xv, and xloadimage is no longer supported.  The
+    image_viewer function has also been removed.
+
+ ** The behavior of struct assignments to non-struct values has been
+    changed.  Previously, it was possible to overwrite an arbitrary
+    value:
+
+      a = 1;
+      a.x = 2;
+
+    This is no longer possible unless a is an empty matrix or cell
+    array.
+
+ ** The dlmread function has been extended to allow specifying a custom
+    value for empty fields.
+
+ ** The dlmread and dlmwrite functions have been modified to accept
+    file IDs (as returned by fopen) in addition to file names.
+
+ ** Octave can now optimize away the interpreter overhead of an
+    anonymous function handle, if the function simply calls another
+    function or handle with some of its parameters bound to certain
+    values.  Example:
+
+      f = @(x) sum (x, 1);
+
+    When f is called, the call is forwarded to @sum with the constant 1
+    appended, and the anonymous function call does not occur on the
+    call stack.
+
+ ** For compatibility with Matlab, mu2lin (x) is now equivalent to
+    mu2lin (x, 0).
+
+ ** The new function `history_control' may be used to control the way
+    command lines are added to the history list when Octave is using
+    readline for command-line editing.  For example
+
+      history_control ("ignoredups")
+
+    tells Octave to avoid adding duplicate lines to the history list.
+
+ ** Octave now uses the gnulib library for improved portability and to
+    avoid bugs in operating system functions.
+
+ ** Deprecated functions.
+
+    The following functions were deprecated in Octave 3.0 and have been
+    removed from Octave 3.4.
+
+      beta_cdf         geometric_pdf        pascal_pdf
+      beta_inv         geometric_rnd        pascal_rnd
+      beta_pdf         hypergeometric_cdf   poisson_cdf
+      beta_rnd         hypergeometric_inv   poisson_inv
+      binomial_cdf     hypergeometric_pdf   poisson_pdf
+      binomial_inv     hypergeometric_rnd   poisson_rnd
+      binomial_pdf     intersection         polyinteg
+      binomial_rnd     is_bool              setstr
+      chisquare_cdf    is_complex           struct_contains
+      chisquare_inv    is_list              struct_elements
+      chisquare_pdf    is_matrix            t_cdf
+      chisquare_rnd    is_scalar            t_inv
+      clearplot        is_square            t_pdf
+      clg              is_stream            t_rnd
+      com2str          is_struct            uniform_cdf
+      exponential_cdf  is_symmetric         uniform_inv
+      exponential_inv  is_vector            uniform_pdf
+      exponential_pdf  isstr                uniform_rnd
+      exponential_rnd  lognormal_cdf        weibcdf
+      f_cdf            lognormal_inv        weibinv
+      f_inv            lognormal_pdf        weibpdf
+      f_pdf            lognormal_rnd        weibrnd
+      f_rnd            meshdom              weibull_cdf
+      gamma_cdf        normal_cdf           weibull_inv
+      gamma_inv        normal_inv           weibull_pdf
+      gamma_pdf        normal_pdf           weibull_rnd
+      gamma_rnd        normal_rnd           wiener_rnd
+      geometric_cdf    pascal_cdf
+      geometric_inv    pascal_inv
+
+    The following functions were deprecated in Octave 3.2 and will
+    be removed from Octave 3.6 (or whatever version is the second major
+    release after 3.2):
+
+      create_set          spcholinv    splu
+      dmult               spcumprod    spmax
+      iscommand           spcumsum     spmin
+      israwcommand        spdet        spprod
+      lchol               spdiag       spqr
+      loadimage           spfind       spsum
+      mark_as_command     sphcat       spsumsq
+      mark_as_rawcommand  spinv        spvcat
+      spatan2             spkron       str2mat
+      spchol              splchol      unmark_command
+      spchol2inv          split        unmark_rawcommand
+
+    The following functions have been deprecated in Octave 3.4 and will
+    be removed from Octave 3.8 (or whatever version is the second major
+    release after 3.4):
+
+      autocor  cellidx   gammai     is_global  replot     values
+      autocov  dispatch  glpkmex    krylovb    saveimage
+      betai    fstat     intwarning perror     strerror
+
+Summary of important user-visible changes for version 3.2:
+---------------------------------------------------------
+
+ ** Compatibility with Matlab graphics has been improved.
+
+    The hggroup object and associated listener callback functions have
+    been added allowing the inclusion of group objects.  Data sources
+    have been added to these group objects such that
+
+           x = 0:0.1:10;
+           y = sin (x);
+           plot (x, y, "ydatasource", "y");
+           for i = 1 : 100
+             pause(0.1)
+             y = sin (x + 0.1 * i);
+             refreshdata ();
+           endfor
+
+    works as expected.  This capability has be used to introduce
+    stem-series, bar-series, etc., objects for better Matlab
+    compatibility.
+
+ ** New graphics functions:
+
+      addlistener                  ezcontour   gcbo         refresh
+      addproperty                  ezcontourf  ginput       refreshdata
+      allchild                     ezmesh      gtext        specular
+      available_graphics_toolkits  ezmeshc     intwarning   surfl
+      graphics_toolkit             ezplot      ishghandle   trisurf
+      cla                          ezplot3     isocolors    waitforbuttonpress
+      clabel                       ezpolar     isonormals
+      comet                        ezsurf      isosurface
+      dellistener                  findall     linkprop
+      diffuse                      gcbf        plotmatrix
+
+ ** New experimental OpenGL/FLTK based plotting system.
+
+    An experimental plotting system based on OpenGL and the FLTK
+    toolkit is now part of Octave.  This graphics toolkit is disabled by
+    default.  You can switch to using it with the command
+
+        graphics_toolkit ("fltk")
+
+    for all future figures or for a particular figure with the command
+
+        graphics_toolkit (h, "fltk")
+
+    where "h" is a valid figure handle.
+
+ ** Functions providing direct access to gnuplot have been removed.
+
+    The functions __gnuplot_plot__, __gnuplot_set__, __gnuplot_raw__,
+     __gnuplot_show__, __gnuplot_replot__, __gnuplot_splot__,
+     __gnuplot_save_data__ and __gnuplot_send_inline_data__ have been
+     removed from Octave.  These function were incompatible with the
+     high level graphics handle code.
+
+ ** The Control, Finance and Quaternion functions have been removed.
+
+    These functions are now available as separate packages from
+
+      http://octave.sourceforge.net/packages.html
+
+    and can be reinstalled using the Octave package manager (see
+    the pkg function).
+
+ ** Specific sparse matrix functions removed.
+
+    The following functions, which handled only sparse matrices have
+    been removed.  Instead of calling these functions directly, you
+    should use the corresponding function without the "sp" prefix.
+
+      spatan2     spcumsum  spkron   spprod
+      spchol      spdet     splchol  spqr
+      spchol2inv  spdiag    splu     spsum
+      spcholinv   spfind    spmax    spsumsqk
+      spcumprod   spinv     spmin
+
+ ** Improvements to the debugger.
+
+    The interactive debugging features have been improved.  Stopping
+    on statements with dbstop should work correctly now.  Stepping
+    into and over functions, and stepping one statement at a time
+    (with dbstep) now works.  Moving up and down the call stack with
+    dbup and dbdown now works.  The dbstack function is now available
+    to print the current function call stack.  The new dbquit function
+    is available to exit the debugging mode.
+
+ ** Improved traceback error messages.
+
+    Traceback error messages are much more concise and easier to
+    understand.  They now display information about the function call
+    stack instead of the stack of all statements that were active at
+    the point of the error.
+
+ ** Object Oriented Programming.
+
+    Octave now includes OOP features and the user can create their own
+    class objects and overloaded functions and operators.  For
+    example, all methods of a class called "myclass" will be found in
+    a directory "@myclass" on the users path.  The class specific
+    versions of functions and operators take precedence over the
+    generic versions of these functions.
+
+    New functions related to OOP include
+
+      class  inferiorto  isobject  loadobj  methods  superiorto
+
+    See the Octave manual for more details.
+
+ ** Parsing of Command-style Functions.
+
+    Octave now parses command-style functions without needing to first
+    declare them with "mark_as_command".  The rules for recognizing a
+    command-style function calls are
+
+      * A command must appear as the first word in a statement,
+        followed by a space.
+
+      * The first character after the space must not be '=' or '('
+
+      * The next token after the space must not look like a binary
+        operator.
+
+    These rules should be mostly compatible with the way Matlab parses
+    command-style function calls and allow users to define commands in
+    .m files without having to mark them as commands.
+
+    Note that previous versions of Octave allowed expressions like
+
+      x = load -text foo.dat
+
+    but an expression like this will now generate a parse error.  In
+    order to assign the value returned by a function to a variable,
+    you must use the normal function call syntax:
+
+      x = load ("-text", "foo.dat");
+
+ ** Block comments.
+
+    Commented code can be between matching "#{" and "#}" or "%{" and
+    "%}" markers, even if the commented code spans several line.  This
+    allows blocks code to be commented, without needing to comment
+    each line.  For example,
+
+    function [s, t] = func (x, y)
+      s = 2 * x;
+    #{
+      s *= y;
+      t = y + x;
+    #}
+    endfunction
+
+    the lines "s *= y;" and "t = y + x" will not be executed.
+
+ ** If any subfunction in a file ends with "end" or "endfunction", then
+    they all must end that way.  Previously, Octave accepted
+
+      function main ()
+        ...
+      # no endfunction here.
+      function sub ()
+        ...
+      endfunction
+
+    but this is no longer allowed.
+
+ ** Special treatment in the parser of expressions like "a' * b".
+
+    In these cases the transpose is no longer explicitly formed and
+    BLAS libraries are called with the transpose flagged,
+    significantly improving performance for these kinds of
+    operations.
+
+ ** Single Precision data type.
+
+    Octave now includes a single precision data type.  Single
+    precision variables can be created with the "single" command, or
+    from functions like ones, eye, etc.  For example,
+
+      single (1)
+      ones (2, 2, "single")
+      zeros (2, 2, "single")
+      eye (2, 2, "single")
+      Inf (2, 2, "single")
+      NaN (2, 2, "single")
+      NA (2, 2, "single")
+
+    all create single precision variables.  For compatibility with
+    Matlab, mixed double/single precision operators and functions
+    return single precision types.
+
+    As a consequence of this addition to Octave the internal
+    representation of the double precision NA value has changed, and
+    so users that make use of data generated by Octave with R or
+    visa-versa are warned that compatibility might not be assured.
+
+ ** Improved array indexing.
+
+    The underlying code used for indexing of arrays has been
+    completely rewritten and indexing is now significantly faster.
+
+ ** Improved memory management.
+
+    Octave will now attempt to share data in some cases where previously
+    a copy would be made, such as certain array slicing operations or
+    conversions between cells, structs and cs-lists.  This usually reduces
+    both time and memory consumption.
+    Also, Octave will now attempt to detect and optimize usage of a vector
+    as a stack, when elements are being repeatedly inserted at/removed from
+    the end of the vector.
+
+ ** Improved performance for reduction operations.
+
+    The performance of the sum, prod, sumsq, cumsum, cumprod, any, all,
+    max and min functions has been significantly improved.
+
+ ** Sorting and searching.
+
+    The performance of sort has been improved, especially when sorting
+    indices are requested.  An efficient built-in issorted
+    implementation was added.  The sortrows function now uses a more
+    efficient algorithm, especially in the homogeneous case.  The lookup
+    function is now a built-in function performing a binary search,
+    optimized for long runs of close elements.  Lookup also works with
+    cell arrays of strings.
+
+ ** Range arithmetics
+
+    For some operations on ranges, Octave will attempt to keep the
+    result as a range.  These include negation, adding a scalar,
+    subtracting a scalar, and multiplying by a scalar.  Ranges with zero
+    increment are allowed and can be constructed using the built-in
+    function `ones'.
+
+ ** Various performance improvements.
+
+    Performance of a number of other built-in operations and functions
+    was improved, including:
+
+    * logical operations
+    * comparison operators
+    * element-wise power
+    * accumarray
+    * cellfun
+    * isnan
+    * isinf
+    * isfinite
+    * nchoosek
+    * repmat
+    * strcmp
+
+ ** 64-bit integer arithmetic.
+
+    Arithmetic with 64-bit integers (int64 and uint64 types) is fully
+    supported, with saturation semantics like the other integer types.
+    Performance of most integer arithmetic operations has been
+    improved by using integer arithmetic directly.  Previously, Octave
+    performed integer math with saturation semantics by converting the
+    operands to double precision, performing the operation, and then
+    converting the result back to an integer value, truncating if
+    necessary.
+
+ ** Diagonal and permutation matrices.
+
+    The interpreter can now treat diagonal and permutation matrices as
+    special objects that store only the non-zero elements, rather than
+    general full matrices.  Therefore, it is now possible to construct
+    and use these matrices in linear algebra without suffering a
+    performance penalty due to storing large numbers of zero elements.
+
+ ** Improvements to fsolve.
+
+    The fsolve function now accepts an option structure argument (see
+    also the optimset function).  The INFO values returned from fsolve
+    have changed to be compatible with Matlab's fsolve function.
+    Additionally, fsolve is now able to solve overdetermined systems,
+    complex-differentiable complex systems, systems with a sparse
+    jacobian and can work in single precision if given single precision
+    inputs.  It can also be called recursively.
+
+ ** Improvements to the norm function.
+
+    The norm function is now able to compute row or column norms of a
+    matrix in a single call, as well as general matrix p-norms.
+
+ ** New functions for computing some eigenvalues or singular values.
+
+    The eigs and svds functions have been included in Octave.  These
+    functions require the ARPACK library (now distributed under a
+    GPL-compatible license).
+
+ ** New QR and Cholesky factorization updating functions.
+
+      choldelete  cholshift   qrdelete  qrshift
+      cholinsert  cholupdate  qrinsert  qrupdate
+
+ ** New quadrature functions.
+
+      dblquad  quadgk  quadv  triplequad
+
+ ** New functions for reading and writing images.
+
+    The imwrite and imread functions have been included in Octave.
+    These functions require the GraphicsMagick library.  The new
+    function imfinfo provides information about an image file (size,
+    type, colors, etc.)
+
+ ** The input_event_hook function has been replaced by the pair of
+    functions add_input_event_hook and remove_input_event_hook so that
+    more than one hook function may be installed at a time.
+
+ ** Other miscellaneous new functions.
+
+      addtodate          hypot                       reallog
+      bicgstab           idivide                     realpow
+      cellslices         info                        realsqrt
+      cgs                interp1q                    rectint
+      command_line_path  isdebugmode                 regexptranslate
+      contrast           isfloat                     restoredefaultpath
+      convn              isstrprop                   roundb
+      cummin             log1p                       rundemos
+      cummax             lsqnonneg                   runlength
+      datetick           matlabroot                  saveobj
+      display            namelengthmax               spaugment
+      expm1              nargoutchk                  strchr
+      filemarker         pathdef                     strvcat
+      fstat              perl                        subspace
+      full               prctile                     symvar
+      fzero              quantile                    treelayout
+      genvarname         re_read_readline_init_file  validatestring
+      histc
+
+ ** Changes to strcat.
+
+    The strcat function is now compatible with Matlab's strcat
+    function, which removes trailing whitespace when concatenating
+    character strings.  For example
+
+      strcat ('foo ', 'bar')
+      ==> 'foobar'
+
+    The new function cstrcat provides the previous behavior of
+    Octave's strcat.
+
+ ** Improvements to the help functions.
+
+    The help system has been mostly re-implemented in .m files to make
+    it easier to modify.  Performance of the lookfor function has been
+    greatly improved by caching the help text from all functions that
+    are distributed with Octave.  The pkg function has been modified
+    to generate cache files for external packages when they are
+    installed.
+
+ ** Deprecated functions.
+
+    The following functions were deprecated in Octave 3.0 and will be
+    removed from Octave 3.4 (or whatever version is the second major
+    release after 3.0):
+
+      beta_cdf         geometric_pdf       pascal_pdf
+      beta_inv         geometric_rnd       pascal_rnd
+      beta_pdf         hypergeometric_cdf  poisson_cdf
+      beta_rnd         hypergeometric_inv  poisson_inv
+      binomial_cdf     hypergeometric_pdf  poisson_pdf
+      binomial_inv     hypergeometric_rnd  poisson_rnd
+      binomial_pdf     intersection        polyinteg
+      binomial_rnd     is_bool             setstr
+      chisquare_cdf    is_complex          struct_contains
+      chisquare_inv    is_list             struct_elements
+      chisquare_pdf    is_matrix           t_cdf
+      chisquare_rnd    is_scalar           t_inv
+      clearplot        is_square           t_pdf
+      clg              is_stream           t_rnd
+      com2str          is_struct           uniform_cdf
+      exponential_cdf  is_symmetric        uniform_inv
+      exponential_inv  is_vector           uniform_pdf
+      exponential_pdf  isstr               uniform_rnd
+      exponential_rnd  lognormal_cdf       weibcdf
+      f_cdf            lognormal_inv       weibinv
+      f_inv            lognormal_pdf       weibpdf
+      f_pdf            lognormal_rnd       weibrnd
+      f_rnd            meshdom             weibull_cdf
+      gamma_cdf        normal_cdf          weibull_inv
+      gamma_inv        normal_inv          weibull_pdf
+      gamma_pdf        normal_pdf          weibull_rnd
+      gamma_rnd        normal_rnd          wiener_rnd
+      geometric_cdf    pascal_cdf
+      geometric_inv    pascal_inv
+
+    The following functions are now deprecated in Octave 3.2 and will
+    be removed from Octave 3.6 (or whatever version is the second major
+    release after 3.2):
+
+      create_set          spcholinv  spmax
+      dmult               spcumprod  spmin
+      iscommand           spcumsum   spprod
+      israwcommand        spdet      spqr
+      lchol               spdiag     spsum
+      loadimage           spfind     spsumsq
+      mark_as_command     spinv      str2mat
+      mark_as_rawcommand  spkron     unmark_command
+      spatan2             splchol    unmark_rawcommand
+      spchol              split
+      spchol2inv          splu
+
 Summary of important user-visible changes for version 3.0:
 ---------------------------------------------------------
 
@@ -196,5 +1716,6 @@
     the distributions using the standard scale factor rather than
     one over the scale factor.
 
+---------------------------------------------------------
 
 See NEWS.2 for old news.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/etc/RELEASE.PROCESS	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,84 @@
+<!----------------------------------------------------------------------------->
+<! This file contains a list of steps to accomplish before producing a release.
+   The format of the file is wiki markup and can be directly used as a page
+   on wiki.octave.org.
+<!----------------------------------------------------------------------------->
+==3.8 Release Tasks==
+
+This page shows the tasks to be completed before the 3.8 release is finalized.
+
+<!----------------------------------------------------------------------------->
+# File bug reports for all outstanding bugs known, but not reported
+#: Completion Date: 10/16/2013
+## Put out a general call for reports on Octave-Maintainers and Octave-Help list
+##: Completion Date: 10/9/2013
+<!----------------------------------------------------------------------------->
+# Review patch tracker/bug list for any patches submitted that may be included before release
+#: Completion Date: 10/24/2013
+<!----------------------------------------------------------------------------->
+# Identify Bugs which *must* be fixed prior to release
+#: Completion Date: 10/20/2013
+## Start discussion about criteria on octave-maintainers list
+## Possible Criteria:
+##* Severity >= 4
+##* Item Group == ("Crash" or "Regression")
+##* Item Group == "Build Failure"
+## Review bugs on tracker for possible inclusion in list
+## Review bugs and update to correct category, such as Patch Submitted.
+<!----------------------------------------------------------------------------->
+# Clear all bugs identified as must-fix
+#: Completion Date: 10/26/2013
+## See [[3.8 Bug Fix List]]
+<!----------------------------------------------------------------------------->
+# GPL License activities
+## Update Copyright statements for all source controlled files
+## Add any new contributors to contributors.in
+<!----------------------------------------------------------------------------->
+# Style-check code base
+## This will produce lots of whitespace changes, but no behavior changes.
+## Must occur after patches have been added since whitespace changes will often prevent patches from applying.
+<!----------------------------------------------------------------------------->
+# Run lint checker on code base
+## cppcheck, Clang sanitize, etc.
+<!----------------------------------------------------------------------------->
+# Verify 'make check' is passing
+## Start discussion on octave-maintainers list about which failing tests must be fixed
+## Identify and fix any tests determined critical in step above
+<!----------------------------------------------------------------------------->
+# Run Octave test suite under Valgrind to check for memory leaks
+## Done: 10/17/13
+<!----------------------------------------------------------------------------->
+# Review documentation
+## Grammar check documentation so that it conforms to Octave standards
+## Spellcheck documentation
+## Verify no functions missing from manual
+## Verify deprecated functions removed from seealso links
+## Verify all formats (Info, HTML, pdf) build correctly
+## Review NEWS for any features which should be announced
+<!----------------------------------------------------------------------------->
+# Localization and Internationalization
+## Submit call for translations for GUI strings.
+## Completion Date: 11/1/13
+<!----------------------------------------------------------------------------->
+# Verify build process and create release candidates
+## Update version information in configure.ac/Makefile.am
+## Verify 'make distcheck' passes
+## Create release candidate
+### 'make dist'
+### hg tag repository with release candidate ID
+### For Windows, create installer [[Windows Installer]]
+### Upload release candidate
+### Announce release candidate to Octave-Maintainers, Octave-Help, on web page
+### Repeat release candidate cycle until clean
+<!----------------------------------------------------------------------------->
+# Final Release
+## hg tag repository with release
+## merge default onto stable to become the current stable release
+## add new release version to Savannah bug tracker
+## Announce final release on Octave mailing lists and web site
+<!----------------------------------------------------------------------------->
+# Post-Release
+## Update configure.ac/Makefile.am versioning to next release cycle
+## Remove all deprecated functions scheduled for deletion in 4.0 from default branch
+
+[[Category:Releases]]
--- a/examples/@FIRfilter/FIRfilter.m	Fri Feb 06 08:31:09 2015 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,20 +0,0 @@
-## -*- texinfo -*-
-## @deftypefn  {Function File} {} FIRfilter ()
-## @deftypefnx {Function File} {} FIRfilter (@var{p})
-## Create a FIR filter with polynomial @var{p} as coefficient vector.
-## @end deftypefn
-
-function f = FIRfilter (p)
-
-  f.polynomial = [];
-  if (nargin == 0)
-    p = @polynomial ([1]);
-  elseif (nargin == 1)
-    if (!isa (p, "polynomial"))
-      error ("FIRfilter: expecting polynomial as input argument");
-    endif
-  else
-    print_usage ();
-  endif
-  f = class (f, "FIRfilter", p);
-endfunction
--- a/examples/@FIRfilter/FIRfilter_aggregation.m	Fri Feb 06 08:31:09 2015 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,21 +0,0 @@
-## -*- texinfo -*-
-## @deftypefn  {Function File} {} FIRfilter ()
-## @deftypefnx {Function File} {} FIRfilter (@var{p})
-## Create a FIR filter with polynomial @var{p} as coefficient vector.
-## @end deftypefn
-
-function f = FIRfilter (p)
-
-  if (nargin == 0)
-    f.polynomial = @polynomial ([1]);
-  elseif (nargin == 1)
-    if (isa (p, "polynomial"))
-      f.polynomial = p;
-    else
-      error ("FIRfilter: expecting polynomial as input argument");
-    endif
-  else
-    print_usage ();
-  endif
-  f = class (f, "FIRfilter");
-endfunction
--- a/examples/@FIRfilter/display.m	Fri Feb 06 08:31:09 2015 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,6 +0,0 @@
-function display (f)
-
-  display (f.polynomial);
-
-endfunction
-
--- a/examples/@FIRfilter/module.mk	Fri Feb 06 08:31:09 2015 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,12 +0,0 @@
-FCN_FILE_DIRS += @FIRfilter
-
-EXTRA_DIST += @FIRfilter/module.mk
-
-at_FIRfilter_FCN_FILES = \
-  @FIRfilter/display.m \
-  @FIRfilter/FIRfilter_aggregation.m \
-  @FIRfilter/FIRfilter.m \
-  @FIRfilter/subsasgn.m \
-  @FIRfilter/subsref.m
-
-FCN_FILES += $(at_FIRfilter_FCN_FILES)
--- a/examples/@FIRfilter/subsasgn.m	Fri Feb 06 08:31:09 2015 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,14 +0,0 @@
-function out = subsasgn (f, index, val)
-  switch (index.type)
-    case "."
-      fld = index.subs;
-      if (strcmp (fld, "polynomial"))
-        out = f;
-        out.polynomial = val;
-      else
-        error ("@FIRfilter/subsref: invalid property \"%s\"", fld);
-      endif
-    otherwise
-      error ("FIRfilter/subsagn: Invalid index type")
-  endswitch
-endfunction
--- a/examples/@FIRfilter/subsref.m	Fri Feb 06 08:31:09 2015 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,16 +0,0 @@
-function out = subsref (f, x)
-  switch (x.type)
-    case "()"
-      n = f.polynomial;
-      out = filter (n.poly, 1, x.subs{1});
-    case "."
-      fld = x.subs;
-      if (strcmp (fld, "polynomial"))
-        out = f.polynomial;
-      else
-        error ("@FIRfilter/subsref: invalid property \"%s\"", fld);
-      endif
-    otherwise
-      error ("@FIRfilter/subsref: invalid subscript type for FIR filter");
-  endswitch
-endfunction
--- a/examples/@polynomial/display.m	Fri Feb 06 08:31:09 2015 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,32 +0,0 @@
-function display (p)
-  a = p.poly;
-  first = true;
-  fprintf ("%s =", inputname (1));
-  for i = 1 : length (a);
-    if (a(i) != 0)
-      if (first)
-        first = false;
-      elseif (a(i) > 0)
-        fprintf (" +");
-      endif
-      if (a(i) < 0)
-        fprintf (" -");
-      endif
-      if (i == 1)
-        fprintf (" %g", abs (a(i)));
-      elseif (abs(a(i)) != 1)
-        fprintf (" %g *", abs (a(i)));
-      endif
-      if (i > 1)
-        fprintf (" X");
-      endif
-      if (i > 2)
-        fprintf (" ^ %d", i - 1);
-      endif
-    endif
-  endfor
-  if (first)
-    fprintf (" 0");
-  endif
-  fprintf ("\n");
-endfunction
--- a/examples/@polynomial/double.m	Fri Feb 06 08:31:09 2015 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,3 +0,0 @@
-function b = double (a)
-  b = a.poly;
-endfunction
--- a/examples/@polynomial/end.m	Fri Feb 06 08:31:09 2015 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,9 +0,0 @@
-function r = end (obj, index_pos, num_indices)
-
-  if (num_indices != 1)
-    error ("polynomial object may only have one index")
-  endif
-
-  r = length (obj.poly) - 1;
-
-endfunction
--- a/examples/@polynomial/get.m	Fri Feb 06 08:31:09 2015 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,18 +0,0 @@
-function s = get (p, f)
-  if (nargin == 1)
-    s.poly = p.poly;
-  elseif (nargin == 2)
-    if (ischar (f))
-      switch (f)
-        case "poly"
-          s = p.poly;
-        otherwise
-          error ("get: invalid property %s", f);
-      endswitch
-    else
-      error ("get: expecting the property to be a string");
-    endif
-  else
-    print_usage ();
-  endif
-endfunction
--- a/examples/@polynomial/module.mk	Fri Feb 06 08:31:09 2015 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,21 +0,0 @@
-FCN_FILE_DIRS += @polynomial
-
-EXTRA_DIST += @polynomial/module.mk
-
-at_polynomial_FCN_FILES = \
-  @polynomial/display.m \
-  @polynomial/double.m \
-  @polynomial/end.m \
-  @polynomial/get.m \
-  @polynomial/mtimes.m \
-  @polynomial/numel.m \
-  @polynomial/plot.m \
-  @polynomial/polynomial.m \
-  @polynomial/polynomial_superiorto.m \
-  @polynomial/polyval.m \
-  @polynomial/roots.m \
-  @polynomial/set.m \
-  @polynomial/subsasgn.m \
-  @polynomial/subsref.m
-
-FCN_FILES += $(at_polynomial_FCN_FILES)
--- a/examples/@polynomial/mtimes.m	Fri Feb 06 08:31:09 2015 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,3 +0,0 @@
-function y = mtimes (a, b)
-  y = polynomial (conv (double (a), double (b)));
-endfunction
--- a/examples/@polynomial/numel.m	Fri Feb 06 08:31:09 2015 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,7 +0,0 @@
-function n = numel (obj, idx)
-
-  # always produce an array.
-  n = 1;
-
-endfunction
-
--- a/examples/@polynomial/plot.m	Fri Feb 06 08:31:09 2015 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,10 +0,0 @@
-function h = plot (p, varargin)
-  n = 128;
-  rmax = max (abs (roots (p.poly)));
-  x = [0 : (n - 1)] / (n - 1) * 2.2 * rmax - 1.1 * rmax;
-  if (nargout > 0)
-    h = plot (x, p(x), varargin{:});
-  else
-    plot (x, p(x), varargin{:});
-  endif
-endfunction
--- a/examples/@polynomial/polynomial.m	Fri Feb 06 08:31:09 2015 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,30 +0,0 @@
-## -*- texinfo -*-
-## @deftypefn  {Function File} {} polynomial ()
-## @deftypefnx {Function File} {} polynomial (@var{a})
-## Create a polynomial object representing the polynomial
-##
-## @example
-## a0 + a1 * x + a2 * x^2 + @dots{} + an * x^n
-## @end example
-##
-## @noindent
-## from a vector of coefficients [a0 a1 a2 @dots{} an].
-## @end deftypefn
-
-function p = polynomial (a)
-  if (nargin == 0)
-    p.poly = [0];
-    p = class (p, "polynomial");
-  elseif (nargin == 1)
-    if (strcmp (class (a), "polynomial"))
-      p = a;
-    elseif (isvector (a) && isreal (a))
-      p.poly = a(:).';
-      p = class (p, "polynomial");
-    else
-      error ("polynomial: expecting real vector");
-    endif
-  else
-    print_usage ();
-  endif
-endfunction
--- a/examples/@polynomial/polynomial_superiorto.m	Fri Feb 06 08:31:09 2015 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,31 +0,0 @@
-## -*- texinfo -*-
-## @deftypefn  {Function File} {} polynomial ()
-## @deftypefnx {Function File} {} polynomial (@var{a})
-## Create a polynomial object representing the polynomial
-##
-## @example
-## a0 + a1 * x + a2 * x^2 + @dots{} + an * x^n
-## @end example
-##
-## @noindent
-## from a vector of coefficients [a0 a1 a2 @dots{} an].
-## @end deftypefn
-
-function p = polynomial (a)
-  if (nargin == 0)
-    p.poly = [0];
-    p = class (p, "polynomial");
-  elseif (nargin == 1)
-    if (strcmp (class (a), "polynomial"))
-      p = a;
-    elseif (isvector (a) && isreal (a))
-      p.poly = a(:).';
-      p = class (p, "polynomial");
-    else
-      error ("polynomial: expecting real vector");
-    endif
-  else
-    print_usage ();
-  endif
-  superiorto ("double");
-endfunction
--- a/examples/@polynomial/polyval.m	Fri Feb 06 08:31:09 2015 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,7 +0,0 @@
-function [y, dy] = polyval (p, varargin)
-  if (nargout == 2)
-    [y, dy] = polyval (fliplr (p.poly), varargin{:});
-  else
-    y = polyval (fliplr (p.poly), varargin{:});
-  endif
-endfunction
--- a/examples/@polynomial/roots.m	Fri Feb 06 08:31:09 2015 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,3 +0,0 @@
-function y = roots (p)
-  y = roots(fliplr(p.poly));
-endfunction
\ No newline at end of file
--- a/examples/@polynomial/set.m	Fri Feb 06 08:31:09 2015 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,20 +0,0 @@
-function s = set (p, varargin)
-  s = p;
-  if (length (varargin) < 2 || rem (length (varargin), 2) != 0)
-    error ("set: expecting property/value pairs");
-  endif
-  while (length (varargin) > 1)
-    prop = varargin{1};
-    val = varargin{2};
-    varargin(1:2) = [];
-    if (ischar (prop) && strcmp (prop, "poly"))
-      if (isvector (val) && isreal (val))
-        s.poly = val(:).';
-      else
-        error ("set: expecting the value to be a real vector");
-      endif
-    else
-      error ("set: invalid property of polynomial class");
-    endif
-  endwhile
-endfunction
--- a/examples/@polynomial/subsasgn.m	Fri Feb 06 08:31:09 2015 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,35 +0,0 @@
-function p = subsasgn (p, s, val)
-  if (length (s) < 1)
-    error ("polynomial: needs index");
-  endif
-  switch (s(1).type)
-    case "{}"
-      ind = s(1).subs;
-      if (numel (ind) != 1)
-        error ("polynomial: need exactly one index");
-      else
-        if (length (s) == 1)
-          if (isnumeric (ind{1}))
-            p.poly(ind{1}+1) = val;
-          else
-            p.poly(ind{1}) = val;
-          endif
-        else
-          error ("polynomial: chained subscripts not allowed for {}");
-        endif
-      endif
-    case "."
-      fld = s(1).subs;
-      if (strcmp (fld, "poly"))
-        if (length (s) == 1)
-          p.poly = val;
-        else
-          p.poly = subsasgn (p.poly, s(2:end), val);
-        endif
-      else
-        error ("@polynomial/subsref: invalid property \"%s\"", fld);
-      endif
-    otherwise
-      error ("invalid subscript type");
-  endswitch
-endfunction
--- a/examples/@polynomial/subsref.m	Fri Feb 06 08:31:09 2015 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,37 +0,0 @@
-function b = subsref (a, s)
-  if (isempty (s))
-    error ("polynomial: missing index");
-  endif
-  switch (s(1).type)
-    case "()"
-      ind = s(1).subs;
-      if (numel (ind) != 1)
-        error ("polynomial: need exactly one index");
-      else
-        b = polyval (fliplr (a.poly), ind{1});
-      endif
-    case "{}"
-      ind = s(1).subs;
-      if (numel (ind) != 1)
-        error ("polynomial: need exactly one index");
-      else
-        if (isnumeric (ind{1}))
-          b = a.poly(ind{1}+1);
-        else
-          b = a.poly(ind{1});
-        endif
-      endif
-    case "."
-      fld = s.subs;
-      if (strcmp (fld, "poly"))
-        b = a.poly;
-      else
-        error ("@polynomial/subsref: invalid property \"%s\"", fld);
-      endif
-    otherwise
-      error ("invalid subscript type");
-  endswitch
-  if (numel (s) > 1)
-    b = subsref (b, s(2:end));
-  endif
-endfunction
--- a/examples/COPYING	Fri Feb 06 08:31:09 2015 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,3 +0,0 @@
-Copyright notices are intentionally omitted from the files in the
-examples directory.  We don't want copyright notices cluttering the
-manual.
--- a/examples/Makefile.am	Fri Feb 06 08:31:09 2015 -0800
+++ b/examples/Makefile.am	Fri Feb 06 08:31:49 2015 -0800
@@ -1,6 +1,6 @@
-# Makefile for Octave's examples directory
+# Makefile for Octave's example directory
 #
-# Copyright (C) 1996-2013 John W. Eaton
+# Copyright (C) 1993-2013 John W. Eaton
 #
 # This file is part of Octave.
 #
@@ -18,47 +18,12 @@
 # along with Octave; see the file COPYING.  If not, see
 # <http://www.gnu.org/licenses/>.
 
+## Pass-through layer.  Simply pass make commands down to SUBDIRS.
+
 include $(top_srcdir)/build-aux/common.mk
 
-EXTRA_DIST =
-
-FCN_FILE_DIRS =
-
-FCN_FILES =
-
-include @polynomial/module.mk
-include @FIRfilter/module.mk
+EXTRA_DIST = \
+  Makefile.am
 
-EXTRA_DIST += \
-  $(FCN_FILES) \
-  addtwomatrices.cc \
-  celldemo.cc \
-  embedded.cc \
-  fortrandemo.cc \
-  fortransub.f \
-  funcdemo.cc \
-  globaldemo.cc \
-  helloworld.cc \
-  make_int.cc \
-  mex_demo.c \
-  mycell.c \
-  myfeval.c \
-  myfevalf.f \
-  myfunc.c \
-  myhello.c \
-  mypow2.c \
-  myprop.c \
-  myset.c \
-  mysparse.c \
-  mystring.c \
-  mystruct.c \
-  oct_demo.cc \
-  oregonator.cc \
-  oregonator.m \
-  paramdemo.cc \
-  standalone.cc \
-  standalonebuiltin.cc \
-  stringdemo.cc \
-  structdemo.cc \
-  unwinddemo.cc
+SUBDIRS = code data
 
--- a/examples/addtwomatrices.cc	Fri Feb 06 08:31:09 2015 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,18 +0,0 @@
-#include <octave/oct.h>
-
-DEFUN_DLD (addtwomatrices, args, , "Add A to B")
-{
-  int nargin = args.length ();
-
-  if (nargin != 2)
-    print_usage ();
-  else
-    {
-      NDArray A = args(0).array_value ();
-      NDArray B = args(1).array_value ();
-      if (! error_state)
-        return octave_value (A + B);
-    }
-
-  return octave_value_list ();
-}
--- a/examples/celldemo.cc	Fri Feb 06 08:31:09 2015 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,23 +0,0 @@
-#include <octave/oct.h>
-#include <octave/Cell.h>
-
-DEFUN_DLD (celldemo, args, , "Cell Demo")
-{
-  octave_value_list retval;
-  int nargin = args.length ();
-
-  if (nargin != 1)
-    print_usage ();
-  else
-    {
-      Cell c = args(0).cell_value ();
-      if (! error_state)
-        for (octave_idx_type i = 0; i < c.numel (); i++)
-          {
-            retval(i) = c(i);          // using operator syntax
-            //retval(i) = c.elem (i);  // using method syntax
-          }
-    }
-
-  return retval;
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/code/@FIRfilter/FIRfilter.m	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,20 @@
+## -*- texinfo -*-
+## @deftypefn  {Function File} {} FIRfilter ()
+## @deftypefnx {Function File} {} FIRfilter (@var{p})
+## Create a FIR filter with polynomial @var{p} as coefficient vector.
+## @end deftypefn
+
+function f = FIRfilter (p)
+
+  f.polynomial = [];
+  if (nargin == 0)
+    p = @polynomial ([1]);
+  elseif (nargin == 1)
+    if (!isa (p, "polynomial"))
+      error ("FIRfilter: expecting polynomial as input argument");
+    endif
+  else
+    print_usage ();
+  endif
+  f = class (f, "FIRfilter", p);
+endfunction
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/code/@FIRfilter/FIRfilter_aggregation.m	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,21 @@
+## -*- texinfo -*-
+## @deftypefn  {Function File} {} FIRfilter ()
+## @deftypefnx {Function File} {} FIRfilter (@var{p})
+## Create a FIR filter with polynomial @var{p} as coefficient vector.
+## @end deftypefn
+
+function f = FIRfilter (p)
+
+  if (nargin == 0)
+    f.polynomial = @polynomial ([1]);
+  elseif (nargin == 1)
+    if (isa (p, "polynomial"))
+      f.polynomial = p;
+    else
+      error ("FIRfilter: expecting polynomial as input argument");
+    endif
+  else
+    print_usage ();
+  endif
+  f = class (f, "FIRfilter");
+endfunction
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/code/@FIRfilter/display.m	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,6 @@
+function display (f)
+
+  display (f.polynomial);
+
+endfunction
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/code/@FIRfilter/module.mk	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,12 @@
+FCN_FILE_DIRS += @FIRfilter
+
+EXTRA_DIST += @FIRfilter/module.mk
+
+at_FIRfilter_FCN_FILES = \
+  @FIRfilter/display.m \
+  @FIRfilter/FIRfilter_aggregation.m \
+  @FIRfilter/FIRfilter.m \
+  @FIRfilter/subsasgn.m \
+  @FIRfilter/subsref.m
+
+FCN_FILES += $(at_FIRfilter_FCN_FILES)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/code/@FIRfilter/subsasgn.m	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,14 @@
+function out = subsasgn (f, index, val)
+  switch (index.type)
+    case "."
+      fld = index.subs;
+      if (strcmp (fld, "polynomial"))
+        out = f;
+        out.polynomial = val;
+      else
+        error ("@FIRfilter/subsref: invalid property \"%s\"", fld);
+      endif
+    otherwise
+      error ("FIRfilter/subsagn: Invalid index type")
+  endswitch
+endfunction
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/code/@FIRfilter/subsref.m	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,16 @@
+function out = subsref (f, x)
+  switch (x.type)
+    case "()"
+      n = f.polynomial;
+      out = filter (n.poly, 1, x.subs{1});
+    case "."
+      fld = x.subs;
+      if (strcmp (fld, "polynomial"))
+        out = f.polynomial;
+      else
+        error ("@FIRfilter/subsref: invalid property \"%s\"", fld);
+      endif
+    otherwise
+      error ("@FIRfilter/subsref: invalid subscript type for FIR filter");
+  endswitch
+endfunction
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/code/@polynomial/display.m	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,32 @@
+function display (p)
+  a = p.poly;
+  first = true;
+  fprintf ("%s =", inputname (1));
+  for i = 1 : length (a);
+    if (a(i) != 0)
+      if (first)
+        first = false;
+      elseif (a(i) > 0)
+        fprintf (" +");
+      endif
+      if (a(i) < 0)
+        fprintf (" -");
+      endif
+      if (i == 1)
+        fprintf (" %g", abs (a(i)));
+      elseif (abs(a(i)) != 1)
+        fprintf (" %g *", abs (a(i)));
+      endif
+      if (i > 1)
+        fprintf (" X");
+      endif
+      if (i > 2)
+        fprintf (" ^ %d", i - 1);
+      endif
+    endif
+  endfor
+  if (first)
+    fprintf (" 0");
+  endif
+  fprintf ("\n");
+endfunction
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/code/@polynomial/double.m	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,3 @@
+function b = double (a)
+  b = a.poly;
+endfunction
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/code/@polynomial/end.m	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,9 @@
+function r = end (obj, index_pos, num_indices)
+
+  if (num_indices != 1)
+    error ("polynomial object may only have one index")
+  endif
+
+  r = length (obj.poly) - 1;
+
+endfunction
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/code/@polynomial/get.m	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,18 @@
+function s = get (p, f)
+  if (nargin == 1)
+    s.poly = p.poly;
+  elseif (nargin == 2)
+    if (ischar (f))
+      switch (f)
+        case "poly"
+          s = p.poly;
+        otherwise
+          error ("get: invalid property %s", f);
+      endswitch
+    else
+      error ("get: expecting the property to be a string");
+    endif
+  else
+    print_usage ();
+  endif
+endfunction
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/code/@polynomial/module.mk	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,21 @@
+FCN_FILE_DIRS += @polynomial
+
+EXTRA_DIST += @polynomial/module.mk
+
+at_polynomial_FCN_FILES = \
+  @polynomial/display.m \
+  @polynomial/double.m \
+  @polynomial/end.m \
+  @polynomial/get.m \
+  @polynomial/mtimes.m \
+  @polynomial/numel.m \
+  @polynomial/plot.m \
+  @polynomial/polynomial.m \
+  @polynomial/polynomial_superiorto.m \
+  @polynomial/polyval.m \
+  @polynomial/roots.m \
+  @polynomial/set.m \
+  @polynomial/subsasgn.m \
+  @polynomial/subsref.m
+
+FCN_FILES += $(at_polynomial_FCN_FILES)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/code/@polynomial/mtimes.m	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,3 @@
+function y = mtimes (a, b)
+  y = polynomial (conv (double (a), double (b)));
+endfunction
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/code/@polynomial/numel.m	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,7 @@
+function n = numel (obj, idx)
+
+  # always produce an array.
+  n = 1;
+
+endfunction
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/code/@polynomial/plot.m	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,10 @@
+function h = plot (p, varargin)
+  n = 128;
+  rmax = max (abs (roots (p.poly)));
+  x = [0 : (n - 1)] / (n - 1) * 2.2 * rmax - 1.1 * rmax;
+  if (nargout > 0)
+    h = plot (x, p(x), varargin{:});
+  else
+    plot (x, p(x), varargin{:});
+  endif
+endfunction
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/code/@polynomial/polynomial.m	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,30 @@
+## -*- texinfo -*-
+## @deftypefn  {Function File} {} polynomial ()
+## @deftypefnx {Function File} {} polynomial (@var{a})
+## Create a polynomial object representing the polynomial
+##
+## @example
+## a0 + a1 * x + a2 * x^2 + @dots{} + an * x^n
+## @end example
+##
+## @noindent
+## from a vector of coefficients [a0 a1 a2 @dots{} an].
+## @end deftypefn
+
+function p = polynomial (a)
+  if (nargin == 0)
+    p.poly = [0];
+    p = class (p, "polynomial");
+  elseif (nargin == 1)
+    if (strcmp (class (a), "polynomial"))
+      p = a;
+    elseif (isvector (a) && isreal (a))
+      p.poly = a(:).';
+      p = class (p, "polynomial");
+    else
+      error ("polynomial: expecting real vector");
+    endif
+  else
+    print_usage ();
+  endif
+endfunction
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/code/@polynomial/polynomial_superiorto.m	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,31 @@
+## -*- texinfo -*-
+## @deftypefn  {Function File} {} polynomial ()
+## @deftypefnx {Function File} {} polynomial (@var{a})
+## Create a polynomial object representing the polynomial
+##
+## @example
+## a0 + a1 * x + a2 * x^2 + @dots{} + an * x^n
+## @end example
+##
+## @noindent
+## from a vector of coefficients [a0 a1 a2 @dots{} an].
+## @end deftypefn
+
+function p = polynomial (a)
+  if (nargin == 0)
+    p.poly = [0];
+    p = class (p, "polynomial");
+  elseif (nargin == 1)
+    if (strcmp (class (a), "polynomial"))
+      p = a;
+    elseif (isvector (a) && isreal (a))
+      p.poly = a(:).';
+      p = class (p, "polynomial");
+    else
+      error ("polynomial: expecting real vector");
+    endif
+  else
+    print_usage ();
+  endif
+  superiorto ("double");
+endfunction
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/code/@polynomial/polyval.m	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,7 @@
+function [y, dy] = polyval (p, varargin)
+  if (nargout == 2)
+    [y, dy] = polyval (fliplr (p.poly), varargin{:});
+  else
+    y = polyval (fliplr (p.poly), varargin{:});
+  endif
+endfunction
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/code/@polynomial/roots.m	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,3 @@
+function y = roots (p)
+  y = roots(fliplr(p.poly));
+endfunction
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/code/@polynomial/set.m	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,20 @@
+function s = set (p, varargin)
+  s = p;
+  if (length (varargin) < 2 || rem (length (varargin), 2) != 0)
+    error ("set: expecting property/value pairs");
+  endif
+  while (length (varargin) > 1)
+    prop = varargin{1};
+    val = varargin{2};
+    varargin(1:2) = [];
+    if (ischar (prop) && strcmp (prop, "poly"))
+      if (isvector (val) && isreal (val))
+        s.poly = val(:).';
+      else
+        error ("set: expecting the value to be a real vector");
+      endif
+    else
+      error ("set: invalid property of polynomial class");
+    endif
+  endwhile
+endfunction
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/code/@polynomial/subsasgn.m	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,35 @@
+function p = subsasgn (p, s, val)
+  if (length (s) < 1)
+    error ("polynomial: needs index");
+  endif
+  switch (s(1).type)
+    case "{}"
+      ind = s(1).subs;
+      if (numel (ind) != 1)
+        error ("polynomial: need exactly one index");
+      else
+        if (length (s) == 1)
+          if (isnumeric (ind{1}))
+            p.poly(ind{1}+1) = val;
+          else
+            p.poly(ind{1}) = val;
+          endif
+        else
+          error ("polynomial: chained subscripts not allowed for {}");
+        endif
+      endif
+    case "."
+      fld = s(1).subs;
+      if (strcmp (fld, "poly"))
+        if (length (s) == 1)
+          p.poly = val;
+        else
+          p.poly = subsasgn (p.poly, s(2:end), val);
+        endif
+      else
+        error ("@polynomial/subsref: invalid property \"%s\"", fld);
+      endif
+    otherwise
+      error ("invalid subscript type");
+  endswitch
+endfunction
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/code/@polynomial/subsref.m	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,37 @@
+function b = subsref (a, s)
+  if (isempty (s))
+    error ("polynomial: missing index");
+  endif
+  switch (s(1).type)
+    case "()"
+      ind = s(1).subs;
+      if (numel (ind) != 1)
+        error ("polynomial: need exactly one index");
+      else
+        b = polyval (fliplr (a.poly), ind{1});
+      endif
+    case "{}"
+      ind = s(1).subs;
+      if (numel (ind) != 1)
+        error ("polynomial: need exactly one index");
+      else
+        if (isnumeric (ind{1}))
+          b = a.poly(ind{1}+1);
+        else
+          b = a.poly(ind{1});
+        endif
+      endif
+    case "."
+      fld = s.subs;
+      if (strcmp (fld, "poly"))
+        b = a.poly;
+      else
+        error ("@polynomial/subsref: invalid property \"%s\"", fld);
+      endif
+    otherwise
+      error ("invalid subscript type");
+  endswitch
+  if (numel (s) > 1)
+    b = subsref (b, s(2:end));
+  endif
+endfunction
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/code/COPYING	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,3 @@
+Copyright notices are intentionally omitted from the files in the
+examples directory.  We don't want copyright notices cluttering the
+manual.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/code/Makefile.am	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,64 @@
+# Makefile for Octave's examples directory
+#
+# 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/>.
+
+include $(top_srcdir)/build-aux/common.mk
+
+EXTRA_DIST =
+
+FCN_FILE_DIRS =
+
+FCN_FILES =
+
+include @polynomial/module.mk
+include @FIRfilter/module.mk
+
+EXTRA_DIST += \
+  $(FCN_FILES) \
+  addtwomatrices.cc \
+  celldemo.cc \
+  embedded.cc \
+  fortrandemo.cc \
+  fortransub.f \
+  funcdemo.cc \
+  globaldemo.cc \
+  helloworld.cc \
+  make_int.cc \
+  mex_demo.c \
+  mycell.c \
+  myfeval.c \
+  myfevalf.f \
+  myfunc.c \
+  myhello.c \
+  mypow2.c \
+  myprop.c \
+  myset.c \
+  mysparse.c \
+  mystring.c \
+  mystruct.c \
+  oct_demo.cc \
+  oregonator.cc \
+  oregonator.m \
+  paramdemo.cc \
+  standalone.cc \
+  standalonebuiltin.cc \
+  stringdemo.cc \
+  structdemo.cc \
+  unwinddemo.cc
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/code/addtwomatrices.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,18 @@
+#include <octave/oct.h>
+
+DEFUN_DLD (addtwomatrices, args, , "Add A to B")
+{
+  int nargin = args.length ();
+
+  if (nargin != 2)
+    print_usage ();
+  else
+    {
+      NDArray A = args(0).array_value ();
+      NDArray B = args(1).array_value ();
+      if (! error_state)
+        return octave_value (A + B);
+    }
+
+  return octave_value_list ();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/code/celldemo.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,23 @@
+#include <octave/oct.h>
+#include <octave/Cell.h>
+
+DEFUN_DLD (celldemo, args, , "Cell Demo")
+{
+  octave_value_list retval;
+  int nargin = args.length ();
+
+  if (nargin != 1)
+    print_usage ();
+  else
+    {
+      Cell c = args(0).cell_value ();
+      if (! error_state)
+        for (octave_idx_type i = 0; i < c.numel (); i++)
+          {
+            retval(i) = c(i);          // using operator syntax
+            //retval(i) = c.elem (i);  // using method syntax
+          }
+    }
+
+  return retval;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/code/embedded.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,35 @@
+#include <iostream>
+#include <octave/oct.h>
+#include <octave/octave.h>
+#include <octave/parse.h>
+#include <octave/toplev.h>
+
+int
+main (void)
+{
+  string_vector argv (2);
+  argv(0) = "embedded";
+  argv(1) = "-q";
+
+  octave_main (2, argv.c_str_vec (), 1);
+
+  octave_idx_type n = 2;
+  octave_value_list in;
+
+  for (octave_idx_type i = 0; i < n; i++)
+    in(i) = octave_value (5 * (i + 2));
+
+  octave_value_list out = feval ("gcd", in, 1);
+
+  if (! error_state && out.length () > 0)
+    std::cout << "GCD of ["
+              << in(0).int_value ()
+              << ", "
+              << in(1).int_value ()
+              << "] is " << out(0).int_value ()
+              << std::endl;
+  else
+    std::cout << "invalid\n";
+
+  clean_up_and_exit (0);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/code/fortrandemo.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,35 @@
+#include <octave/oct.h>
+#include <octave/f77-fcn.h>
+
+extern "C"
+{
+  F77_RET_T
+  F77_FUNC (fortransub, FORTSUB)
+    (const int&, double*, F77_CHAR_ARG_DECL F77_CHAR_ARG_LEN_DECL);
+}
+
+DEFUN_DLD (fortrandemo, args, , "Fortran Demo")
+{
+  octave_value_list retval;
+  int nargin = args.length ();
+
+  if (nargin != 1)
+    print_usage ();
+  else
+    {
+      NDArray a = args(0).array_value ();
+      if (! error_state)
+        {
+          double *av = a.fortran_vec ();
+          octave_idx_type na = a.numel ();
+          OCTAVE_LOCAL_BUFFER (char, ctmp, 128);
+
+          F77_XFCN (fortransub, FORTSUB,
+                    (na, av, ctmp F77_CHAR_ARG_LEN (128)));
+
+          retval(1) = std::string (ctmp);
+          retval(0) = a;
+        }
+    }
+  return retval;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/code/fortransub.f	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,21 @@
+      subroutine fortransub (n, a, s)
+      implicit none
+      character*(*) s
+      real*8 a(*)
+      integer*4 i, n, ioerr
+      do i = 1, n
+        if (a(i) .eq. 0d0) then
+          call xstopx ('fortransub: divide by zero')
+        else
+          a(i) = 1d0 / a(i)
+        endif
+      enddo
+      write (unit = s, fmt = '(a,i3,a,a)', iostat = ioerr)
+     $       'There are ', n,
+     $       ' values in the input vector', char(0)
+      if (ioerr .ne. 0) then
+        call xstopx ('fortransub: error writing string')
+      endif
+      return
+      end
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/code/funcdemo.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,32 @@
+#include <octave/oct.h>
+#include <octave/parse.h>
+
+DEFUN_DLD (funcdemo, args, nargout, "Function Demo")
+{
+  octave_value_list retval;
+  int nargin = args.length ();
+
+  if (nargin < 2)
+    print_usage ();
+  else
+    {
+      octave_value_list newargs;
+      for (octave_idx_type i = nargin - 1; i > 0; i--)
+        newargs(i-1) = args(i);
+      if (args(0).is_function_handle () || args(0).is_inline_function ())
+        {
+          octave_function *fcn = args(0).function_value ();
+          if (! error_state)
+            retval = feval (fcn, newargs, nargout);
+        }
+      else if (args(0).is_string ())
+        {
+          std::string fcn = args(0).string_value ();
+          if (! error_state)
+            retval = feval (fcn, newargs, nargout);
+        }
+      else
+        error ("funcdemo: INPUT must be string, inline, or function handle");
+    }
+  return retval;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/code/globaldemo.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,25 @@
+#include <octave/oct.h>
+
+DEFUN_DLD (globaldemo, args, , "Global Demo")
+{
+  octave_value retval;
+  int nargin = args.length ();
+
+  if (nargin != 1)
+    print_usage ();
+  else
+    {
+      std::string s = args(0).string_value ();
+      if (! error_state)
+        {
+          octave_value tmp = get_global_value (s, true);
+          if (tmp.is_defined ())
+            retval = tmp;
+          else
+            retval = "Global variable not found";
+
+          set_global_value ("a", 42.0);
+        }
+    }
+  return retval;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/code/helloworld.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,13 @@
+#include <octave/oct.h>
+
+DEFUN_DLD (helloworld, args, nargout,
+           "Hello World Help String")
+{
+  int nargin = args.length ();
+
+  octave_stdout << "Hello World has "
+                << nargin << " input arguments and "
+                << nargout << " output arguments.\n";
+
+  return octave_value_list ();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/code/make_int.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,314 @@
+#include <octave/config.h>
+
+#include <cstdlib>
+
+#include <string>
+
+#include <ostream>
+
+#include <octave/lo-mappers.h>
+#include <octave/lo-utils.h>
+#include <octave/mx-base.h>
+#include <octave/str-vec.h>
+
+#include <octave/defun-dld.h>
+#include <octave/error.h>
+#include <octave/gripes.h>
+#include <octave/oct-obj.h>
+#include <octave/ops.h>
+#include <octave/ov-base.h>
+#include <octave/ov-typeinfo.h>
+#include <octave/ov.h>
+#include <octave/ov-scalar.h>
+#include <octave/pager.h>
+#include <octave/pr-output.h>
+#include <octave/symtab.h>
+#include <octave/variables.h>
+
+class octave_value_list;
+
+class tree_walker;
+
+// Integer values.
+
+class
+octave_integer : public octave_base_value
+{
+public:
+
+  octave_integer (void)
+    : octave_base_value (), scalar (0) { }
+
+  octave_integer (int i)
+    : octave_base_value (), scalar (i) { }
+
+  octave_integer (const octave_integer& s)
+    : octave_base_value (), scalar (s.scalar) { }
+
+  ~octave_integer (void) { }
+
+  octave_base_value *clone (void) { return new octave_integer (*this); }
+
+#if 0
+  void *operator new (size_t size);
+  void operator delete (void *p, size_t size);
+#endif
+
+  idx_vector index_vector (void) const { return idx_vector ((double) scalar); }
+
+  int rows (void) const { return 1; }
+  int columns (void) const { return 1; }
+
+  bool is_constant (void) const { return true; }
+
+  bool is_defined (void) const { return true; }
+  bool is_real_scalar (void) const { return true; }
+
+  octave_value all (void) const { return (double) (scalar != 0); }
+  octave_value any (void) const { return (double) (scalar != 0); }
+
+  bool is_real_type (void) const { return true; }
+  bool is_scalar_type (void) const { return true; }
+  bool is_numeric_type (void) const { return true; }
+
+  bool valid_as_scalar_index (void) const
+  { return scalar == 1; }
+
+  bool valid_as_zero_index (void) const
+  { return scalar == 0; }
+
+  bool is_true (void) const { return (scalar != 0); }
+
+  double double_value (bool = false) const { return (double) scalar; }
+
+  int integer_value (bool = false) const { return scalar; }
+
+  Matrix matrix_value (bool = false) const { return Matrix (1, 1, scalar); }
+
+  Complex complex_value (bool = false) const { return scalar; }
+
+  ComplexMatrix complex_matrix_value (bool = false) const
+  { return  ComplexMatrix (1, 1, Complex (scalar)); }
+
+  octave_value gnot (void) const { return octave_value ((double) ! scalar); }
+
+  octave_value uminus (void) const { return new octave_integer (- scalar); }
+
+  octave_value transpose (void) const { return new octave_integer (scalar); }
+
+  octave_value hermitian (void) const { return new octave_integer (scalar); }
+
+  void increment (void) { ++scalar; }
+
+  void decrement (void) { --scalar; }
+
+  void print (std::ostream& os, bool pr_as_read_syntax = false) const;
+
+private:
+
+  int scalar;
+
+
+  DECLARE_OV_TYPEID_FUNCTIONS_AND_DATA
+};
+
+void
+octave_integer::print (std::ostream& os, bool pr_as_read_syntax) const
+{
+  os << scalar;
+  // octave_print_internal (os, scalar, pr_as_read_syntax);
+}
+
+#ifdef DEFUNOP_OP
+#undef DEFUNOP_OP
+#endif
+
+#define DEFUNOP_OP(name, t, op) \
+  UNOPDECL (name, a) \
+  { \
+    CAST_UNOP_ARG (const octave_ ## t&); \
+    return octave_value (new octave_integer (op v.t ## _value ())); \
+  }
+
+DEFUNOP_OP (gnot, integer, !)
+DEFUNOP_OP (uminus, integer, -)
+DEFUNOP_OP (transpose, integer, /* no-op */)
+DEFUNOP_OP (hermitian, integer, /* no-op */)
+
+DEFNCUNOP_METHOD (incr, integer, increment)
+DEFNCUNOP_METHOD (decr, integer, decrement)
+
+#ifdef DEFBINOP_OP
+#undef DEFBINOP_OP
+#endif
+
+#define DEFBINOP_OP(name, t1, t2, op) \
+  BINOPDECL (name, a1, a2) \
+  { \
+    CAST_BINOP_ARGS (const octave_ ## t1&, const octave_ ## t2&); \
+    return octave_value \
+      (new octave_integer (v1.t1 ## _value () op v2.t2 ## _value ())); \
+  }
+
+// integer by integer ops.
+
+DEFBINOP_OP (add, integer, integer, +)
+DEFBINOP_OP (sub, integer, integer, -)
+DEFBINOP_OP (mul, integer, integer, *)
+
+DEFBINOP (div, integer, integer)
+{
+  CAST_BINOP_ARGS (const octave_integer&, const octave_integer&);
+
+  int d = v2.integer_value ();
+
+  if (d == 0)
+    gripe_divide_by_zero ();
+
+  return new octave_integer (v1.integer_value () / d);
+}
+
+
+DEFBINOP (i_s_div, integer, scalar)
+{
+  CAST_BINOP_ARGS (const octave_integer&, const octave_scalar&);
+
+  double d = v2.double_value ();
+
+  if (d == 0.0)
+    gripe_divide_by_zero ();
+
+  return new octave_scalar (v1.double_value () / d);
+}
+
+DEFBINOP (ldiv, integer, integer)
+{
+  CAST_BINOP_ARGS (const octave_integer&, const octave_integer&);
+
+  int d = v1.integer_value ();
+
+  if (d == 0)
+    gripe_divide_by_zero ();
+
+  return new octave_integer (v2.integer_value () / d);
+}
+
+DEFBINOP_OP (lt, integer, integer, <)
+DEFBINOP_OP (le, integer, integer, <=)
+DEFBINOP_OP (eq, integer, integer, ==)
+DEFBINOP_OP (ge, integer, integer, >=)
+DEFBINOP_OP (gt, integer, integer, >)
+DEFBINOP_OP (ne, integer, integer, !=)
+
+DEFBINOP_OP (el_mul, integer, integer, !=)
+
+DEFBINOP (el_div, integer, integer)
+{
+  CAST_BINOP_ARGS (const octave_integer&, const octave_integer&);
+
+  int d = v2.integer_value ();
+
+  if (d == 0)
+    gripe_divide_by_zero ();
+
+  return new octave_integer (v1.integer_value () / d);
+}
+
+DEFBINOP (el_ldiv, integer, integer)
+{
+  CAST_BINOP_ARGS (const octave_integer&, const octave_integer&);
+
+  int d = v1.integer_value ();
+
+  if (d == 0)
+    gripe_divide_by_zero ();
+
+  return new octave_integer (v2.integer_value () / d);
+}
+
+DEFBINOP_OP (el_and, integer, integer, &&)
+DEFBINOP_OP (el_or, integer, integer, ||)
+
+DEFUN_DLD (make_int, args, ,
+           "int_val = make_int (val)\n\
+\n\
+Creates an integer variable from VAL.")
+{
+  static bool type_loaded = false;
+
+  if (! type_loaded)
+    {
+      octave_integer::register_type ();
+      mlock ();
+
+      octave_stdout << "installing integer type at type-id = "
+                    << octave_integer::static_type_id () << "\n";
+
+      INSTALL_UNOP (op_not, octave_integer, gnot);
+      INSTALL_UNOP (op_uminus, octave_integer, uminus);
+      INSTALL_UNOP (op_transpose, octave_integer, transpose);
+      INSTALL_UNOP (op_hermitian, octave_integer, hermitian);
+
+      INSTALL_NCUNOP (op_incr, octave_integer, incr);
+      INSTALL_NCUNOP (op_decr, octave_integer, decr);
+
+      INSTALL_BINOP (op_add, octave_integer, octave_integer, add);
+      INSTALL_BINOP (op_sub, octave_integer, octave_integer, sub);
+      INSTALL_BINOP (op_mul, octave_integer, octave_integer, mul);
+      INSTALL_BINOP (op_div, octave_integer, octave_integer, div);
+      INSTALL_BINOP (op_ldiv, octave_integer, octave_integer, ldiv);
+      INSTALL_BINOP (op_lt, octave_integer, octave_integer, lt);
+      INSTALL_BINOP (op_le, octave_integer, octave_integer, le);
+      INSTALL_BINOP (op_eq, octave_integer, octave_integer, eq);
+      INSTALL_BINOP (op_ge, octave_integer, octave_integer, ge);
+      INSTALL_BINOP (op_gt, octave_integer, octave_integer, gt);
+      INSTALL_BINOP (op_ne, octave_integer, octave_integer, ne);
+      INSTALL_BINOP (op_el_mul, octave_integer, octave_integer, el_mul);
+      INSTALL_BINOP (op_el_div, octave_integer, octave_integer, el_div);
+      INSTALL_BINOP (op_el_ldiv, octave_integer, octave_integer, el_ldiv);
+      INSTALL_BINOP (op_el_and, octave_integer, octave_integer, el_and);
+      INSTALL_BINOP (op_el_or, octave_integer, octave_integer, el_or);
+
+      INSTALL_BINOP (op_div, octave_integer, octave_scalar, i_s_div);
+    }
+
+  octave_value retval;
+
+  if (args.length () == 1)
+    {
+      double d = args(0).double_value ();
+
+      if (! error_state)
+        retval = octave_value (new octave_integer (NINT (d)));
+    }
+  else
+    usage ("make_int");
+
+  return retval;
+}
+
+DEFUN_DLD (doit, args, ,
+           "doit (I)")
+{
+  octave_value_list retval;
+
+  if (args(0).type_id () == octave_integer::static_type_id ())
+    {
+      // At this point, we know we have a handle for an octave_integer
+      // object, so we can peek at the representation and extract the
+      // data.
+
+      const octave_base_value& rep = args(0).get_rep ();
+
+      int my_value = ((const octave_integer&) rep) . integer_value ();
+
+      message ("doit", "your lucky number is: %d", my_value);
+    }
+  else
+    gripe_wrong_type_arg ("doit", args(0));
+
+  return retval;
+}
+
+
+DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA (octave_integer, "integer", "integer");
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/code/mex_demo.c	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,58 @@
+// mex_demo.c -- example of a dynamically linked function for Octave.
+
+// To use this file, your version of Octave must support dynamic
+// linking.  To find out if it does, type the command
+//
+//   octave_config_info ("ENABLE_DYNAMIC_LINKING")
+//
+// at the Octave prompt.  Support for dynamic linking is included if
+// this expression returns the string "yes".
+//
+// To compile this file, type the command
+//
+//   mkoctfile --mex mex_demo.c
+//
+// from within Octave or from the shell prompt.  This will create a file
+// called mex_demo.mex that can be loaded by Octave.  To test the mex_demo.mex
+// file, start Octave and type the command
+//
+// d = mex_demo ("easy as", 1, 2, 3)
+//
+// at the Octave prompt.  Octave should respond by printing
+//
+//   Hello, world!
+//   I have 4 inputs and 1 output
+//   d =  1.2346
+
+// Additional samples of code are in the examples directory of the Octave
+// distribution.  See also the chapter External Code Interface in the
+// documentation.
+
+#include "mex.h"
+
+// Every user function should include "mex.h" which imports the basic set of
+// function prototypes necessary for dynamically linked functions.  In
+// particular, it will declare mexFunction which is used by every function
+// which will be visible to Octave.  A mexFunction is visible in Octave under
+// the name of the source code file without the extension.
+
+// The four arguments to mexFunction are:
+// 1) The number of return arguments (# of left-hand side args).
+// 2) An array of pointers to return arguments.
+// 3) The number of input arguments (# of right-hand side args).
+// 4) An array of pointers to input arguments.
+
+void
+mexFunction (int nlhs, mxArray *plhs[],
+             int nrhs, const mxArray *prhs[])
+{
+  mexPrintf ("Hello, World!\n");
+
+  mexPrintf ("I have %d inputs and %d outputs\n", nrhs, nlhs);
+
+  mxArray *v = mxCreateDoubleMatrix (1, 1, mxREAL);
+  double *data = mxGetPr (v);
+  *data = 1.23456789;
+
+  plhs[0] = v;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/code/mycell.c	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,18 @@
+#include "mex.h"
+
+void
+mexFunction (int nlhs, mxArray* plhs[],
+             int nrhs, const mxArray* prhs[])
+{
+  mwSize n;
+  mwIndex i;
+
+  if (nrhs != 1 || ! mxIsCell (prhs[0]))
+    mexErrMsgTxt ("ARG1 must be a cell");
+
+  n = mxGetNumberOfElements (prhs[0]);
+  n = (n > nlhs ? nlhs : n);
+
+  for (i = 0; i < n; i++)
+    plhs[i] = mxDuplicateArray (mxGetCell (prhs[0], i));
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/code/myfeval.c	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,27 @@
+#include "mex.h"
+
+void
+mexFunction (int nlhs, mxArray* plhs[],
+             int nrhs, const mxArray* prhs[])
+{
+  char *str;
+
+  mexPrintf ("Starting file myfeval.mex\n");
+
+  mexPrintf ("I have %d inputs and %d outputs\n", nrhs, nlhs);
+
+  if (nrhs < 1 || ! mxIsString (prhs[0]))
+    mexErrMsgTxt ("ARG1 must be a function name");
+
+  str = mxArrayToString (prhs[0]);
+
+  mexPrintf ("I'm going to call the function %s\n", str);
+
+  if (nlhs == 0)
+    nlhs = 1;  // Octave's automatic 'ans' variable
+
+  /* Cast prhs just to get rid of 'const' qualifier and stop compile warning */
+  mexCallMATLAB (nlhs, plhs, nrhs-1, (mxArray**)prhs+1, str);
+
+  mxFree (str);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/code/myfevalf.f	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,30 @@
+      subroutine mexFunction (nlhs, plhs, nrhs, prhs)
+
+      implicit none
+
+      integer*4 nlhs, nrhs
+
+* The following will need to be integer*8 on 64-bit systems, otherwise
+* these variables won't be large enough to hold pointers...
+      integer*4 plhs(*), prhs(*)
+
+      integer*4 mxIsString, mxGetString, mxGetN, mexCallMATLAB
+      integer*4 status, len
+      character*100 str
+
+      call mexPrintf ('Hello, World!')
+
+      if (nrhs .lt. 1 .or. mxIsString (prhs(1)) .ne. 1) then
+        call mexErrMsgTxt ('function name expected')
+      endif
+
+      len = mxGetN (prhs(1))
+
+      status = mxGetString (prhs(1), str, 100)
+
+      call mexPrintf ('FORTRAN will call the interpreter now')
+
+      status = mexCallMATLAB (nlhs, plhs, nrhs-1, prhs(2), str(1:len))
+
+      return
+      end
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/code/myfunc.c	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,15 @@
+#include "mex.h"
+
+void
+mexFunction (int nlhs, mxArray *plhs[],
+             int nrhs, const mxArray *prhs[])
+{
+  const char *nm;
+
+  nm = mexFunctionName ();
+  mexPrintf ("You called function: %s\n", nm);
+  if (strcmp (nm, "myfunc") == 0)
+    mexPrintf ("This is the principal function\n", nm);
+
+  return;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/code/myhello.c	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,10 @@
+#include "mex.h"
+
+void
+mexFunction (int nlhs, mxArray *plhs[],
+             int nrhs, const mxArray *prhs[])
+{
+  mexPrintf ("Hello, World!\n");
+
+  mexPrintf ("I have %d inputs and %d outputs\n", nrhs, nlhs);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/code/mypow2.c	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,39 @@
+#include "mex.h"
+
+void
+mexFunction (int nlhs, mxArray* plhs[],
+             int nrhs, const mxArray* prhs[])
+{
+  mwSize n;
+  mwIndex i;
+  double *vri, *vro;
+
+  if (nrhs != 1 || ! mxIsNumeric (prhs[0]))
+    mexErrMsgTxt ("ARG1 must be a matrix");
+
+  n = mxGetNumberOfElements (prhs[0]);
+  plhs[0] = mxCreateNumericArray (mxGetNumberOfDimensions (prhs[0]),
+                                  mxGetDimensions (prhs[0]),
+                                  mxGetClassID (prhs[0]),
+                                  mxIsComplex (prhs[0]));
+  vri = mxGetPr (prhs[0]);
+  vro = mxGetPr (plhs[0]);
+
+  if (mxIsComplex (prhs[0]))
+    {
+      double *vii, *vio;
+      vii = mxGetPi (prhs[0]);
+      vio = mxGetPi (plhs[0]);
+
+      for (i = 0; i < n; i++)
+        {
+          vro[i] = vri[i] * vri[i] - vii[i] * vii[i];
+          vio[i] = 2 * vri[i] * vii[i];
+        }
+    }
+  else
+    {
+      for (i = 0; i < n; i++)
+        vro[i] = vri[i] * vri[i];
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/code/myprop.c	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,24 @@
+#include "mex.h"
+
+void
+mexFunction (int nlhs, mxArray* plhs[],
+             int nrhs, const mxArray* prhs[])
+{
+  double handle;
+  char property[256];
+
+  if (nrhs < 2 || nrhs > 3)
+    mexErrMsgTxt ("incorrect number of arguments");
+  if (!mxIsDouble (prhs[0]))
+    mexErrMsgTxt ("handle expected to be a double scalar");
+  if (!mxIsChar (prhs[1]))
+    mexErrMsgTxt ("expected property to be a string");
+
+  handle = mxGetScalar (prhs[0]);
+  mxGetString (prhs[1], property, 256);
+  plhs[0] = mxDuplicateArray (mexGet (handle, property));
+
+  if (nrhs == 3)
+    if (mexSet (handle, property, mxDuplicateArray (prhs[2])))
+      mexErrMsgTxt ("failed to set property");
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/code/myset.c	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,34 @@
+#include "mex.h"
+
+void
+mexFunction (int nlhs, mxArray* plhs[],
+             int nrhs, const mxArray* prhs[])
+{
+  char *str;
+  mxArray *v;
+
+  if (nrhs != 2 || ! mxIsString (prhs[0]))
+    mexErrMsgTxt ("expects symbol name and value");
+
+  str = mxArrayToString (prhs[0]);
+
+  v = mexGetArray (str, "global");
+
+  if (v)
+    {
+      mexPrintf ("%s is a global variable with the following value:\n", str);
+      mexCallMATLAB (0, NULL, 1, &v, "disp");
+    }
+
+  v = mexGetArray (str, "caller");
+
+  if (v)
+    {
+      mexPrintf ("%s is a caller variable with the following value:\n", str);
+      mexCallMATLAB (0, NULL, 1, &v, "disp");
+    }
+
+  // WARNING!! Can't do this in MATLAB!  Must copy variable first.
+  mxSetName (prhs[1], str);
+  mexPutArray (prhs[1], "caller");
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/code/mysparse.c	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,117 @@
+#include "mex.h"
+
+void
+mexFunction (int nlhs, mxArray *plhs[],
+             int nrhs, const mxArray *prhs[])
+{
+  mwSize m, n, nz;
+  mxArray *v;
+  mwIndex i;
+  double *pr, *pi;
+  double *pr2, *pi2;
+  mwIndex *ir, *jc;
+  mwIndex *ir2, *jc2;
+
+  if (nrhs != 1 || ! mxIsSparse (prhs[0]))
+    mexErrMsgTxt ("ARG1 must be a sparse matrix");
+
+  m = mxGetM (prhs[0]);
+  n = mxGetN (prhs[0]);
+  nz = mxGetNzmax (prhs[0]);
+
+  if (mxIsComplex (prhs[0]))
+    {
+      mexPrintf ("Matrix is %d-by-%d complex sparse matrix", m, n);
+      mexPrintf (" with %d elements\n", nz);
+
+      pr = mxGetPr (prhs[0]);
+      pi = mxGetPi (prhs[0]);
+      ir = mxGetIr (prhs[0]);
+      jc = mxGetJc (prhs[0]);
+
+      i = n;
+      while (jc[i] == jc[i-1] && i != 0) i--;
+
+      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);
+      pr2 = mxGetPr (v);
+      pi2 = mxGetPi (v);
+      ir2 = mxGetIr (v);
+      jc2 = mxGetJc (v);
+
+      for (i = 0; i < nz; i++)
+        {
+          pr2[i] = 2 * pr[i];
+          pi2[i] = 2 * pi[i];
+          ir2[i] = ir[i];
+        }
+      for (i = 0; i < n + 1; i++)
+        jc2[i] = jc[i];
+
+      if (nlhs > 0)
+        plhs[0] = v;
+    }
+  else if (mxIsLogical (prhs[0]))
+    {
+      mxLogical *pbr, *pbr2;
+      mexPrintf ("Matrix is %d-by-%d logical sparse matrix", m, n);
+      mexPrintf (" with %d elements\n", nz);
+
+      pbr = mxGetLogicals (prhs[0]);
+      ir = mxGetIr (prhs[0]);
+      jc = mxGetJc (prhs[0]);
+
+      i = n;
+      while (jc[i] == jc[i-1] && i != 0) i--;
+      mexPrintf ("last nonzero element (%d, %d) = %d\n",
+                 ir[nz-1]+ 1, i, pbr[nz-1]);
+
+      v = mxCreateSparseLogicalMatrix (m, n, nz);
+      pbr2 = mxGetLogicals (v);
+      ir2 = mxGetIr (v);
+      jc2 = mxGetJc (v);
+
+      for (i = 0; i < nz; i++)
+        {
+          pbr2[i] = pbr[i];
+          ir2[i] = ir[i];
+        }
+      for (i = 0; i < n + 1; i++)
+        jc2[i] = jc[i];
+
+      if (nlhs > 0)
+        plhs[0] = v;
+    }
+  else
+    {
+      mexPrintf ("Matrix is %d-by-%d real sparse matrix", m, n);
+      mexPrintf (" with %d elements\n", nz);
+
+      pr = mxGetPr (prhs[0]);
+      ir = mxGetIr (prhs[0]);
+      jc = mxGetJc (prhs[0]);
+
+      i = n;
+      while (jc[i] == jc[i-1] && i != 0) i--;
+      mexPrintf ("last nonzero element (%d, %d) = %g\n",
+                 ir[nz-1]+ 1, i, pr[nz-1]);
+
+      v = mxCreateSparse (m, n, nz, mxREAL);
+      pr2 = mxGetPr (v);
+      ir2 = mxGetIr (v);
+      jc2 = mxGetJc (v);
+
+      for (i = 0; i < nz; i++)
+        {
+          pr2[i] = 2 * pr[i];
+          ir2[i] = ir[i];
+        }
+      for (i = 0; i < n + 1; i++)
+        jc2[i] = jc[i];
+
+      if (nlhs > 0)
+        plhs[0] = v;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/code/mystring.c	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,25 @@
+#include <string.h>
+#include "mex.h"
+
+void
+mexFunction (int nlhs, mxArray *plhs[],
+             int nrhs, const mxArray *prhs[])
+{
+  mwSize m, n;
+  mwIndex i, j;
+  mxChar *pi, *po;
+
+  if (nrhs != 1 || ! mxIsChar (prhs[0])
+      || mxGetNumberOfDimensions (prhs[0]) > 2)
+    mexErrMsgTxt ("ARG1 must be a char matrix");
+
+  m = mxGetM (prhs[0]);
+  n = mxGetN (prhs[0]);
+  pi = mxGetChars (prhs[0]);
+  plhs[0] = mxCreateNumericMatrix (m, n, mxCHAR_CLASS, mxREAL);
+  po = mxGetChars (plhs[0]);
+
+  for (j = 0; j < n; j++)
+    for (i = 0; i < m; i++)
+      po[j*m + m - 1 - i] = pi[j*m + i];
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/code/mystruct.c	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,36 @@
+#include "mex.h"
+
+void
+mexFunction (int nlhs, mxArray* plhs[],
+             int nrhs, const mxArray* prhs[])
+{
+  int i;
+  mwIndex j;
+  mxArray *v;
+  const char *keys[] = { "this", "that" };
+
+  if (nrhs != 1 || ! mxIsStruct (prhs[0]))
+    mexErrMsgTxt ("expects struct");
+
+  for (i = 0; i < mxGetNumberOfFields (prhs[0]); i++)
+    for (j = 0; j < mxGetNumberOfElements (prhs[0]); j++)
+      {
+        mexPrintf ("field %s(%d) = ", mxGetFieldNameByNumber (prhs[0], i), j);
+        v = mxGetFieldByNumber (prhs[0], j, i);
+        mexCallMATLAB (0, NULL, 1, &v, "disp");
+      }
+
+  v = mxCreateStructMatrix (2, 2, 2, keys);
+
+  mxSetFieldByNumber (v, 0, 0, mxCreateString ("this1"));
+  mxSetFieldByNumber (v, 0, 1, mxCreateString ("that1"));
+  mxSetFieldByNumber (v, 1, 0, mxCreateString ("this2"));
+  mxSetFieldByNumber (v, 1, 1, mxCreateString ("that2"));
+  mxSetFieldByNumber (v, 2, 0, mxCreateString ("this3"));
+  mxSetFieldByNumber (v, 2, 1, mxCreateString ("that3"));
+  mxSetFieldByNumber (v, 3, 0, mxCreateString ("this4"));
+  mxSetFieldByNumber (v, 3, 1, mxCreateString ("that4"));
+
+  if (nlhs)
+    plhs[0] = v;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/code/oct_demo.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,84 @@
+// oct_demo.cc -- example of a dynamically linked function for Octave.
+
+// To use this file, your version of Octave must support dynamic
+// linking.  To find out if it does, type the command
+//
+//   octave_config_info ("ENABLE_DYNAMIC_LINKING")
+//
+// at the Octave prompt.  Support for dynamic linking is included if
+// this expression returns the string "yes".
+//
+// To compile this file, type the command
+//
+//   mkoctfile oct_demo.cc
+//
+// from within Octave or from the shell prompt.  This will create a file
+// called oct_demo.oct that can be loaded by Octave.  To test the
+// oct_demo.oct file, start Octave and type the command
+//
+//   oct_demo ("easy as", 1, 2, 3)
+//
+// at the Octave prompt.  Octave should respond by printing
+//
+//   Hello, world!
+//   easy as
+//   1
+//   2
+//   3
+//   ans = 3
+
+// Additional samples of real dynamically loaded functions are available in
+// the files of the libinterp/dldfcn directory of the Octave distribution.
+// See also the chapter External Code Interface in the documentation.
+
+#include <iostream>
+
+#include <octave/oct.h>
+
+// Every user function should include <octave/oct.h> which imports the
+// basic set of Octave header files required.  In particular this will define
+// the DEFUN_DLD macro (defun-dld.h) which is used for every user function
+// that is visible to Octave.
+
+// The four arguments to the DEFUN_DLD macro are:
+// 1) The function name as seen in Octave.
+// 2) The variable to hold any inputs (of type octave_value_list)
+// 3) The number of output arguments
+// 4) A string to use as help text if 'help <function_name>' is entered.
+//
+// Note below that the third parameter (nargout) of DEFUN_DLD is not used,
+// so it is omitted from the list of arguments in order to avoid a warning
+// from gcc about an unused function parameter.
+
+DEFUN_DLD (oct_demo, args, ,
+           "[...] = oct_demo (...)\n\
+\n\
+Print a greeting followed by the values of all the arguments passed.\n\
+Return all arguments in reverse order.")
+{
+  // The list of values to return.  See the declaration in oct-obj.h
+
+  octave_value_list retval;
+
+  // This stream is normally connected to the pager.
+
+  octave_stdout << "Hello, world!\n";
+
+  // The inputs to this function are available in args.
+
+  int nargin = args.length ();
+
+  // The octave_value_list class is a zero-based array of octave_value objects.
+  // The declaration for the octave_value class is in the file ov.h.
+  // The print() method will send its output to octave_stdout,
+  // so it will also end up going through the pager.
+
+  for (int i = 0; i < nargin; i++)
+    {
+      octave_value tmp = args(i);
+      tmp.print (octave_stdout);
+      retval(nargin-i-1) = tmp;
+    }
+
+  return retval;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/code/oregonator.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,22 @@
+#include <octave/oct.h>
+
+DEFUN_DLD (oregonator, args, ,
+           "The `oregonator'.\n\
+\n\
+Reference:\n\
+\n\
+  Oscillations in chemical systems.  IV.  Limit cycle behavior in a\n\
+  model of a real chemical reaction. Richard J. Field and Richard\n\
+  M. Noyes, The Journal of Chemical Physics, Volume 60 Number 5,\n\
+  March 1974.")
+{
+  ColumnVector dx (3);
+
+  ColumnVector x (args(0).vector_value ());
+
+  dx(0) = 77.27 * (x(1) - x(0)*x(1) + x(0) - 8.375e-06*pow (x(0), 2.0));
+  dx(1) = (x(2) - x(0)*x(1) - x(1)) / 77.27;
+  dx(2) = 0.161*(x(0) - x(2));
+
+  return octave_value (dx);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/code/oregonator.m	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,18 @@
+## The `oregonator'.
+##
+## Reference:
+##
+##   Oscillations in chemical systems.  IV.  Limit cycle behavior in a
+##   model of a real chemical reaction. Richard J. Field and Richard
+##   M. Noyes, The Journal of Chemical Physics, Volume 60 Number 5,
+##   March 1974.
+
+function dx = oregonator (x, t)
+
+  dx = zeros (3, 1);
+
+  dx(1) = 77.27*(x(2) - x(1)*x(2) + x(1) - 8.375e-06*x(1)^2);
+  dx(2) = (x(3) - x(1)*x(2) - x(2)) / 77.27;
+  dx(3) = 0.161*(x(1) - x(3));
+
+end
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/code/paramdemo.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,30 @@
+#include <octave/oct.h>
+
+DEFUN_DLD (paramdemo, args, nargout, "Parameter Check Demo")
+{
+  octave_value retval;
+  int nargin = args.length ();
+
+  if (nargin != 1)
+    print_usage ();
+  else if (nargout != 0)
+    error ("paramdemo: OUTPUT argument required");
+  else
+    {
+      NDArray m = args(0).array_value ();
+      double min_val = -10.0;
+      double max_val = 10.0;
+      octave_stdout << "Properties of input array:\n";
+      if (m.any_element_is_negative ())
+        octave_stdout << "  includes negative values\n";
+      if (m.any_element_is_inf_or_nan ())
+        octave_stdout << "  includes Inf or NaN values\n";
+      if (m.any_element_not_one_or_zero ())
+        octave_stdout << "  includes other values than 1 and 0\n";
+      if (m.all_elements_are_int_or_inf_or_nan ())
+        octave_stdout << "  includes only int, Inf or NaN values\n";
+      if (m.all_integers (min_val, max_val))
+        octave_stdout << "  includes only integers in [-10,10]\n";
+    }
+  return retval;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/code/standalone.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,19 @@
+#include <iostream>
+#include <octave/oct.h>
+
+int
+main (void)
+{
+  std::cout << "Hello Octave world!\n";
+
+  int n = 2;
+  Matrix a_matrix = Matrix (n, n);
+
+  for (octave_idx_type i = 0; i < n; i++)
+    for (octave_idx_type j = 0; j < n; j++)
+      a_matrix(i,j) = (i + 1) * 10 + (j + 1);
+
+  std::cout << a_matrix;
+
+  return 0;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/code/standalonebuiltin.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,28 @@
+#include <iostream>
+#include <octave/oct.h>
+#include <octave/builtin-defun-decls.h>
+
+int
+main (void)
+{
+  int n = 2;
+  Matrix a_matrix = Matrix (n, n);
+
+  for (octave_idx_type i = 0; i < n; i++)
+    for (octave_idx_type j = 0; j < n; j++)
+      a_matrix(i,j) = (i + 1) * 10 + (j + 1);
+
+  std::cout << "This is a matrix:" << std::endl
+            << a_matrix            << std::endl;
+
+  octave_value_list in;
+  in(0) = a_matrix;
+
+  octave_value_list out = Fnorm (in, 1);
+  double norm_of_the_matrix = out(0).double_value ();
+
+  std::cout << "This is the norm of the matrix:" << std::endl
+            << norm_of_the_matrix                << std::endl;
+
+  return 0;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/code/stringdemo.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,29 @@
+#include <octave/oct.h>
+
+DEFUN_DLD (stringdemo, args, , "String Demo")
+{
+  octave_value_list retval;
+  int nargin = args.length ();
+
+  if (nargin != 1)
+    print_usage ();
+  else
+    {
+      charMatrix ch = args(0).char_matrix_value ();
+
+      if (! error_state)
+        {
+          retval(1) = octave_value (ch, '\'');  // Single Quote String
+
+          octave_idx_type nr = ch.rows ();
+          for (octave_idx_type i = 0; i < nr / 2; i++)
+            {
+              std::string tmp = ch.row_as_string (i);
+              ch.insert (ch.row_as_string (nr-i-1).c_str (), i, 0);
+              ch.insert (tmp.c_str (), nr-i-1, 0);
+            }
+          retval(0) = octave_value (ch, '"');  // Double Quote String
+        }
+    }
+  return retval;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/code/structdemo.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,45 @@
+#include <octave/oct.h>
+#include <octave/ov-struct.h>
+
+DEFUN_DLD (structdemo, args, , "Struct Demo")
+{
+  octave_value retval;
+  int nargin = args.length ();
+
+  if (args.length () == 2)
+    {
+      octave_scalar_map arg0 = args(0).scalar_map_value ();
+      //octave_map arg0 = args(0).map_value ();
+
+      if (! error_state)
+        {
+          std::string arg1 = args(1).string_value ();
+
+          if (! error_state)
+            {
+              octave_value tmp = arg0.contents (arg1);
+              //octave_value tmp = arg0.contents (arg1)(0);
+
+              if (tmp.is_defined ())
+                {
+                  octave_scalar_map st;
+
+                  st.assign ("selected", tmp);
+
+                  retval = octave_value (st);
+                }
+              else
+                error ("structdemo: struct does not have a field named '%s'\n",
+                       arg1.c_str ());
+            }
+          else
+            error ("structdemo: ARG2 must be a character string");
+        }
+      else
+        error ("structdemo: ARG1 must be a struct");
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/code/unwinddemo.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,47 @@
+#include <octave/oct.h>
+#include <octave/unwind-prot.h>
+
+void
+my_err_handler (const char *fmt, ...)
+{
+  // Do nothing!!
+}
+
+void
+my_err_with_id_handler (const char *id, const char *fmt, ...)
+{
+  // Do nothing!!
+}
+
+DEFUN_DLD (unwinddemo, args, nargout, "Unwind Demo")
+{
+  octave_value retval;
+  int nargin = args.length ();
+
+  if (nargin < 2)
+    print_usage ();
+  else
+    {
+      NDArray a = args(0).array_value ();
+      NDArray b = args(1).array_value ();
+
+      if (! error_state)
+        {
+          // Declare unwind_protect frame which lasts as long as
+          // the variable frame has scope.
+          unwind_protect frame;
+          frame.add_fcn (set_liboctave_warning_handler,
+                         current_liboctave_warning_handler);
+
+          frame.add_fcn (set_liboctave_warning_with_id_handler,
+                         current_liboctave_warning_with_id_handler);
+
+          set_liboctave_warning_handler (my_err_handler);
+          set_liboctave_warning_with_id_handler (my_err_with_id_handler);
+
+          retval = octave_value (quotient (a, b));
+        }
+    }
+
+  return retval;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/data/Makefile.am	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,29 @@
+# Makefile for Octave's examples/data directory
+#
+# 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/>.
+
+include $(top_srcdir)/build-aux/common.mk
+
+DATA_FILES = \
+   penny.mat
+
+octdata_DATA = $(DATA_FILES)
+
+EXTRA_DIST = $(DATA_FILES)
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/data/penny.mat	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,135 @@
+# Created by Octave 3.8.1, Sun Jun 01 16:28:53 2014 CEST <weber@t61>
+# name: P
+# type: matrix
+# rows: 128
+# columns: 128
+ 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 18 43 68 89 107 120 135 149 162 172 180 192 196 203 207 211 210 212 213 214 212 210 209 204 201 194 183 177 163 148 130 116 98 81 60 35 6 4 3 3 3 3 3 2 3 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 3 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
+ 2 2 2 2 3 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 6 33 63 90 111 132 152 172 190 199 209 215 219 222 224 225 226 228 228 229 228 229 230 228 229 230 229 228 227 226 225 221 216 216 207 197 189 171 151 128 107 81 52 21 4 3 3 3 2 3 3 3 2 2 2 2 3 2 3 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
+ 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 9 44 78 104 130 159 183 200 214 222 225 227 230 230 233 235 235 235 235 235 235 235 235 234 233 233 234 234 233 233 232 232 232 231 232 231 230 228 227 226 223 220 213 203 183 157 130 100 70 34 5 3 3 3 3 2 3 2 3 2 2 2 2 2 2 3 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
+ 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 2 2 2 2 2 2 2 2 1 2 2 2 2 2 27 64 99 129 160 186 206 218 226 229 231 234 235 236 236 235 235 232 229 226 221 219 218 216 216 214 214 215 216 218 220 221 223 226 228 229 230 231 231 231 230 230 229 228 227 226 222 218 209 188 159 128 96 58 15 4 3 3 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
+ 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 35 75 110 140 174 202 217 227 232 234 235 236 236 234 228 221 214 208 203 199 196 195 193 192 190 190 189 188 188 189 190 191 191 193 192 193 194 197 201 206 213 218 223 227 229 230 230 229 227 226 226 223 220 213 196 164 127 91 49 5 4 3 3 2 2 2 2 3 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 2
+ 2 2 2 2 2 2 2 2 2 2 2 2 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 10 52 92 129 164 196 217 226 232 235 236 237 234 224 214 205 198 193 191 187 186 187 183 183 182 181 179 178 178 181 179 179 179 179 180 180 180 179 178 179 180 182 184 186 190 195 200 209 217 223 227 228 229 228 227 225 224 222 217 204 173 135 96 52 5 3 3 3 3 3 2 3 2 2 2 2 2 3 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
+ 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 2 2 2 2 2 1 8 52 93 131 165 200 221 229 234 236 237 234 225 212 201 193 188 185 183 180 178 176 175 174 173 173 182 174 171 177 180 170 175 184 170 169 176 180 179 177 172 169 169 171 174 176 178 179 182 185 188 194 203 212 221 226 228 227 227 226 224 223 219 208 184 144 103 54 5 3 3 3 3 2 3 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 3 2
+ 2 2 2 2 2 2 2 2 2 1 2 1 2 2 2 2 2 2 2 2 1 2 2 2 2 2 2 1 13 49 90 131 167 203 222 230 232 235 236 225 214 202 194 189 186 181 178 175 172 170 168 167 167 164 163 164 188 177 163 185 188 163 176 175 159 159 172 182 175 170 161 159 159 161 163 166 168 170 171 173 176 178 182 185 193 202 213 221 225 227 226 225 224 223 220 211 188 145 101 48 5 3 3 2 3 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
+ 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 4 45 88 128 166 201 222 231 234 234 232 219 204 193 189 186 183 179 175 171 167 164 163 160 158 156 155 155 154 154 171 178 158 184 185 160 175 159 148 148 165 170 153 150 147 148 150 151 153 156 157 159 161 163 165 169 173 175 177 180 185 192 204 216 223 225 226 224 224 223 221 212 188 141 91 34 4 3 2 2 2 2 3 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 3 2 2 2
+ 2 2 2 2 2 2 2 2 2 2 2 1 2 2 2 1 2 2 2 2 2 2 1 2 3 41 82 125 163 199 220 228 229 235 229 216 201 191 185 181 180 180 184 186 174 163 158 155 152 150 148 145 145 144 144 145 154 173 159 174 174 169 168 142 136 137 159 166 161 141 138 138 141 142 144 146 148 149 151 154 157 160 170 170 169 172 174 176 179 186 198 210 222 226 225 224 224 222 220 212 181 130 80 15 3 3 3 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
+ 2 2 2 2 1 2 2 2 2 1 2 2 2 2 2 2 2 2 2 2 2 2 2 20 71 114 154 194 220 230 230 235 231 215 200 193 187 180 177 173 181 198 188 183 188 162 150 146 143 141 139 136 135 135 135 135 138 162 167 159 156 166 155 129 126 127 151 143 137 129 129 130 132 133 136 137 140 141 144 145 148 151 165 177 183 174 167 168 170 173 176 182 195 211 222 225 225 223 222 221 219 206 166 114 53 4 3 2 3 2 3 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
+ 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 2 2 2 33 85 132 172 211 231 236 233 233 220 206 196 191 184 179 174 169 165 164 188 174 156 162 176 146 139 135 132 130 128 126 125 125 125 125 139 156 146 130 154 147 119 116 117 139 139 122 122 120 121 122 126 127 128 130 132 135 137 139 141 146 150 173 177 176 173 162 163 167 171 175 181 193 208 220 224 223 223 222 220 217 197 159 102 36 4 3 2 3 2 3 3 2 2 2 2 2 2 2 2 2 2 2 2 2 2
+ 2 2 2 2 2 2 2 2 2 2 2 2 1 2 2 2 2 2 2 2 14 72 124 166 210 235 244 239 235 221 203 195 191 187 187 181 169 162 158 156 154 174 166 143 145 166 136 129 126 122 120 118 116 115 114 114 115 127 139 118 114 133 118 106 106 110 134 136 135 128 114 114 115 117 118 120 122 124 127 128 131 134 138 145 165 147 150 153 153 155 159 163 169 173 176 183 198 214 222 224 223 222 220 219 209 177 118 53 4 3 3 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
+ 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 2 2 2 38 96 144 187 227 246 247 240 228 207 198 191 186 186 200 195 194 180 156 151 147 144 158 166 137 136 155 129 120 116 113 111 109 106 105 104 104 104 106 109 101 100 102 99 97 97 99 105 109 112 110 105 105 107 108 110 112 114 116 119 120 124 126 131 148 151 138 140 142 146 148 151 166 175 168 169 172 175 185 202 217 223 223 222 220 219 218 201 142 79 4 3 3 3 3 2 2 2 2 2 2 3 2 2 2 2 2 2 2
+ 2 2 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 56 114 161 204 242 249 245 236 216 203 195 188 182 178 192 187 168 170 182 157 143 138 136 140 160 137 134 143 117 111 108 105 102 98 98 96 95 93 93 92 92 90 89 89 88 88 87 89 89 91 91 94 95 98 98 100 102 105 106 108 111 113 115 118 123 146 133 130 132 135 138 141 147 174 179 183 172 164 167 171 176 193 210 221 223 223 221 220 220 212 164 102 27 4 3 3 2 2 2 2 2 2 2 2 2 2 2 2 2 2
+ 2 2 2 2 2 2 2 1 2 2 2 2 2 2 2 2 2 67 126 172 217 248 248 245 228 210 201 193 186 181 174 171 193 173 156 150 163 164 135 130 126 126 149 148 141 120 107 102 99 96 94 91 89 87 87 85 83 82 82 82 82 82 82 80 81 81 82 82 82 84 87 89 91 93 94 97 99 101 103 105 107 112 122 137 121 122 125 128 131 135 147 168 154 161 179 160 159 163 166 172 180 201 216 222 222 222 218 219 216 182 121 52 4 3 3 2 2 2 3 2 2 2 2 2 2 2 2 2
+ 2 2 1 2 2 2 2 2 2 2 2 1 2 2 2 7 83 137 185 230 249 247 238 217 204 198 193 187 179 172 166 162 182 173 148 142 146 163 128 122 117 116 126 126 111 100 96 93 91 88 86 83 81 79 78 76 75 76 78 80 85 89 89 81 78 76 76 76 77 78 80 81 83 85 87 89 91 92 95 97 100 104 116 118 113 115 118 121 125 131 156 163 143 147 170 153 153 156 159 164 168 175 192 211 221 223 222 220 219 219 189 133 65 4 3 2 2 3 2 2 2 2 2 2 2 2 2 2
+ 2 2 2 2 2 2 2 2 2 2 2 2 2 2 20 91 147 197 240 248 248 232 209 200 196 193 198 196 175 165 158 154 163 172 142 135 139 155 121 113 110 106 103 99 93 90 86 84 82 80 78 75 73 72 73 72 72 86 90 93 97 100 100 93 95 93 93 91 83 78 81 85 82 80 81 82 84 86 88 90 93 95 99 102 104 107 110 114 120 130 150 154 162 162 152 143 144 149 153 158 162 165 172 184 205 219 223 222 220 219 220 205 151 80 4 3 3 3 3 3 3 2 3 3 2 2 2 2
+ 2 1 2 2 2 2 1 2 2 2 2 2 2 3 80 141 192 233 249 250 232 210 200 194 190 198 197 183 170 159 153 148 143 153 160 140 143 145 115 106 102 97 93 89 85 81 78 75 74 72 71 68 69 72 83 90 91 95 97 94 101 106 111 108 103 98 97 104 107 108 104 99 98 89 75 76 77 78 80 82 85 88 91 94 96 99 102 106 112 128 138 127 141 153 134 134 138 142 146 151 170 162 163 168 175 193 213 222 222 221 219 219 220 180 111 30 3 3 2 3 2 2 2 1 2 2 2 2
+ 2 1 2 1 2 2 2 1 2 2 2 2 35 97 156 207 245 251 246 220 205 196 190 184 190 196 170 163 158 157 145 139 133 132 142 143 133 112 101 96 91 88 84 78 77 72 69 68 65 66 66 68 83 89 93 101 106 111 114 115 114 116 122 119 111 107 115 121 122 114 107 102 101 98 82 71 72 72 74 76 79 81 84 87 90 93 96 101 107 119 116 118 138 141 126 129 133 137 142 162 167 155 158 163 167 175 193 214 222 222 221 219 219 219 169 97 9 3 2 3 2 2 2 2 2 2 2 2
+ 2 2 2 2 2 1 2 1 2 2 1 31 102 158 210 247 253 243 217 205 196 188 181 176 188 189 161 155 168 176 142 132 125 120 117 113 106 99 93 88 83 80 76 72 69 65 62 60 61 70 85 88 88 90 101 114 121 126 131 133 131 131 137 132 131 136 135 135 130 125 121 118 114 105 96 90 76 69 70 72 73 76 77 82 84 87 90 93 99 103 106 111 131 134 120 125 127 132 143 161 148 148 153 158 163 166 172 189 212 221 221 220 219 221 219 171 96 8 3 3 2 2 2 2 2 2 2 2
+ 1 1 2 2 1 2 2 2 2 2 6 81 143 197 241 253 247 222 206 197 190 182 175 169 168 187 162 150 154 166 163 130 120 114 109 105 98 92 87 82 78 72 69 65 62 59 57 57 65 88 96 100 101 103 110 122 134 140 144 147 146 148 150 146 145 144 142 139 134 131 133 133 131 120 108 107 102 92 80 78 74 72 74 75 78 81 83 87 91 95 98 102 110 119 115 116 120 126 148 150 137 141 146 166 168 159 164 169 181 205 219 222 221 220 218 221 187 112 16 3 3 2 2 2 2 2 2 2
+ 1 2 2 2 2 2 2 2 2 2 80 140 194 241 254 244 220 205 197 190 183 175 168 163 158 169 173 148 142 152 148 123 112 106 102 96 92 86 81 76 70 67 63 60 56 53 55 68 86 91 97 106 111 114 118 128 146 153 154 153 157 156 153 149 147 146 141 135 129 130 142 144 145 138 125 118 117 124 124 117 108 94 79 71 73 75 78 82 85 89 92 97 100 103 108 111 115 126 148 134 131 135 148 166 151 152 157 162 168 179 204 220 222 221 220 218 222 182 105 11 3 2 2 2 2 2 2 2
+ 2 2 2 2 2 2 2 1 1 66 135 189 237 253 248 220 205 198 190 183 175 168 162 157 151 150 158 160 156 147 126 113 106 101 96 90 85 80 75 71 64 60 57 54 51 51 71 79 90 94 110 118 124 131 138 143 155 162 161 156 161 161 155 146 143 139 135 129 127 136 150 151 149 140 129 127 131 139 136 131 118 98 85 74 70 70 73 76 79 82 86 90 94 98 102 106 109 125 141 124 126 134 157 146 142 148 152 157 163 169 182 204 220 222 220 219 217 223 175 93 4 3 2 2 3 3 2 2
+ 2 1 2 1 1 2 2 1 54 125 182 235 252 249 224 206 198 191 185 176 169 161 155 150 145 140 137 134 131 120 110 104 99 95 89 84 79 75 70 64 59 54 52 49 56 76 89 97 101 114 124 133 147 154 152 152 165 168 168 163 165 165 157 140 130 130 129 129 135 149 153 153 151 137 127 133 139 148 151 142 122 108 94 87 69 66 69 71 74 77 81 85 88 92 95 100 104 115 136 124 128 148 140 133 137 141 146 152 158 165 171 182 205 220 222 220 219 219 223 170 88 4 3 3 2 2 2 2
+ 2 2 1 1 2 2 1 58 128 186 235 252 244 219 205 197 195 187 176 168 161 154 148 143 137 132 126 121 113 108 103 98 93 86 81 76 73 67 61 57 53 51 53 70 95 108 114 120 127 138 148 160 167 164 162 169 175 176 173 173 169 168 156 139 131 132 136 142 146 149 151 155 147 134 138 146 150 158 157 145 131 115 99 89 84 70 65 68 70 74 76 80 84 87 91 94 99 105 122 133 135 126 123 128 133 137 144 157 172 168 169 174 188 211 221 221 220 218 226 214 142 45 3 3 2 2 3 3
+ 1 2 2 2 2 2 43 114 173 225 248 245 220 207 198 192 200 202 172 164 155 148 142 136 131 125 120 113 107 101 97 91 86 79 74 69 66 60 57 53 55 73 95 112 126 132 135 142 149 160 169 177 179 178 179 181 181 181 180 178 176 170 163 144 136 134 137 141 145 144 151 156 149 148 150 153 159 160 159 154 146 131 114 101 89 83 64 62 65 68 71 74 78 81 85 88 92 96 101 107 111 114 117 121 127 132 140 171 170 181 169 168 174 187 212 221 221 219 219 228 208 129 30 3 3 2 2 2
+ 2 2 2 1 2 23 96 161 217 245 245 225 209 202 194 189 182 193 190 161 150 143 137 131 125 119 113 106 101 96 91 85 79 74 68 64 60 56 53 53 68 86 111 131 141 145 148 155 165 176 181 185 187 186 185 186 185 185 184 183 178 169 165 148 136 133 134 141 147 148 152 155 146 143 143 149 159 158 156 158 152 143 121 107 96 83 63 59 60 63 67 69 72 76 79 82 86 90 94 98 103 107 113 118 122 128 137 166 149 162 170 162 167 173 191 214 221 221 219 218 227 197 109 4 3 3 2 3
+ 2 2 2 1 2 64 130 189 235 248 236 214 205 198 195 187 179 173 186 184 151 141 133 126 121 116 109 103 98 93 87 81 75 69 64 60 56 53 50 59 73 90 113 139 146 150 151 153 171 180 183 188 188 187 188 189 189 187 185 184 177 168 165 156 143 142 142 142 151 149 145 150 138 133 136 146 151 151 154 154 151 146 139 111 91 85 69 55 56 58 61 63 66 69 73 76 79 84 88 91 96 100 106 111 125 132 128 156 153 144 150 154 159 164 171 190 213 222 221 220 218 229 198 113 4 2 3 3
+ 2 2 2 2 60 128 188 235 249 234 213 204 198 211 216 208 195 184 182 181 160 135 125 120 115 108 102 97 91 86 80 74 69 63 58 55 52 51 58 77 92 109 134 146 152 156 153 172 179 181 186 191 186 184 189 191 191 190 190 185 179 178 171 155 150 150 150 153 154 147 151 148 141 140 141 144 143 142 142 139 131 128 122 98 83 75 61 51 52 54 56 61 62 66 69 72 76 79 82 87 91 96 102 108 131 132 125 156 147 138 143 149 154 160 168 175 200 220 222 220 218 225 227 159 62 4 2 3
+ 1 2 2 35 108 172 224 248 240 216 208 199 192 191 205 200 184 174 168 163 148 127 120 114 108 103 97 92 87 80 75 70 64 60 55 51 50 63 81 92 107 125 143 152 160 163 169 182 180 180 187 192 188 186 188 191 194 194 193 192 190 187 176 162 157 157 159 160 158 154 156 155 152 147 148 146 142 136 130 126 118 110 106 90 75 68 53 45 48 50 52 55 58 61 64 67 71 74 77 82 86 91 96 102 117 137 137 151 138 133 139 144 150 156 163 170 180 207 220 222 220 218 231 216 134 24 3 3
+ 2 2 2 67 138 197 236 249 226 214 205 197 188 181 177 189 186 157 146 138 130 121 116 110 104 99 93 88 82 77 72 66 61 57 53 48 49 73 90 103 119 133 151 159 166 175 180 187 183 177 182 190 192 189 186 191 194 195 195 194 192 189 184 173 165 163 164 167 165 161 162 162 154 156 157 157 153 145 134 122 114 105 91 76 66 60 45 41 43 45 48 51 53 56 58 62 65 68 72 76 80 85 90 94 101 113 128 132 125 127 132 138 144 153 169 163 170 180 207 222 222 220 219 231 211 129 15 3
+ 2 2 43 116 179 232 251 233 216 207 205 203 183 175 169 164 175 168 139 130 122 114 108 104 98 92 88 82 77 72 67 62 57 52 48 45 53 85 103 114 127 141 158 172 178 186 190 192 188 179 178 184 192 193 190 190 191 193 194 193 193 189 185 179 174 174 173 173 173 170 166 164 167 167 166 166 164 159 148 133 118 100 72 58 54 41 35 36 38 41 43 47 49 52 55 57 60 64 68 71 75 78 84 89 94 100 106 112 116 121 127 133 140 153 181 172 166 172 186 214 222 221 219 217 233 190 97 3
+ 2 12 89 159 217 251 243 220 209 201 202 210 192 171 163 155 150 152 135 122 115 108 102 98 92 87 82 77 72 67 63 57 53 47 44 43 67 94 108 119 134 142 161 177 185 190 194 195 192 185 180 182 193 194 190 187 187 191 191 194 195 193 188 184 183 182 181 180 179 173 175 176 175 174 173 172 172 170 163 149 130 106 73 50 34 31 30 32 35 37 40 42 44 48 51 54 56 60 63 66 70 74 80 84 89 94 100 106 110 116 122 128 135 144 169 187 166 168 176 195 218 222 221 219 224 230 157 49
+ 2 81 152 210 249 246 222 210 201 193 187 191 195 173 154 146 138 131 122 114 106 101 95 90 85 79 75 71 65 61 56 51 47 43 40 56 82 103 114 133 139 150 166 180 186 189 194 195 192 184 181 193 196 194 190 188 189 191 193 195 191 186 188 189 187 187 185 183 183 183 183 181 181 181 180 178 179 178 172 160 140 114 81 36 26 26 26 29 31 33 36 39 41 44 47 50 52 55 60 63 67 71 75 80 85 90 96 102 108 114 121 126 134 153 174 182 181 166 172 182 211 222 221 220 218 233 190 91
+ 53 126 188 244 247 228 215 205 195 188 180 174 178 181 159 140 131 123 115 108 100 95 89 84 79 74 70 65 60 56 51 47 42 37 37 63 86 109 122 138 146 157 167 179 187 191 192 188 186 189 191 197 197 194 192 189 189 194 195 191 183 185 189 188 189 188 188 186 186 185 186 186 185 186 184 183 183 181 178 172 156 134 102 51 23 24 24 26 28 30 33 34 37 40 43 46 49 51 55 59 62 66 71 75 80 86 91 97 103 109 117 124 147 160 155 161 178 171 167 174 193 217 223 221 220 224 229 150
+ 98 167 227 247 239 221 209 199 189 181 173 167 160 162 160 137 125 117 109 102 95 89 83 78 73 69 65 59 54 51 47 42 37 33 36 67 88 116 131 141 156 164 169 180 187 191 190 180 174 186 196 198 197 196 195 193 190 192 192 185 180 185 191 192 191 190 189 189 188 189 189 189 190 190 188 186 186 184 182 176 165 147 122 79 24 20 21 23 25 26 28 29 34 35 38 41 44 47 51 55 57 62 66 70 76 81 87 93 99 106 117 141 148 138 136 142 152 156 162 168 177 201 221 222 221 220 232 205
+ 141 204 247 249 226 214 203 194 184 175 167 160 153 146 139 127 118 110 103 96 89 84 78 72 68 64 59 55 50 45 41 38 33 30 34 69 91 122 136 147 161 167 170 179 183 188 189 180 173 180 196 196 193 190 188 189 186 186 185 180 180 185 188 190 191 192 191 191 190 190 190 191 192 192 190 190 188 186 183 179 169 154 134 102 43 18 18 19 22 23 24 27 28 32 35 37 41 44 47 49 54 57 62 66 71 77 83 88 94 102 115 128 124 125 130 136 143 149 157 164 172 185 213 221 222 220 218 231
+ 163 224 250 242 222 211 200 191 181 172 163 156 149 141 132 123 114 107 99 92 85 79 74 68 64 59 55 51 46 41 38 33 30 28 34 67 92 118 137 148 159 165 169 178 183 185 188 186 183 183 192 190 184 181 182 179 175 177 180 178 180 182 182 187 191 191 190 191 190 190 191 191 192 192 192 192 191 189 186 180 173 161 145 122 82 23 16 18 18 20 20 22 24 27 30 33 35 38 43 45 49 52 56 61 66 71 77 81 88 95 102 110 114 119 124 131 136 143 150 157 166 175 190 216 223 221 220 224
+ 211 252 245 224 213 202 192 182 174 165 156 149 140 132 123 115 107 99 92 85 78 73 68 63 58 54 50 44 40 36 32 29 25 25 50 76 103 123 139 151 158 165 175 179 180 186 187 187 188 187 183 180 178 176 173 171 172 175 173 174 180 180 183 187 190 189 189 189 190 189 190 191 192 192 192 193 192 189 185 178 168 158 142 119 83 23 14 14 15 17 17 19 22 24 27 30 33 36 39 41 45 49 54 59 62 68 73 79 85 91 99 105 111 117 122 128 134 141 147 155 164 172 182 208 222 222 221 218
+ 242 255 231 218 207 196 187 177 169 160 152 143 135 126 117 109 101 94 87 81 74 69 63 58 54 47 44 39 36 31 28 26 22 22 51 76 100 121 133 148 157 165 175 177 179 185 187 188 189 184 176 174 174 172 171 175 176 173 168 171 179 184 185 187 189 189 189 189 188 187 188 190 190 191 191 192 192 188 184 178 168 157 143 122 91 31 13 12 13 14 15 16 18 21 24 27 30 32 36 39 42 47 51 55 60 64 69 75 81 87 94 101 106 112 118 125 130 137 144 151 159 167 176 192 218 223 221 220
+ 250 251 227 214 204 194 183 175 165 156 148 140 131 122 113 105 97 90 83 77 71 65 59 54 48 45 40 36 31 29 26 22 20 20 33 70 91 112 128 143 156 163 172 177 179 183 185 181 183 183 181 173 171 173 179 183 180 173 172 175 178 182 188 187 189 189 189 188 185 184 185 186 187 189 190 191 190 188 185 179 169 159 147 132 107 57 13 10 10 11 12 14 15 17 20 22 25 28 32 35 38 42 45 50 54 59 64 70 76 82 88 94 102 107 113 119 125 131 138 145 153 161 169 178 198 220 223 221
+ 255 231 218 205 196 185 177 167 158 150 140 132 123 114 106 98 90 84 77 71 64 59 53 49 43 38 34 31 27 25 21 18 16 16 32 73 97 114 132 149 158 164 170 176 178 180 180 176 176 181 182 180 177 184 187 187 179 176 177 181 184 182 187 187 186 187 187 184 181 180 182 183 185 187 188 189 188 187 183 177 168 157 148 133 104 48 10 9 8 9 10 11 12 15 17 20 23 26 29 33 36 40 44 47 52 57 61 67 73 79 85 92 99 106 111 117 123 129 136 143 151 158 166 176 190 218 224 222
+ 245 224 211 201 191 181 172 162 153 144 136 126 117 108 100 93 85 78 73 66 59 54 49 45 39 34 30 27 24 21 18 16 14 13 28 65 94 116 134 149 157 160 167 176 178 177 175 174 173 174 174 178 183 188 186 183 177 173 172 180 185 184 183 183 181 184 184 182 179 176 177 180 181 182 184 186 187 186 182 177 170 162 152 138 112 62 10 8 7 7 8 8 10 12 15 17 20 23 27 30 33 37 41 45 49 53 58 63 69 76 81 87 94 101 107 113 119 125 132 139 147 154 163 171 181 206 223 223
+ 231 218 207 196 185 176 167 157 149 139 131 121 112 103 96 88 80 74 68 62 55 50 45 40 35 30 27 23 21 18 15 13 11 11 29 60 82 111 133 148 157 162 164 176 179 175 169 170 169 171 174 178 184 185 177 171 168 166 170 177 181 181 177 179 178 179 180 179 174 170 171 174 175 177 181 183 183 183 181 179 175 166 158 145 121 75 14 6 5 5 5 6 7 9 13 14 18 20 24 27 31 34 38 41 46 50 55 61 66 72 77 84 90 97 103 109 116 122 129 135 143 150 158 167 176 191 219 224
+ 224 212 201 191 181 172 162 153 143 134 125 115 107 99 91 83 77 70 64 57 51 46 41 36 32 27 24 20 19 15 13 11 10 10 28 65 83 108 130 145 155 163 164 173 179 173 164 168 169 172 180 184 183 177 169 160 158 164 168 168 172 171 169 174 175 175 176 174 168 166 166 168 169 171 174 177 178 179 181 181 178 171 162 149 130 91 31 6 4 4 3 4 5 7 9 11 14 18 20 25 28 31 35 39 44 48 52 57 62 68 74 80 87 93 100 106 112 118 125 132 139 147 155 163 172 180 208 224
+ 219 207 196 187 177 167 158 148 138 130 120 111 103 94 85 79 72 66 59 54 48 42 37 32 28 24 22 18 15 13 11 10 8 7 25 66 88 109 129 140 151 159 163 168 177 173 162 166 173 182 184 182 174 165 161 152 154 163 161 158 161 160 163 165 166 170 174 170 165 162 161 160 162 164 166 169 172 175 180 181 178 171 161 152 133 98 42 6 4 3 2 3 3 5 7 9 12 15 18 22 25 29 32 36 40 44 49 53 58 64 70 76 83 89 96 103 109 116 121 129 135 143 150 159 167 176 194 220
+ 213 203 193 182 172 163 154 144 135 125 116 106 98 89 82 74 67 61 56 49 44 38 34 30 26 22 18 16 13 11 9 7 5 6 20 62 85 107 125 133 145 154 158 163 171 173 162 162 173 182 179 172 157 148 152 146 150 154 149 149 150 152 155 156 159 166 170 166 160 157 155 154 155 158 160 163 168 176 180 178 170 156 146 139 126 96 48 6 4 3 3 2 2 2 4 7 9 12 16 19 23 26 30 33 38 41 45 51 55 61 68 73 80 86 92 99 106 112 118 126 133 140 147 155 163 172 181 212
+ 212 201 192 181 171 161 152 143 132 123 113 104 96 87 80 72 65 59 53 47 42 36 32 28 24 21 17 15 11 10 8 6 4 4 10 53 71 97 118 127 133 147 155 156 165 170 165 161 170 176 168 163 145 132 136 147 143 140 140 139 142 148 150 152 156 163 163 160 156 151 150 150 151 152 155 158 164 174 178 173 160 137 118 114 110 92 57 10 4 3 2 2 2 2 2 4 6 10 13 16 20 23 27 30 34 37 41 46 51 57 63 69 75 81 88 94 101 108 114 120 127 135 142 151 158 166 174 190
+ 205 195 184 174 164 155 146 136 125 116 106 98 90 81 73 67 60 54 48 41 37 32 28 23 20 17 14 11 8 7 6 5 3 3 29 58 77 98 117 127 130 142 153 153 158 167 163 161 172 162 156 147 126 120 138 141 129 123 129 131 140 147 148 152 156 163 159 156 149 146 146 145 147 150 155 160 168 174 171 158 136 101 84 84 86 69 36 4 3 2 2 2 2 2 2 2 5 7 11 15 18 22 25 28 31 35 40 44 49 55 60 66 73 79 87 93 100 107 113 120 126 134 141 148 156 164 172 185
+ 203 194 182 173 163 153 143 134 124 114 104 96 87 80 72 64 58 52 46 40 34 30 26 22 18 15 13 10 8 6 4 3 3 3 20 53 75 89 108 120 130 136 147 154 158 165 168 164 170 159 156 145 127 121 127 135 122 112 115 126 137 147 146 149 155 161 160 158 151 148 147 146 144 147 153 159 165 166 160 145 135 116 76 68 71 64 35 4 3 3 2 3 2 2 2 2 3 5 9 11 15 19 22 24 28 31 35 40 45 51 56 62 69 75 82 89 95 102 109 115 122 129 135 143 151 159 167 176
+ 197 188 177 167 157 147 137 124 117 107 98 90 82 74 67 60 53 47 41 36 31 27 22 19 16 12 9 7 5 3 3 2 2 3 31 60 74 90 106 119 131 139 144 147 155 164 172 175 173 158 156 138 121 113 124 123 111 104 109 125 141 149 149 150 159 162 160 158 155 154 152 148 146 147 153 155 155 149 135 131 121 92 60 59 64 57 20 4 3 2 3 2 2 2 2 2 2 3 7 10 13 17 19 23 25 29 34 39 44 49 55 61 68 74 81 87 95 102 108 115 121 127 135 142 150 158 167 175
+ 194 184 173 163 153 143 133 123 113 104 95 87 79 71 64 57 51 45 39 33 28 25 20 17 13 11 9 6 3 2 2 2 2 2 33 58 71 85 101 114 126 137 142 141 147 158 166 172 172 161 156 136 112 107 116 113 109 111 117 127 141 147 154 153 158 163 164 161 159 158 156 153 149 149 150 149 141 130 123 119 112 78 51 49 58 58 30 4 3 2 2 2 2 2 2 3 3 2 5 8 11 13 16 20 23 27 32 36 42 47 53 58 65 72 78 85 92 99 106 112 119 125 132 139 147 155 163 173
+ 191 181 170 160 149 139 130 119 110 101 92 83 75 67 61 54 48 42 36 31 26 22 18 14 12 9 7 4 3 3 2 2 2 2 31 54 69 84 97 109 122 132 138 141 144 148 154 162 167 162 155 134 107 109 108 109 113 119 125 132 142 149 153 158 160 162 162 164 162 161 160 158 154 151 149 145 133 127 124 123 112 76 49 45 51 55 45 7 3 3 2 2 2 2 2 2 2 2 3 6 9 12 13 18 21 25 29 34 39 44 50 56 63 70 76 83 91 97 104 110 117 123 129 137 144 153 161 169
+ 190 179 169 158 149 139 129 118 108 99 90 82 75 67 60 53 47 41 35 30 25 22 18 15 11 8 6 4 3 3 2 3 3 2 16 42 60 79 93 105 116 126 133 141 145 144 143 143 156 163 157 141 110 107 107 119 122 124 128 132 139 147 155 159 161 162 163 163 163 163 164 163 160 157 153 150 138 131 129 128 118 92 53 49 49 53 52 36 5 2 3 2 2 3 2 2 2 2 2 3 6 9 12 15 19 22 26 31 35 40 47 53 59 66 73 79 87 93 100 106 113 119 126 132 140 148 156 164
+ 184 173 163 152 143 132 122 112 103 94 86 78 71 63 56 50 43 37 32 28 23 20 16 12 10 6 4 3 3 3 3 3 2 2 13 37 59 76 91 106 116 123 131 139 145 140 136 140 147 158 153 136 110 100 110 132 131 128 129 130 135 144 151 156 158 160 162 162 163 163 164 163 161 158 156 151 141 136 133 128 116 81 55 54 54 55 53 41 6 3 3 3 2 2 2 2 2 2 2 2 5 8 11 14 18 21 25 30 35 40 46 52 59 65 72 78 86 92 99 105 112 119 125 131 139 148 156 165
+ 180 170 160 150 139 129 119 109 99 93 83 75 67 60 54 47 41 36 30 26 22 18 14 11 8 5 4 3 3 2 3 2 3 2 2 28 53 67 81 101 111 116 127 130 137 137 128 136 139 155 151 140 112 100 107 131 131 127 125 124 126 133 141 146 149 153 158 159 158 158 160 159 160 158 157 155 150 144 139 131 116 84 62 57 56 56 54 48 27 4 3 2 3 2 2 2 2 2 2 2 3 7 9 13 16 21 24 28 33 38 44 50 57 64 70 77 84 90 97 104 110 117 123 130 137 145 153 162
+ 178 167 157 147 136 126 116 106 97 88 80 73 65 58 51 45 39 34 29 25 21 17 13 10 8 5 3 3 3 2 2 2 2 2 2 19 46 62 67 89 103 108 122 124 127 131 126 129 136 148 151 143 121 104 106 121 126 121 118 117 119 123 130 135 139 146 152 152 151 150 151 154 156 156 156 156 155 152 145 133 114 84 69 60 57 57 55 52 41 6 3 3 3 2 2 2 2 2 2 2 2 4 8 11 14 19 23 27 32 37 42 49 55 61 68 75 82 89 95 102 108 115 121 128 136 143 151 159
+ 175 164 154 144 133 123 113 104 94 86 78 71 64 57 50 43 38 33 28 24 20 16 13 10 7 4 3 2 3 2 2 2 2 2 2 12 38 55 59 71 88 103 120 124 125 130 131 132 132 138 148 141 131 116 109 108 116 112 110 112 115 120 124 128 133 139 144 142 140 138 142 147 151 153 153 154 153 152 147 135 116 87 73 62 58 58 56 54 49 28 3 3 2 2 2 2 2 2 2 2 2 3 7 10 13 17 21 26 30 35 41 47 53 60 66 73 80 88 94 100 106 113 120 126 134 141 149 158
+ 172 162 152 141 131 121 110 101 92 84 77 69 62 55 48 42 36 31 27 23 20 15 12 10 6 4 3 3 3 3 2 2 2 2 3 2 27 45 59 67 79 101 117 124 126 128 127 130 129 129 142 139 131 132 128 113 112 107 105 107 111 117 120 125 129 133 135 133 130 127 131 139 146 150 151 151 151 149 144 133 115 94 77 66 60 58 57 56 53 43 5 3 3 3 2 3 2 2 2 2 2 2 5 9 12 16 19 24 28 34 40 45 52 58 65 72 78 85 91 99 105 112 118 125 132 140 147 155
+ 170 160 149 139 128 118 108 100 91 82 75 67 60 54 47 41 35 31 26 22 18 15 12 9 6 4 3 3 3 3 3 3 2 2 2 1 12 39 57 68 82 101 113 120 121 123 119 116 119 122 132 140 132 133 134 122 111 106 103 104 110 115 119 121 126 128 127 127 122 120 121 128 138 146 147 148 149 148 140 129 113 96 84 70 60 58 56 55 55 50 27 4 3 2 3 3 2 2 2 2 2 2 4 7 11 15 19 23 27 32 37 44 51 56 63 70 77 83 91 97 103 110 117 123 131 139 146 154
+ 168 158 147 136 126 116 106 97 88 80 73 65 59 52 46 40 35 30 26 22 19 15 12 9 6 4 3 3 3 2 2 2 2 2 2 2 2 34 57 63 78 96 104 112 118 117 119 111 115 120 122 131 135 139 137 126 115 105 104 105 110 116 117 117 123 126 124 124 123 118 116 120 128 138 142 144 145 143 135 124 111 101 87 68 64 62 57 53 53 52 38 5 3 3 2 3 2 2 2 2 2 2 4 6 10 14 17 21 26 31 36 43 48 56 62 69 75 82 89 96 102 109 115 122 129 137 144 152
+ 166 156 145 134 124 114 105 95 87 79 71 64 57 50 45 39 34 30 26 22 19 15 12 9 6 4 3 3 2 2 3 2 3 3 2 2 2 27 53 60 71 89 96 101 113 116 116 118 117 115 114 112 124 138 141 132 119 102 105 106 112 114 115 115 118 124 124 120 122 120 118 115 119 128 132 135 137 135 128 120 111 103 82 70 75 76 68 60 56 51 38 5 3 3 3 2 2 2 2 2 2 3 2 6 10 13 17 20 24 30 35 41 47 53 60 68 75 81 88 94 101 107 114 121 128 136 142 151
+ 165 154 143 133 122 112 103 94 85 78 70 62 56 50 44 39 33 28 25 21 18 15 12 9 7 4 3 3 3 2 2 2 2 2 2 2 2 15 47 59 65 83 92 98 108 115 116 117 113 108 107 104 102 122 136 134 115 96 106 109 112 115 115 116 117 122 124 122 122 121 117 113 113 118 123 125 126 124 121 116 111 100 72 67 74 73 67 58 49 39 21 4 3 3 2 3 2 2 2 2 2 2 2 4 8 12 15 19 24 28 33 39 46 53 59 66 73 80 87 94 100 106 114 119 127 134 141 149
+ 163 153 141 131 121 111 101 92 84 76 69 61 56 49 43 38 33 30 25 21 18 15 12 10 7 4 3 2 2 2 2 2 2 2 2 2 2 3 33 55 68 79 90 100 107 110 110 113 109 102 95 97 89 92 112 113 100 95 104 112 114 116 117 118 119 121 123 122 120 119 117 113 109 110 113 116 114 113 111 110 106 92 64 60 59 55 44 29 18 6 4 3 2 2 2 3 2 2 2 2 2 2 2 4 7 11 14 18 22 28 32 38 45 51 58 65 71 78 86 92 99 105 112 118 125 132 140 148
+ 161 151 140 130 119 109 100 91 83 75 68 61 55 49 43 37 33 29 25 21 19 15 12 9 7 4 3 3 2 2 2 1 2 2 2 2 2 2 14 40 57 72 85 97 105 106 101 103 106 97 95 91 84 79 79 90 95 98 105 112 116 118 121 123 121 121 122 122 121 119 116 111 104 101 105 101 99 98 99 100 93 78 65 58 54 47 12 3 3 2 2 2 2 3 2 2 2 2 2 2 2 3 2 3 6 10 13 17 21 26 31 37 43 50 57 63 70 77 84 91 97 104 111 117 124 131 139 146
+ 160 149 138 129 117 108 98 89 82 74 67 60 55 48 42 37 32 28 25 21 18 15 12 10 8 5 4 3 2 3 2 2 2 2 2 2 2 2 7 33 47 65 76 90 99 103 101 97 104 102 95 92 86 83 77 85 96 102 108 113 118 120 121 124 125 123 124 123 121 119 115 109 101 99 99 94 90 91 94 94 86 77 70 63 57 44 6 3 3 2 2 2 2 2 2 2 2 2 2 2 2 2 2 3 6 9 12 16 20 25 31 36 42 49 55 63 70 76 83 90 97 103 110 116 123 130 137 145
+ 158 147 137 127 116 107 97 89 81 73 67 60 53 47 42 37 32 28 25 21 19 16 13 11 8 6 4 3 3 2 2 2 2 2 2 2 2 2 6 33 40 63 71 80 87 92 100 99 100 102 97 92 89 86 83 84 95 104 110 114 119 121 122 126 126 127 125 123 121 118 114 107 99 97 95 85 84 88 92 89 81 78 74 66 57 42 5 3 3 3 2 2 2 2 2 2 2 2 2 2 2 2 2 2 5 8 11 16 20 24 30 35 42 48 54 62 68 75 83 90 96 103 109 115 122 129 136 144
+ 157 147 137 126 116 107 97 88 80 73 66 59 53 46 41 37 33 29 25 22 20 16 14 11 9 7 5 3 3 3 3 3 3 2 2 2 2 2 3 29 38 60 66 76 79 83 93 94 90 98 96 93 91 90 88 87 92 101 109 115 118 122 123 127 127 127 126 121 117 117 112 105 100 98 93 81 85 89 85 84 81 75 70 63 53 38 5 3 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 5 8 11 15 19 24 28 35 40 47 54 61 68 75 82 89 96 103 108 115 122 128 136 143
+ 159 148 138 128 117 108 99 90 82 74 67 61 54 48 43 37 33 29 26 23 20 17 14 13 10 8 6 5 4 3 2 3 2 2 2 2 2 2 2 8 34 51 59 72 80 79 85 93 94 93 93 94 93 93 94 92 91 94 103 111 117 121 122 126 127 127 125 120 114 112 111 106 101 99 94 84 90 91 89 86 72 61 58 53 45 29 5 3 3 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 3 6 10 14 17 22 27 33 39 45 51 58 66 73 80 87 93 100 106 113 120 126 133 141
+ 156 145 135 124 114 105 96 88 80 72 66 58 53 47 42 37 33 29 25 23 20 18 15 13 11 8 7 5 4 3 3 2 2 3 2 2 2 1 2 6 32 47 57 73 82 81 84 86 90 90 92 93 94 94 95 94 91 92 102 110 116 121 122 126 127 126 123 118 115 112 109 104 100 100 91 89 94 93 91 77 58 53 51 43 29 7 3 2 3 3 2 2 2 2 2 2 2 2 2 2 2 2 2 2 4 7 11 15 19 24 29 34 40 46 52 60 67 74 81 88 95 102 108 114 121 128 136 142
+ 157 147 137 127 117 107 98 89 82 74 67 61 54 48 43 38 34 31 27 25 21 19 16 14 12 10 8 7 5 4 3 3 2 2 2 2 2 2 2 2 13 34 40 59 74 77 77 82 82 86 90 93 95 97 97 97 95 91 93 103 111 115 119 124 125 124 123 122 118 114 110 108 104 102 94 91 96 96 91 74 63 63 61 53 39 6 3 3 3 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 3 7 10 14 18 22 27 32 38 44 51 58 64 72 80 86 93 100 106 112 119 126 132 140
+ 155 145 134 124 114 105 96 88 80 73 66 60 53 47 42 38 34 30 27 24 22 19 16 14 13 11 9 7 5 4 4 3 2 3 2 2 2 2 2 2 4 23 33 44 56 68 77 78 80 86 90 93 98 100 100 98 96 93 90 98 108 113 115 121 123 121 123 123 119 115 114 111 107 103 93 93 94 94 84 67 64 61 55 44 23 4 3 2 2 2 3 2 2 2 2 2 2 2 2 2 2 2 2 2 5 8 11 15 19 24 28 34 39 45 52 59 66 73 81 88 94 101 108 114 121 127 135 142
+ 154 144 134 124 114 105 95 88 80 73 67 60 54 48 43 39 35 31 28 26 22 20 17 15 13 11 9 7 6 5 4 4 3 3 2 2 2 2 2 2 2 3 15 29 47 61 72 76 80 86 90 95 98 101 102 101 98 95 90 93 104 110 113 118 120 120 122 122 121 119 117 114 110 104 94 91 91 90 84 70 66 60 48 23 4 3 3 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 4 8 11 15 19 24 29 34 40 46 53 60 66 73 80 87 94 101 108 114 121 128 135 142
+ 157 146 136 126 116 107 98 90 82 76 69 62 57 51 45 41 37 33 30 27 24 21 19 17 15 13 11 8 7 7 6 4 3 4 3 2 2 2 2 2 2 2 2 6 37 55 66 74 80 85 90 95 99 101 103 103 101 97 95 91 96 104 110 114 118 118 120 121 122 123 121 116 114 108 98 94 90 91 90 80 69 61 48 21 4 3 3 2 3 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 4 8 10 14 18 22 28 33 39 45 52 58 65 72 79 86 92 99 106 113 119 127 133 141
+ 154 144 134 124 114 105 96 89 80 75 68 62 56 50 45 41 38 34 30 28 25 22 19 18 16 13 11 10 8 7 6 5 5 4 3 2 2 2 2 2 2 2 2 18 46 59 69 77 83 88 93 97 100 102 104 105 103 98 95 92 93 100 105 111 115 115 115 120 122 123 121 119 114 107 97 96 96 94 93 86 75 63 50 33 5 3 3 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 3 5 8 11 16 19 24 29 35 41 47 53 60 67 74 81 88 94 101 108 115 121 128 135 143
+ 155 145 134 124 114 106 97 88 82 75 69 63 57 52 47 43 39 36 32 29 26 23 21 19 17 15 13 11 9 8 7 6 5 4 3 3 2 2 2 2 2 2 4 36 55 68 74 79 85 90 94 97 100 103 105 106 106 102 96 93 92 94 98 104 110 114 114 118 120 121 123 120 115 110 102 99 103 102 100 96 86 75 62 51 30 4 3 3 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 5 9 13 16 20 25 30 35 41 48 55 60 68 74 82 89 95 102 109 115 122 129 136 143
+ 155 144 134 123 114 105 97 89 82 76 69 64 59 53 49 45 41 37 34 31 27 25 23 20 19 16 14 12 11 10 7 7 6 5 3 3 3 2 2 2 2 2 20 41 57 70 81 86 88 91 94 98 101 103 105 107 106 104 98 94 91 90 90 97 101 109 114 117 118 118 121 121 117 113 106 103 106 106 106 102 93 86 78 65 50 31 6 3 3 2 2 2 2 2 1 2 2 2 2 2 2 2 2 3 6 9 13 17 21 26 31 36 42 49 55 61 68 75 82 89 95 102 109 116 123 130 137 144
+ 154 144 134 124 114 106 98 90 83 77 71 65 60 55 50 45 42 39 36 33 30 27 24 22 19 17 15 15 13 11 9 8 7 6 5 4 3 2 2 2 2 11 38 49 59 70 81 90 95 97 97 98 100 103 104 106 107 105 101 96 92 88 88 91 95 103 107 109 113 114 118 121 118 117 111 106 109 110 109 104 96 92 87 78 66 49 26 4 3 3 2 2 2 2 2 2 2 2 2 2 2 2 2 4 6 10 14 18 22 27 32 38 43 49 55 62 69 76 83 90 97 103 110 117 124 130 137 145
+ 154 145 135 124 115 107 98 90 84 77 72 67 61 56 51 48 44 41 38 34 31 29 26 24 22 20 17 16 15 12 12 10 9 7 5 5 3 3 2 2 2 23 48 63 72 75 82 88 94 100 102 102 101 102 103 105 105 104 102 98 93 90 87 88 91 95 101 104 105 109 113 118 119 117 114 106 110 110 106 102 96 92 88 80 68 51 28 4 3 2 2 2 2 2 2 2 2 2 2 2 2 2 2 4 7 11 15 19 23 28 34 38 45 50 57 63 70 77 84 91 98 105 111 118 125 131 138 146
+ 158 149 142 128 119 113 104 96 87 80 75 70 66 60 55 51 47 44 41 38 34 31 29 26 25 23 21 18 16 15 14 13 11 10 8 6 5 3 2 2 3 29 51 67 77 86 90 90 92 96 100 104 106 104 103 103 103 103 102 99 95 90 87 86 88 91 95 100 99 100 103 108 114 113 114 109 107 107 101 98 94 89 84 77 67 51 30 5 3 3 2 1 2 2 2 2 2 2 2 2 2 2 2 5 8 11 14 18 24 28 33 39 45 50 57 63 70 77 84 90 97 104 111 118 124 130 137 145
+ 156 157 164 130 127 142 132 123 95 81 77 96 92 84 62 53 70 70 65 52 36 33 44 45 42 39 35 24 27 20 17 16 16 15 9 6 4 3 2 3 18 46 64 76 84 91 98 99 96 96 99 103 107 109 107 104 102 101 100 97 93 87 85 84 86 88 91 93 92 91 93 99 105 106 102 99 98 97 93 91 88 81 73 69 57 40 16 4 3 3 2 2 2 2 2 2 2 2 2 2 1 2 4 7 9 13 17 22 26 31 36 42 47 54 60 67 74 80 87 93 100 107 114 121 127 133 140 147
+ 158 158 170 132 128 145 119 123 114 83 80 105 90 79 63 55 79 70 64 73 47 35 52 62 53 57 48 26 33 44 20 22 42 22 9 6 4 3 2 3 32 55 70 80 88 94 100 104 105 100 99 101 105 108 109 108 106 101 99 96 92 87 83 79 81 84 86 87 87 85 84 88 91 93 85 81 81 82 82 82 81 77 66 58 49 31 6 3 3 3 2 2 2 2 2 2 2 2 2 2 2 2 5 8 10 14 18 23 28 32 37 43 49 56 61 68 74 81 88 94 102 108 115 121 128 135 141 149
+ 159 159 171 133 130 150 120 126 114 85 83 108 83 71 60 57 82 67 51 74 54 36 36 42 56 44 27 23 23 46 43 46 37 14 9 6 4 3 3 13 45 64 76 85 92 97 102 105 108 109 105 102 102 105 107 109 109 107 102 98 93 88 83 79 79 80 81 82 82 82 83 80 76 77 73 66 64 65 65 65 66 64 56 44 34 17 4 3 2 2 2 2 2 2 2 2 2 2 2 2 2 3 6 9 12 15 20 24 29 34 39 44 51 58 63 69 76 83 89 96 104 110 117 123 129 136 142 150
+ 160 160 173 136 132 152 142 138 111 87 85 111 104 87 62 58 85 82 78 76 47 38 35 36 63 40 26 22 23 31 53 45 18 13 9 7 4 3 3 33 57 72 82 90 96 101 104 108 109 111 112 111 105 103 104 106 108 109 107 102 97 91 84 78 76 79 79 79 78 79 82 78 68 62 58 53 49 47 46 47 47 45 39 26 15 5 3 3 2 2 2 2 2 2 2 2 2 1 2 2 2 4 7 10 14 18 22 26 31 36 42 47 52 59 65 72 78 84 91 98 104 111 118 124 130 138 144 151
+ 166 158 178 144 130 154 126 120 130 95 87 107 92 77 64 61 78 83 73 78 49 39 36 36 59 51 27 23 22 24 39 43 17 13 10 7 5 4 10 43 64 78 88 93 100 103 106 108 109 111 112 114 114 111 105 104 105 107 108 107 105 99 91 82 76 76 76 76 77 77 78 76 69 58 49 39 34 29 26 26 25 24 21 10 4 3 3 2 2 2 2 2 2 2 2 1 2 2 2 2 3 5 8 11 14 18 23 27 32 36 42 47 53 60 66 72 79 85 92 98 105 112 118 124 130 137 143 150
+ 172 161 177 145 133 156 135 123 127 96 90 109 90 76 69 63 79 75 54 71 61 41 37 37 59 52 28 23 21 23 39 41 17 12 11 7 5 7 35 58 76 87 94 99 103 107 109 109 111 111 111 113 115 116 114 107 104 106 107 107 107 105 101 91 79 74 75 76 76 74 73 71 65 57 46 30 14 7 5 4 3 3 3 2 2 2 2 2 2 2 3 2 2 2 2 2 2 2 2 2 4 7 10 13 16 20 25 30 34 39 44 50 56 62 68 74 81 88 94 101 107 113 120 126 132 139 145 152
+ 167 162 159 140 138 144 138 126 104 94 93 107 104 96 74 64 81 64 52 64 63 42 37 38 61 42 26 23 21 24 45 31 16 11 8 7 8 34 59 76 88 96 102 106 108 110 111 110 110 110 112 112 114 116 117 115 109 106 106 107 107 106 104 99 86 76 74 77 75 73 68 64 59 53 38 14 4 3 2 2 2 2 2 2 2 2 2 2 2 2 2 1 2 2 2 2 2 2 2 4 6 9 12 16 20 23 28 33 38 44 48 53 60 66 72 79 85 91 98 105 111 117 123 130 135 142 149 156
+ 171 161 153 144 135 128 122 114 106 99 93 90 83 77 72 66 63 60 55 52 48 45 41 37 40 35 27 24 21 21 28 27 15 10 9 8 16 49 72 87 97 104 108 112 113 113 113 112 110 110 109 111 113 114 115 117 118 115 109 107 106 107 106 105 101 94 84 79 77 74 72 64 57 49 39 9 5 4 3 3 3 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 3 6 8 10 14 17 21 25 30 34 39 44 50 55 61 67 73 80 87 93 100 106 112 119 125 130 136 142 149 156
+ 170 161 152 143 135 128 122 114 107 100 94 88 82 77 71 66 63 60 55 52 48 43 40 36 35 30 26 23 21 20 19 17 14 11 10 19 46 65 85 97 106 111 114 117 117 117 115 113 111 110 109 111 112 114 115 116 117 118 116 110 107 107 107 106 104 101 96 89 80 77 73 64 53 38 21 8 7 7 5 5 3 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 3 6 8 10 14 16 20 24 29 33 38 43 48 53 59 65 72 78 84 91 97 104 110 116 122 128 134 140 147 153 160
+ 172 163 154 146 138 131 124 116 109 103 96 90 84 78 73 68 64 60 56 52 48 44 40 37 33 31 27 24 21 19 17 14 13 11 15 41 61 76 89 100 109 114 119 120 121 119 117 115 113 111 110 110 111 113 114 115 116 118 119 117 112 108 107 106 106 105 103 100 92 82 75 63 40 20 11 10 9 9 8 7 6 5 3 3 2 2 2 2 2 2 2 2 2 2 2 2 2 5 7 10 13 15 19 22 26 31 35 40 46 50 55 62 67 74 80 86 93 100 106 112 119 124 130 136 142 148 155 162
+ 175 166 157 149 141 133 127 119 111 105 99 92 86 80 75 70 66 62 58 53 49 45 41 38 34 32 27 24 21 19 16 14 11 14 34 57 72 85 95 103 110 115 120 122 124 123 121 120 116 114 112 110 110 111 113 113 115 116 119 120 118 112 109 107 107 106 107 105 103 94 77 63 34 15 12 11 13 12 10 9 8 6 4 3 3 3 3 3 2 3 2 2 2 2 2 2 4 6 9 12 15 18 22 25 29 33 37 42 48 53 58 64 69 77 83 90 96 102 108 114 121 126 132 138 144 151 157 163
+ 177 168 160 151 143 136 128 121 114 107 101 94 89 82 77 73 68 64 59 55 50 47 44 39 35 32 29 26 22 19 16 15 14 24 48 66 79 90 98 105 109 113 117 122 125 125 124 123 120 117 114 112 111 110 111 111 113 115 118 120 120 120 113 109 109 108 108 108 107 105 95 72 51 22 15 14 14 13 13 12 10 7 4 4 3 3 2 3 2 2 2 2 2 2 2 3 5 8 11 14 18 20 23 27 32 36 41 45 49 56 61 67 73 79 86 91 98 105 111 117 123 129 135 140 146 153 159 166
+ 182 173 164 156 147 140 132 125 118 111 104 98 92 87 81 76 71 67 62 57 53 50 45 41 39 34 31 28 24 21 18 16 16 31 54 70 82 91 99 105 109 112 114 117 122 125 127 127 126 122 119 116 114 111 112 111 110 113 116 118 121 123 122 116 110 109 110 111 111 108 106 96 69 44 20 16 16 16 15 13 12 9 7 5 3 3 2 3 2 2 2 2 2 2 4 5 7 10 12 16 18 22 26 29 34 38 42 46 51 57 61 67 73 79 86 92 99 106 112 118 124 130 135 142 148 155 160 166
+ 184 175 166 158 151 142 135 127 120 113 107 101 94 89 84 78 73 68 64 60 55 51 47 43 39 35 32 29 25 22 19 18 21 45 63 76 86 94 100 105 109 112 114 116 119 123 126 129 129 127 123 120 117 114 112 111 110 111 114 117 119 122 123 124 118 111 111 114 115 113 109 97 79 56 36 19 18 18 16 14 12 10 8 6 3 3 3 3 3 3 3 2 3 3 5 6 9 12 14 17 20 25 28 32 35 40 44 48 53 59 64 70 76 82 88 95 101 108 114 121 126 132 137 143 149 156 162 169
+ 186 176 170 160 153 145 137 130 123 116 110 104 97 91 87 81 75 70 65 61 56 54 48 45 40 38 33 30 27 22 20 18 31 55 70 81 90 97 102 106 111 113 115 116 118 121 122 126 130 131 129 124 121 118 114 112 110 111 112 115 118 122 125 126 125 120 116 116 120 122 121 104 89 82 69 42 31 29 18 15 13 11 9 7 4 4 2 2 2 2 2 3 4 5 7 9 11 14 17 20 23 27 30 33 39 41 47 50 56 61 67 72 79 85 91 98 103 111 117 123 129 135 140 145 152 158 165 171
+ 187 178 169 161 153 145 138 131 123 117 110 104 98 93 87 81 76 72 66 61 57 52 48 44 41 37 33 30 26 22 20 26 51 70 80 91 97 102 108 111 115 117 118 119 120 122 121 123 127 133 132 128 125 121 117 113 112 111 112 114 118 122 125 127 128 127 122 120 123 137 135 118 97 90 82 56 31 30 19 16 14 12 9 7 6 5 4 4 4 4 4 5 7 7 9 12 14 17 19 23 26 29 34 37 41 45 50 54 60 65 71 77 83 90 96 102 108 115 121 127 133 138 144 150 156 161 169 176
+ 193 183 174 166 157 150 143 135 128 121 114 108 102 96 91 85 79 75 69 65 60 56 52 47 44 39 35 31 27 23 21 32 58 74 86 95 102 108 112 115 119 121 122 124 124 123 122 122 121 126 133 133 130 127 123 119 115 112 112 113 116 120 124 127 129 129 130 130 134 137 141 127 104 96 91 73 43 30 29 19 16 13 12 9 8 7 6 5 5 5 6 7 9 10 12 13 15 19 21 25 28 32 35 38 42 47 51 55 61 66 72 78 85 91 97 104 110 116 122 128 134 139 145 150 157 163 170 178
+ 193 184 175 166 159 150 142 136 129 122 115 109 103 97 92 86 80 75 71 65 61 56 52 48 44 40 35 32 28 25 29 57 75 87 97 106 112 116 119 123 125 127 128 128 128 127 126 124 122 122 128 134 134 131 127 122 117 114 114 114 116 121 125 128 131 131 131 138 140 137 143 127 109 97 88 67 39 31 35 20 16 15 13 11 10 8 7 8 8 8 9 10 11 12 14 17 19 22 24 27 31 35 39 42 45 50 54 59 64 70 76 83 90 96 102 108 114 120 127 132 138 143 148 154 160 167 174 182
+ 196 187 178 170 161 154 146 138 131 125 118 111 106 101 95 89 84 77 72 67 63 59 54 50 45 41 36 32 29 28 50 72 87 98 107 114 120 123 127 130 132 134 133 132 132 131 128 125 123 121 121 126 132 134 131 126 120 116 115 116 117 121 125 128 133 132 132 142 143 135 143 135 111 93 86 62 31 28 27 19 18 17 15 13 11 11 9 10 10 10 12 13 13 15 17 19 22 25 27 30 34 38 41 45 48 52 57 62 67 73 80 86 92 98 105 111 118 124 130 135 141 146 151 157 163 170 177 185
+ 199 190 181 172 164 156 148 140 134 127 120 115 108 103 97 92 86 80 74 70 65 60 55 51 47 43 37 34 31 41 70 87 99 110 118 124 130 132 135 136 139 139 139 138 136 134 132 128 125 122 121 121 125 134 134 129 123 120 118 118 119 120 127 131 135 135 136 145 147 147 143 132 98 82 70 43 31 36 25 21 20 18 16 14 13 13 12 12 13 14 14 15 16 18 19 22 24 27 30 34 37 40 43 47 51 58 59 65 71 77 83 89 96 101 108 115 121 128 134 138 143 148 153 159 166 173 181 187
+ 203 194 184 175 167 159 151 144 137 130 123 118 112 106 100 94 89 83 77 72 67 62 57 53 48 44 39 36 40 67 87 101 112 121 127 132 136 140 141 142 144 144 143 142 141 139 136 133 129 125 123 122 122 128 136 134 129 123 120 119 119 120 125 132 136 137 138 146 149 149 143 130 100 84 67 48 44 37 27 22 22 20 19 17 16 15 15 15 15 16 18 19 20 26 23 26 28 31 35 38 41 44 47 51 54 58 64 70 78 82 87 93 99 105 112 118 124 132 138 142 146 151 157 162 168 176 183 190
+ 206 198 190 181 172 164 156 149 142 135 128 123 116 110 104 99 92 86 81 75 71 65 61 55 51 46 43 42 59 81 98 112 122 130 135 140 142 144 146 147 147 147 147 146 144 143 142 139 136 132 128 127 125 125 129 137 135 129 123 121 119 119 123 129 136 140 138 142 144 142 142 132 113 98 82 63 52 50 31 27 24 23 21 20 18 17 16 17 18 19 20 22 24 45 47 29 30 35 56 68 72 65 51 53 57 61 72 99 110 112 94 94 100 107 113 119 128 154 169 154 149 152 157 164 170 177 185 192
+ 207 200 190 182 173 165 158 150 143 136 130 123 118 111 106 100 94 88 82 76 71 66 61 56 51 48 47 64 86 103 117 127 134 139 144 147 148 150 150 149 148 148 147 146 144 144 143 143 141 137 133 131 128 127 127 135 135 130 124 121 119 119 122 130 138 143 145 147 148 147 140 130 119 104 88 72 58 53 47 30 27 25 23 21 22 20 19 20 21 21 24 26 30 58 42 32 35 66 68 58 66 85 69 59 62 69 105 104 101 125 109 100 105 112 118 126 154 173 176 150 152 156 162 168 175 184 189 196
+ 211 202 194 186 177 169 161 154 147 140 134 127 121 115 108 102 96 91 85 79 74 68 63 59 55 52 65 86 105 119 130 137 143 145 150 152 153 153 152 150 149 148 146 142 139 138 139 141 142 140 138 136 133 130 127 129 136 134 127 121 118 118 121 128 138 145 148 151 151 152 147 136 126 114 99 83 67 56 53 46 30 28 26 24 24 22 22 23 24 25 27 29 32 62 45 35 43 74 50 47 52 78 90 64 66 75 111 96 94 125 117 104 109 115 122 149 164 167 179 151 155 159 165 172 179 187 193 199
+ 214 205 198 188 180 172 165 158 151 145 137 130 124 118 112 106 100 94 88 82 77 71 66 61 57 65 86 105 121 131 140 145 149 151 154 155 156 155 153 152 150 149 147 143 139 134 130 130 134 139 140 140 136 132 128 127 132 136 130 122 118 117 119 125 137 145 151 155 156 155 152 144 132 123 111 95 78 64 55 53 45 32 29 27 26 25 26 26 26 28 30 31 37 65 47 38 44 75 55 50 53 71 98 68 70 77 107 121 120 135 110 108 113 121 146 161 145 163 181 154 157 162 168 175 182 190 195 203
+ 217 209 201 193 185 176 169 162 154 147 141 134 127 122 115 109 102 96 90 83 79 73 68 64 63 85 104 121 133 142 149 152 155 156 157 158 158 158 156 154 152 151 149 147 143 139 133 126 125 128 133 139 139 135 131 129 128 136 133 126 120 118 118 123 134 146 154 156 158 159 157 152 138 129 121 109 94 76 63 54 54 45 33 30 29 28 29 29 30 32 33 35 40 69 50 41 45 70 80 57 57 72 102 72 74 91 119 120 121 135 122 112 118 144 164 146 146 169 185 160 161 166 171 178 185 192 199 209
+ 222 213 204 196 189 180 173 165 158 151 144 137 131 125 118 112 106 99 93 87 82 76 70 67 80 104 121 135 145 152 157 159 160 161 161 160 159 159 157 156 154 152 149 149 148 144 140 132 124 121 122 127 135 137 134 130 128 132 136 130 125 121 121 123 132 145 155 159 161 162 160 157 148 132 127 121 110 92 77 63 54 54 45 35 32 32 31 33 33 34 36 39 44 72 52 45 47 52 66 58 62 83 104 75 78 108 117 96 100 120 145 117 128 160 171 172 176 185 192 191 190 170 174 181 188 195 203 219
+ 225 217 208 200 192 185 176 169 162 155 148 141 135 129 122 116 108 103 96 91 85 79 73 74 99 120 135 147 156 162 165 166 167 165 164 162 160 158 157 155 152 151 151 150 151 149 145 139 131 123 119 119 124 133 136 131 128 130 138 133 127 124 123 126 131 144 156 161 163 164 163 161 155 141 130 126 121 110 94 77 62 54 55 45 36 34 35 35 37 38 39 42 48 75 55 49 52 54 57 60 65 97 102 77 83 113 118 98 104 125 154 124 128 142 149 156 165 183 195 185 184 174 177 184 192 199 207 231
+ 232 223 215 206 199 191 183 176 167 161 154 147 141 134 127 121 114 108 102 96 89 84 77 81 111 129 145 157 166 172 175 175 173 173 170 167 163 158 156 153 151 148 149 150 151 151 150 147 141 132 124 118 118 122 132 135 133 129 136 139 132 128 126 126 132 140 154 162 164 165 166 164 160 154 139 131 127 123 114 98 81 63 54 56 47 39 38 39 39 40 43 45 49 74 70 53 55 58 60 64 70 103 96 80 84 96 127 125 122 142 155 129 127 131 136 142 149 168 193 169 171 175 180 187 194 201 212 234
+ 238 227 219 211 203 195 187 180 172 164 158 151 144 138 131 125 118 112 107 99 92 86 82 101 126 145 160 172 179 182 184 184 183 181 179 177 173 167 161 156 151 147 144 147 150 152 152 150 147 139 131 122 118 118 123 134 141 145 144 143 138 132 129 129 131 140 152 162 166 167 167 168 165 161 152 136 132 128 123 112 97 79 61 56 59 46 42 42 43 43 46 49 52 59 59 56 59 62 64 69 92 106 83 83 88 93 109 132 143 145 135 127 131 134 138 145 151 164 183 170 173 179 185 191 198 206 224 236
+ 245 229 220 212 205 198 190 182 175 167 160 153 147 140 134 127 121 114 107 102 94 88 99 130 150 164 175 182 187 188 189 189 188 186 184 181 179 175 170 165 157 151 145 143 146 149 151 150 149 143 135 125 119 117 121 130 143 154 153 149 142 137 133 133 135 142 154 165 168 169 170 170 168 165 159 142 135 132 127 119 104 89 71 60 60 59 47 46 46 48 49 52 55 57 58 62 64 67 71 96 105 85 84 87 93 99 105 112 120 124 127 132 136 139 143 150 156 163 168 171 177 184 191 197 204 217 236 236
+ 241 238 227 219 211 204 196 189 181 174 166 159 152 147 140 134 127 120 113 106 99 96 116 143 161 173 181 186 191 192 191 192 191 190 187 185 182 180 177 172 168 162 156 147 142 143 147 149 150 148 143 136 127 122 117 122 134 149 156 152 148 142 138 137 136 142 150 162 169 171 172 172 172 171 168 160 143 138 134 126 114 102 89 74 64 64 63 52 50 51 52 56 58 59 62 65 67 71 88 106 93 85 87 91 97 101 107 112 118 123 128 133 138 142 147 152 158 164 169 175 180 186 193 199 207 224 237 235
+ 219 247 232 224 217 208 201 193 185 177 171 164 158 151 145 138 132 125 118 111 104 110 138 159 173 181 186 190 191 194 193 193 192 192 190 187 185 182 178 175 172 168 164 158 149 139 140 145 147 149 146 143 136 127 121 119 128 142 157 155 150 146 142 141 140 143 150 160 169 171 173 173 175 175 174 169 155 143 139 133 120 110 100 87 74 66 68 64 55 54 55 58 61 64 66 68 72 76 86 89 86 88 92 96 100 106 112 116 121 126 131 137 142 146 152 157 162 168 173 179 185 191 197 204 214 234 236 234
+ 197 244 235 228 219 211 203 195 188 181 174 168 161 155 148 141 135 128 120 114 111 137 158 174 183 188 191 192 193 195 195 193 193 191 190 188 184 181 178 175 172 169 166 162 153 143 136 139 145 147 147 145 142 135 126 120 125 140 156 156 151 146 145 143 144 146 152 161 169 173 175 176 179 180 178 174 163 147 143 138 125 115 106 97 85 74 71 73 62 60 61 62 65 69 71 74 76 80 84 88 91 94 97 101 106 112 117 121 127 131 136 141 147 152 157 163 168 173 179 185 192 197 204 212 232 237 235 230
+ 165 227 246 231 224 216 207 201 193 186 179 172 166 159 153 146 139 132 126 120 127 153 168 181 188 193 196 196 196 194 195 195 193 193 190 187 184 181 178 175 172 170 167 164 157 149 138 133 140 145 146 146 146 141 133 125 124 133 154 158 153 149 148 147 148 148 152 159 168 174 176 178 181 183 182 180 172 155 149 145 136 124 116 108 98 86 78 77 77 66 65 67 68 71 75 79 81 84 88 92 95 98 101 106 111 116 120 125 129 135 140 145 150 156 161 167 172 178 184 190 196 202 209 221 236 235 233 231
+ 129 191 241 238 229 222 213 206 199 192 184 177 171 165 158 151 144 137 130 125 141 162 176 186 193 197 199 198 197 196 196 195 194 192 190 187 183 179 176 174 171 170 168 164 158 152 144 134 134 140 143 144 146 144 140 132 128 132 149 161 158 153 150 150 150 152 152 156 165 175 178 181 183 185 186 184 178 166 156 152 146 137 125 117 109 99 89 81 82 82 72 72 73 77 79 82 85 90 92 95 101 103 107 111 116 120 125 130 135 139 144 149 155 159 165 171 176 182 189 195 200 206 215 234 237 235 232 225
+ 85 155 212 246 234 226 219 211 203 197 190 182 175 169 162 156 149 141 136 132 152 169 181 191 198 201 202 201 199 197 196 195 194 192 190 186 183 178 175 172 171 168 167 164 160 153 146 139 132 134 139 141 143 144 142 136 134 134 144 162 162 158 153 148 149 150 150 153 160 170 179 182 185 188 189 187 182 176 164 159 154 147 138 128 118 109 101 91 83 88 87 77 78 81 83 87 90 92 97 101 104 107 111 115 120 125 129 133 139 143 148 153 159 164 169 175 181 187 194 199 204 211 226 237 236 233 230 186
+ 19 94 163 220 244 233 226 218 210 202 197 189 182 175 168 161 155 147 140 137 154 172 184 192 199 203 205 205 203 200 196 194 193 192 190 187 183 179 175 173 170 169 168 167 163 157 151 145 138 129 132 135 137 142 144 140 138 137 140 154 167 165 160 154 152 152 150 148 152 160 176 184 186 190 191 190 188 183 175 167 163 155 148 139 128 119 111 103 94 88 94 93 83 85 87 90 93 96 101 104 108 111 115 119 123 128 132 137 141 146 151 156 162 167 174 178 184 190 196 201 207 215 234 237 235 232 226 162
+ 1 68 139 197 244 238 229 222 214 206 200 193 185 178 172 165 157 150 145 142 166 182 190 197 202 205 207 207 205 201 197 193 192 191 190 185 182 177 174 172 171 169 167 169 167 159 152 148 142 132 127 130 131 139 144 141 139 140 142 153 170 170 166 163 163 162 160 156 159 165 178 187 191 194 194 193 191 187 181 173 166 158 152 143 132 123 114 109 101 92 96 102 93 89 92 95 98 102 106 109 113 117 120 125 129 133 137 142 147 152 156 162 166 173 178 185 191 196 202 207 214 232 238 236 232 228 169 84
+ 1 3 73 143 200 243 237 230 222 215 206 200 193 185 178 171 164 157 150 147 166 184 192 198 203 206 208 208 207 204 199 194 191 190 189 186 183 178 175 172 171 171 172 171 171 167 161 153 148 142 128 121 124 129 140 143 140 140 142 145 164 174 173 169 167 166 166 161 157 160 172 187 192 196 197 196 195 192 189 182 175 166 157 151 143 131 122 115 110 102 96 102 109 103 97 99 102 105 109 113 116 120 124 128 133 136 140 145 150 155 160 165 170 175 181 187 193 199 203 210 220 237 236 235 231 211 138 37
+ 2 2 27 97 162 221 243 234 228 220 212 205 198 191 183 176 168 162 154 152 171 187 195 200 205 207 208 209 209 205 201 195 191 190 188 185 183 180 176 173 171 170 171 170 173 171 167 161 153 148 136 117 117 120 133 142 140 140 144 144 158 176 178 175 172 171 169 165 160 160 169 186 196 200 200 199 197 196 194 189 181 175 166 156 149 139 129 121 117 112 102 104 112 116 105 104 106 109 112 117 120 124 128 132 136 141 145 149 154 159 164 169 174 180 186 193 197 202 208 215 234 238 234 233 224 160 74 4
+ 2 1 1 49 117 180 229 242 233 226 219 210 204 196 188 182 173 166 159 157 177 191 198 203 206 208 209 209 209 208 203 197 191 189 187 184 183 181 178 175 172 172 169 168 171 173 169 163 159 154 145 124 111 114 124 139 140 142 143 142 152 174 182 181 177 174 173 169 164 161 167 185 199 204 204 201 200 199 199 195 188 183 175 164 154 146 137 129 122 118 110 109 114 122 122 111 111 113 117 121 125 129 133 137 141 145 149 154 159 163 167 173 179 185 191 196 201 206 214 229 237 237 233 228 180 103 4 4
+ 1 1 1 17 84 149 207 243 238 230 222 214 207 200 192 185 177 168 162 168 186 196 202 205 208 210 210 210 210 208 205 198 190 186 184 183 182 181 180 178 175 173 166 166 168 172 170 163 158 156 150 131 110 111 119 137 140 141 142 142 152 174 187 186 182 178 175 172 165 162 167 185 203 207 207 203 203 203 202 197 192 187 183 172 158 147 141 133 127 123 117 116 119 127 131 123 118 120 123 127 130 134 137 142 146 151 154 159 164 169 173 179 185 191 196 201 206 213 228 237 236 233 229 189 111 12 3 3
+ 1 1 1 1 34 100 162 218 243 236 229 221 212 204 197 189 181 173 167 176 192 200 205 208 210 212 211 211 210 210 208 205 197 189 184 182 182 182 182 180 178 176 168 168 166 168 171 168 160 153 152 143 120 107 112 134 139 141 142 140 148 169 187 191 188 184 180 176 170 164 166 179 201 209 210 207 205 206 206 202 196 190 188 181 169 153 145 141 135 129 123 123 121 130 138 139 128 125 128 131 135 138 143 146 151 155 159 164 168 173 179 185 191 196 200 206 211 224 237 237 234 230 200 129 37 3 4 3
+ 1 1 1 1 1 37 101 162 215 241 238 229 221 212 203 196 188 180 173 177 194 203 207 211 212 213 213 213 212 211 211 209 206 199 192 185 185 182 182 182 180 179 175 173 169 168 168 171 167 157 149 149 138 113 107 123 138 141 142 140 143 162 182 195 196 192 186 181 177 170 166 171 191 210 212 210 207 208 208 207 201 196 191 190 183 171 154 145 142 138 130 125 127 127 139 146 147 133 132 135 138 141 145 149 153 157 162 167 172 177 182 188 195 199 203 209 217 234 238 235 231 224 166 89 6 4 4 3
+ 1 1 1 1 1 4 68 132 186 230 242 233 226 215 207 199 191 183 177 189 202 208 212 213 215 215 215 215 214 214 212 211 208 204 199 194 188 184 183 182 180 180 175 175 172 169 168 170 170 162 148 144 141 117 109 124 139 143 143 140 146 167 185 198 202 197 193 187 182 174 169 172 191 212 215 211 208 210 212 210 204 200 193 193 190 181 165 150 145 142 133 128 133 133 144 151 154 143 138 140 143 147 151 155 159 163 168 173 178 184 189 195 200 204 210 217 235 238 236 231 221 164 90 5 4 3 3 3
+ 1 2 1 1 1 1 14 79 140 193 235 240 232 222 213 204 196 187 181 193 205 211 215 217 218 219 219 218 217 216 215 213 210 206 203 200 196 191 188 184 183 180 180 178 176 173 170 169 171 169 156 144 141 128 112 120 140 143 143 143 146 165 186 198 206 205 199 194 187 179 172 173 187 213 217 215 211 212 214 215 211 205 198 195 193 190 181 163 149 145 139 133 139 137 146 156 160 159 145 145 147 151 155 159 163 168 173 178 184 189 196 200 204 210 216 233 238 237 232 225 176 106 10 3 3 3 3 3
+
+
--- a/examples/embedded.cc	Fri Feb 06 08:31:09 2015 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,35 +0,0 @@
-#include <iostream>
-#include <octave/oct.h>
-#include <octave/octave.h>
-#include <octave/parse.h>
-#include <octave/toplev.h>
-
-int
-main (void)
-{
-  string_vector argv (2);
-  argv(0) = "embedded";
-  argv(1) = "-q";
-
-  octave_main (2, argv.c_str_vec (), 1);
-
-  octave_idx_type n = 2;
-  octave_value_list in;
-
-  for (octave_idx_type i = 0; i < n; i++)
-    in(i) = octave_value (5 * (i + 2));
-
-  octave_value_list out = feval ("gcd", in, 1);
-
-  if (! error_state && out.length () > 0)
-    std::cout << "GCD of ["
-              << in(0).int_value ()
-              << ", "
-              << in(1).int_value ()
-              << "] is " << out(0).int_value ()
-              << std::endl;
-  else
-    std::cout << "invalid\n";
-
-  clean_up_and_exit (0);
-}
--- a/examples/fortrandemo.cc	Fri Feb 06 08:31:09 2015 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,35 +0,0 @@
-#include <octave/oct.h>
-#include <octave/f77-fcn.h>
-
-extern "C"
-{
-  F77_RET_T
-  F77_FUNC (fortransub, FORTSUB)
-    (const int&, double*, F77_CHAR_ARG_DECL F77_CHAR_ARG_LEN_DECL);
-}
-
-DEFUN_DLD (fortrandemo, args, , "Fortran Demo")
-{
-  octave_value_list retval;
-  int nargin = args.length ();
-
-  if (nargin != 1)
-    print_usage ();
-  else
-    {
-      NDArray a = args(0).array_value ();
-      if (! error_state)
-        {
-          double *av = a.fortran_vec ();
-          octave_idx_type na = a.numel ();
-          OCTAVE_LOCAL_BUFFER (char, ctmp, 128);
-
-          F77_XFCN (fortransub, FORTSUB,
-                    (na, av, ctmp F77_CHAR_ARG_LEN (128)));
-
-          retval(1) = std::string (ctmp);
-          retval(0) = a;
-        }
-    }
-  return retval;
-}
--- a/examples/fortransub.f	Fri Feb 06 08:31:09 2015 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,21 +0,0 @@
-      subroutine fortransub (n, a, s)
-      implicit none
-      character*(*) s
-      real*8 a(*)
-      integer*4 i, n, ioerr
-      do i = 1, n
-        if (a(i) .eq. 0d0) then
-          call xstopx ('fortransub: divide by zero')
-        else
-          a(i) = 1d0 / a(i)
-        endif
-      enddo
-      write (unit = s, fmt = '(a,i3,a,a)', iostat = ioerr)
-     $       'There are ', n,
-     $       ' values in the input vector', char(0)
-      if (ioerr .ne. 0) then
-        call xstopx ('fortransub: error writing string')
-      endif
-      return
-      end
-
--- a/examples/funcdemo.cc	Fri Feb 06 08:31:09 2015 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,32 +0,0 @@
-#include <octave/oct.h>
-#include <octave/parse.h>
-
-DEFUN_DLD (funcdemo, args, nargout, "Function Demo")
-{
-  octave_value_list retval;
-  int nargin = args.length ();
-
-  if (nargin < 2)
-    print_usage ();
-  else
-    {
-      octave_value_list newargs;
-      for (octave_idx_type i = nargin - 1; i > 0; i--)
-        newargs(i-1) = args(i);
-      if (args(0).is_function_handle () || args(0).is_inline_function ())
-        {
-          octave_function *fcn = args(0).function_value ();
-          if (! error_state)
-            retval = feval (fcn, newargs, nargout);
-        }
-      else if (args(0).is_string ())
-        {
-          std::string fcn = args(0).string_value ();
-          if (! error_state)
-            retval = feval (fcn, newargs, nargout);
-        }
-      else
-        error ("funcdemo: INPUT must be string, inline, or function handle");
-    }
-  return retval;
-}
--- a/examples/globaldemo.cc	Fri Feb 06 08:31:09 2015 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,25 +0,0 @@
-#include <octave/oct.h>
-
-DEFUN_DLD (globaldemo, args, , "Global Demo")
-{
-  octave_value retval;
-  int nargin = args.length ();
-
-  if (nargin != 1)
-    print_usage ();
-  else
-    {
-      std::string s = args(0).string_value ();
-      if (! error_state)
-        {
-          octave_value tmp = get_global_value (s, true);
-          if (tmp.is_defined ())
-            retval = tmp;
-          else
-            retval = "Global variable not found";
-
-          set_global_value ("a", 42.0);
-        }
-    }
-  return retval;
-}
--- a/examples/helloworld.cc	Fri Feb 06 08:31:09 2015 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,13 +0,0 @@
-#include <octave/oct.h>
-
-DEFUN_DLD (helloworld, args, nargout,
-           "Hello World Help String")
-{
-  int nargin = args.length ();
-
-  octave_stdout << "Hello World has "
-                << nargin << " input arguments and "
-                << nargout << " output arguments.\n";
-
-  return octave_value_list ();
-}
--- a/examples/make_int.cc	Fri Feb 06 08:31:09 2015 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,316 +0,0 @@
-#include <octave/config.h>
-
-#include <cstdlib>
-
-#include <string>
-
-#include <ostream>
-
-#include <octave/lo-mappers.h>
-#include <octave/lo-utils.h>
-#include <octave/mx-base.h>
-#include <octave/str-vec.h>
-
-#include <octave/defun-dld.h>
-#include <octave/error.h>
-#include <octave/gripes.h>
-#include <octave/oct-obj.h>
-#include <octave/ops.h>
-#include <octave/ov-base.h>
-#include <octave/ov-typeinfo.h>
-#include <octave/ov.h>
-#include <octave/ov-scalar.h>
-#include <octave/pager.h>
-#include <octave/pr-output.h>
-#include <octave/symtab.h>
-#include <octave/variables.h>
-
-class octave_value_list;
-
-class tree_walker;
-
-// Integer values.
-
-class
-octave_integer : public octave_base_value
-{
-public:
-
-  octave_integer (void)
-    : octave_base_value (), scalar (0) { }
-
-  octave_integer (int i)
-    : octave_base_value (), scalar (i) { }
-
-  octave_integer (const octave_integer& s)
-    : octave_base_value (), scalar (s.scalar) { }
-
-  ~octave_integer (void) { }
-
-  octave_base_value *clone (void) { return new octave_integer (*this); }
-
-#if 0
-  void *operator new (size_t size);
-  void operator delete (void *p, size_t size);
-#endif
-
-  idx_vector index_vector (void) const { return idx_vector ((double) scalar); }
-
-  int rows (void) const { return 1; }
-  int columns (void) const { return 1; }
-
-  bool is_constant (void) const { return true; }
-
-  bool is_defined (void) const { return true; }
-  bool is_real_scalar (void) const { return true; }
-
-  octave_value all (void) const { return (double) (scalar != 0); }
-  octave_value any (void) const { return (double) (scalar != 0); }
-
-  bool is_real_type (void) const { return true; }
-  bool is_scalar_type (void) const { return true; }
-  bool is_numeric_type (void) const { return true; }
-
-  bool valid_as_scalar_index (void) const
-  { return scalar == 1; }
-
-  bool valid_as_zero_index (void) const
-  { return scalar == 0; }
-
-  bool is_true (void) const { return (scalar != 0); }
-
-  double double_value (bool = false) const { return (double) scalar; }
-
-  int integer_value (bool = false) const { return scalar; }
-
-  Matrix matrix_value (bool = false) const { return Matrix (1, 1, scalar); }
-
-  Complex complex_value (bool = false) const { return scalar; }
-
-  ComplexMatrix complex_matrix_value (bool = false) const
-  { return  ComplexMatrix (1, 1, Complex (scalar)); }
-
-  octave_value gnot (void) const { return octave_value ((double) ! scalar); }
-
-  octave_value uminus (void) const { return new octave_integer (- scalar); }
-
-  octave_value transpose (void) const { return new octave_integer (scalar); }
-
-  octave_value hermitian (void) const { return new octave_integer (scalar); }
-
-  void increment (void) { ++scalar; }
-
-  void decrement (void) { --scalar; }
-
-  void print (std::ostream& os, bool pr_as_read_syntax = false) const;
-
-private:
-
-  int scalar;
-
-  DECLARE_OCTAVE_ALLOCATOR
-
-  DECLARE_OV_TYPEID_FUNCTIONS_AND_DATA
-};
-
-void
-octave_integer::print (std::ostream& os, bool pr_as_read_syntax) const
-{
-  os << scalar;
-  // octave_print_internal (os, scalar, pr_as_read_syntax);
-}
-
-#ifdef DEFUNOP_OP
-#undef DEFUNOP_OP
-#endif
-
-#define DEFUNOP_OP(name, t, op) \
-  UNOPDECL (name, a) \
-  { \
-    CAST_UNOP_ARG (const octave_ ## t&); \
-    return octave_value (new octave_integer (op v.t ## _value ())); \
-  }
-
-DEFUNOP_OP (gnot, integer, !)
-DEFUNOP_OP (uminus, integer, -)
-DEFUNOP_OP (transpose, integer, /* no-op */)
-DEFUNOP_OP (hermitian, integer, /* no-op */)
-
-DEFNCUNOP_METHOD (incr, integer, increment)
-DEFNCUNOP_METHOD (decr, integer, decrement)
-
-#ifdef DEFBINOP_OP
-#undef DEFBINOP_OP
-#endif
-
-#define DEFBINOP_OP(name, t1, t2, op) \
-  BINOPDECL (name, a1, a2) \
-  { \
-    CAST_BINOP_ARGS (const octave_ ## t1&, const octave_ ## t2&); \
-    return octave_value \
-      (new octave_integer (v1.t1 ## _value () op v2.t2 ## _value ())); \
-  }
-
-// integer by integer ops.
-
-DEFBINOP_OP (add, integer, integer, +)
-DEFBINOP_OP (sub, integer, integer, -)
-DEFBINOP_OP (mul, integer, integer, *)
-
-DEFBINOP (div, integer, integer)
-{
-  CAST_BINOP_ARGS (const octave_integer&, const octave_integer&);
-
-  int d = v2.integer_value ();
-
-  if (d == 0)
-    gripe_divide_by_zero ();
-
-  return new octave_integer (v1.integer_value () / d);
-}
-
-
-DEFBINOP (i_s_div, integer, scalar)
-{
-  CAST_BINOP_ARGS (const octave_integer&, const octave_scalar&);
-
-  double d = v2.double_value ();
-
-  if (d == 0.0)
-    gripe_divide_by_zero ();
-
-  return new octave_scalar (v1.double_value () / d);
-}
-
-DEFBINOP (ldiv, integer, integer)
-{
-  CAST_BINOP_ARGS (const octave_integer&, const octave_integer&);
-
-  int d = v1.integer_value ();
-
-  if (d == 0)
-    gripe_divide_by_zero ();
-
-  return new octave_integer (v2.integer_value () / d);
-}
-
-DEFBINOP_OP (lt, integer, integer, <)
-DEFBINOP_OP (le, integer, integer, <=)
-DEFBINOP_OP (eq, integer, integer, ==)
-DEFBINOP_OP (ge, integer, integer, >=)
-DEFBINOP_OP (gt, integer, integer, >)
-DEFBINOP_OP (ne, integer, integer, !=)
-
-DEFBINOP_OP (el_mul, integer, integer, !=)
-
-DEFBINOP (el_div, integer, integer)
-{
-  CAST_BINOP_ARGS (const octave_integer&, const octave_integer&);
-
-  int d = v2.integer_value ();
-
-  if (d == 0)
-    gripe_divide_by_zero ();
-
-  return new octave_integer (v1.integer_value () / d);
-}
-
-DEFBINOP (el_ldiv, integer, integer)
-{
-  CAST_BINOP_ARGS (const octave_integer&, const octave_integer&);
-
-  int d = v1.integer_value ();
-
-  if (d == 0)
-    gripe_divide_by_zero ();
-
-  return new octave_integer (v2.integer_value () / d);
-}
-
-DEFBINOP_OP (el_and, integer, integer, &&)
-DEFBINOP_OP (el_or, integer, integer, ||)
-
-DEFUN_DLD (make_int, args, ,
-           "int_val = make_int (val)\n\
-\n\
-Creates an integer variable from VAL.")
-{
-  static bool type_loaded = false;
-
-  if (! type_loaded)
-    {
-      octave_integer::register_type ();
-      mlock ();
-
-      octave_stdout << "installing integer type at type-id = "
-                    << octave_integer::static_type_id () << "\n";
-
-      INSTALL_UNOP (op_not, octave_integer, gnot);
-      INSTALL_UNOP (op_uminus, octave_integer, uminus);
-      INSTALL_UNOP (op_transpose, octave_integer, transpose);
-      INSTALL_UNOP (op_hermitian, octave_integer, hermitian);
-
-      INSTALL_NCUNOP (op_incr, octave_integer, incr);
-      INSTALL_NCUNOP (op_decr, octave_integer, decr);
-
-      INSTALL_BINOP (op_add, octave_integer, octave_integer, add);
-      INSTALL_BINOP (op_sub, octave_integer, octave_integer, sub);
-      INSTALL_BINOP (op_mul, octave_integer, octave_integer, mul);
-      INSTALL_BINOP (op_div, octave_integer, octave_integer, div);
-      INSTALL_BINOP (op_ldiv, octave_integer, octave_integer, ldiv);
-      INSTALL_BINOP (op_lt, octave_integer, octave_integer, lt);
-      INSTALL_BINOP (op_le, octave_integer, octave_integer, le);
-      INSTALL_BINOP (op_eq, octave_integer, octave_integer, eq);
-      INSTALL_BINOP (op_ge, octave_integer, octave_integer, ge);
-      INSTALL_BINOP (op_gt, octave_integer, octave_integer, gt);
-      INSTALL_BINOP (op_ne, octave_integer, octave_integer, ne);
-      INSTALL_BINOP (op_el_mul, octave_integer, octave_integer, el_mul);
-      INSTALL_BINOP (op_el_div, octave_integer, octave_integer, el_div);
-      INSTALL_BINOP (op_el_ldiv, octave_integer, octave_integer, el_ldiv);
-      INSTALL_BINOP (op_el_and, octave_integer, octave_integer, el_and);
-      INSTALL_BINOP (op_el_or, octave_integer, octave_integer, el_or);
-
-      INSTALL_BINOP (op_div, octave_integer, octave_scalar, i_s_div);
-    }
-
-  octave_value retval;
-
-  if (args.length () == 1)
-    {
-      double d = args(0).double_value ();
-
-      if (! error_state)
-        retval = octave_value (new octave_integer (NINT (d)));
-    }
-  else
-    usage ("make_int");
-
-  return retval;
-}
-
-DEFUN_DLD (doit, args, ,
-           "doit (I)")
-{
-  octave_value_list retval;
-
-  if (args(0).type_id () == octave_integer::static_type_id ())
-    {
-      // At this point, we know we have a handle for an octave_integer
-      // object, so we can peek at the representation and extract the
-      // data.
-
-      const octave_base_value& rep = args(0).get_rep ();
-
-      int my_value = ((const octave_integer&) rep) . integer_value ();
-
-      message ("doit", "your lucky number is: %d", my_value);
-    }
-  else
-    gripe_wrong_type_arg ("doit", args(0));
-
-  return retval;
-}
-
-DEFINE_OCTAVE_ALLOCATOR (octave_integer);
-
-DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA (octave_integer, "integer", "integer");
--- a/examples/mex_demo.c	Fri Feb 06 08:31:09 2015 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,58 +0,0 @@
-// mex_demo.c -- example of a dynamically linked function for Octave.
-
-// To use this file, your version of Octave must support dynamic
-// linking.  To find out if it does, type the command
-//
-//   octave_config_info ("ENABLE_DYNAMIC_LINKING")
-//
-// at the Octave prompt.  Support for dynamic linking is included if
-// this expression returns the string "yes".
-//
-// To compile this file, type the command
-//
-//   mkoctfile --mex mex_demo.c
-//
-// from within Octave or from the shell prompt.  This will create a file
-// called mex_demo.mex that can be loaded by Octave.  To test the mex_demo.mex
-// file, start Octave and type the command
-//
-// d = mex_demo ("easy as", 1, 2, 3)
-//
-// at the Octave prompt.  Octave should respond by printing
-//
-//   Hello, world!
-//   I have 4 inputs and 1 output
-//   d =  1.2346
-
-// Additional samples of code are in the examples directory of the Octave
-// distribution.  See also the chapter External Code Interface in the
-// documentation.
-
-#include "mex.h"
-
-// Every user function should include "mex.h" which imports the basic set of
-// function prototypes necessary for dynamically linked functions.  In
-// particular, it will declare mexFunction which is used by every function
-// which will be visible to Octave.  A mexFunction is visible in Octave under
-// the name of the source code file without the extension.
-
-// The four arguments to mexFunction are:
-// 1) The number of return arguments (# of left-hand side args).
-// 2) An array of pointers to return arguments.
-// 3) The number of input arguments (# of right-hand side args).
-// 4) An array of pointers to input arguments.
-
-void
-mexFunction (int nlhs, mxArray *plhs[],
-             int nrhs, const mxArray *prhs[])
-{
-  mexPrintf ("Hello, World!\n");
-
-  mexPrintf ("I have %d inputs and %d outputs\n", nrhs, nlhs);
-
-  mxArray *v = mxCreateDoubleMatrix (1, 1, mxREAL);
-  double *data = mxGetPr (v);
-  *data = 1.23456789;
-
-  plhs[0] = v;
-}
--- a/examples/mycell.c	Fri Feb 06 08:31:09 2015 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,18 +0,0 @@
-#include "mex.h"
-
-void
-mexFunction (int nlhs, mxArray* plhs[],
-             int nrhs, const mxArray* prhs[])
-{
-  mwSize n;
-  mwIndex i;
-
-  if (nrhs != 1 || ! mxIsCell (prhs[0]))
-    mexErrMsgTxt ("ARG1 must be a cell");
-
-  n = mxGetNumberOfElements (prhs[0]);
-  n = (n > nlhs ? nlhs : n);
-
-  for (i = 0; i < n; i++)
-    plhs[i] = mxDuplicateArray (mxGetCell (prhs[0], i));
-}
--- a/examples/myfeval.c	Fri Feb 06 08:31:09 2015 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,27 +0,0 @@
-#include "mex.h"
-
-void
-mexFunction (int nlhs, mxArray* plhs[],
-             int nrhs, const mxArray* prhs[])
-{
-  char *str;
-
-  mexPrintf ("Starting file myfeval.mex\n");
-
-  mexPrintf ("I have %d inputs and %d outputs\n", nrhs, nlhs);
-
-  if (nrhs < 1 || ! mxIsString (prhs[0]))
-    mexErrMsgTxt ("ARG1 must be a function name");
-
-  str = mxArrayToString (prhs[0]);
-
-  mexPrintf ("I'm going to call the function %s\n", str);
-
-  if (nlhs == 0)
-    nlhs = 1;  // Octave's automatic 'ans' variable
-
-  /* Cast prhs just to get rid of 'const' qualifier and stop compile warning */
-  mexCallMATLAB (nlhs, plhs, nrhs-1, (mxArray**)prhs+1, str);
-
-  mxFree (str);
-}
--- a/examples/myfevalf.f	Fri Feb 06 08:31:09 2015 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,30 +0,0 @@
-      subroutine mexFunction (nlhs, plhs, nrhs, prhs)
-
-      implicit none
-
-      integer*4 nlhs, nrhs
-
-* The following will need to be integer*8 on 64-bit systems, otherwise
-* these variables won't be large enough to hold pointers...
-      integer*4 plhs(*), prhs(*)
-
-      integer*4 mxIsString, mxGetString, mxGetN, mexCallMATLAB
-      integer*4 status, len
-      character*100 str
-
-      call mexPrintf ('Hello, World!')
-
-      if (nrhs .lt. 1 .or. mxIsString (prhs(1)) .ne. 1) then
-        call mexErrMsgTxt ('function name expected')
-      endif
-
-      len = mxGetN (prhs(1))
-
-      status = mxGetString (prhs(1), str, 100)
-
-      call mexPrintf ('FORTRAN will call the interpreter now')
-
-      status = mexCallMATLAB (nlhs, plhs, nrhs-1, prhs(2), str(1:len))
-
-      return
-      end
--- a/examples/myfunc.c	Fri Feb 06 08:31:09 2015 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,15 +0,0 @@
-#include "mex.h"
-
-void
-mexFunction (int nlhs, mxArray *plhs[],
-             int nrhs, const mxArray *prhs[])
-{
-  const char *nm;
-
-  nm = mexFunctionName ();
-  mexPrintf ("You called function: %s\n", nm);
-  if (strcmp (nm, "myfunc") == 0)
-    mexPrintf ("This is the principal function\n", nm);
-
-  return;
-}
--- a/examples/myhello.c	Fri Feb 06 08:31:09 2015 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,10 +0,0 @@
-#include "mex.h"
-
-void
-mexFunction (int nlhs, mxArray *plhs[],
-             int nrhs, const mxArray *prhs[])
-{
-  mexPrintf ("Hello, World!\n");
-
-  mexPrintf ("I have %d inputs and %d outputs\n", nrhs, nlhs);
-}
--- a/examples/mypow2.c	Fri Feb 06 08:31:09 2015 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,39 +0,0 @@
-#include "mex.h"
-
-void
-mexFunction (int nlhs, mxArray* plhs[],
-             int nrhs, const mxArray* prhs[])
-{
-  mwSize n;
-  mwIndex i;
-  double *vri, *vro;
-
-  if (nrhs != 1 || ! mxIsNumeric (prhs[0]))
-    mexErrMsgTxt ("ARG1 must be a matrix");
-
-  n = mxGetNumberOfElements (prhs[0]);
-  plhs[0] = mxCreateNumericArray (mxGetNumberOfDimensions (prhs[0]),
-                                  mxGetDimensions (prhs[0]),
-                                  mxGetClassID (prhs[0]),
-                                  mxIsComplex (prhs[0]));
-  vri = mxGetPr (prhs[0]);
-  vro = mxGetPr (plhs[0]);
-
-  if (mxIsComplex (prhs[0]))
-    {
-      double *vii, *vio;
-      vii = mxGetPi (prhs[0]);
-      vio = mxGetPi (plhs[0]);
-
-      for (i = 0; i < n; i++)
-        {
-          vro[i] = vri[i] * vri[i] - vii[i] * vii[i];
-          vio[i] = 2 * vri[i] * vii[i];
-        }
-    }
-  else
-    {
-      for (i = 0; i < n; i++)
-        vro[i] = vri[i] * vri[i];
-    }
-}
--- a/examples/myprop.c	Fri Feb 06 08:31:09 2015 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,24 +0,0 @@
-#include "mex.h"
-
-void
-mexFunction (int nlhs, mxArray* plhs[],
-             int nrhs, const mxArray* prhs[])
-{
-  double handle;
-  char property[256];
-
-  if (nrhs < 2 || nrhs > 3)
-    mexErrMsgTxt ("incorrect number of arguments");
-  if (!mxIsDouble (prhs[0]))
-    mexErrMsgTxt ("handle expected to be a double scalar");
-  if (!mxIsChar (prhs[1]))
-    mexErrMsgTxt ("expected property to be a string");
-
-  handle = mxGetScalar (prhs[0]);
-  mxGetString (prhs[1], property, 256);
-  plhs[0] = mxDuplicateArray (mexGet (handle, property));
-
-  if (nrhs == 3)
-    if (mexSet (handle, property, mxDuplicateArray (prhs[2])))
-      mexErrMsgTxt ("failed to set property");
-}
--- a/examples/myset.c	Fri Feb 06 08:31:09 2015 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,34 +0,0 @@
-#include "mex.h"
-
-void
-mexFunction (int nlhs, mxArray* plhs[],
-             int nrhs, const mxArray* prhs[])
-{
-  char *str;
-  mxArray *v;
-
-  if (nrhs != 2 || ! mxIsString (prhs[0]))
-    mexErrMsgTxt ("expects symbol name and value");
-
-  str = mxArrayToString (prhs[0]);
-
-  v = mexGetArray (str, "global");
-
-  if (v)
-    {
-      mexPrintf ("%s is a global variable with the following value:\n", str);
-      mexCallMATLAB (0, NULL, 1, &v, "disp");
-    }
-
-  v = mexGetArray (str, "caller");
-
-  if (v)
-    {
-      mexPrintf ("%s is a caller variable with the following value:\n", str);
-      mexCallMATLAB (0, NULL, 1, &v, "disp");
-    }
-
-  // WARNING!! Can't do this in MATLAB!  Must copy variable first.
-  mxSetName (prhs[1], str);
-  mexPutArray (prhs[1], "caller");
-}
--- a/examples/mysparse.c	Fri Feb 06 08:31:09 2015 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,117 +0,0 @@
-#include "mex.h"
-
-void
-mexFunction (int nlhs, mxArray *plhs[],
-             int nrhs, const mxArray *prhs[])
-{
-  mwSize m, n, nz;
-  mxArray *v;
-  mwIndex i;
-  double *pr, *pi;
-  double *pr2, *pi2;
-  mwIndex *ir, *jc;
-  mwIndex *ir2, *jc2;
-
-  if (nrhs != 1 || ! mxIsSparse (prhs[0]))
-    mexErrMsgTxt ("ARG1 must be a sparse matrix");
-
-  m = mxGetM (prhs[0]);
-  n = mxGetN (prhs[0]);
-  nz = mxGetNzmax (prhs[0]);
-
-  if (mxIsComplex (prhs[0]))
-    {
-      mexPrintf ("Matrix is %d-by-%d complex sparse matrix", m, n);
-      mexPrintf (" with %d elements\n", nz);
-
-      pr = mxGetPr (prhs[0]);
-      pi = mxGetPi (prhs[0]);
-      ir = mxGetIr (prhs[0]);
-      jc = mxGetJc (prhs[0]);
-
-      i = n;
-      while (jc[i] == jc[i-1] && i != 0) i--;
-
-      mexPrintf ("last non-zero element (%d, %d) = (%g, %g)\n",
-                 ir[nz-1]+ 1, i, pr[nz-1], pi[nz-1]);
-
-      v = mxCreateSparse (m, n, nz, mxCOMPLEX);
-      pr2 = mxGetPr (v);
-      pi2 = mxGetPi (v);
-      ir2 = mxGetIr (v);
-      jc2 = mxGetJc (v);
-
-      for (i = 0; i < nz; i++)
-        {
-          pr2[i] = 2 * pr[i];
-          pi2[i] = 2 * pi[i];
-          ir2[i] = ir[i];
-        }
-      for (i = 0; i < n + 1; i++)
-        jc2[i] = jc[i];
-
-      if (nlhs > 0)
-        plhs[0] = v;
-    }
-  else if (mxIsLogical (prhs[0]))
-    {
-      mxLogical *pbr, *pbr2;
-      mexPrintf ("Matrix is %d-by-%d logical sparse matrix", m, n);
-      mexPrintf (" with %d elements\n", nz);
-
-      pbr = mxGetLogicals (prhs[0]);
-      ir = mxGetIr (prhs[0]);
-      jc = mxGetJc (prhs[0]);
-
-      i = n;
-      while (jc[i] == jc[i-1] && i != 0) i--;
-      mexPrintf ("last non-zero element (%d, %d) = %d\n",
-                 ir[nz-1]+ 1, i, pbr[nz-1]);
-
-      v = mxCreateSparseLogicalMatrix (m, n, nz);
-      pbr2 = mxGetLogicals (v);
-      ir2 = mxGetIr (v);
-      jc2 = mxGetJc (v);
-
-      for (i = 0; i < nz; i++)
-        {
-          pbr2[i] = pbr[i];
-          ir2[i] = ir[i];
-        }
-      for (i = 0; i < n + 1; i++)
-        jc2[i] = jc[i];
-
-      if (nlhs > 0)
-        plhs[0] = v;
-    }
-  else
-    {
-      mexPrintf ("Matrix is %d-by-%d real sparse matrix", m, n);
-      mexPrintf (" with %d elements\n", nz);
-
-      pr = mxGetPr (prhs[0]);
-      ir = mxGetIr (prhs[0]);
-      jc = mxGetJc (prhs[0]);
-
-      i = n;
-      while (jc[i] == jc[i-1] && i != 0) i--;
-      mexPrintf ("last non-zero element (%d, %d) = %g\n",
-                 ir[nz-1]+ 1, i, pr[nz-1]);
-
-      v = mxCreateSparse (m, n, nz, mxREAL);
-      pr2 = mxGetPr (v);
-      ir2 = mxGetIr (v);
-      jc2 = mxGetJc (v);
-
-      for (i = 0; i < nz; i++)
-        {
-          pr2[i] = 2 * pr[i];
-          ir2[i] = ir[i];
-        }
-      for (i = 0; i < n + 1; i++)
-        jc2[i] = jc[i];
-
-      if (nlhs > 0)
-        plhs[0] = v;
-    }
-}
--- a/examples/mystring.c	Fri Feb 06 08:31:09 2015 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,25 +0,0 @@
-#include <string.h>
-#include "mex.h"
-
-void
-mexFunction (int nlhs, mxArray *plhs[],
-             int nrhs, const mxArray *prhs[])
-{
-  mwSize m, n;
-  mwIndex i, j;
-  mxChar *pi, *po;
-
-  if (nrhs != 1 || ! mxIsChar (prhs[0])
-      || mxGetNumberOfDimensions (prhs[0]) > 2)
-    mexErrMsgTxt ("ARG1 must be a char matrix");
-
-  m = mxGetM (prhs[0]);
-  n = mxGetN (prhs[0]);
-  pi = mxGetChars (prhs[0]);
-  plhs[0] = mxCreateNumericMatrix (m, n, mxCHAR_CLASS, mxREAL);
-  po = mxGetChars (plhs[0]);
-
-  for (j = 0; j < n; j++)
-    for (i = 0; i < m; i++)
-      po[j*m + m - 1 - i] = pi[j*m + i];
-}
--- a/examples/mystruct.c	Fri Feb 06 08:31:09 2015 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,36 +0,0 @@
-#include "mex.h"
-
-void
-mexFunction (int nlhs, mxArray* plhs[],
-             int nrhs, const mxArray* prhs[])
-{
-  int i;
-  mwIndex j;
-  mxArray *v;
-  const char *keys[] = { "this", "that" };
-
-  if (nrhs != 1 || ! mxIsStruct (prhs[0]))
-    mexErrMsgTxt ("expects struct");
-
-  for (i = 0; i < mxGetNumberOfFields (prhs[0]); i++)
-    for (j = 0; j < mxGetNumberOfElements (prhs[0]); j++)
-      {
-        mexPrintf ("field %s(%d) = ", mxGetFieldNameByNumber (prhs[0], i), j);
-        v = mxGetFieldByNumber (prhs[0], j, i);
-        mexCallMATLAB (0, NULL, 1, &v, "disp");
-      }
-
-  v = mxCreateStructMatrix (2, 2, 2, keys);
-
-  mxSetFieldByNumber (v, 0, 0, mxCreateString ("this1"));
-  mxSetFieldByNumber (v, 0, 1, mxCreateString ("that1"));
-  mxSetFieldByNumber (v, 1, 0, mxCreateString ("this2"));
-  mxSetFieldByNumber (v, 1, 1, mxCreateString ("that2"));
-  mxSetFieldByNumber (v, 2, 0, mxCreateString ("this3"));
-  mxSetFieldByNumber (v, 2, 1, mxCreateString ("that3"));
-  mxSetFieldByNumber (v, 3, 0, mxCreateString ("this4"));
-  mxSetFieldByNumber (v, 3, 1, mxCreateString ("that4"));
-
-  if (nlhs)
-    plhs[0] = v;
-}
--- a/examples/oct_demo.cc	Fri Feb 06 08:31:09 2015 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,84 +0,0 @@
-// oct_demo.cc -- example of a dynamically linked function for Octave.
-
-// To use this file, your version of Octave must support dynamic
-// linking.  To find out if it does, type the command
-//
-//   octave_config_info ("ENABLE_DYNAMIC_LINKING")
-//
-// at the Octave prompt.  Support for dynamic linking is included if
-// this expression returns the string "yes".
-//
-// To compile this file, type the command
-//
-//   mkoctfile oct_demo.cc
-//
-// from within Octave or from the shell prompt.  This will create a file
-// called oct_demo.oct that can be loaded by Octave.  To test the
-// oct_demo.oct file, start Octave and type the command
-//
-//   oct_demo ("easy as", 1, 2, 3)
-//
-// at the Octave prompt.  Octave should respond by printing
-//
-//   Hello, world!
-//   easy as
-//   1
-//   2
-//   3
-//   ans = 3
-
-// Additional samples of real dynamically loaded functions are available in
-// the files of the libinterp/dldfcn directory of the Octave distribution.
-// See also the chapter External Code Interface in the documentation.
-
-#include <iostream>
-
-#include <octave/oct.h>
-
-// Every user function should include <octave/oct.h> which imports the
-// basic set of Octave header files required.  In particular this will define
-// the DEFUN_DLD macro (defun-dld.h) which is used for every user function
-// that is visible to Octave.
-
-// The four arguments to the DEFUN_DLD macro are:
-// 1) The function name as seen in Octave.
-// 2) The variable to hold any inputs (of type octave_value_list)
-// 3) The number of output arguments
-// 4) A string to use as help text if 'help <function_name>' is entered.
-//
-// Note below that the third parameter (nargout) of DEFUN_DLD is not used,
-// so it is omitted from the list of arguments in order to avoid a warning
-// from gcc about an unused function parameter.
-
-DEFUN_DLD (oct_demo, args, ,
-           "[...] = oct_demo (...)\n\
-\n\
-Print a greeting followed by the values of all the arguments passed.\n\
-Return all arguments in reverse order.")
-{
-  // The list of values to return.  See the declaration in oct-obj.h
-
-  octave_value_list retval;
-
-  // This stream is normally connected to the pager.
-
-  octave_stdout << "Hello, world!\n";
-
-  // The inputs to this function are available in args.
-
-  int nargin = args.length ();
-
-  // The octave_value_list class is a zero-based array of octave_value objects.
-  // The declaration for the octave_value class is in the file ov.h.
-  // The print() method will send its output to octave_stdout,
-  // so it will also end up going through the pager.
-
-  for (int i = 0; i < nargin; i++)
-    {
-      octave_value tmp = args(i);
-      tmp.print (octave_stdout);
-      retval(nargin-i-1) = tmp;
-    }
-
-  return retval;
-}
--- a/examples/oregonator.cc	Fri Feb 06 08:31:09 2015 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,22 +0,0 @@
-#include <octave/oct.h>
-
-DEFUN_DLD (oregonator, args, ,
-           "The `oregonator'.\n\
-\n\
-Reference:\n\
-\n\
-  Oscillations in chemical systems.  IV.  Limit cycle behavior in a\n\
-  model of a real chemical reaction. Richard J. Field and Richard\n\
-  M. Noyes, The Journal of Chemical Physics, Volume 60 Number 5,\n\
-  March 1974.")
-{
-  ColumnVector dx (3);
-
-  ColumnVector x (args(0).vector_value ());
-
-  dx(0) = 77.27 * (x(1) - x(0)*x(1) + x(0) - 8.375e-06*pow (x(0), 2.0));
-  dx(1) = (x(2) - x(0)*x(1) - x(1)) / 77.27;
-  dx(2) = 0.161*(x(0) - x(2));
-
-  return octave_value (dx);
-}
--- a/examples/oregonator.m	Fri Feb 06 08:31:09 2015 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,18 +0,0 @@
-## The `oregonator'.
-##
-## Reference:
-##
-##   Oscillations in chemical systems.  IV.  Limit cycle behavior in a
-##   model of a real chemical reaction. Richard J. Field and Richard
-##   M. Noyes, The Journal of Chemical Physics, Volume 60 Number 5,
-##   March 1974.
-
-function dx = oregonator (x, t)
-
-  dx = zeros (3, 1);
-
-  dx(1) = 77.27*(x(2) - x(1)*x(2) + x(1) - 8.375e-06*x(1)^2);
-  dx(2) = (x(3) - x(1)*x(2) - x(2)) / 77.27;
-  dx(3) = 0.161*(x(1) - x(3));
-
-end
--- a/examples/paramdemo.cc	Fri Feb 06 08:31:09 2015 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,30 +0,0 @@
-#include <octave/oct.h>
-
-DEFUN_DLD (paramdemo, args, nargout, "Parameter Check Demo")
-{
-  octave_value retval;
-  int nargin = args.length ();
-
-  if (nargin != 1)
-    print_usage ();
-  else if (nargout != 0)
-    error ("paramdemo: OUTPUT argument required");
-  else
-    {
-      NDArray m = args(0).array_value ();
-      double min_val = -10.0;
-      double max_val = 10.0;
-      octave_stdout << "Properties of input array:\n";
-      if (m.any_element_is_negative ())
-        octave_stdout << "  includes negative values\n";
-      if (m.any_element_is_inf_or_nan ())
-        octave_stdout << "  includes Inf or NaN values\n";
-      if (m.any_element_not_one_or_zero ())
-        octave_stdout << "  includes other values than 1 and 0\n";
-      if (m.all_elements_are_int_or_inf_or_nan ())
-        octave_stdout << "  includes only int, Inf or NaN values\n";
-      if (m.all_integers (min_val, max_val))
-        octave_stdout << "  includes only integers in [-10,10]\n";
-    }
-  return retval;
-}
--- a/examples/standalone.cc	Fri Feb 06 08:31:09 2015 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,19 +0,0 @@
-#include <iostream>
-#include <octave/oct.h>
-
-int
-main (void)
-{
-  std::cout << "Hello Octave world!\n";
-
-  int n = 2;
-  Matrix a_matrix = Matrix (n, n);
-
-  for (octave_idx_type i = 0; i < n; i++)
-    for (octave_idx_type j = 0; j < n; j++)
-      a_matrix(i,j) = (i + 1) * 10 + (j + 1);
-
-  std::cout << a_matrix;
-
-  return 0;
-}
--- a/examples/standalonebuiltin.cc	Fri Feb 06 08:31:09 2015 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,28 +0,0 @@
-#include <iostream>
-#include <octave/oct.h>
-#include <octave/builtin-defun-decls.h>
-
-int
-main (void)
-{
-  int n = 2;
-  Matrix a_matrix = Matrix (n, n);
-
-  for (octave_idx_type i = 0; i < n; i++)
-    for (octave_idx_type j = 0; j < n; j++)
-      a_matrix(i,j) = (i + 1) * 10 + (j + 1);
-
-  std::cout << "This is a matrix:" << std::endl
-            << a_matrix            << std::endl;
-
-  octave_value_list in;
-  in(0) = a_matrix;
-
-  octave_value_list out = Fnorm (in, 1);
-  double norm_of_the_matrix = out(0).double_value ();
-
-  std::cout << "This is the norm of the matrix:" << std::endl
-            << norm_of_the_matrix                << std::endl;
-
-  return 0;
-}
--- a/examples/stringdemo.cc	Fri Feb 06 08:31:09 2015 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,29 +0,0 @@
-#include <octave/oct.h>
-
-DEFUN_DLD (stringdemo, args, , "String Demo")
-{
-  octave_value_list retval;
-  int nargin = args.length ();
-
-  if (nargin != 1)
-    print_usage ();
-  else
-    {
-      charMatrix ch = args(0).char_matrix_value ();
-
-      if (! error_state)
-        {
-          retval(1) = octave_value (ch, '\'');  // Single Quote String
-
-          octave_idx_type nr = ch.rows ();
-          for (octave_idx_type i = 0; i < nr / 2; i++)
-            {
-              std::string tmp = ch.row_as_string (i);
-              ch.insert (ch.row_as_string (nr-i-1).c_str (), i, 0);
-              ch.insert (tmp.c_str (), nr-i-1, 0);
-            }
-          retval(0) = octave_value (ch, '"');  // Double Quote String
-        }
-    }
-  return retval;
-}
--- a/examples/structdemo.cc	Fri Feb 06 08:31:09 2015 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,45 +0,0 @@
-#include <octave/oct.h>
-#include <octave/ov-struct.h>
-
-DEFUN_DLD (structdemo, args, , "Struct Demo")
-{
-  octave_value retval;
-  int nargin = args.length ();
-
-  if (args.length () == 2)
-    {
-      octave_scalar_map arg0 = args(0).scalar_map_value ();
-      //octave_map arg0 = args(0).map_value ();
-
-      if (! error_state)
-        {
-          std::string arg1 = args(1).string_value ();
-
-          if (! error_state)
-            {
-              octave_value tmp = arg0.contents (arg1);
-              //octave_value tmp = arg0.contents (arg1)(0);
-
-              if (tmp.is_defined ())
-                {
-                  octave_scalar_map st;
-
-                  st.assign ("selected", tmp);
-
-                  retval = octave_value (st);
-                }
-              else
-                error ("structdemo: struct does not have a field named '%s'\n",
-                       arg1.c_str ());
-            }
-          else
-            error ("structdemo: ARG2 must be a character string");
-        }
-      else
-        error ("structdemo: ARG1 must be a struct");
-    }
-  else
-    print_usage ();
-
-  return retval;
-}
--- a/examples/unwinddemo.cc	Fri Feb 06 08:31:09 2015 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,34 +0,0 @@
-#include <octave/oct.h>
-#include <octave/unwind-prot.h>
-
-void
-my_err_handler (const char *fmt, ...)
-{
-  // Do nothing!!
-}
-
-DEFUN_DLD (unwinddemo, args, nargout, "Unwind Demo")
-{
-  octave_value retval;
-  int nargin = args.length ();
-
-  if (nargin < 2)
-    print_usage ();
-  else
-    {
-      NDArray a = args(0).array_value ();
-      NDArray b = args(1).array_value ();
-
-      if (! error_state)
-        {
-          // Declare unwind_protect frame which lasts as long as
-          // the variable frame has scope.
-          unwind_protect frame;
-          frame.protect_var (current_liboctave_warning_handler);
-
-          set_liboctave_warning_handler (my_err_handler);
-          retval = octave_value (quotient (a, b));
-        }
-    }
-  return retval;
-}
--- a/libgui/Makefile.am	Fri Feb 06 08:31:09 2015 -0800
+++ b/libgui/Makefile.am	Fri Feb 06 08:31:49 2015 -0800
@@ -34,6 +34,7 @@
   languages/en_US.ts \
   languages/es_ES.ts \
   languages/fr_FR.ts \
+  languages/it_IT.ts \
   languages/nl_NL.ts \
   languages/pt_BR.ts \
   languages/pt_PT.ts \
@@ -53,6 +54,7 @@
 noinst_LTLIBRARIES =
 
 include src/module.mk
+include graphics/module.mk
 include qterminal-module.mk
 
 ## liboctgui merely collects a bunch of compiled convenience libraries.
@@ -67,6 +69,7 @@
 liboctgui_la_LIBADD = \
   qterminal/libqterminal.la \
   src/libgui-src.la \
+  graphics/libgui-graphics.la \
   $(top_builddir)/libinterp/liboctinterp.la \
   $(top_builddir)/liboctave/liboctave.la \
   $(LIBOCTGUI_LINK_DEPS)
@@ -103,7 +106,7 @@
 ( echo '#ifdef HAVE_CONFIG_H'; \
   echo '#include <config.h>'; \
   echo '#endif'; \
-  $(RCC) $< ) > $@-t
+  $(RCC) -name $(@D) $< ) > $@-t
 mv $@-t $@
 endef
 
--- a/libgui/default-qt-settings.in	Fri Feb 06 08:31:09 2015 -0800
+++ b/libgui/default-qt-settings.in	Fri Feb 06 08:31:49 2015 -0800
@@ -550,10 +550,10 @@
 Bash\style2\eolfill=false
 Bash\style2\font=__default_font__, __default_font_size__, 0, 0, 0
 Bash\style2\paper=16777215
-Bash\style3\color=11184640
+Bash\style3\color=43647
 Bash\style3\eolfill=false
 Bash\style3\font=__default_font__, __default_font_size__, 0, 0, 0
-Bash\style3\paper=16711680
+Bash\style0\paper=16777215
 Bash\style4\color=127
 Bash\style4\eolfill=false
 Bash\style4\font=__default_font__, __default_font_size__, 1, 0, 0
@@ -600,3 +600,11 @@
 Bash\defaultpaper=16777215
 Bash\defaultfont=__default_font__, __default_font_size__, 0, 0, 0
 Bash\autoindentstyle=-1
+Text\style0\color=0
+Text\style0\eolfill=false
+Text\style0\font=__default_font__, __default_font_size__, 0, 0, 0
+Text\style0\paper=16777215
+Text\defaultcolor=0
+Text\defaultpaper=16777215
+Text\defaultfont=__default_font__, __default_font_size__, 0, 0, 0
+Text\autoindentstyle=-1
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libgui/graphics/Backend.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,203 @@
+/*
+
+Copyright (C) 2011-2014 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 <QApplication>
+#include <QThread>
+
+#include <stdint.h>
+
+#include "Backend.h"
+#include "Logger.h"
+#include "Object.h"
+#include "ObjectFactory.h"
+#include "ObjectProxy.h"
+
+//#if INTPTR_MAX == INT32_MAX
+//# define OCTAVE_PTR_TYPE octave_uint32
+//# define OCTAVE_INTPTR_TYPE uint32_t
+//# define OCTAVE_PTR_SCALAR uint32_scalar_value
+//#else
+# define OCTAVE_PTR_TYPE octave_uint64
+# define OCTAVE_INTPTR_TYPE uint64_t
+# define OCTAVE_PTR_SCALAR uint64_scalar_value
+//#endif
+
+namespace QtHandles
+{
+
+static std::string toolkitObjectProperty (const graphics_object& go)
+{
+  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"))
+    return std::string ("__object__");
+  else
+    qCritical ("QtHandles::Backend: no __object__ property known for object "
+               "of type %s", go.type ().c_str ());
+
+  return std::string ();
+}
+
+Backend::Backend (void)
+  : QObject (), base_graphics_toolkit ("qt")
+{
+  ObjectFactory* factory = ObjectFactory::instance ();
+
+  connect (this, SIGNAL (createObject (double)),
+           factory, SLOT (createObject (double)));
+}
+
+Backend::~Backend (void)
+{
+}
+
+bool Backend::initialize (const graphics_object& go)
+{
+  if (go.isa ("figure")
+      || go.isa ("uicontrol")
+      || go.isa ("uipanel")
+      || go.isa ("uimenu")
+      || go.isa ("uicontextmenu")
+      || go.isa ("uitoolbar")
+      || go.isa ("uipushtool")
+      || go.isa ("uitoggletool"))
+    {
+      Logger::debug ("Backend::initialize %s from thread %08x",
+                     go.type ().c_str (), QThread::currentThreadId ());
+
+      ObjectProxy* proxy = new ObjectProxy ();
+      graphics_object gObj (go);
+
+      OCTAVE_PTR_TYPE tmp (reinterpret_cast <OCTAVE_INTPTR_TYPE> (proxy));
+      gObj.get_properties ().set(toolkitObjectProperty (go), tmp);
+
+      emit createObject (go.get_handle ().value ());
+
+      return true;
+    }
+
+  return false;
+}
+
+void Backend::update (const graphics_object& go, int pId)
+{
+  // Rule out obvious properties we want to ignore.
+  if (pId == figure::properties::ID___PLOT_STREAM__
+      || pId == uicontrol::properties::ID___OBJECT__
+      || pId == uipanel::properties::ID___OBJECT__
+      || pId == uimenu::properties::ID___OBJECT__
+      || pId == uicontextmenu::properties::ID___OBJECT__
+      || pId == uitoolbar::properties::ID___OBJECT__
+      || pId == uipushtool::properties::ID___OBJECT__
+      || pId == uitoggletool::properties::ID___OBJECT__
+      || pId == base_properties::ID___MODIFIED__)
+    return;
+
+  Logger::debug ("Backend::update %s(%d) from thread %08x",
+                 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
+
+          finalize (go);
+          initialize (go);
+        }
+      else
+        proxy->update (pId);
+    }
+}
+
+void Backend::finalize (const graphics_object& go)
+{
+  Logger::debug ("Backend::finalize %s from thread %08x",
+                 go.type ().c_str (), QThread::currentThreadId ());
+
+  ObjectProxy* proxy = toolkitObjectProxy (go);
+
+  if (proxy)
+    {
+      proxy->finalize ();
+      delete proxy;
+
+      graphics_object gObj (go);
+
+      gObj.get_properties ().set (toolkitObjectProperty (go), Matrix ());
+    }
+}
+
+void Backend::redraw_figure (const graphics_object& go) const
+{
+  if (go.get_properties ().is_visible ())
+    {
+      ObjectProxy* proxy = toolkitObjectProxy (go);
+
+      if (proxy)
+        proxy->redraw ();
+    }
+}
+
+Object* Backend::toolkitObject (const graphics_object& go)
+{
+  ObjectProxy* proxy = toolkitObjectProxy (go);
+
+  if (proxy)
+    return proxy->object ();
+
+  return 0;
+}
+
+ObjectProxy* Backend::toolkitObjectProxy (const graphics_object& go)
+{
+  if (go)
+    {
+      octave_value ov = go.get (toolkitObjectProperty (go));
+
+      if (ov.is_defined () && ! ov.is_empty ())
+        {
+          OCTAVE_INTPTR_TYPE ptr = ov.OCTAVE_PTR_SCALAR ().value ();
+
+          if (! error_state)
+            return reinterpret_cast<ObjectProxy*> (ptr);
+        }
+    }
+
+  return 0;
+}
+
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libgui/graphics/Backend.h	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,67 @@
+/*
+
+Copyright (C) 2011-2014 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/>.
+
+*/
+
+#ifndef __QtHandles_Backend__
+#define __QtHandles_Backend__ 1
+
+#include <QObject>
+
+#include "graphics.h"
+
+namespace QtHandles
+{
+
+class Object;
+class ObjectProxy;
+
+class Backend :
+  public QObject,
+  public base_graphics_toolkit
+{
+  Q_OBJECT
+
+public:
+  Backend (void);
+
+  ~Backend (void);
+
+  bool is_valid (void) const { return true; }
+
+  void redraw_figure (const graphics_object& h) const;
+
+  void update (const graphics_object& obj, int pId);
+
+  bool initialize (const graphics_object& obj);
+
+  void finalize (const graphics_object& obj);
+
+  static Object* toolkitObject (const graphics_object& go);
+
+  static ObjectProxy* toolkitObjectProxy (const graphics_object& go);
+
+signals:
+  void createObject (double handle);
+};
+
+}; // namespace QtHandles
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libgui/graphics/BaseControl.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,232 @@
+/*
+
+Copyright (C) 2011-2014 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 <QEvent>
+#include <QKeyEvent>
+#include <QMouseEvent>
+#include <QWidget>
+
+#include "BaseControl.h"
+#include "ContextMenu.h"
+#include "QtHandlesUtils.h"
+
+namespace QtHandles
+{
+
+static void updatePalette (const uicontrol::properties& props, QWidget* w)
+{
+  QPalette p = w->palette ();
+
+  if (props.style_is ("edit")
+      || props.style_is ("listbox")
+      || props.style_is ("popupmenu"))
+    {
+      p.setColor (QPalette::Base,
+                  Utils::fromRgb (props.get_backgroundcolor_rgb ()));
+      p.setColor (QPalette::Text,
+                  Utils::fromRgb (props.get_foregroundcolor_rgb ()));
+    }
+  else if (props.style_is ("pushbutton")
+           || props.style_is ("togglebutton"))
+    {
+      p.setColor (QPalette::Button,
+                  Utils::fromRgb (props.get_backgroundcolor_rgb ()));
+      p.setColor (QPalette::ButtonText,
+                  Utils::fromRgb (props.get_foregroundcolor_rgb ()));
+    }
+  else
+    {
+      p.setColor (QPalette::Window,
+                  Utils::fromRgb (props.get_backgroundcolor_rgb ()));
+      p.setColor (QPalette::WindowText,
+                  Utils::fromRgb (props.get_foregroundcolor_rgb ()));
+    }
+
+  w->setPalette (p);
+}
+
+BaseControl::BaseControl (const graphics_object& go, QWidget* w)
+  : Object (go, w), m_normalizedFont (false), m_keyPressHandlerDefined (false)
+{
+  init (w);
+}
+
+void BaseControl::init (QWidget* w, bool callBase)
+{
+  if (callBase)
+    Object::init (w, callBase);
+
+  uicontrol::properties& up = properties<uicontrol> ();
+
+  Matrix bb = up.get_boundingbox (false);
+  w->setGeometry (xround (bb(0)), xround (bb(1)),
+                  xround (bb(2)), xround (bb(3)));
+  w->setFont (Utils::computeFont<uicontrol> (up, bb(3)));
+  updatePalette (up, w);
+  w->setEnabled (up.enable_is ("on"));
+  w->setToolTip (Utils::fromStdString (up.get_tooltipstring ()));
+  w->setVisible (up.is_visible ());
+  m_keyPressHandlerDefined = ! up.get_keypressfcn ().is_empty ();
+
+  w->installEventFilter (this);
+
+  m_normalizedFont = up.fontunits_is ("normalized");
+}
+
+BaseControl::~BaseControl (void)
+{
+}
+
+void BaseControl::update (int pId)
+{
+  uicontrol::properties& up = properties<uicontrol> ();
+  QWidget* w = qWidget<QWidget> ();
+
+   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)));
+        }
+      break;
+    case uicontrol::properties::ID_FONTNAME:
+    case uicontrol::properties::ID_FONTSIZE:
+    case uicontrol::properties::ID_FONTWEIGHT:
+    case uicontrol::properties::ID_FONTANGLE:
+      w->setFont (Utils::computeFont<uicontrol> (up));
+      break;
+    case uicontrol::properties::ID_FONTUNITS:
+      // FIXME: We shouldn't have to do anything, octave should update
+      //        the "fontsize" property automatically to the new units.
+      //        Hence the actual font used shouldn't change.
+      m_normalizedFont = up.fontunits_is ("normalized");
+      break;
+    case uicontrol::properties::ID_BACKGROUNDCOLOR:
+    case uicontrol::properties::ID_FOREGROUNDCOLOR:
+      updatePalette (up, w);
+      break;
+    case uicontrol::properties::ID_ENABLE:
+      w->setEnabled (up.enable_is ("on"));
+      break;
+    case uicontrol::properties::ID_TOOLTIPSTRING:
+      w->setToolTip (Utils::fromStdString (up.get_tooltipstring ()));
+      break;
+    case base_properties::ID_VISIBLE:
+      w->setVisible (up.is_visible ());
+      break;
+    case uicontrol::properties::ID_KEYPRESSFCN:
+      m_keyPressHandlerDefined = ! up.get_keypressfcn ().is_empty ();
+      break;
+    default:
+      break;
+    }
+}
+
+bool BaseControl::eventFilter (QObject* watched, QEvent* xevent)
+{
+  switch (xevent->type ())
+    {
+    case QEvent::Resize:
+      if (m_normalizedFont)
+        {
+          gh_manager::auto_lock lock;
+
+          qWidget<QWidget> ()->setFont (Utils::computeFont<uicontrol>
+                                        (properties<uicontrol> ()));
+        }
+      break;
+    case QEvent::MouseButtonPress:
+        {
+          gh_manager::auto_lock lock;
+
+          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::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;
+
+          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);
+          gh_manager::post_callback (fig.get_handle (), "windowbuttonmotionfcn");
+        }
+      break;
+    case QEvent::KeyPress:
+      if (m_keyPressHandlerDefined)
+        {
+          gh_manager::auto_lock lock;
+
+          octave_scalar_map keyData =
+            Utils::makeKeyEventStruct (dynamic_cast<QKeyEvent*> (xevent));
+          graphics_object fig = object ().get_ancestor ("figure");
+
+          gh_manager::post_set (fig.get_handle (), "currentcharacter",
+                                keyData.getfield ("Character"), false);
+          gh_manager::post_callback (m_handle, "keypressfcn", keyData);
+        }
+      break;
+    default: break;
+    }
+
+  return Object::eventFilter (watched, xevent);
+}
+
+}; // namespace QtHandles
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libgui/graphics/BaseControl.h	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,55 @@
+/*
+
+Copyright (C) 2011-2014 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/>.
+
+*/
+
+#ifndef __QtHandles_BaseControl__
+#define __QtHandles_BaseControl__ 1
+
+#include "Object.h"
+
+class QEvent;
+class QObject;
+
+namespace QtHandles
+{
+
+class BaseControl : public Object
+{
+public:
+  BaseControl (const graphics_object& go, QWidget* w);
+  ~BaseControl (void);
+
+  Container* innerContainer (void) { return 0; }
+
+  bool eventFilter (QObject* watched, QEvent* e);
+
+protected:
+  void init (QWidget* w, bool callBase = false);
+  void update (int pId);
+
+private:
+  bool m_normalizedFont;
+  bool m_keyPressHandlerDefined;
+};
+
+}; // namespace QtHandles
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libgui/graphics/ButtonControl.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,122 @@
+/*
+
+Copyright (C) 2011-2014 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 <QAbstractButton>
+
+#include "ButtonControl.h"
+#include "Container.h"
+#include "QtHandlesUtils.h"
+
+namespace QtHandles
+{
+
+ButtonControl::ButtonControl (const graphics_object& go, QAbstractButton* btn)
+    : BaseControl (go, btn), m_blockCallback (false)
+{
+  uicontrol::properties& up = properties<uicontrol> ();
+
+  btn->setText (Utils::fromStdString (up.get_string_string ()));
+  if (btn->isCheckable () || up.style_is ("togglebutton"))
+    {
+      btn->setCheckable (true);
+
+      Matrix value = up.get_value ().matrix_value ();
+
+      if (value.numel () > 0 && value(0) == up.get_max ())
+        btn->setChecked (true);
+    }
+
+  connect (btn, SIGNAL (clicked (void)), SLOT (clicked (void)));
+  connect (btn, SIGNAL (toggled (bool)), SLOT (toggled (bool)));
+}
+
+ButtonControl::~ButtonControl (void)
+{
+}
+
+void ButtonControl::update (int pId)
+{
+  uicontrol::properties& up = properties<uicontrol> ();
+  QAbstractButton* btn = qWidget<QAbstractButton> ();
+
+  switch (pId)
+    {
+    case uicontrol::properties::ID_STRING:
+      btn->setText (Utils::fromStdString (up.get_string_string ()));
+      break;
+    case uicontrol::properties::ID_VALUE:
+      m_blockCallback = true;
+      if (btn->isCheckable ())
+        {
+          Matrix value = up.get_value ().matrix_value ();
+
+          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);
+            }
+        }
+      m_blockCallback = false;
+      break;
+    default:
+      BaseControl::update (pId);
+      break;
+    }
+}
+
+void ButtonControl::toggled (bool checked)
+{
+  QAbstractButton* btn = qWidget<QAbstractButton> ();
+
+  if (! m_blockCallback && btn->isCheckable ())
+    {
+      gh_manager::auto_lock lock;
+
+      uicontrol::properties& up = properties<uicontrol> ();
+
+      Matrix oldValue = up.get_value ().matrix_value ();
+      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);
+      gh_manager::post_callback (m_handle, "callback");
+    }
+}
+
+void ButtonControl::clicked (void)
+{
+  QAbstractButton* btn = qWidget<QAbstractButton> ();
+
+  if (! btn->isCheckable ())
+    gh_manager::post_callback (m_handle, "callback");
+}
+
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libgui/graphics/ButtonControl.h	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,54 @@
+/*
+
+Copyright (C) 2011-2014 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/>.
+
+*/
+
+#ifndef __QtHandles_ButtonControl__
+#define __QtHandles_ButtonControl__ 1
+
+#include "BaseControl.h"
+
+class QAbstractButton;
+
+namespace QtHandles
+{
+
+class ButtonControl : public BaseControl
+{
+  Q_OBJECT
+
+public:
+  ButtonControl (const graphics_object& go, QAbstractButton* btn);
+  ~ButtonControl (void);
+
+protected:
+  void update (int pId);
+
+private slots:
+  void clicked (void);
+  void toggled (bool checked);
+
+private:
+  bool m_blockCallback;
+};
+
+}; // namespace QtHandles
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libgui/graphics/Canvas.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,416 @@
+/*
+
+Copyright (C) 2011-2014 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 <QApplication>
+#include <QList>
+#include <QMouseEvent>
+#include <QRectF>
+
+#include "Backend.h"
+#include "Canvas.h"
+#include "ContextMenu.h"
+#include "GLCanvas.h"
+#include "QtHandlesUtils.h"
+
+namespace QtHandles
+{
+
+void Canvas::redraw (bool sync)
+{
+  if (sync)
+    qWidget ()->repaint ();
+  else
+    qWidget ()->update ();
+}
+
+void Canvas::blockRedraw (bool block)
+{
+  m_redrawBlocked = block;
+}
+
+void Canvas::updateCurrentPoint(const graphics_object& fig,
+                                const graphics_object& obj, QMouseEvent* event)
+{
+  gh_manager::post_set (fig.get_handle (), "currentpoint",
+                        Utils::figureCurrentPoint (fig, event), false);
+
+  Matrix children = obj.get_properties ().get_children ();
+  octave_idx_type num_children = children.numel ();
+
+  for (int i = 0; i < num_children; i++)
+    {
+      graphics_object childObj (gh_manager::get_object (children(i)));
+
+      if (childObj.isa ("axes"))
+        {
+          axes::properties& ap = Utils::properties<axes> (childObj);
+          Matrix x_zlim = ap.get_transform_zlim ();
+          graphics_xform x_form = ap.get_transform ();
+
+          ColumnVector p1 = x_form.untransform (event->x (), event->y (),
+                                                x_zlim(0));
+          ColumnVector p2 = x_form.untransform (event->x (), event->y (),
+                                                x_zlim(1));
+
+          Matrix cp (2, 3, 0.0);
+
+          cp(0,0) = p1(0); cp(0,1) = p1(1); cp(0,2) = p1(2);
+          cp(1,0) = p2(0); cp(1,1) = p2(1); cp(1,2) = p2(2);
+
+          gh_manager::post_set (childObj.get_handle (), "currentpoint", cp,
+                                false);
+        }
+    }
+}
+
+void Canvas::canvasPaintEvent (void)
+{
+  if (! m_redrawBlocked)
+    {
+      gh_manager::auto_lock lock;
+
+      draw (m_handle);
+
+      if (m_mouseMode == ZoomMode && m_mouseAxes.ok ())
+        drawZoomBox (m_mouseAnchor, m_mouseCurrent);
+    }
+}
+
+void Canvas::canvasMouseMoveEvent (QMouseEvent* event)
+{
+  gh_manager::auto_lock lock;
+  graphics_object ax = gh_manager::get_object (m_mouseAxes);
+
+  if (m_mouseMode != NoMode && ax.valid_object ())
+    {
+      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 ();
+
+              // 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;
+
+              // 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 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;
+        }
+    }
+  else if (m_mouseMode == NoMode)
+    {
+      graphics_object obj = gh_manager::get_object (m_handle);
+
+      if (obj.valid_object ())
+        {
+          graphics_object figObj (obj.get_ancestor ("figure"));
+
+          updateCurrentPoint (figObj, obj, event);
+          gh_manager::post_callback (figObj.get_handle (),
+                                     "windowbuttonmotionfcn");
+        }
+    }
+}
+
+void Canvas::canvasMousePressEvent (QMouseEvent* event)
+{
+  gh_manager::auto_lock lock;
+  graphics_object obj = gh_manager::get_object (m_handle);
+
+  if (obj.valid_object ())
+    {
+      graphics_object figObj (obj.get_ancestor ("figure"));
+      graphics_object currentObj, axesObj;
+      QList<graphics_object> axesList;
+
+      Matrix children = obj.get_properties ().get_children ();
+      octave_idx_type num_children = children.numel ();
+
+      for (int i = 0; i < num_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));
+
+              r.adjust (-5, -5, 5, 5);
+              if (r.contains (event->posF ()))
+                {
+                  currentObj = childObj;
+                  break;
+                }
+            }
+        }
+
+      if (! currentObj)
+        {
+          for (QList<graphics_object>::ConstIterator it = axesList.begin ();
+               it != axesList.end (); ++it)
+            {
+              graphics_object go = selectFromAxes (*it, event->pos ());
+
+              if (go)
+                {
+                  currentObj = go;
+                  axesObj = *it;
+                }
+              // FIXME: is this really necessary? the axes object should
+              //        have been selected through selectFromAxes anyway
+              else if (it->get_properties ().is_hittest ())
+                {
+                  Matrix bb = it->get_properties ().get_boundingbox (true);
+                  QRectF r (bb(0), bb(1), bb(2), bb(3));
+
+                  if (r.contains (event->posF ()))
+                    axesObj = *it;
+                }
+
+              if (axesObj)
+                break;
+            }
+
+          if (axesObj)
+            {
+              if (axesObj.get_properties ().handlevisibility_is ("on"))
+                Utils::properties<figure> (figObj)
+                  .set_currentaxes (axesObj.get_handle ().as_octave_value ());
+              if (! currentObj)
+                currentObj = axesObj;
+            }
+        }
+
+      if (! currentObj)
+        currentObj = obj;
+
+      if (currentObj.get_properties ().handlevisibility_is ("on"))
+        Utils::properties<figure> (figObj)
+          .set_currentobject (currentObj.get_handle ().as_octave_value ());
+      else
+        Utils::properties<figure> (figObj).set_currentobject (octave_NaN);
+
+      Figure* fig = dynamic_cast<Figure*> (Backend::toolkitObject (figObj));
+
+      MouseMode newMouseMode = NoMode;
+
+      if (fig)
+        newMouseMode = fig->mouseMode ();
+
+      switch (newMouseMode)
+        {
+        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 (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);
+
+                          ap.clear_zoom_stack ();
+                          ap.set_xlimmode ("auto");
+                          ap.set_ylimmode ("auto");
+                          ap.set_zlimmode ("auto");
+                        }
+                      break;
+                    }
+                  redraw (false);
+                }
+            }
+          break;
+        default:
+          break;
+        }
+    }
+}
+
+void Canvas::canvasMouseReleaseEvent (QMouseEvent* event)
+{
+  if (m_mouseMode == ZoomMode
+      && m_mouseAxes.ok ()
+      && m_mouseAnchor != event->pos ())
+    {
+      gh_manager::auto_lock lock;
+      graphics_object ax = gh_manager::get_object (m_mouseAxes);
+
+      if (ax.valid_object ())
+        {
+          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 ());
+
+          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));
+
+          ap.zoom (xl, yl);
+
+          redraw (false);
+        }
+    }
+  else if (m_mouseMode == NoMode)
+    {
+      gh_manager::auto_lock lock;
+      graphics_object obj = gh_manager::get_object (m_handle);
+
+      if (obj.valid_object ())
+        {
+          graphics_object figObj (obj.get_ancestor ("figure"));
+
+          updateCurrentPoint (figObj, obj, event);
+          gh_manager::post_callback (figObj.get_handle (),
+                                     "windowbuttonupfcn");
+        }
+    }
+
+  m_mouseAxes = graphics_handle ();
+  m_mouseMode = NoMode;
+}
+
+bool Canvas::canvasKeyPressEvent (QKeyEvent* event)
+{
+  if (m_eventMask & KeyPress)
+    {
+      octave_scalar_map eventData = Utils::makeKeyEventStruct (event);
+
+      gh_manager::post_set (m_handle, "currentcharacter",
+                            eventData.getfield ("Character"), false);
+      gh_manager::post_callback (m_handle, "keypressfcn", eventData);
+
+      return true;
+    }
+
+  return false;
+}
+
+bool Canvas::canvasKeyReleaseEvent (QKeyEvent* event)
+{
+  if (! event->isAutoRepeat () && (m_eventMask & KeyRelease))
+    {
+      gh_manager::post_callback (m_handle, "keyreleasefcn",
+                                 Utils::makeKeyEventStruct (event));
+
+      return true;
+    }
+
+  return false;
+}
+
+Canvas* Canvas::create (const std::string& /* name */, QWidget* parent,
+                        const graphics_handle& handle)
+{
+  // Only OpenGL
+  return new GLCanvas (parent, handle);
+}
+
+}; // namespace QtHandles
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libgui/graphics/Canvas.h	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,100 @@
+/*
+
+Copyright (C) 2011-2014 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/>.
+
+*/
+
+#ifndef __QtHandles_Canvas__
+#define __QtHandles_Canvas__ 1
+
+#include <QPoint>
+
+#include "graphics.h"
+
+#include "Figure.h"
+
+class QKeyEvent;
+class QMouseEvent;
+class QWidget;
+
+namespace QtHandles
+{
+
+class Canvas
+{
+public:
+  enum EventMask
+    {
+      KeyPress   = 0x01,
+      KeyRelease = 0x02
+    };
+
+public:
+  virtual ~Canvas (void) { }
+
+  void redraw (bool sync = false);
+  void blockRedraw (bool block = true);
+
+  void addEventMask (int m) { m_eventMask |= m; }
+  void clearEventMask (int m) { m_eventMask &= (~m); }
+  void setEventMask (int m) { m_eventMask = m; }
+
+  virtual QWidget* qWidget (void) = 0;
+
+  static Canvas* create (const std::string& name, QWidget* parent,
+                         const graphics_handle& handle);
+
+protected:
+  virtual void draw (const graphics_handle& handle) = 0;
+  virtual void drawZoomBox (const QPoint& p1, const QPoint& p2) = 0;
+  virtual void resize (int x, int y, int width, int height) = 0;
+  virtual graphics_object selectFromAxes (const graphics_object& ax,
+                                          const QPoint& pt) = 0;
+
+protected:
+  Canvas (const graphics_handle& handle)
+    : m_handle (handle),
+      m_redrawBlocked (false),
+      m_mouseMode (NoMode),
+      m_eventMask (0)
+    { }
+
+  void canvasPaintEvent (void);
+  void canvasMouseMoveEvent (QMouseEvent* event);
+  void canvasMousePressEvent (QMouseEvent* event);
+  void canvasMouseReleaseEvent (QMouseEvent* event);
+  bool canvasKeyPressEvent (QKeyEvent* event);
+  bool canvasKeyReleaseEvent (QKeyEvent* event);
+
+  void updateCurrentPoint (const graphics_object& fig,
+                           const graphics_object& obj, QMouseEvent *event);
+
+private:
+  graphics_handle m_handle;
+  bool m_redrawBlocked;
+  MouseMode m_mouseMode;
+  QPoint m_mouseAnchor;
+  QPoint m_mouseCurrent;
+  graphics_handle m_mouseAxes;
+  int m_eventMask;
+};
+
+}; // namespace QtHandles
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libgui/graphics/CheckBoxControl.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,60 @@
+/*
+
+Copyright (C) 2011-2014 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 <QCheckBox>
+
+#include "CheckBoxControl.h"
+#include "Container.h"
+
+namespace QtHandles
+{
+
+CheckBoxControl* CheckBoxControl::create (const graphics_object& go)
+{
+  Object* parent = Object::parentObject (go);
+
+  if (parent)
+    {
+      Container* container = parent->innerContainer ();
+
+      if (container)
+        return new CheckBoxControl (go, new QCheckBox (container));
+    }
+
+  return 0;
+}
+
+CheckBoxControl::CheckBoxControl (const graphics_object& go, QCheckBox* box)
+    : ButtonControl (go, box)
+{
+  box->setAutoFillBackground (true);
+}
+
+CheckBoxControl::~CheckBoxControl (void)
+{
+}
+
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libgui/graphics/CheckBoxControl.h	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,44 @@
+/*
+
+Copyright (C) 2011-2014 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/>.
+
+*/
+
+#ifndef __QtHandles_CheckBoxControl__
+#define __QtHandles_CheckBoxControl__ 1
+
+#include "ButtonControl.h"
+
+class QCheckBox;
+
+namespace QtHandles
+{
+
+class CheckBoxControl : public ButtonControl
+{
+public:
+  CheckBoxControl (const graphics_object& go, QCheckBox* box);
+  ~CheckBoxControl (void);
+
+  static CheckBoxControl* create (const graphics_object& go);
+};
+
+}; // namespace QtHandles
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libgui/graphics/Container.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,107 @@
+/*
+
+Copyright (C) 2011-2014 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 <QChildEvent>
+#include <QVBoxLayout>
+
+#include "graphics.h"
+
+#include "Canvas.h"
+#include "Container.h"
+#include "Object.h"
+#include "QtHandlesUtils.h"
+
+namespace QtHandles
+{
+
+Container::Container (QWidget* xparent)
+  : ContainerBase (xparent), m_canvas (0)
+{
+  setFocusPolicy (Qt::ClickFocus);
+}
+
+Container::~Container (void)
+{
+}
+
+Canvas* Container::canvas (const graphics_handle& gh, bool xcreate)
+{
+  if (! m_canvas && xcreate)
+    {
+      graphics_object go = gh_manager::get_object (gh);
+
+      if (go)
+        {
+          graphics_object fig = go.get_ancestor ("figure");
+
+          m_canvas = Canvas::create (fig.get("renderer").string_value (),
+                                     this, gh);
+
+          QWidget* canvasWidget = m_canvas->qWidget ();
+
+          canvasWidget->lower ();
+          canvasWidget->show ();
+          canvasWidget->setGeometry (0, 0, width (), height ());
+        }
+    }
+
+  return m_canvas;
+}
+
+void Container::resizeEvent (QResizeEvent* /* event */)
+{
+  if (m_canvas)
+    m_canvas->qWidget ()->setGeometry (0, 0, width (), height ());
+
+  gh_manager::auto_lock lock;
+
+  foreach (QObject* qObj, children ())
+    {
+      if (qObj->isWidgetType ())
+        {
+          Object* obj = Object::fromQObject (qObj);
+
+          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)));
+            }
+        }
+    }
+}
+
+void Container::childEvent (QChildEvent* xevent)
+{
+  if (xevent->child ()->isWidgetType ())
+    {
+      qobject_cast<QWidget*> (xevent->child ())->setMouseTracking (hasMouseTracking ());
+    }
+}
+
+}; // namespace QtHandles
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libgui/graphics/Container.h	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,57 @@
+/*
+
+Copyright (C) 2011-2014 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/>.
+
+*/
+
+#ifndef __QtHandles_Container__
+#define __QtHandles_Container__ 1
+
+#include <QWidget>
+
+#include "GenericEventNotify.h"
+
+#include "graphics.h"
+
+namespace QtHandles
+{
+
+DECLARE_GENERICEVENTNOTIFY_SENDER(ContainerBase, QWidget);
+
+class Canvas;
+
+class Container : public ContainerBase
+{
+public:
+  Container (QWidget* parent);
+  ~Container (void);
+
+  Canvas* canvas (const graphics_handle& handle, bool create = true);
+
+protected:
+  void childEvent (QChildEvent* event);
+  void resizeEvent (QResizeEvent* event);
+
+private:
+  Canvas* m_canvas;
+};
+
+}; // namespace QtHandles
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libgui/graphics/ContextMenu.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,132 @@
+/*
+
+Copyright (C) 2011-2014 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 <QMenu>
+
+#include "Backend.h"
+#include "ContextMenu.h"
+#include "QtHandlesUtils.h"
+
+namespace QtHandles
+{
+
+ContextMenu* ContextMenu::create (const graphics_object& go)
+{
+  Object* xparent = Object::parentObject (go);
+
+  if (xparent)
+    {
+      QWidget* w = xparent->qWidget<QWidget> ();
+
+      return new ContextMenu (go, new QMenu (w));
+    }
+
+  return 0;
+}
+
+ContextMenu::ContextMenu (const graphics_object& go, QMenu* xmenu)
+    : Object (go, xmenu)
+{
+  xmenu->setAutoFillBackground (true);
+
+  connect (xmenu, SIGNAL (aboutToShow (void)), SLOT (aboutToShow (void)));
+  connect (xmenu, SIGNAL (aboutToHide (void)), SLOT (aboutToHide (void)));
+}
+
+ContextMenu::~ContextMenu (void)
+{
+}
+
+void ContextMenu::update (int pId)
+{
+  uicontextmenu::properties& up = properties<uicontextmenu> ();
+  QMenu* xmenu = qWidget<QMenu> ();
+
+  switch (pId)
+    {
+    case base_properties::ID_VISIBLE:
+      if (up.is_visible ())
+        {
+          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);
+
+          xmenu->popup (pt);
+        }
+      else
+        xmenu->hide ();
+      break;
+    default:
+      Object::update (pId);
+      break;
+    }
+}
+
+void ContextMenu::aboutToShow (void)
+{
+  gh_manager::post_callback (m_handle, "callback");
+  gh_manager::post_set (m_handle, "visible", "on", false);
+}
+
+void ContextMenu::aboutToHide (void)
+{
+  gh_manager::post_set (m_handle, "visible", "off", false);
+}
+
+QWidget* ContextMenu::menu (void)
+{
+  return qWidget<QWidget> ();
+}
+
+void ContextMenu::executeAt (const base_properties& props, const QPoint& pt)
+{
+  graphics_handle h = props.get_uicontextmenu ();
+
+  if (h.ok ())
+    {
+      graphics_object go = gh_manager::get_object (h);
+
+      if (go.valid_object ())
+        {
+          ContextMenu* cMenu =
+            dynamic_cast<ContextMenu*> (Backend::toolkitObject (go));
+
+          if (cMenu)
+            {
+              QMenu* menu = cMenu->qWidget<QMenu> ();
+
+              if (menu)
+                menu->popup (pt);
+            }
+        }
+    }
+}
+
+}; // namespace QtHandles
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libgui/graphics/ContextMenu.h	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,61 @@
+/*
+
+Copyright (C) 2011-2014 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/>.
+
+*/
+
+#ifndef __QtHandles_ContextMenu__
+#define __QtHandles_ContextMenu__ 1
+
+#include <QPoint>
+
+#include "MenuContainer.h"
+#include "Object.h"
+
+class QMenu;
+
+namespace QtHandles
+{
+
+class ContextMenu : public Object, public MenuContainer
+{
+  Q_OBJECT
+
+public:
+  ContextMenu (const graphics_object& go, QMenu* menu);
+  ~ContextMenu (void);
+
+  static ContextMenu* create (const graphics_object& go);
+  static void executeAt (const base_properties& props, const QPoint& pt);
+
+  Container* innerContainer (void) { return 0; }
+
+  QWidget* menu (void);
+
+protected:
+  void update (int pId);
+
+private slots:
+  void aboutToShow (void);
+  void aboutToHide (void);
+};
+
+}; // namespace QtHandles
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libgui/graphics/EditControl.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,220 @@
+/*
+
+Copyright (C) 2011-2014 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 <QLineEdit>
+
+#include "Container.h"
+#include "EditControl.h"
+#include "TextEdit.h"
+#include "QtHandlesUtils.h"
+
+namespace QtHandles
+{
+
+EditControl* EditControl::create (const graphics_object& go)
+{
+  Object* parent = Object::parentObject (go);
+
+  if (parent)
+    {
+      Container* container = parent->innerContainer ();
+
+      if (container)
+        {
+          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));
+        }
+    }
+
+  return 0;
+}
+
+EditControl::EditControl (const graphics_object& go, QLineEdit* edit)
+     : BaseControl (go, edit), m_multiLine (false), m_textChanged (false)
+{
+  init (edit);
+}
+
+void EditControl::init (QLineEdit* edit, bool callBase)
+{
+  if (callBase)
+    BaseControl::init (edit, callBase);
+
+  m_multiLine = false;
+  initCommon (edit);
+
+  uicontrol::properties& up = properties<uicontrol> ();
+
+  edit->setText (Utils::fromStdString (up.get_string_string ()));
+  edit->setAlignment (Utils::fromHVAlign (up.get_horizontalalignment (),
+                                          up.get_verticalalignment ()));
+
+  connect (edit, SIGNAL (textEdited (const QString&)),
+           SLOT (textChanged (void)));
+  connect (edit, SIGNAL (editingFinished (void)),
+           SLOT (editingFinished (void)));
+}
+
+EditControl::EditControl (const graphics_object& go, TextEdit* edit)
+     : BaseControl (go, edit), m_multiLine (true), m_textChanged (false)
+{
+  init (edit);
+}
+
+void EditControl::init (TextEdit* edit, bool callBase)
+{
+  if (callBase)
+    BaseControl::init (edit, callBase);
+
+  m_multiLine = true;
+  initCommon (edit);
+
+  uicontrol::properties& up = properties<uicontrol> ();
+
+  edit->setAcceptRichText (false);
+  // FIXME: support string_vector
+  edit->setPlainText (Utils::fromStdString (up.get_string_string ()));
+
+  connect (edit, SIGNAL (textChanged (void)),
+           SLOT (textChanged (void)));
+  connect (edit, SIGNAL (editingFinished (void)),
+           SLOT (editingFinished (void)));
+}
+
+EditControl::~EditControl (void)
+{
+}
+
+void EditControl::initCommon (QWidget*)
+{
+  m_textChanged = false;
+}
+
+void EditControl::update (int pId)
+{
+  bool handled = false;
+
+  if (m_multiLine)
+    handled = updateMultiLine (pId);
+  else
+    handled = updateSingleLine (pId);
+
+  if (! handled)
+    {
+      switch (pId)
+        {
+        default:
+          BaseControl::update (pId);
+          break;
+        }
+    }
+}
+
+bool EditControl::updateSingleLine (int pId)
+{
+  uicontrol::properties& up = properties<uicontrol> ();
+  QLineEdit* edit = qWidget<QLineEdit> ();
+
+  switch (pId)
+    {
+    case uicontrol::properties::ID_STRING:
+      edit->setText (Utils::fromStdString (up.get_string_string ()));
+      return true;
+    case uicontrol::properties::ID_HORIZONTALALIGNMENT:
+    case uicontrol::properties::ID_VERTICALALIGNMENT:
+      edit->setAlignment (Utils::fromHVAlign (up.get_horizontalalignment (),
+                                              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 ();
+
+          delete edit;
+          init (new TextEdit (container), true);
+        }
+      return true;
+    default:
+      break;
+    }
+
+  return false;
+}
+
+bool EditControl::updateMultiLine (int pId)
+{
+  uicontrol::properties& up = properties<uicontrol> ();
+  TextEdit* edit = qWidget<TextEdit> ();
+
+  switch (pId)
+    {
+    case uicontrol::properties::ID_STRING:
+      edit->setPlainText (Utils::fromStdString (up.get_string_string ()));
+      return true;
+    case uicontrol::properties::ID_MIN:
+    case uicontrol::properties::ID_MAX:
+      if ((up.get_max () - up.get_min ()) <= 1)
+        {
+          QWidget* container = edit->parentWidget ();
+
+          delete edit;
+          init (new QLineEdit (container), true);
+        }
+      return true;
+    default:
+      break;
+    }
+
+  return false;
+}
+
+void EditControl::textChanged (void)
+{
+  m_textChanged = true;
+}
+
+void EditControl::editingFinished (void)
+{
+  if (m_textChanged)
+    {
+      QString txt = (m_multiLine
+                     ? qWidget<TextEdit> ()->toPlainText ()
+                     : qWidget<QLineEdit> ()->text ());
+
+      gh_manager::post_set (m_handle, "string", Utils::toStdString (txt), false);
+      gh_manager::post_callback (m_handle, "callback");
+
+      m_textChanged = false;
+    }
+}
+
+}; // namespace QtHandles
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libgui/graphics/EditControl.h	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,68 @@
+/*
+
+Copyright (C) 2011-2014 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/>.
+
+*/
+
+#ifndef __QtHandles_EditControl__
+#define __QtHandles_EditControl__ 1
+
+#include "BaseControl.h"
+
+class QLineEdit;
+class QWidget;
+
+namespace QtHandles
+{
+
+class TextEdit;
+
+class EditControl : public BaseControl
+{
+  Q_OBJECT
+
+public:
+  EditControl (const graphics_object& go, QLineEdit* edit);
+  EditControl (const graphics_object& go, TextEdit* edit);
+  ~EditControl (void);
+
+  static EditControl* create (const graphics_object& go);
+
+protected:
+  void update (int pId);
+
+private:
+  void init (QLineEdit* edit, bool callBase = false);
+  void init (TextEdit* edit, bool callBase = false);
+  void initCommon (QWidget* widget);
+  bool updateSingleLine (int pId);
+  bool updateMultiLine (int pId);
+
+private slots:
+  void textChanged (void);
+  void editingFinished (void);
+
+private:
+  bool m_multiLine;
+  bool m_textChanged;
+};
+
+}; // namespace QtHandles
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libgui/graphics/Figure.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,677 @@
+/*
+
+Copyright (C) 2011-2014 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 <QAction>
+#include <QActionEvent>
+#include <QActionGroup>
+#include <QApplication>
+#include <QEvent>
+#include <QFrame>
+#include <QMainWindow>
+#include <QMenu>
+#include <QMenuBar>
+#include <QMessageBox>
+#include <QtDebug>
+#include <QTimer>
+#include <QToolBar>
+
+#include "Canvas.h"
+#include "Container.h"
+#include "Figure.h"
+#include "FigureWindow.h"
+#include "MouseModeActionGroup.h"
+#include "QtHandlesUtils.h"
+
+namespace QtHandles
+{
+
+#define ABOUT_TEXT "<b>QtHandles</b> - a Qt-based toolkit for <a href=\"http://www.octave.org\">Octave</a>.<br><br>Copyright (C) 2011-2014 Michael Goffioul"
+
+DECLARE_GENERICEVENTNOTIFY_SENDER(MenuBar, QMenuBar);
+
+static bool hasUiControlChildren (const figure::properties& fp)
+{
+  Matrix kids = fp.get_all_children ();
+
+  for (int i = 0; i < kids.numel (); i++)
+    {
+      graphics_object go (gh_manager::get_object (kids(i)));
+
+      if (go && (go.isa ("uicontrol") || go.isa ("uipanel")
+                 || go.isa ("uibuttongroup")))
+        return true;
+    }
+
+  return false;
+}
+
+static bool hasUiMenuChildren (const figure::properties& fp)
+{
+  Matrix kids = fp.get_all_children ();
+
+  for (int i = 0; i < kids.numel (); i++)
+    {
+      graphics_object go (gh_manager::get_object (kids(i)));
+
+      if (go && go.isa ("uimenu"))
+        return true;
+    }
+
+  return false;
+}
+
+static QRect boundingBoxToRect (const Matrix& bb)
+{
+  QRect r;
+
+  if (bb.numel () == 4)
+    {
+      r = QRect (xround (bb(0)), xround (bb(1)),
+                 xround (bb(2)), xround (bb(3)));
+      if (! r.isValid ())
+        r = QRect ();
+    }
+
+  return r;
+}
+
+Figure* Figure::create (const graphics_object& go)
+{
+  return new Figure (go, new FigureWindow ());
+}
+
+Figure::Figure (const graphics_object& go, FigureWindow* win)
+     : Object (go, win), m_blockUpdates (false), m_mouseMode (NoMode),
+       m_lastMouseMode (NoMode), m_figureToolBar (0), m_menuBar (0),
+       m_innerRect (), m_outerRect ()
+{
+  m_container = new Container (win);
+  win->setCentralWidget (m_container);
+
+  figure::properties& fp = properties<figure> ();
+
+  createFigureToolBarAndMenuBar ();
+
+  int offset = 0;
+  if (fp.toolbar_is ("figure")
+      || (fp.toolbar_is ("auto") && ! hasUiControlChildren (fp)))
+    offset += m_figureToolBar->sizeHint ().height ();
+  else
+    m_figureToolBar->hide ();
+  if (fp.menubar_is ("figure") || hasUiMenuChildren (fp))
+    offset += m_menuBar->sizeHint ().height () + 1;
+  else
+    m_menuBar->hide ();
+
+  m_innerRect = boundingBoxToRect (fp.get_boundingbox (true));
+  m_outerRect = boundingBoxToRect (fp.get_boundingbox (false));
+
+  //qDebug () << "Figure::Figure:" << m_innerRect;
+  win->setGeometry (m_innerRect.adjusted (0, -offset, 0, 0));
+  //qDebug () << "Figure::Figure(adjusted)" << m_innerRect.adjusted (0, -offset, 0, 0);
+  win->setWindowTitle (Utils::fromStdString (fp.get_title ()));
+
+  int eventMask = 0;
+  if (! fp.get_keypressfcn ().is_empty ())
+    eventMask |= Canvas::KeyPress;
+  if (! fp.get_keyreleasefcn ().is_empty ())
+    eventMask |= Canvas::KeyRelease;
+  m_container->canvas (m_handle)->setEventMask (eventMask);
+
+  if (! fp.get_windowbuttonmotionfcn ().is_empty ())
+    {
+      m_container->setMouseTracking (true);
+      m_container->canvas (m_handle)->qWidget ()->setMouseTracking (true);
+    }
+
+  connect (this, SIGNAL (asyncUpdate (void)),
+           this, SLOT (updateContainer (void)));
+
+  if (fp.is_visible ())
+    QTimer::singleShot (0, win, SLOT (show ()));
+  else
+    win->hide ();
+
+  win->addReceiver (this);
+  m_container->addReceiver (this);
+}
+
+Figure::~Figure (void)
+{
+}
+
+void Figure::createFigureToolBarAndMenuBar (void)
+{
+  QMainWindow* win = qWidget<QMainWindow> ();
+
+  m_figureToolBar = win->addToolBar (tr ("Figure ToolBar"));
+  m_figureToolBar->setMovable (false);
+  m_figureToolBar->setFloatable (false);
+
+  MouseModeActionGroup* mouseModeGroup = new MouseModeActionGroup (win);
+  connect (mouseModeGroup, SIGNAL (modeChanged (MouseMode)),
+           SLOT (setMouseMode (MouseMode)));
+  m_figureToolBar->addActions (mouseModeGroup->actions ());
+
+  m_menuBar = new MenuBar (win);
+  win->setMenuBar (m_menuBar);
+
+  QMenu* fileMenu = m_menuBar->addMenu (tr ("&File"));
+  fileMenu->menuAction ()->setObjectName ("builtinMenu");
+  fileMenu->addAction (tr ("&New Figure"), this, SLOT (fileNewFigure (void)));
+  fileMenu->addAction (tr ("&Open..."))->setEnabled (false);
+  fileMenu->addSeparator ();
+  fileMenu->addAction (tr ("&Save"))->setEnabled (false);
+  fileMenu->addAction (tr ("Save &As"))->setEnabled (false);
+  fileMenu->addSeparator ();
+  fileMenu->addAction (tr ("&Close Figure"), this,
+                       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);
+  editMenu->addAction (tr ("Cu&t"), this, SLOT (editCut (void)),
+                       Qt::CTRL|Qt::Key_X)->setEnabled (false);
+  editMenu->addAction (tr ("&Paste"), this, SLOT (editPaste(void)),
+                       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)));
+  helpMenu->addAction (tr ("About &Qt"), qApp, SLOT (aboutQt (void)));
+
+  m_menuBar->addReceiver (this);
+}
+
+Container* Figure::innerContainer (void)
+{
+  return m_container;
+}
+
+void Figure::redraw (void)
+{
+  Canvas* canvas = m_container->canvas (m_handle);
+
+  if (canvas)
+    {
+    canvas->redraw ();
+    //canvas->setMouseMode (RotateMode);
+    }
+
+  foreach (QFrame* frame,
+           qWidget<QWidget> ()->findChildren<QFrame*> ("UIPanel"))
+    {
+      Object* obj = Object::fromQObject (frame);
+
+      if (obj)
+        obj->slotRedraw ();
+    }
+}
+
+void Figure::beingDeleted (void)
+{
+  Canvas* canvas = m_container->canvas (m_handle.value (), false);
+
+  if (canvas)
+    canvas->blockRedraw (true);
+
+  m_menuBar->removeReceiver (this);
+  m_container->removeReceiver (this);
+  qWidget<FigureWindow> ()->removeReceiver (this);
+}
+
+void Figure::update (int pId)
+{
+  if (m_blockUpdates)
+    return;
+
+  figure::properties& fp = properties<figure> ();
+  QMainWindow* win = qWidget<QMainWindow> ();
+
+  m_blockUpdates = true;
+
+  switch (pId)
+    {
+    case figure::properties::ID_POSITION:
+        {
+          m_innerRect = boundingBoxToRect (fp.get_boundingbox (true));
+          //qDebug () << "Figure::update(position):" << m_innerRect;
+          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;
+          //qDebug () << "Figure::update(position)(adjusted):" << 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:
+      win->setWindowTitle (Utils::fromStdString (fp.get_title ()));
+      break;
+    case figure::properties::ID_VISIBLE:
+      if (fp.is_visible ())
+        QTimer::singleShot (0, win, SLOT (show ()));
+      else
+        win->hide ();
+      break;
+    case figure::properties::ID_TOOLBAR:
+      if (fp.toolbar_is ("none"))
+        showFigureToolBar (false);
+      else if (fp.toolbar_is ("figure"))
+        showFigureToolBar (true);
+      else // "auto"
+        showFigureToolBar (! hasUiControlChildren (fp));
+      break;
+    case figure::properties::ID_MENUBAR:
+      showMenuBar (fp.menubar_is ("figure"));
+      break;
+    case figure::properties::ID_KEYPRESSFCN:
+      if (fp.get_keypressfcn ().is_empty ())
+        m_container->canvas (m_handle)->clearEventMask (Canvas::KeyPress);
+      else
+        m_container->canvas (m_handle)->addEventMask (Canvas::KeyPress);
+      break;
+    case figure::properties::ID_KEYRELEASEFCN:
+      if (fp.get_keyreleasefcn ().is_empty ())
+        m_container->canvas (m_handle)->clearEventMask (Canvas::KeyRelease);
+      else
+        m_container->canvas (m_handle)->addEventMask (Canvas::KeyRelease);
+      break;
+    case figure::properties::ID_WINDOWBUTTONMOTIONFCN:
+        {
+          bool hasCallback = ! fp.get_windowbuttonmotionfcn ().is_empty ();
+
+          m_container->setMouseTracking (hasCallback);
+          foreach (QWidget* w, m_container->findChildren<QWidget*> ())
+            { w->setMouseTracking (hasCallback); }
+        }
+      break;
+    default:
+      break;
+    }
+
+  m_blockUpdates = false;
+}
+
+void Figure::showFigureToolBar (bool visible)
+{
+  if ((! m_figureToolBar->isHidden ()) != visible)
+    {
+      int dy = m_figureToolBar->sizeHint ().height ();
+      QRect r = qWidget<QWidget> ()->geometry ();
+
+      if (! visible)
+        r.adjust (0, dy, 0, 0);
+      else
+        r.adjust (0, -dy, 0, 0);
+
+      m_blockUpdates = true;
+      qWidget<QWidget> ()->setGeometry (r);
+      m_figureToolBar->setVisible (visible);
+      m_blockUpdates = false;
+
+      updateBoundingBox (false);
+
+      if (visible)
+        m_mouseMode = m_lastMouseMode;
+      else
+        {
+          m_lastMouseMode = m_mouseMode;
+          m_mouseMode = NoMode;
+        }
+    }
+}
+
+void Figure::showMenuBar (bool visible)
+{
+  int h1 = m_menuBar->sizeHint ().height ();
+
+  foreach (QAction* a, m_menuBar->actions ())
+    if (a->objectName () == "builtinMenu")
+      a->setVisible (visible);
+
+  int h2 = m_menuBar->sizeHint ().height ();
+
+  if (! visible)
+    visible = hasUiMenuChildren (properties<figure> ());
+
+  if ((! m_menuBar->isHidden ()) != visible)
+    {
+      int dy = qMax (h1, h2) + 1;
+      QRect r = qWidget<QWidget> ()->geometry ();
+
+      //qDebug () << "Figure::showMenuBar:" << r;
+      if (! visible)
+        r.adjust (0, dy, 0, 0);
+      else
+        r.adjust (0, -dy, 0, 0);
+      //qDebug () << "Figure::showMenuBar(adjusted):" << r;
+
+      m_blockUpdates = true;
+      qWidget<QWidget> ()->setGeometry (r);
+      m_menuBar->setVisible (visible);
+      m_blockUpdates = false;
+
+      updateBoundingBox (false);
+    }
+}
+
+void Figure::updateMenuBar (void)
+{
+  gh_manager::auto_lock lock;
+  graphics_object go = object ();
+
+  if (go.valid_object ())
+    showMenuBar (Utils::properties<figure> (go).menubar_is ("figure"));
+}
+
+QWidget* Figure::menu (void)
+{
+  return qWidget<QMainWindow> ()->menuBar ();
+}
+
+struct UpdateBoundingBoxData
+{
+  Matrix m_bbox;
+  bool m_internal;
+  graphics_handle m_handle;
+  Figure* m_figure;
+};
+
+void Figure::updateBoundingBoxHelper (void* data)
+{
+  gh_manager::auto_lock lock;
+
+  UpdateBoundingBoxData* d = reinterpret_cast<UpdateBoundingBoxData*> (data);
+  graphics_object go = gh_manager::get_object (d->m_handle);
+
+  if (go.valid_object ())
+    {
+      figure::properties& fp = Utils::properties<figure> (go);
+
+      //qDebug ("Figure::updateBoundingBoxHelper: internal=%d, bbox=[%g %g %g %g]",
+      //        d->m_internal, d->m_bbox(0), d->m_bbox(1), d->m_bbox(2), d->m_bbox(3));
+      fp.set_boundingbox (d->m_bbox, d->m_internal, false);
+
+      if (d->m_internal)
+        emit d->m_figure->asyncUpdate ();
+    }
+
+  delete d;
+}
+
+void Figure::updateBoundingBox (bool internal, int flags)
+{
+  QWidget* win = qWidget<QWidget> ();
+  Matrix bb (1, 4);
+
+  if (internal)
+    {
+      QRect r = m_innerRect;
+
+      if (flags & UpdateBoundingBoxPosition)
+        r.moveTopLeft (win->mapToGlobal (m_container->pos ()));
+      if (flags & UpdateBoundingBoxSize)
+        r.setSize (m_container->size ());
+
+      if (r.isValid () && r != m_innerRect)
+        {
+          //qDebug() << "inner rect changed:" << m_innerRect << "->>" << r;
+          m_innerRect = r;
+
+          bb(0) = r.x ();
+          bb(1) = r.y ();
+          bb(2) = r.width ();
+          bb(3) = r.height ();
+        }
+      else
+        return;
+    }
+  else
+    {
+      QRect r = m_outerRect;
+
+      if (flags & UpdateBoundingBoxPosition)
+        r.moveTopLeft (win->pos ());
+      if (flags & UpdateBoundingBoxSize)
+        r.setSize (win->frameGeometry ().size ());
+
+      if (r.isValid () && r != m_outerRect)
+        {
+          //qDebug() << "outer rect changed:" << m_outerRect << "->>" << r;
+          m_outerRect = r;
+
+          bb(0) = r.x ();
+          bb(1) = r.y ();
+          bb(2) = r.width ();
+          bb(3) = r.height ();
+        }
+      else
+        return;
+    }
+
+  UpdateBoundingBoxData* d = new UpdateBoundingBoxData ();
+
+  d->m_bbox = bb;
+  d->m_internal = internal;
+  d->m_handle = m_handle;
+  d->m_figure = this;
+
+  //qDebug ("Figure::updateBoundingBox: internal=%d, bbox=[%g %g %g %g]",
+  //        d->m_internal, d->m_bbox(0), d->m_bbox(1), d->m_bbox(2), d->m_bbox(3));
+  gh_manager::post_function (Figure::updateBoundingBoxHelper, d);
+}
+
+bool Figure::eventNotifyBefore (QObject* obj, QEvent* xevent)
+{
+  if (! m_blockUpdates)
+    {
+      if (obj == m_container)
+        {
+          // Do nothing...
+        }
+      else if (obj == m_menuBar)
+        {
+          switch (xevent->type ())
+            {
+            case QEvent::ActionRemoved:
+                {
+                  QAction* a = dynamic_cast<QActionEvent*> (xevent)->action ();
+
+                  if (! a->isSeparator ()
+                      && a->objectName () != "builtinMenu")
+                    updateMenuBar ();
+                }
+              break;
+            default:
+              break;
+            }
+        }
+      else
+        {
+          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* xevent)
+{
+  if (! m_blockUpdates)
+    {
+      if (watched == m_container)
+        {
+          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;
+            }
+        }
+      else if (watched == m_menuBar)
+        {
+          switch (xevent->type ())
+            {
+            case QEvent::ActionAdded:
+                {
+                  QAction* a = dynamic_cast<QActionEvent*> (xevent)->action ();
+
+                  if (! a->isSeparator ()
+                      && a->objectName () != "builtinMenu")
+                    updateMenuBar ();
+                }
+              break;
+            default:
+              break;
+            }
+        }
+      else
+        {
+          switch (xevent->type ())
+            {
+            case QEvent::Move:
+              updateBoundingBox (false, UpdateBoundingBoxPosition);
+              updateBoundingBox (true, UpdateBoundingBoxPosition);
+              break;
+            case QEvent::Resize:
+              updateBoundingBox (false, UpdateBoundingBoxSize);
+              break;
+            default:
+              break;
+            }
+        }
+    }
+}
+
+void Figure::helpAboutQtHandles (void)
+{
+  QMessageBox::about (qWidget<QMainWindow> (), tr ("About QtHandles"),
+                      ABOUT_TEXT);
+}
+
+void Figure::fileNewFigure (void)
+{
+}
+
+void Figure::fileCloseFigure (void)
+{
+  qWidget<QMainWindow> ()->close ();
+}
+
+void Figure::editCopy (void)
+{
+}
+
+void Figure::editCut (void)
+{
+}
+
+void Figure::editPaste (void)
+{
+}
+
+void Figure::addCustomToolBar (QToolBar* bar, bool visible)
+{
+  QMainWindow* win = qWidget<QMainWindow> ();
+
+  if (! visible)
+    win->addToolBar (bar);
+  else
+    {
+      QSize sz = bar->sizeHint ();
+      QRect r = win->geometry ();
+      //qDebug () << "Figure::addCustomToolBar:" << r;
+
+      r.adjust (0, -sz.height (), 0, 0);
+
+      m_blockUpdates = true;
+      win->setGeometry (r);
+      win->addToolBarBreak ();
+      win->addToolBar (bar);
+      m_blockUpdates = false;
+
+      //qDebug () << "Figure::addCustomToolBar:" << win->geometry ();
+      updateBoundingBox (false);
+    }
+}
+
+void Figure::showCustomToolBar (QToolBar* bar, bool visible)
+{
+  QMainWindow* win = qWidget<QMainWindow> ();
+
+  if ((! bar->isHidden ()) != visible)
+    {
+      QSize sz = bar->sizeHint ();
+      QRect r = win->geometry ();
+
+      if (visible)
+        r.adjust (0, -sz.height (), 0, 0);
+      else
+        r.adjust (0, sz.height (), 0, 0);
+
+      m_blockUpdates = true;
+      win->setGeometry (r);
+      bar->setVisible (visible);
+      m_blockUpdates = false;
+
+      updateBoundingBox (false);
+    }
+}
+
+void Figure::updateContainer (void)
+{
+  redraw ();
+}
+
+}; // namespace QtHandles
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libgui/graphics/Figure.h	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,124 @@
+/*
+
+Copyright (C) 2011-2014 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/>.
+
+*/
+
+#ifndef __QtHandles_Figure__
+#define __QtHandles_Figure__ 1
+
+#include <QRect>
+
+#include "GenericEventNotify.h"
+#include "MenuContainer.h"
+#include "Object.h"
+
+class QMainWindow;
+class QToolBar;
+
+namespace QtHandles
+{
+
+enum MouseMode
+{
+  NoMode        = 0,
+  RotateMode    = 1,
+  ZoomMode      = 2,
+  PanMode       = 3,
+  SelectMode    = 4
+};
+
+class Container;
+class FigureWindow;
+class MenuBar;
+class ToolBar;
+
+class Figure :
+  public Object,
+  public MenuContainer,
+  public GenericEventNotifyReceiver
+{
+  Q_OBJECT
+
+  friend class ToolBar;
+
+public:
+  Figure (const graphics_object& go, FigureWindow* win);
+  ~Figure (void);
+
+  static Figure* create (const graphics_object& go);
+
+  MouseMode mouseMode (void) { return m_mouseMode; }
+
+  Container* innerContainer (void);
+  QWidget* menu (void);
+
+  bool eventNotifyBefore (QObject* watched, QEvent* event);
+  void eventNotifyAfter (QObject* watched, QEvent* event);
+
+protected:
+  enum UpdateBoundingBoxFlag
+    {
+      UpdateBoundingBoxPosition = 0x1,
+      UpdateBoundingBoxSize     = 0x2,
+      UpdateBoundingBoxAll      = 0x3
+    };
+
+protected:
+  void redraw (void);
+  void update (int pId);
+  void updateBoundingBox (bool internal = false, int flags = 0);
+  void beingDeleted (void);
+
+private:
+  void createFigureToolBarAndMenuBar (void);
+  void showFigureToolBar (bool visible);
+  void showMenuBar (bool visible);
+  void addCustomToolBar (QToolBar* bar, bool visible);
+  void showCustomToolBar (QToolBar* bar, bool visible);
+
+  static void updateBoundingBoxHelper (void*);
+
+private slots:
+  void setMouseMode (MouseMode mode) { m_mouseMode = mode; }
+  void fileNewFigure (void);
+  void fileCloseFigure (void);
+  void editCopy (void);
+  void editCut (void);
+  void editPaste (void);
+  void helpAboutQtHandles (void);
+  void updateMenuBar (void);
+  void updateContainer (void);
+
+signals:
+  void asyncUpdate (void);
+
+private:
+  Container* m_container;
+  bool m_blockUpdates;
+  MouseMode m_mouseMode, m_lastMouseMode;
+  QToolBar* m_figureToolBar;
+  MenuBar* m_menuBar;
+  QRect m_innerRect;
+  QRect m_outerRect;
+};
+
+}; // namespace QtHandles
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libgui/graphics/FigureWindow.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,49 @@
+/*
+
+Copyright (C) 2011-2014 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 <QMenu>
+
+#include "FigureWindow.h"
+
+namespace QtHandles
+{
+
+FigureWindow::FigureWindow (QWidget* xparent)
+  : FigureWindowBase (xparent)
+{
+}
+
+FigureWindow::~FigureWindow (void)
+{
+}
+
+QMenu* FigureWindow::createPopupMenu (void)
+{
+  // For the time being, disable menubar/toolbar popup menu
+  return 0;
+}
+
+}; // namespace QtHandles
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libgui/graphics/FigureWindow.h	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,48 @@
+/*
+
+Copyright (C) 2011-2014 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/>.
+
+*/
+
+#ifndef __QtHandles_FigureWindow__
+#define __QtHandles_FigureWindow__ 1
+
+#include <QMainWindow>
+
+#include "GenericEventNotify.h"
+
+namespace QtHandles
+{
+
+DECLARE_GENERICEVENTNOTIFY_SENDER(FigureWindowBase, QMainWindow);
+
+class FigureWindow : public FigureWindowBase
+{
+  Q_OBJECT
+
+public:
+  FigureWindow (QWidget* parent = 0);
+  ~FigureWindow (void);
+
+  QMenu* createPopupMenu (void);
+};
+
+}; // namespace QtHandles
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libgui/graphics/GLCanvas.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,149 @@
+/*
+
+Copyright (C) 2011-2014 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
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "gl-render.h"
+#include "graphics.h"
+
+#include "GLCanvas.h"
+#include "gl-select.h"
+
+namespace QtHandles
+{
+
+GLCanvas::GLCanvas (QWidget* xparent, const graphics_handle& gh)
+  : QGLWidget (QGLFormat(QGL::SampleBuffers), xparent), Canvas (gh)
+{
+  setFocusPolicy (Qt::ClickFocus);
+}
+
+GLCanvas::~GLCanvas (void)
+{
+}
+
+void GLCanvas::draw (const graphics_handle& gh)
+{
+  graphics_object go = gh_manager::get_object (gh);
+
+  if (go)
+    {
+      opengl_renderer r;
+
+      r.set_viewport (width (), height ());
+      r.draw(go);
+    }
+}
+
+graphics_object GLCanvas::selectFromAxes (const graphics_object& ax,
+                                          const QPoint& pt)
+{
+  makeCurrent ();
+
+  if (ax)
+    {
+      opengl_selector s;
+
+      s.set_viewport (width (), height ());
+      return s.select (ax, pt.x (), height () - pt.y ());
+    }
+
+  return graphics_object ();
+}
+
+inline void glDrawZoomBox (const QPoint& p1, const QPoint& p2)
+{
+  glVertex2d (p1.x (), p1.y ());
+  glVertex2d (p2.x (), p1.y ());
+  glVertex2d (p2.x (), p2.y ());
+  glVertex2d (p1.x (), p2.y ());
+  glVertex2d (p1.x (), p1.y ());
+}
+
+void GLCanvas::drawZoomBox (const QPoint& p1, const QPoint& p2)
+{
+  glPushMatrix ();
+
+  glMatrixMode (GL_MODELVIEW);
+  glLoadIdentity ();
+
+  glMatrixMode (GL_PROJECTION);
+  glLoadIdentity ();
+  glOrtho (0, width (), height (), 0, 1, -1);
+
+  glPushAttrib (GL_DEPTH_BUFFER_BIT | GL_CURRENT_BIT);
+  glDisable (GL_DEPTH_TEST);
+
+  glBegin (GL_POLYGON);
+  glColor4f (0.45, 0.62, 0.81, 0.1);
+  glDrawZoomBox (p1, p2);
+  glEnd ();
+
+  glBegin (GL_LINE_STRIP);
+  glLineWidth (1.5);
+  glColor4f (0.45, 0.62, 0.81, 0.9);
+  glDrawZoomBox (p1, p2);
+  glEnd ();
+
+  glPopAttrib ();
+  glPopMatrix ();
+}
+
+void GLCanvas::paintGL (void)
+{
+  canvasPaintEvent ();
+}
+
+void GLCanvas::mouseMoveEvent (QMouseEvent* xevent)
+{
+  canvasMouseMoveEvent (xevent);
+}
+
+void GLCanvas::mousePressEvent (QMouseEvent* xevent)
+{
+  canvasMousePressEvent (xevent);
+}
+
+void GLCanvas::mouseReleaseEvent (QMouseEvent* xevent)
+{
+  canvasMouseReleaseEvent (xevent);
+}
+
+void GLCanvas::keyPressEvent (QKeyEvent* xevent)
+{
+  if (! canvasKeyPressEvent (xevent))
+    QGLWidget::keyPressEvent (xevent);
+}
+
+void GLCanvas::keyReleaseEvent (QKeyEvent* xevent)
+{
+  if (! canvasKeyReleaseEvent (xevent))
+    QGLWidget::keyReleaseEvent (xevent);
+}
+
+}; // namespace QtHandles
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libgui/graphics/GLCanvas.h	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,58 @@
+/*
+
+Copyright (C) 2011-2014 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/>.
+
+*/
+
+#ifndef __QtHandles_GLCanvas__
+#define __QtHandles_GLCanvas__ 1
+
+#include <QGLWidget>
+
+#include "Canvas.h"
+
+namespace QtHandles
+{
+
+class GLCanvas : public QGLWidget, public Canvas
+{
+public:
+  GLCanvas (QWidget* parent, const graphics_handle& handle);
+  ~GLCanvas (void);
+
+  void draw (const graphics_handle& handle);
+  void drawZoomBox (const QPoint& p1, const QPoint& p2);
+  void resize (int /* x */, int /* y */,
+               int /* width */, int /* height */) { }
+  graphics_object selectFromAxes (const graphics_object& ax,
+                                  const QPoint& pt);
+  QWidget* qWidget (void) { return this; }
+
+protected:
+  void paintGL (void);
+  void mouseMoveEvent (QMouseEvent* event);
+  void mousePressEvent (QMouseEvent* event);
+  void mouseReleaseEvent (QMouseEvent* event);
+  void keyPressEvent (QKeyEvent* event);
+  void keyReleaseEvent (QKeyEvent* event);
+};
+
+}; // namespace QtHandles
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libgui/graphics/GenericEventNotify.h	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,104 @@
+/*
+
+Copyright (C) 2011-2014 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/>.
+
+*/
+
+#ifndef __GenericEventNotify_h__
+#define __GenericEventNotify_h__ 1
+
+#include <QSet>
+
+class QEvent;
+class QObject;
+class QWidget;
+
+namespace QtHandles
+{
+
+class GenericEventNotifyReceiver;
+
+class GenericEventNotifySender
+{
+public:
+  GenericEventNotifySender (void) : m_receivers () { }
+  virtual ~GenericEventNotifySender (void) { }
+
+  void addReceiver (GenericEventNotifyReceiver* r)
+    { m_receivers.insert (r); }
+
+  void removeReceiver (GenericEventNotifyReceiver* r)
+    { m_receivers.remove (r); }
+
+protected:
+  bool notifyReceiversBefore (QObject* obj, QEvent* evt);
+  void notifyReceiversAfter (QObject* obj, QEvent* evt);
+
+private:
+  QSet<GenericEventNotifyReceiver*> m_receivers;
+};
+
+class GenericEventNotifyReceiver
+{
+public:
+  GenericEventNotifyReceiver (void) { }
+  virtual ~GenericEventNotifyReceiver (void) { }
+
+  virtual bool eventNotifyBefore (QObject* obj, QEvent* evt) = 0;
+  virtual void eventNotifyAfter (QObject* obj, QEvent* evt) = 0;
+};
+
+inline
+bool GenericEventNotifySender::notifyReceiversBefore (QObject* obj,
+                                                      QEvent* evt)
+{
+  foreach (GenericEventNotifyReceiver* r, m_receivers)
+    if (r->eventNotifyBefore (obj, evt))
+      return true;
+  return false;
+}
+
+inline
+void GenericEventNotifySender::notifyReceiversAfter (QObject* obj,
+                                                     QEvent* evt)
+{
+  foreach (GenericEventNotifyReceiver* r, m_receivers)
+    r->eventNotifyAfter (obj, evt);
+}
+
+#define DECLARE_GENERICEVENTNOTIFY_SENDER(T,B) \
+class T : public B, public GenericEventNotifySender \
+{ \
+public: \
+  T (QWidget* xparent) : B (xparent), GenericEventNotifySender () { } \
+  ~ T (void) { } \
+\
+  bool event (QEvent* evt) \
+    { \
+      bool result = true; \
+      if (! notifyReceiversBefore (this, evt)) \
+        result = B::event (evt); \
+      notifyReceiversAfter (this, evt); \
+      return result; \
+    } \
+}
+
+};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libgui/graphics/KeyMap.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,258 @@
+/*
+
+Copyright (C) 2011-2014 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 <QMap>
+#include <Qt>
+
+#include "KeyMap.h"
+
+namespace QtHandles
+{
+
+namespace KeyMap
+{
+
+std::string qKeyToKeyString (int key)
+{
+  static QMap<int, std::string> keyMapper;
+
+  if (keyMapper.isEmpty ())
+    {
+      keyMapper[Qt::Key_Escape] = "escape";
+      keyMapper[Qt::Key_Tab] = "tab";
+      keyMapper[Qt::Key_Backtab] = "backtab";
+      keyMapper[Qt::Key_Backspace] = "backspace";
+      keyMapper[Qt::Key_Return] = "return";
+      keyMapper[Qt::Key_Enter] = "enter";
+      keyMapper[Qt::Key_Insert] = "insert";
+      keyMapper[Qt::Key_Delete] = "delete";
+      keyMapper[Qt::Key_Pause] = "pause";
+      keyMapper[Qt::Key_Print] = "print";
+      keyMapper[Qt::Key_SysReq] = "sysreq";
+      keyMapper[Qt::Key_Clear] = "clear";
+      keyMapper[Qt::Key_Home] = "home";
+      keyMapper[Qt::Key_End] = "end";
+      keyMapper[Qt::Key_Left] = "left";
+      keyMapper[Qt::Key_Up] = "up";
+      keyMapper[Qt::Key_Right] = "right";
+      keyMapper[Qt::Key_Down] = "down";
+      keyMapper[Qt::Key_PageUp] = "pageup";
+      keyMapper[Qt::Key_PageDown] = "pagedown";
+      keyMapper[Qt::Key_Shift] = "shift";
+      keyMapper[Qt::Key_Control] = "control";
+      keyMapper[Qt::Key_Meta] = "meta";
+      keyMapper[Qt::Key_Alt] = "alt";
+      keyMapper[Qt::Key_CapsLock] = "capslock";
+      keyMapper[Qt::Key_NumLock] = "numlock";
+      keyMapper[Qt::Key_ScrollLock] = "scrolllock";
+      keyMapper[Qt::Key_F1] = "f1";
+      keyMapper[Qt::Key_F2] = "f2";
+      keyMapper[Qt::Key_F3] = "f3";
+      keyMapper[Qt::Key_F4] = "f4";
+      keyMapper[Qt::Key_F5] = "f5";
+      keyMapper[Qt::Key_F6] = "f6";
+      keyMapper[Qt::Key_F7] = "f7";
+      keyMapper[Qt::Key_F8] = "f8";
+      keyMapper[Qt::Key_F9] = "f9";
+      keyMapper[Qt::Key_F10] = "f10";
+      keyMapper[Qt::Key_F11] = "f11";
+      keyMapper[Qt::Key_F12] = "f12";
+      keyMapper[Qt::Key_F13] = "f13";
+      keyMapper[Qt::Key_F14] = "f14";
+      keyMapper[Qt::Key_F15] = "f15";
+      keyMapper[Qt::Key_F16] = "f16";
+      keyMapper[Qt::Key_F17] = "f17";
+      keyMapper[Qt::Key_F18] = "f18";
+      keyMapper[Qt::Key_F19] = "f19";
+      keyMapper[Qt::Key_F20] = "f20";
+      keyMapper[Qt::Key_F21] = "f21";
+      keyMapper[Qt::Key_F22] = "f22";
+      keyMapper[Qt::Key_F23] = "f23";
+      keyMapper[Qt::Key_F24] = "f24";
+      keyMapper[Qt::Key_F25] = "f25";
+      keyMapper[Qt::Key_F26] = "f26";
+      keyMapper[Qt::Key_F27] = "f27";
+      keyMapper[Qt::Key_F28] = "f28";
+      keyMapper[Qt::Key_F29] = "f29";
+      keyMapper[Qt::Key_F30] = "f30";
+      keyMapper[Qt::Key_F31] = "f31";
+      keyMapper[Qt::Key_F32] = "f32";
+      keyMapper[Qt::Key_F33] = "f33";
+      keyMapper[Qt::Key_F34] = "f34";
+      keyMapper[Qt::Key_F35] = "f35";
+      keyMapper[Qt::Key_Super_L] = "super_l";
+      keyMapper[Qt::Key_Super_R] = "super_r";
+      keyMapper[Qt::Key_Menu] = "menu";
+      keyMapper[Qt::Key_Hyper_L] = "hyper_l";
+      keyMapper[Qt::Key_Hyper_R] = "hyper_r";
+      keyMapper[Qt::Key_Help] = "help";
+      keyMapper[Qt::Key_Direction_L] = "direction_l";
+      keyMapper[Qt::Key_Direction_R] = "direction_r";
+      keyMapper[Qt::Key_Space] = "space";
+      keyMapper[Qt::Key_Any] = "any";
+      keyMapper[Qt::Key_Exclam] = "exclam";
+      keyMapper[Qt::Key_QuoteDbl] = "quotedbl";
+      keyMapper[Qt::Key_NumberSign] = "numbersign";
+      keyMapper[Qt::Key_Dollar] = "dollar";
+      keyMapper[Qt::Key_Percent] = "percent";
+      keyMapper[Qt::Key_Ampersand] = "ampersand";
+      keyMapper[Qt::Key_Apostrophe] = "apostrophe";
+      keyMapper[Qt::Key_ParenLeft] = "parenleft";
+      keyMapper[Qt::Key_ParenRight] = "parenright";
+      keyMapper[Qt::Key_Asterisk] = "asterisk";
+      keyMapper[Qt::Key_Plus] = "plus";
+      keyMapper[Qt::Key_Comma] = "comma";
+      keyMapper[Qt::Key_Minus] = "minus";
+      keyMapper[Qt::Key_Period] = "period";
+      keyMapper[Qt::Key_Slash] = "slash";
+      keyMapper[Qt::Key_0] = "0";
+      keyMapper[Qt::Key_1] = "1";
+      keyMapper[Qt::Key_2] = "2";
+      keyMapper[Qt::Key_3] = "3";
+      keyMapper[Qt::Key_4] = "4";
+      keyMapper[Qt::Key_5] = "5";
+      keyMapper[Qt::Key_6] = "6";
+      keyMapper[Qt::Key_7] = "7";
+      keyMapper[Qt::Key_8] = "8";
+      keyMapper[Qt::Key_9] = "9";
+      keyMapper[Qt::Key_Colon] = "colon";
+      keyMapper[Qt::Key_Semicolon] = "semicolon";
+      keyMapper[Qt::Key_Less] = "less";
+      keyMapper[Qt::Key_Equal] = "equal";
+      keyMapper[Qt::Key_Greater] = "greater";
+      keyMapper[Qt::Key_Question] = "question";
+      keyMapper[Qt::Key_At] = "at";
+      keyMapper[Qt::Key_A] = "a";
+      keyMapper[Qt::Key_B] = "b";
+      keyMapper[Qt::Key_C] = "c";
+      keyMapper[Qt::Key_D] = "d";
+      keyMapper[Qt::Key_E] = "e";
+      keyMapper[Qt::Key_F] = "f";
+      keyMapper[Qt::Key_G] = "g";
+      keyMapper[Qt::Key_H] = "h";
+      keyMapper[Qt::Key_I] = "i";
+      keyMapper[Qt::Key_J] = "j";
+      keyMapper[Qt::Key_K] = "k";
+      keyMapper[Qt::Key_L] = "l";
+      keyMapper[Qt::Key_M] = "m";
+      keyMapper[Qt::Key_N] = "n";
+      keyMapper[Qt::Key_O] = "o";
+      keyMapper[Qt::Key_P] = "p";
+      keyMapper[Qt::Key_Q] = "q";
+      keyMapper[Qt::Key_R] = "r";
+      keyMapper[Qt::Key_S] = "s";
+      keyMapper[Qt::Key_T] = "t";
+      keyMapper[Qt::Key_U] = "u";
+      keyMapper[Qt::Key_V] = "v";
+      keyMapper[Qt::Key_W] = "w";
+      keyMapper[Qt::Key_X] = "x";
+      keyMapper[Qt::Key_Y] = "y";
+      keyMapper[Qt::Key_Z] = "z";
+      keyMapper[Qt::Key_BracketLeft] = "bracketleft";
+      keyMapper[Qt::Key_Backslash] = "backslash";
+      keyMapper[Qt::Key_BracketRight] = "bracketright";
+      keyMapper[Qt::Key_AsciiCircum] = "asciicircum";
+      keyMapper[Qt::Key_Underscore] = "underscore";
+      keyMapper[Qt::Key_QuoteLeft] = "quoteleft";
+      keyMapper[Qt::Key_BraceLeft] = "braceleft";
+      keyMapper[Qt::Key_Bar] = "bar";
+      keyMapper[Qt::Key_BraceRight] = "braceright";
+      keyMapper[Qt::Key_AsciiTilde] = "asciitilde";
+
+      keyMapper[Qt::Key_nobreakspace] = "nobreakspace";
+      keyMapper[Qt::Key_exclamdown] = "exclamdown";
+      keyMapper[Qt::Key_cent] = "cent";
+      keyMapper[Qt::Key_sterling] = "sterling";
+      keyMapper[Qt::Key_currency] = "currency";
+      keyMapper[Qt::Key_yen] = "yen";
+      keyMapper[Qt::Key_brokenbar] = "brokenbar";
+      keyMapper[Qt::Key_section] = "section";
+      keyMapper[Qt::Key_diaeresis] = "diaeresis";
+      keyMapper[Qt::Key_copyright] = "copyright";
+      keyMapper[Qt::Key_ordfeminine] = "ordfeminine";
+      keyMapper[Qt::Key_guillemotleft] = "guillemotleft";
+      keyMapper[Qt::Key_notsign] = "notsign";
+      keyMapper[Qt::Key_hyphen] = "hyphen";
+      keyMapper[Qt::Key_registered] = "registered";
+      keyMapper[Qt::Key_macron] = "macron";
+      keyMapper[Qt::Key_degree] = "degree";
+      keyMapper[Qt::Key_plusminus] = "plusminus";
+      keyMapper[Qt::Key_twosuperior] = "twosuperior";
+      keyMapper[Qt::Key_threesuperior] = "threesuperior";
+      keyMapper[Qt::Key_acute] = "acute";
+      keyMapper[Qt::Key_mu] = "mu";
+      keyMapper[Qt::Key_paragraph] = "paragraph";
+      keyMapper[Qt::Key_periodcentered] = "periodcentered";
+      keyMapper[Qt::Key_cedilla] = "cedilla";
+      keyMapper[Qt::Key_onesuperior] = "onesuperior";
+      keyMapper[Qt::Key_masculine] = "masculine";
+      keyMapper[Qt::Key_guillemotright] = "guillemotright";
+      keyMapper[Qt::Key_onequarter] = "onequarter";
+      keyMapper[Qt::Key_onehalf] = "onehalf";
+      keyMapper[Qt::Key_threequarters] = "threequarters";
+      keyMapper[Qt::Key_questiondown] = "questiondown";
+      keyMapper[Qt::Key_Agrave] = "agrave";
+      keyMapper[Qt::Key_Aacute] = "aacute";
+      keyMapper[Qt::Key_Acircumflex] = "acircumflex";
+      keyMapper[Qt::Key_Atilde] = "atilde";
+      keyMapper[Qt::Key_Adiaeresis] = "adiaeresis";
+      keyMapper[Qt::Key_Aring] = "aring";
+      keyMapper[Qt::Key_AE] = "ae";
+      keyMapper[Qt::Key_Ccedilla] = "ccedilla";
+      keyMapper[Qt::Key_Egrave] = "egrave";
+      keyMapper[Qt::Key_Eacute] = "eacute";
+      keyMapper[Qt::Key_Ecircumflex] = "ecircumflex";
+      keyMapper[Qt::Key_Ediaeresis] = "ediaeresis";
+      keyMapper[Qt::Key_Igrave] = "igrave";
+      keyMapper[Qt::Key_Iacute] = "iacute";
+      keyMapper[Qt::Key_Icircumflex] = "icircumflex";
+      keyMapper[Qt::Key_Idiaeresis] = "idiaeresis";
+      keyMapper[Qt::Key_ETH] = "eth";
+      keyMapper[Qt::Key_Ntilde] = "ntilde";
+      keyMapper[Qt::Key_Ograve] = "ograve";
+      keyMapper[Qt::Key_Oacute] = "oacute";
+      keyMapper[Qt::Key_Ocircumflex] = "ocircumflex";
+      keyMapper[Qt::Key_Otilde] = "otilde";
+      keyMapper[Qt::Key_Odiaeresis] = "odiaeresis";
+      keyMapper[Qt::Key_multiply] = "multiply";
+      keyMapper[Qt::Key_Ooblique] = "ooblique";
+      keyMapper[Qt::Key_Ugrave] = "ugrave";
+      keyMapper[Qt::Key_Uacute] = "uacute";
+      keyMapper[Qt::Key_Ucircumflex] = "ucircumflex";
+      keyMapper[Qt::Key_Udiaeresis] = "udiaeresis";
+      keyMapper[Qt::Key_Yacute] = "yacute";
+      keyMapper[Qt::Key_THORN] = "thorn";
+      keyMapper[Qt::Key_ssharp] = "ssharp";
+      keyMapper[Qt::Key_division] = "division";
+      keyMapper[Qt::Key_ydiaeresis] = "ydiaeresis";
+    }
+
+  return keyMapper.value (key, std::string ("<unknown key>"));
+}
+
+}; //namespace KeyMap
+
+}; // namespace QtHandles
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libgui/graphics/KeyMap.h	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,40 @@
+/*
+
+Copyright (C) 2011-2014 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/>.
+
+*/
+
+#ifndef __QtHandles__KeyMap__
+#define __QtHandles__KeyMap__ 1
+
+#include <string>
+
+namespace QtHandles
+{
+
+namespace KeyMap
+{
+
+std::string qKeyToKeyString (int key);
+
+}; // namespace KeyMap
+
+}; // namespace QtHandles
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libgui/graphics/ListBoxControl.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,170 @@
+/*
+
+Copyright (C) 2011-2014 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 <QListWidget>
+
+#include "Container.h"
+#include "ListBoxControl.h"
+#include "QtHandlesUtils.h"
+
+namespace QtHandles
+{
+
+static void updateSelection (QListWidget* list, const Matrix& value)
+{
+  octave_idx_type n = value.numel ();
+  int lc = list->count ();
+
+  list->clearSelection ();
+
+  for (octave_idx_type i = 0; i < n; 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;
+        }
+      else
+        {
+          // Invalid selection.
+          list->clearSelection ();
+          break;
+        }
+    }
+}
+
+ListBoxControl* ListBoxControl::create (const graphics_object& go)
+{
+  Object* parent = Object::parentObject (go);
+
+  if (parent)
+    {
+      Container* container = parent->innerContainer ();
+
+      if (container)
+        return new ListBoxControl (go, new QListWidget (container));
+    }
+
+  return 0;
+}
+
+ListBoxControl::ListBoxControl (const graphics_object& go, QListWidget* list)
+     : BaseControl (go, list), m_blockCallback (false)
+{
+  uicontrol::properties& up = properties<uicontrol> ();
+
+  list->addItems (Utils::fromStringVector (up.get_string_vector ()));
+  if ((up.get_max () - up.get_min ()) > 1)
+    list->setSelectionMode (QAbstractItemView::ExtendedSelection);
+  else
+    list->setSelectionMode (QAbstractItemView::SingleSelection);
+  Matrix value = up.get_value ().matrix_value ();
+  if (value.numel () > 0)
+    {
+      octave_idx_type n = value.numel ();
+      int lc = list->count ();
+
+      for (octave_idx_type i = 0; i < n; 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;
+            }
+        }
+    }
+
+  list->removeEventFilter (this);
+  list->viewport ()->installEventFilter (this);
+
+  connect (list, SIGNAL (itemSelectionChanged (void)),
+           SLOT (itemSelectionChanged (void)));
+}
+
+ListBoxControl::~ListBoxControl (void)
+{
+}
+
+void ListBoxControl::update (int pId)
+{
+  uicontrol::properties& up = properties<uicontrol> ();
+  QListWidget* list = qWidget<QListWidget> ();
+
+  switch (pId)
+    {
+    case uicontrol::properties::ID_STRING:
+      m_blockCallback = true;
+      list->clear ();
+      list->addItems (Utils::fromStringVector (up.get_string_vector ()));
+      updateSelection (list, up.get_value ().matrix_value ());
+      m_blockCallback = false;
+      break;
+    case uicontrol::properties::ID_MIN:
+    case uicontrol::properties::ID_MAX:
+      if ((up.get_max () - up.get_min ()) > 1)
+        list->setSelectionMode (QAbstractItemView::ExtendedSelection);
+      else
+        list->setSelectionMode (QAbstractItemView::SingleSelection);
+      break;
+    case uicontrol::properties::ID_VALUE:
+      m_blockCallback = true;
+      updateSelection (list, up.get_value ().matrix_value ());
+      m_blockCallback = false;
+      break;
+    default:
+      BaseControl::update (pId);
+      break;
+    }
+}
+
+void ListBoxControl::itemSelectionChanged (void)
+{
+  if (! m_blockCallback)
+    {
+      QListWidget* list = qWidget<QListWidget> ();
+
+      QModelIndexList l = list->selectionModel ()->selectedIndexes ();
+      Matrix value (dim_vector (1, l.size ()));
+      int i = 0;
+
+      foreach (const QModelIndex& idx, l)
+       value(i++) = (idx.row () + 1);
+
+      gh_manager::post_set (m_handle, "value", octave_value (value), false);
+      gh_manager::post_callback (m_handle, "callback");
+    }
+}
+
+}; // namespace QtHandles
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libgui/graphics/ListBoxControl.h	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,55 @@
+/*
+
+Copyright (C) 2011-2014 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/>.
+
+*/
+
+#ifndef __QtHandles_ListBoxControl__
+#define __QtHandles_ListBoxControl__ 1
+
+#include "BaseControl.h"
+
+class QListWidget;
+
+namespace QtHandles
+{
+
+class ListBoxControl : public BaseControl
+{
+  Q_OBJECT
+
+public:
+  ListBoxControl (const graphics_object& go, QListWidget* list);
+  ~ListBoxControl (void);
+
+  static ListBoxControl* create (const graphics_object& go);
+
+protected:
+  void update (int pId);
+
+private slots:
+  void itemSelectionChanged (void);
+
+private:
+  bool m_blockCallback;
+};
+
+}; // namespace QtHandles
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libgui/graphics/Logger.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,86 @@
+/*
+
+Copyright (C) 2011-2014 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 <QMutex>
+#include <QMutexLocker>
+#include <QProcessEnvironment>
+
+#include <cstdio>
+
+#include "Logger.h"
+
+namespace QtHandles
+{
+
+Logger* Logger::s_instance = 0;
+QMutex* Logger::s_mutex = 0;
+
+Logger::Logger (void)
+    : m_debugEnabled (false)
+{
+  QProcessEnvironment pe (QProcessEnvironment::systemEnvironment ());
+
+  if (pe.value ("QTHANDLES_DEBUG", "0") != "0")
+    m_debugEnabled = true;
+}
+
+Logger::~Logger (void)
+{
+}
+
+Logger* Logger::instance (void)
+{
+  if (! s_instance)
+    {
+      s_instance = new Logger ();
+      s_mutex = new QMutex ();
+    }
+
+  return s_instance;
+}
+
+#define STATIC_LOGGER(fun) \
+void Logger::fun (const char* fmt, ...) \
+{ \
+  QMutexLocker lock (s_mutex); \
+  va_list vl; \
+  va_start (vl, fmt); \
+  instance ()->fun ## V (fmt, vl); \
+  va_end (vl); \
+}
+
+STATIC_LOGGER (debug)
+
+void Logger::debugV (const char* fmt, va_list arg)
+{
+  if (m_debugEnabled)
+    {
+      vfprintf (stderr, fmt, arg);
+      fprintf (stderr, "\n");
+    }
+}
+
+}; // namespace QtHandles
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libgui/graphics/Logger.h	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,55 @@
+/*
+
+Copyright (C) 2011-2014 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/>.
+
+*/
+
+#ifndef __QtHandles_Logger__
+#define __QtHandles_Logger__ 1
+
+#include <cstdarg>
+
+class QMutex;
+
+namespace QtHandles
+{
+
+class Logger
+{
+public:
+  static void debug (const char* fmt, ...);
+
+private:
+  bool m_debugEnabled;
+
+  static Logger* s_instance;
+  static QMutex* s_mutex;
+
+private:
+  Logger (void);
+  ~Logger (void);
+
+  static Logger* instance (void);
+
+  void debugV (const char* fmt, va_list arg);
+};
+
+}; // namespace QtHandles
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libgui/graphics/Menu.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,307 @@
+/*
+
+Copyright (C) 2011-2014 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 <QAction>
+#include <QMainWindow>
+#include <QMenu>
+#include <QMenuBar>
+
+#include "Figure.h"
+#include "Menu.h"
+#include "QtHandlesUtils.h"
+
+namespace QtHandles
+{
+
+static QKeySequence accelSequence (const uimenu::properties& up)
+{
+  std::string s (up.get_accelerator ());
+
+  if (! s.empty ())
+    {
+      char c = s[0];
+      int keyMod = Qt::CTRL;
+
+      if (c >= 'A' && c <= 'Z')
+        keyMod |= Qt::SHIFT;
+      if (c >= 'a' && c <= 'z')
+        c -= ('a' - 'A');
+      if (c >= 'A' && c <= 'Z')
+        return QKeySequence (keyMod | static_cast<int> (c));
+    }
+
+  return QKeySequence ();
+}
+
+Menu* Menu::create (const graphics_object& go)
+{
+  Object* parent_obj = Object::parentObject (go);
+
+  if (parent_obj)
+    {
+      QObject* qObj = parent_obj->qObject ();
+
+      if (qObj)
+        return new Menu (go, new QAction (qObj), parent_obj);
+    }
+
+  return 0;
+}
+
+Menu::Menu (const graphics_object& go, QAction* action, Object* xparent)
+    : Object (go, action), m_parent (0), m_separator (0)
+{
+  uimenu::properties& up = properties<uimenu> ();
+
+  action->setText (Utils::fromStdString (up.get_label ()));
+  if (up.is_checked ())
+    {
+      action->setCheckable (true);
+      action->setChecked (up.is_checked ());
+    }
+  action->setEnabled (up.is_enable ());
+  action->setShortcut (accelSequence (up));
+  action->setVisible (up.is_visible ());
+  if (up.is_separator ())
+    {
+      m_separator = new QAction (action);
+      m_separator->setSeparator (true);
+      m_separator->setVisible (up.is_visible ());
+    }
+
+  MenuContainer* menuContainer = dynamic_cast<MenuContainer*> (xparent);
+
+  if (menuContainer)
+    m_parent = menuContainer->menu ();
+
+  if (m_parent)
+    {
+      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);
+
+          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);
+        }
+      else
+        {
+
+          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;
+                  }
+              }
+
+          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);
+        }
+    }
+
+  connect (action, SIGNAL (triggered (bool)), SLOT (actionTriggered (void)));
+}
+
+Menu::~Menu (void)
+{
+}
+
+void Menu::update (int pId)
+{
+  uimenu::properties& up = properties<uimenu> ();
+  QAction* action = qWidget<QAction> ();
+
+  switch (pId)
+    {
+    case uimenu::properties::ID_LABEL:
+      action->setText (Utils::fromStdString (up.get_label ()));
+      break;
+    case uimenu::properties::ID_CHECKED:
+      if (up.is_checked ())
+        {
+          action->setCheckable (true);
+          action->setChecked (up.is_checked ());
+        }
+      else
+        {
+          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));
+      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);
+            }
+        }
+      else
+        {
+          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 ());
+      break;
+    case uimenu::properties::ID_POSITION:
+      if (m_separator)
+        m_parent->removeAction (m_separator);
+      m_parent->removeAction (action);
+        {
+          int pos = static_cast<int> (up.get_position ());
+          QAction* before = 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;
+                      }
+                  }
+            }
+
+          if (m_separator)
+            m_parent->insertAction (before, m_separator);
+          m_parent->insertAction (before, action);
+          updateSiblingPositions ();
+        }
+      break;
+    default:
+      Object::update (pId);
+      break;
+    }
+}
+
+QWidget* Menu::menu (void)
+{
+  QAction* action = qWidget<QAction> ();
+  QMenu* _menu = action->menu ();
+
+  if (! _menu)
+    {
+      _menu = new QMenu (action->parentWidget ());
+      action->setMenu (_menu);
+      action->setShortcut (QKeySequence ());
+      connect (_menu, SIGNAL (aboutToShow (void)),
+               this, SLOT (actionHovered (void)));
+    }
+
+  return _menu;
+}
+
+void Menu::actionTriggered (void)
+{
+  QAction* action = qWidget<QAction> ();
+
+  if (action->isCheckable ())
+    action->setChecked (! action->isChecked ());
+  gh_manager::post_callback (m_handle, "callback");
+}
+
+void Menu::actionHovered (void)
+{
+  gh_manager::post_callback (m_handle, "callback");
+}
+
+void Menu::updateSiblingPositions (void)
+{
+  if (m_parent)
+    {
+      double count = 1.0;
+
+      foreach (QAction* a, m_parent->actions ())
+        {
+          if (! a->isSeparator () && a->objectName () != "builtinMenu")
+            {
+              Object* aObj = Object::fromQObject (a);
+
+              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);
+
+                      up.get_property ("position").set
+                        (octave_value (count), true, false);
+                    }
+                }
+
+              count++;
+            }
+        }
+    }
+}
+
+}; // namespace QtHandles
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libgui/graphics/Menu.h	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,67 @@
+/*
+
+Copyright (C) 2011-2014 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/>.
+
+*/
+
+#ifndef __QtHandles_Menu__
+#define __QtHandles_Menu__ 1
+
+#include "MenuContainer.h"
+#include "Object.h"
+
+class QAction;
+class QMenu;
+class QWidget;
+
+namespace QtHandles
+{
+
+class Menu : public Object, public MenuContainer
+{
+  Q_OBJECT
+
+public:
+  Menu (const graphics_object& go, QAction* action, Object* parent);
+  ~Menu (void);
+
+  static Menu* create (const graphics_object& go);
+
+  Container* innerContainer (void) { return 0; }
+
+  QWidget* menu (void);
+
+protected:
+  void update (int pId);
+
+private slots:
+  void actionTriggered (void);
+  void actionHovered (void);
+
+private:
+  void updateSiblingPositions (void);
+
+private:
+  QWidget* m_parent;
+  QAction* m_separator;
+};
+
+}; // namespace QtHandles
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libgui/graphics/MenuContainer.h	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,39 @@
+/*
+
+Copyright (C) 2011-2014 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/>.
+
+*/
+
+#ifndef __QtHandles_MenuContainer__
+#define __QtHandles_MenuContainer__ 1
+
+class QWidget;
+
+namespace QtHandles
+{
+
+class MenuContainer
+{
+public:
+  virtual QWidget* menu (void) = 0;
+};
+
+}; // namespace QtHandles
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libgui/graphics/MouseModeActionGroup.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,93 @@
+/*
+
+Copyright (C) 2011-2014 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 <QAction>
+#include <QIcon>
+
+#include "Figure.h"
+#include "MouseModeActionGroup.h"
+
+namespace QtHandles
+{
+
+MouseModeActionGroup::MouseModeActionGroup (QObject* xparent)
+  : QObject (xparent), m_current (0)
+{
+  m_actions.append (new QAction (QIcon (":/images/rotate.png"),
+                                 tr ("Rotate"), this));
+  m_actions.append (new QAction (QIcon (":/images/zoom.png"),
+                                 tr ("Zoom"), this));
+  m_actions.append (new QAction (QIcon (":/images/pan.png"),
+                                 tr ("Pan"), this));
+  m_actions.append (new QAction (QIcon (":/images/select.png"),
+                                 tr ("Select"), this));
+  m_actions[2]->setEnabled (false);
+  m_actions[3]->setEnabled (false);
+
+  foreach (QAction* a, m_actions)
+    {
+      a->setCheckable (true);
+      connect (a, SIGNAL (toggled (bool)), this, SLOT (actionToggled (bool)));
+    }
+}
+
+MouseModeActionGroup::~MouseModeActionGroup (void)
+{
+}
+
+void MouseModeActionGroup::actionToggled (bool checked)
+{
+  if (! checked)
+    {
+      if (sender () == m_current)
+        {
+          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));
+        }
+    }
+}
+
+MouseMode MouseModeActionGroup::mouseMode (void) const
+{
+  int i = (m_current ? -1 : m_actions.indexOf (m_current));
+
+  return static_cast<MouseMode> (i+1);
+}
+
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libgui/graphics/MouseModeActionGroup.h	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,60 @@
+/*
+
+Copyright (C) 2011-2014 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/>.
+
+*/
+
+#ifndef __QtHandles_MouseModeActionGroup__
+#define __QtHandles_MouseModeActionGroup__ 1
+
+#include <QList>
+#include <QObject>
+
+#include "Figure.h"
+
+class QAction;
+
+namespace QtHandles
+{
+
+class MouseModeActionGroup : public QObject
+{
+  Q_OBJECT
+
+public:
+  MouseModeActionGroup (QObject* parent = 0);
+  ~MouseModeActionGroup (void);
+
+  QList<QAction*> actions (void) const { return m_actions; }
+  MouseMode mouseMode (void) const;
+
+signals:
+  void modeChanged (MouseMode mode);
+
+private slots:
+  void actionToggled (bool checked);
+
+private:
+  QList<QAction*> m_actions;
+  QAction* m_current;
+};
+
+};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libgui/graphics/Object.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,162 @@
+/*
+
+Copyright (C) 2011-2014 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 <QVariant>
+
+#include "Backend.h"
+#include "Object.h"
+#include "QtHandlesUtils.h"
+
+namespace QtHandles
+{
+
+Object::Object (const graphics_object& go, QObject* obj)
+  : QObject (), m_handle (go.get_handle ()), m_qobject (0)
+{
+  gh_manager::auto_lock lock (false);
+
+  if (! lock)
+    qCritical ("QtHandles::Object::Object: "
+               "creating Object (h=%g) without a valid lock!!!",
+               m_handle.value ());
+
+  init (obj);
+}
+
+void Object::init (QObject* obj, bool)
+{
+  if (m_qobject)
+    qCritical ("QtHandles::Object::init: "
+               "resetting QObject while in invalid state");
+
+  m_qobject = obj;
+
+  if (m_qobject)
+    {
+      m_qobject->setProperty ("QtHandles::Object",
+                              qVariantFromValue<void*> (this));
+      connect (m_qobject, SIGNAL (destroyed (QObject*)),
+               SLOT (objectDestroyed (QObject*)));
+    }
+}
+
+Object::~Object (void)
+{
+}
+
+graphics_object Object::object (void) const
+{
+  gh_manager::auto_lock lock (false);
+
+  if (! lock)
+    qCritical ("QtHandles::Object::object: "
+               "accessing graphics object (h=%g) without a valid lock!!!",
+               m_handle.value ());
+
+  return gh_manager::get_object (m_handle);
+}
+
+void Object::slotUpdate (int pId)
+{
+  gh_manager::auto_lock lock;
+
+  switch (pId)
+    {
+    // Special case for objects being deleted, as it's very likely
+    // that the graphics_object already has been destroyed when this
+    // is executed (because of the async behavior).
+    case base_properties::ID_BEINGDELETED:
+      beingDeleted ();
+      break;
+    default:
+      if (object ().valid_object ())
+        update (pId);
+      break;
+    }
+}
+
+void Object::slotFinalize (void)
+{
+  gh_manager::auto_lock lock;
+
+  finalize ();
+}
+
+void Object::slotRedraw (void)
+{
+  gh_manager::auto_lock lock;
+
+  if (object ().valid_object ())
+    redraw ();
+}
+
+void Object::update (int /* pId */)
+{
+}
+
+void Object::finalize (void)
+{
+  if (m_qobject)
+    {
+      delete m_qobject;
+      m_qobject = 0;
+    }
+  deleteLater ();
+}
+
+void Object::redraw (void)
+{
+}
+
+void Object::beingDeleted (void)
+{
+}
+
+void Object::objectDestroyed (QObject* obj)
+{
+  if (obj && obj == m_qobject)
+    m_qobject = 0;
+}
+
+Object* Object::parentObject (const graphics_object& go)
+{
+  Object* parent = Backend::toolkitObject
+    (gh_manager::get_object (go.get_parent ()));
+
+  return parent;
+}
+
+Object* Object::fromQObject (QObject* obj)
+{
+  QVariant v = obj->property ("QtHandles::Object");
+
+  if (v.isValid ())
+    return reinterpret_cast<Object*> (qVariantValue<void*> (v));
+
+  return 0;
+}
+
+}; // namespace QtHandles
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libgui/graphics/Object.h	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,103 @@
+/*
+
+Copyright (C) 2011-2014 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/>.
+
+*/
+
+#ifndef __QtHandles_Object__
+#define __QtHandles_Object__ 1
+
+#include <QObject>
+
+#include "graphics.h"
+
+class QObject;
+class QWidget;
+
+namespace QtHandles
+{
+
+class Container;
+class ObjectProxy;
+
+class Object : public QObject
+{
+  Q_OBJECT
+
+public:
+  Object (const graphics_object& go, QObject* obj = 0);
+
+  virtual ~Object (void);
+
+  base_properties& properties (void)
+    { return object ().get_properties (); }
+
+  const base_properties& properties (void) const
+    { return object ().get_properties (); }
+
+  template <class T>
+  typename T::properties& properties (void)
+    {
+      return dynamic_cast<typename T::properties&>
+        (object ().get_properties ());
+    }
+
+  template <class T>
+  const typename T::properties& properties (void) const
+    {
+      return dynamic_cast<const typename T::properties&>
+        (object ().get_properties ());
+    }
+
+  graphics_object object (void) const;
+
+  virtual QObject* qObject (void) { return m_qobject; }
+
+  template <class T>
+  T* qWidget (void) { return qobject_cast<T*>(qObject ()); }
+
+  virtual Container* innerContainer (void) = 0;
+
+  static Object* fromQObject (QObject* obj);
+
+public slots:
+  void slotUpdate (int pId);
+  void slotFinalize (void);
+  void slotRedraw (void);
+
+  void objectDestroyed (QObject *obj = 0);
+
+protected:
+  static Object* parentObject (const graphics_object& go);
+  void init (QObject* obj, bool callBase = false);
+
+  virtual void update (int pId);
+  virtual void finalize (void);
+  virtual void redraw (void);
+
+  virtual void beingDeleted (void);
+
+protected:
+  graphics_handle m_handle;
+  QObject* m_qobject;
+};
+
+}; // namespace QtHandles
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libgui/graphics/ObjectFactory.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,149 @@
+/*
+
+Copyright (C) 2011-2014 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 <QApplication>
+#include <QThread>
+
+#include "graphics.h"
+
+#include "Backend.h"
+#include "CheckBoxControl.h"
+#include "ContextMenu.h"
+#include "EditControl.h"
+#include "Figure.h"
+#include "ListBoxControl.h"
+#include "Logger.h"
+#include "Menu.h"
+#include "ObjectFactory.h"
+#include "ObjectProxy.h"
+#include "Panel.h"
+#include "PopupMenuControl.h"
+#include "PushButtonControl.h"
+#include "PushTool.h"
+#include "RadioButtonControl.h"
+#include "SliderControl.h"
+#include "TextControl.h"
+#include "ToggleButtonControl.h"
+#include "ToggleTool.h"
+#include "ToolBar.h"
+#include "QtHandlesUtils.h"
+
+namespace QtHandles
+{
+
+ObjectFactory* ObjectFactory::instance (void)
+{
+  static ObjectFactory s_instance;
+  static bool s_instanceCreated = false;
+
+  if (! s_instanceCreated)
+    {
+      if (QThread::currentThread () != QApplication::instance ()->thread ())
+        s_instance.moveToThread (QApplication::instance ()->thread ());
+      s_instanceCreated = true;
+    }
+
+  return &s_instance;
+}
+
+void ObjectFactory::createObject (double handle)
+{
+  gh_manager::auto_lock lock;
+
+  graphics_object go (gh_manager::get_object (graphics_handle (handle)));
+
+  if (go.valid_object ())
+    {
+      if (go.get_properties ().is_beingdeleted ())
+        qWarning ("ObjectFactory::createObject: object is being deleted");
+      else
+        {
+          ObjectProxy* proxy = Backend::toolkitObjectProxy (go);
+
+          if (proxy)
+            {
+              Logger::debug ("ObjectFactory::createObject: "
+                             "create %s from thread %08x",
+                             go.type ().c_str (), QThread::currentThreadId ());
+
+              Object* obj = 0;
+
+              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 (obj)
+                proxy->setObject (obj);
+            }
+          else
+            qWarning ("ObjectFactory::createObject: no proxy for handle %g",
+                      handle);
+        }
+    }
+  else
+    qWarning ("ObjectFactory::createObject: invalid object for handle %g",
+              handle);
+}
+
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libgui/graphics/ObjectFactory.h	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,53 @@
+/*
+
+Copyright (C) 2011-2014 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/>.
+
+*/
+
+#ifndef __QtHandles_ObjectFactory__
+#define __QtHandles_ObjectFactory__ 1
+
+#include <QObject>
+
+class graphics_object;
+
+namespace QtHandles
+{
+
+class Object;
+
+class ObjectFactory : public QObject
+{
+  Q_OBJECT
+
+public:
+  static ObjectFactory* instance (void);
+
+public slots:
+  void createObject (double handle);
+
+private:
+  ObjectFactory (void)
+    : QObject ()
+    { }
+};
+
+};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libgui/graphics/ObjectProxy.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,94 @@
+/*
+
+Copyright (C) 2011-2014 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 "oct-mutex.h"
+
+#include "Object.h"
+#include "ObjectProxy.h"
+
+namespace QtHandles
+{
+
+ObjectProxy::ObjectProxy (Object* obj)
+  : QObject (), m_object (0)
+{
+  init (obj);
+}
+
+void ObjectProxy::init (Object* obj)
+{
+  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)));
+        }
+
+      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)));
+        }
+    }
+}
+
+void ObjectProxy::setObject (Object* obj)
+{
+  emit sendFinalize ();
+  init (obj);
+}
+
+void ObjectProxy::update (int pId)
+{
+  if (octave_thread::is_octave_thread ())
+    emit sendUpdate (pId);
+  else
+    m_object->slotUpdate (pId);
+}
+
+void ObjectProxy::finalize (void)
+{
+  emit sendFinalize ();
+  init (0);
+}
+
+void ObjectProxy::redraw (void)
+{
+  emit sendRedraw ();
+}
+
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libgui/graphics/ObjectProxy.h	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,61 @@
+/*
+
+Copyright (C) 2011-2014 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/>.
+
+*/
+
+#ifndef __QtHandles_ObjectProxy__
+#define __QtHandles_ObjectProxy__ 1
+
+#include <QObject>
+
+namespace QtHandles
+{
+
+class Object;
+
+class ObjectProxy : public QObject
+{
+  Q_OBJECT
+
+public:
+   ObjectProxy (Object* obj = 0);
+
+   void update (int pId);
+   void finalize (void);
+   void redraw (void);
+
+   Object* object (void) { return m_object; }
+   void setObject (Object* obj);
+
+signals:
+   void sendUpdate (int pId);
+   void sendFinalize (void);
+   void sendRedraw (void);
+
+private:
+   void init (Object* obj);
+
+private:
+   Object* m_object;
+};
+
+};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libgui/graphics/Panel.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,358 @@
+/*
+
+Copyright (C) 2011-2014 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 <QEvent>
+#include <QFrame>
+#include <QLabel>
+#include <QMouseEvent>
+#include <QTimer>
+
+#include "Canvas.h"
+#include "Container.h"
+#include "ContextMenu.h"
+#include "Panel.h"
+#include "QtHandlesUtils.h"
+
+namespace QtHandles
+{
+
+static int frameStyleFromProperties (const uipanel::properties& pp)
+{
+  if (pp.bordertype_is ("none"))
+    return QFrame::NoFrame;
+  else if (pp.bordertype_is ("etchedin"))
+    return (QFrame::Box | QFrame::Sunken);
+  else if (pp.bordertype_is ("etchedout"))
+    return (QFrame::Box | QFrame::Raised);
+  else if (pp.bordertype_is ("beveledin"))
+    return (QFrame::Panel | QFrame::Sunken);
+  else if (pp.bordertype_is ("beveledout"))
+    return (QFrame::Panel | QFrame::Raised);
+  else
+    return (QFrame::Panel | QFrame::Plain);
+}
+
+static void setupPalette (const uipanel::properties& pp, QPalette& p)
+{
+  p.setColor (QPalette::Window,
+              Utils::fromRgb (pp.get_backgroundcolor_rgb ()));
+  p.setColor (QPalette::WindowText,
+              Utils::fromRgb (pp.get_foregroundcolor_rgb ()));
+  p.setColor (QPalette::Light,
+              Utils::fromRgb (pp.get_highlightcolor_rgb ()));
+  p.setColor (QPalette::Dark,
+              Utils::fromRgb (pp.get_shadowcolor_rgb ()));
+}
+
+static int borderWidthFromProperties (const uipanel::properties& pp)
+{
+  int bw = 0;
+
+  if (! pp.bordertype_is ("none"))
+    {
+      bw = xround (pp.get_borderwidth ());
+      if (pp.bordertype_is ("etchedin") || pp.bordertype_is ("etchedout"))
+        bw *= 2;
+    }
+
+  return bw;
+}
+
+Panel* Panel::create (const graphics_object& go)
+{
+  Object* parent = Object::parentObject (go);
+
+  if (parent)
+    {
+      Container* container = parent->innerContainer ();
+
+      if (container)
+        return new Panel (go, new QFrame (container));
+    }
+
+  return 0;
+}
+
+Panel::Panel (const graphics_object& go, QFrame* frame)
+    : Object (go, frame), m_container (0), m_title (0), m_blockUpdates (false)
+{
+  uipanel::properties& pp = properties<uipanel> ();
+
+  frame->setObjectName ("UIPanel");
+  frame->setAutoFillBackground (true);
+  Matrix bb = pp.get_boundingbox (false);
+  frame->setGeometry (xround (bb(0)), xround (bb(1)),
+                      xround (bb(2)), xround (bb(3)));
+  frame->setFrameStyle (frameStyleFromProperties (pp));
+  frame->setLineWidth (xround (pp.get_borderwidth ()));
+  QPalette pal = frame->palette ();
+  setupPalette (pp, pal);
+  frame->setPalette (pal);
+
+  m_container = new Container (frame);
+  m_container->canvas (m_handle);
+
+  if (frame->hasMouseTracking ())
+    {
+      foreach (QWidget* w, frame->findChildren<QWidget*> ())
+        { w->setMouseTracking (true); }
+    }
+
+  QString title = Utils::fromStdString (pp.get_title ());
+  if (! title.isEmpty ())
+    {
+      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, bb(3)));
+    }
+
+  frame->installEventFilter (this);
+  m_container->installEventFilter (this);
+
+  if (pp.is_visible ())
+    QTimer::singleShot (0, frame, SLOT (show (void)));
+  else
+    frame->hide ();
+}
+
+Panel::~Panel (void)
+{
+}
+
+bool Panel::eventFilter (QObject* watched, QEvent* xevent)
+{
+  if (! m_blockUpdates)
+    {
+      if (watched == qObject ())
+        {
+          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 (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*> (xevent);
+
+                  if (m->button () == Qt::RightButton)
+                    {
+                      gh_manager::auto_lock lock;
+
+                      ContextMenu::executeAt (properties (), m->globalPos ());
+                    }
+                }
+              break;
+            default:
+              break;
+            }
+        }
+      else if (watched == m_container)
+        {
+          switch (xevent->type ())
+            {
+            case QEvent::Resize:
+              if (qWidget<QWidget> ()->isVisible ())
+                {
+                  gh_manager::auto_lock lock;
+
+                  properties ().update_boundingbox ();
+                }
+              break;
+            default:
+              break;
+            }
+        }
+    }
+
+  return false;
+}
+
+void Panel::update (int pId)
+{
+  uipanel::properties& pp = properties<uipanel> ();
+  QFrame* frame = qWidget<QFrame> ();
+
+  m_blockUpdates = true;
+
+  switch (pId)
+    {
+    case uipanel::properties::ID_POSITION:
+        {
+          Matrix bb = pp.get_boundingbox (false);
+
+          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 ()));
+      updateLayout ();
+      break;
+    case uipanel::properties::ID_BACKGROUNDCOLOR:
+    case uipanel::properties::ID_FOREGROUNDCOLOR:
+    case uipanel::properties::ID_HIGHLIGHTCOLOR:
+    case uipanel::properties::ID_SHADOWCOLOR:
+        {
+          QPalette pal = frame->palette ();
+
+          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 ());
+
+          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 ();
+        }
+    case uipanel::properties::ID_TITLEPOSITION:
+      updateLayout ();
+      break;
+    case uipanel::properties::ID_BORDERTYPE:
+      frame->setFrameStyle (frameStyleFromProperties (pp));
+      updateLayout ();
+      break;
+    case uipanel::properties::ID_FONTNAME:
+    case uipanel::properties::ID_FONTSIZE:
+    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 ();
+        }
+      break;
+    case uipanel::properties::ID_VISIBLE:
+      frame->setVisible (pp.is_visible ());
+      updateLayout ();
+      break;
+    default:
+      break;
+    }
+
+  m_blockUpdates = false;
+}
+
+void Panel::redraw (void)
+{
+  Canvas* canvas = m_container->canvas (m_handle);
+
+  if (canvas)
+    canvas->redraw ();
+}
+
+void Panel::updateLayout (void)
+{
+  uipanel::properties& pp = properties<uipanel> ();
+  QFrame* frame = qWidget<QFrame> ();
+
+  Matrix bb = pp.get_boundingbox (true);
+  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));
+  m_container->setGeometry (xround (bb(0)), xround (bb(1)),
+                            xround (bb(2)), xround (bb(3)));
+
+  if (m_blockUpdates)
+    pp.update_boundingbox ();
+
+  if (m_title)
+    {
+      QSize sz = m_title->sizeHint ();
+      int offset = 5;
+
+      if (pp.titleposition_is ("lefttop"))
+        m_title->move (bw+offset, 0);
+      else if (pp.titleposition_is ("righttop"))
+        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 ());
+      else if (pp.titleposition_is ("rightbottom"))
+        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);
+      else if (pp.titleposition_is ("centerbottom"))
+        m_title->move (frame->width () / 2 - sz.width () / 2,
+                       frame->height () - sz.height ());
+    }
+}
+
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libgui/graphics/Panel.h	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,63 @@
+/*
+
+Copyright (C) 2011-2014 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/>.
+
+*/
+
+#ifndef __QtHandles_Panel__
+#define __QtHandles_Panel__ 1
+
+#include "Object.h"
+
+class QFrame;
+class QLabel;
+
+namespace QtHandles
+{
+
+class Container;
+
+class Panel : public Object
+{
+public:
+  Panel (const graphics_object& go, QFrame* frame);
+  ~Panel (void);
+
+  Container* innerContainer (void) { return m_container; }
+
+  bool eventFilter (QObject* watched, QEvent* event);
+
+  static Panel* create (const graphics_object& go);
+
+protected:
+  void update (int pId);
+  void redraw (void);
+
+private:
+  void updateLayout (void);
+
+private:
+  Container* m_container;
+  QLabel* m_title;
+  bool m_blockUpdates;
+};
+
+}; // namespace QtHandles
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libgui/graphics/PopupMenuControl.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,130 @@
+/*
+
+Copyright (C) 2011-2014 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 <QComboBox>
+
+#include "Container.h"
+#include "PopupMenuControl.h"
+#include "QtHandlesUtils.h"
+
+namespace QtHandles
+{
+
+PopupMenuControl* PopupMenuControl::create (const graphics_object& go)
+{
+  Object* parent = Object::parentObject (go);
+
+  if (parent)
+    {
+      Container* container = parent->innerContainer ();
+
+      if (container)
+        return new PopupMenuControl (go, new QComboBox (container));
+    }
+
+  return 0;
+}
+
+PopupMenuControl::PopupMenuControl (const graphics_object& go, QComboBox *box)
+     : BaseControl (go, box), m_blockUpdate (false)
+{
+  uicontrol::properties& up = properties<uicontrol> ();
+
+  box->addItems (Utils::fromStdString (up.get_string_string ()).split ('|'));
+
+  connect (box, SIGNAL (currentIndexChanged (int)),
+           SLOT (currentIndexChanged (int)));
+}
+
+PopupMenuControl::~PopupMenuControl (void)
+{
+}
+
+void PopupMenuControl::update (int pId)
+{
+  uicontrol::properties& up = properties<uicontrol> ();
+  QComboBox* box = qWidget<QComboBox> ();
+
+  switch (pId)
+    {
+    case uicontrol::properties::ID_STRING:
+      m_blockUpdate = true;
+        {
+          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);
+            }
+        }
+      m_blockUpdate = false;
+      break;
+    case uicontrol::properties::ID_VALUE:
+        {
+          Matrix value = up.get_value ().matrix_value ();
+
+          if (value.numel () > 0)
+            {
+              int newIndex = int (value(0)) - 1;
+
+              if (newIndex >= 0 && newIndex < box->count ()
+                  && newIndex != box->currentIndex ())
+                {
+                  box->setCurrentIndex (newIndex);
+                }
+            }
+        }
+      break;
+    default:
+      BaseControl::update (pId);
+      break;
+    }
+}
+
+void PopupMenuControl::currentIndexChanged (int index)
+{
+  if (! m_blockUpdate)
+    {
+      gh_manager::post_set (m_handle, "value",
+                            octave_value (double (index + 1)),
+                            false);
+      gh_manager::post_callback (m_handle, "callback");
+    }
+}
+
+}; // namespace QtHandles
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libgui/graphics/PopupMenuControl.h	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,55 @@
+/*
+
+Copyright (C) 2011-2014 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/>.
+
+*/
+
+#ifndef __QtHandles_PopupMenuControl__
+#define __QtHandles_PopupMenuControl__ 1
+
+#include "BaseControl.h"
+
+class QComboBox;
+
+namespace QtHandles
+{
+
+class PopupMenuControl : public BaseControl
+{
+  Q_OBJECT
+
+public:
+  PopupMenuControl (const graphics_object& go, QComboBox* box);
+  ~PopupMenuControl (void);
+
+  static PopupMenuControl* create (const graphics_object& go);
+
+protected:
+  void update (int pId);
+
+private slots:
+  void currentIndexChanged (int index);
+
+private:
+  bool m_blockUpdate;
+};
+
+}; // namespace QtHandles
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libgui/graphics/PushButtonControl.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,78 @@
+/*
+
+Copyright (C) 2011-2014 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 <QPushButton>
+#include <QtDebug>
+
+#include "PushButtonControl.h"
+#include "Container.h"
+#include "QtHandlesUtils.h"
+
+namespace QtHandles
+{
+
+PushButtonControl* PushButtonControl::create (const graphics_object& go)
+{
+  Object* parent = Object::parentObject (go);
+
+  if (parent)
+    {
+      Container* container = parent->innerContainer ();
+
+      if (container)
+        return new PushButtonControl (go, new QPushButton (container));
+    }
+
+  return 0;
+}
+
+PushButtonControl::PushButtonControl (const graphics_object& go, QPushButton* btn)
+  : ButtonControl (go, btn)
+{
+  btn->setAutoFillBackground (true);
+}
+
+PushButtonControl::~PushButtonControl (void)
+{
+}
+
+void PushButtonControl::update (int pId)
+{
+  uicontrol::properties& up = properties<uicontrol> ();
+  QPushButton* btn = qWidget<QPushButton> ();
+
+  switch (pId)
+    {
+    case uicontrol::properties::ID_STRING:
+      btn->setText (Utils::fromStdString (up.get_string_string ()));
+      break;
+    default:
+      BaseControl::update (pId);
+      break;
+    }
+}
+
+}; // namespave QtHandles
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libgui/graphics/PushButtonControl.h	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,47 @@
+/*
+
+Copyright (C) 2011-2014 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/>.
+
+*/
+
+#ifndef __QtHandles_PushButtonControl__
+#define __QtHandles_PushButtonControl__ 1
+
+#include "ButtonControl.h"
+
+class QPushButton;
+
+namespace QtHandles
+{
+
+class PushButtonControl : public ButtonControl
+{
+public:
+  PushButtonControl (const graphics_object& go, QPushButton* btn);
+  ~PushButtonControl (void);
+
+  static PushButtonControl* create (const graphics_object& go);
+
+protected:
+  void update (int pId);
+};
+
+}; // namespace QtHandles
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libgui/graphics/PushTool.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,74 @@
+/*
+
+Copyright (C) 2011-2014 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 "PushTool.h"
+
+#include "ToolBarButton.cc"
+
+namespace QtHandles
+{
+
+PushTool* PushTool::create (const graphics_object& go)
+{
+  Object* parent = Object::parentObject (go);
+
+  if (parent)
+    {
+      QWidget* parentWidget = parent->qWidget<QWidget> ();
+
+      if (parentWidget)
+        return new PushTool (go, new QAction (parentWidget));
+    }
+
+  return 0;
+}
+
+PushTool::PushTool (const graphics_object& go, QAction* action)
+    : ToolBarButton<uipushtool> (go, action)
+{
+  connect (action, SIGNAL (triggered (bool)), this, SLOT (clicked (void)));
+}
+
+PushTool::~PushTool (void)
+{
+}
+
+void PushTool::update (int pId)
+{
+  switch (pId)
+    {
+    default:
+      ToolBarButton<uipushtool>::update (pId);
+      break;
+    }
+}
+
+void PushTool::clicked (void)
+{
+  gh_manager::post_callback (m_handle, "clickedcallback");
+}
+
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libgui/graphics/PushTool.h	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,50 @@
+/*
+
+Copyright (C) 2011-2014 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/>.
+
+*/
+
+#ifndef __QtHandles_PushTool__
+#define __QtHandles_PushTool__ 1
+
+#include "ToolBarButton.h"
+
+namespace QtHandles
+{
+
+class PushTool : public ToolBarButton<uipushtool>
+{
+  Q_OBJECT
+
+public:
+  PushTool (const graphics_object& go, QAction* action);
+  ~PushTool (void);
+
+  static PushTool* create (const graphics_object& go);
+
+protected:
+  void update (int pId);
+
+private slots:
+  void clicked (void);
+};
+
+}; // namespace QtHandles
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libgui/graphics/QtHandlesUtils.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,324 @@
+/*
+
+Copyright (C) 2011-2014 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 <QApplication>
+#include <QKeyEvent>
+#include <QMouseEvent>
+
+#include <list>
+
+#include "ov.h"
+#include "graphics.h"
+
+#include "Backend.h"
+#include "Container.h"
+#include "KeyMap.h"
+#include "Object.h"
+#include "QtHandlesUtils.h"
+
+namespace QtHandles
+{
+
+namespace Utils
+{
+
+QString fromStdString (const std::string& s)
+{
+  return QString::fromLocal8Bit (s.c_str ());
+}
+
+std::string toStdString (const QString& s)
+{
+  return std::string (s.toLocal8Bit ().data ());
+}
+
+QStringList fromStringVector (const string_vector& v)
+{
+  QStringList l;
+  octave_idx_type n = v.length ();
+
+  for (octave_idx_type i = 0; i < n; i++)
+    l << fromStdString (v[i]);
+
+  return l;
+}
+
+string_vector toStringVector (const QStringList& l)
+{
+  string_vector v (l.length ());
+  int i = 0;
+
+  foreach (const QString& s, l)
+    v[i++] = toStdString (s);
+
+  return v;
+}
+
+template <class T>
+QFont computeFont (const typename T::properties& props, int height)
+{
+  QFont f (fromStdString (props.get_fontname ()));
+
+  static std::map<std::string, QFont::Weight> weightMap;
+  static std::map<std::string, QFont::Style> angleMap;
+  static bool mapsInitialized = false;
+
+  if (! mapsInitialized)
+    {
+      weightMap[std::string ("normal")] = QFont::Normal;
+      weightMap[std::string ("light")] = QFont::Light;
+      weightMap[std::string ("demi")] = QFont::DemiBold;
+      weightMap[std::string ("bold")] = QFont::Normal;
+
+      angleMap[std::string ("normal")] = QFont::StyleNormal;
+      angleMap[std::string ("italic")] = QFont::StyleItalic;
+      angleMap[std::string ("oblique")] = QFont::StyleOblique;
+
+      mapsInitialized = true;
+    }
+
+  f.setPointSizeF (props.get_fontsize_points (height));
+  f.setWeight (weightMap[props.get_fontweight ()]);
+  f.setStyle (angleMap[props.get_fontangle ()]);
+
+  return f;
+}
+
+template QFont computeFont<uicontrol> (const uicontrol::properties& props,
+                                       int height);
+template QFont computeFont<uipanel> (const uipanel::properties& props,
+                                     int height);
+
+QColor fromRgb (const Matrix& rgb)
+{
+  QColor c;
+
+  if (rgb.numel () == 3)
+    c.setRgbF (rgb(0), rgb(1), rgb(2));
+
+  return c;
+}
+
+Matrix toRgb (const QColor& c)
+{
+  Matrix rgb (1, 3);
+  double* rgbData = rgb.fortran_vec ();
+
+  c.getRgbF (rgbData, rgbData+1, rgbData+2);
+
+  return rgb;
+}
+
+std::string figureSelectionType (QMouseEvent* event, bool isDoubleClick)
+{
+  if (isDoubleClick)
+    return std::string ("open");
+  else
+    {
+      Qt::MouseButtons buttons = event->buttons ();
+      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 defined (Q_WS_WIN)
+          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");
+#endif
+        }
+      else if (buttons == Qt::LeftButton)
+        {
+          if (mods == Qt::ShiftModifier)
+            return std::string ("extend");
+          else if (mods == Qt::ControlModifier)
+            return std::string ("alt");
+        }
+    }
+
+  return std::string ("normal");
+}
+
+Matrix figureCurrentPoint (const graphics_object& fig, QMouseEvent* event)
+{
+  Object* tkFig = Backend::toolkitObject (fig);
+
+  if (tkFig)
+    {
+      Container* c = tkFig->innerContainer ();
+
+      if (c)
+        {
+          QPoint qp = c->mapFromGlobal (event->globalPos ());
+
+          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)
+{
+  Qt::Alignment flags;
+
+  if (halign.compare ("left"))
+    flags |= Qt::AlignLeft;
+  else if (halign.compare ("center"))
+    flags |= Qt::AlignHCenter;
+  else if (halign.compare ("right"))
+    flags |= Qt::AlignRight;
+  else
+    flags |= Qt::AlignLeft;
+
+  if (valign.compare ("middle"))
+    flags |= Qt::AlignVCenter;
+  else if (valign.compare ("top"))
+    flags |= Qt::AlignTop;
+  else if (valign.compare ("bottom"))
+    flags |= Qt::AlignBottom;
+  else
+    flags |= Qt::AlignVCenter;
+
+  return flags;
+}
+
+QImage makeImageFromCData (const octave_value& v, int width, int height)
+{
+  dim_vector dv (v.dims ());
+
+  if (dv.length () == 3 && dv(2) == 3)
+    {
+      int w = qMin (dv(1), static_cast<octave_idx_type> (width));
+      int h = qMin (dv(0), static_cast<octave_idx_type> (height));
+
+      int x_off = (w < width ? (width - w) / 2 : 0);
+      int y_off = (h < height ? (height - h) / 2 : 0);
+
+      QImage img (width, height, QImage::Format_ARGB32);
+      img.fill (qRgba (0, 0, 0, 0));
+
+      if (v.is_uint8_type ())
+        {
+          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;
+
+                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 ();
+
+          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));
+              }
+        }
+      else if (v.is_real_type ())
+        {
+          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);
+
+                img.setPixel (x_off + i, y_off + j,
+                              qRgba (xround (r * 255),
+                                     xround (g * 255),
+                                     xround (b * 255),
+                                     a));
+              }
+        }
+
+      return img;
+    }
+
+  return QImage ();
+}
+
+octave_scalar_map makeKeyEventStruct (QKeyEvent* event)
+{
+  octave_scalar_map retval;
+
+  retval.setfield ("Key", KeyMap::qKeyToKeyString (event->key ()));
+  retval.setfield ("Character", toStdString (event->text ()));
+
+  std::list<std::string> modList;
+  Qt::KeyboardModifiers mods = event->modifiers ();
+
+  if (mods & Qt::ShiftModifier)
+    modList.push_back ("shift");
+  if (mods & Qt::ControlModifier)
+#ifdef Q_OS_MAC
+    modList.push_back ("command");
+#else
+    modList.push_back ("control");
+#endif
+  if (mods & Qt::AltModifier)
+    modList.push_back ("alt");
+#ifdef Q_OS_MAC
+  if (mods & Qt::MetaModifier)
+    modList.push_back ("control");
+#endif
+
+  retval.setfield ("Modifier", Cell (modList));
+
+  return retval;
+}
+
+}; // namespace Utils
+
+}; // namespace QtHandles
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libgui/graphics/QtHandlesUtils.h	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,82 @@
+/*
+
+Copyright (C) 2011-2014 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/>.
+
+*/
+
+#ifndef __QtHandles_Utils__
+#define __QtHandles_Utils__ 1
+
+#include <QColor>
+#include <QFont>
+#include <QImage>
+#include <QString>
+#include <QStringList>
+
+#include <string>
+
+#include "graphics.h"
+
+class QKeyEvent;
+class QMouseEvent;
+
+namespace QtHandles
+{
+
+namespace Utils
+{
+  QString fromStdString (const std::string& s);
+  std::string toStdString (const QString& s);
+
+  QStringList fromStringVector (const string_vector& v);
+  string_vector toStringVector (const QStringList& l);
+
+  template <class T>
+  QFont computeFont (const typename T::properties& props, int height = -1);
+
+  QColor fromRgb (const Matrix& rgb);
+  Matrix toRgb (const QColor& c);
+
+  Qt::Alignment fromHVAlign (const caseless_str& halign,
+                             const caseless_str& valign);
+
+  std::string figureSelectionType (QMouseEvent* event,
+                                   bool isDoubleClick = false);
+
+  Matrix figureCurrentPoint (const graphics_object& fig, QMouseEvent* event);
+
+  template <class T>
+  inline typename T::properties&
+  properties (graphics_object obj)
+    { return dynamic_cast<typename T::properties&> (obj.get_properties ()); }
+
+  template <class T>
+  inline typename T::properties&
+  properties (const graphics_handle& h)
+    { return Utils::properties<T> (gh_manager::get_object (h)); }
+
+  QImage makeImageFromCData (const octave_value& v, int width = -1,
+                             int height = -1);
+
+  octave_scalar_map makeKeyEventStruct (QKeyEvent* event);
+};
+
+}; // namespace QtHandles
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libgui/graphics/RadioButtonControl.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,63 @@
+/*
+
+Copyright (C) 2011-2014 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 <QRadioButton>
+
+#include "RadioButtonControl.h"
+#include "Container.h"
+#include "QtHandlesUtils.h"
+
+namespace QtHandles
+{
+
+RadioButtonControl* RadioButtonControl::create (const graphics_object& go)
+{
+  Object* parent = Object::parentObject (go);
+
+  if (parent)
+    {
+      Container* container = parent->innerContainer ();
+
+      if (container)
+        return new RadioButtonControl (go, new QRadioButton (container));
+    }
+
+  return 0;
+}
+
+RadioButtonControl::RadioButtonControl (const graphics_object& go,
+                                        QRadioButton* radio)
+    : ButtonControl (go, radio)
+{
+  radio->setAutoFillBackground (true);
+  radio->setAutoExclusive (false);
+}
+
+RadioButtonControl::~RadioButtonControl (void)
+{
+}
+
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libgui/graphics/RadioButtonControl.h	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,44 @@
+/*
+
+Copyright (C) 2011-2014 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/>.
+
+*/
+
+#ifndef __QtHandles_RadioButton__
+#define __QtHandles_RadioButton__ 1
+
+#include "ButtonControl.h"
+
+class QRadioButton;
+
+namespace QtHandles
+{
+
+class RadioButtonControl : public ButtonControl
+{
+public:
+  RadioButtonControl (const graphics_object& go, QRadioButton* box);
+  ~RadioButtonControl (void);
+
+  static RadioButtonControl* create (const graphics_object& go);
+};
+
+}; // namespace QtHandles
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libgui/graphics/SliderControl.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,150 @@
+/*
+
+Copyright (C) 2011-2014 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 <QScrollBar>
+
+#include "Container.h"
+#include "SliderControl.h"
+#include "QtHandlesUtils.h"
+
+#define RANGE_INT_MAX 1000000
+
+namespace QtHandles
+{
+
+SliderControl* SliderControl::create (const graphics_object& go)
+{
+  Object* parent = Object::parentObject (go);
+
+  if (parent)
+    {
+      Container* container = parent->innerContainer ();
+
+      if (container)
+        return new SliderControl (go, new QScrollBar (container));
+    }
+
+  return 0;
+}
+
+SliderControl::SliderControl (const graphics_object& go,
+                              QAbstractSlider* slider)
+    : BaseControl (go, slider), m_blockUpdates (false)
+{
+  uicontrol::properties& up = properties<uicontrol> ();
+
+  slider->setTracking (false);
+  Matrix bb = up.get_boundingbox ();
+  slider->setOrientation (bb(2) > bb(3) ? Qt::Horizontal : Qt::Vertical);
+  Matrix steps = up.get_sliderstep ().matrix_value ();
+  slider->setMinimum (0);
+  slider->setMaximum (RANGE_INT_MAX);
+  slider->setSingleStep (xround (steps(0) * RANGE_INT_MAX));
+  slider->setPageStep (xround (steps(1) * RANGE_INT_MAX));
+  Matrix value = up.get_value ().matrix_value ();
+  if (value.numel () > 0)
+    {
+      double dmin = up.get_min (), dmax = up.get_max ();
+
+      slider->setValue (xround (((value(0) - dmin) / (dmax - dmin))
+                                * RANGE_INT_MAX));
+    }
+
+  connect (slider, SIGNAL (valueChanged (int)), SLOT (valueChanged (int)));
+}
+
+SliderControl::~SliderControl (void)
+{
+}
+
+void SliderControl::update (int pId)
+{
+  uicontrol::properties& up = properties<uicontrol> ();
+  QScrollBar* slider = qWidget<QScrollBar> ();
+
+  switch (pId)
+    {
+    case uicontrol::properties::ID_SLIDERSTEP:
+        {
+          Matrix steps = up.get_sliderstep ().matrix_value ();
+
+          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 ();
+
+          if (value.numel () > 0)
+            {
+              int ival = xround (((value(0) - dmin) / (dmax - dmin))
+                                 * RANGE_INT_MAX);
+
+              m_blockUpdates = true;
+              slider->setValue (ival);
+              m_blockUpdates = false;
+            }
+        }
+      break;
+    default:
+      BaseControl::update (pId);
+      break;
+    }
+}
+
+void SliderControl::valueChanged (int ival)
+{
+  if (! m_blockUpdates)
+    {
+      gh_manager::auto_lock lock;
+      graphics_object go = object ();
+
+      if (go.valid_object ())
+        {
+          uicontrol::properties& up = Utils::properties<uicontrol> (go);
+
+          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);
+
+          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");
+            }
+        }
+    }
+}
+
+}; // namespace QtHandles
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libgui/graphics/SliderControl.h	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,55 @@
+/*
+
+Copyright (C) 2011-2014 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/>.
+
+*/
+
+#ifndef __QtHandles_SliderControl__
+#define __QtHandles_SliderControl__ 1
+
+#include "BaseControl.h"
+
+class QAbstractSlider;
+
+namespace QtHandles
+{
+
+class SliderControl : public BaseControl
+{
+  Q_OBJECT
+
+public:
+  SliderControl (const graphics_object& go, QAbstractSlider* slider);
+  ~SliderControl (void);
+
+  static SliderControl* create (const graphics_object& go);
+
+protected:
+  void update (int pId);
+
+private slots:
+  void valueChanged (int ival);
+
+private:
+  bool m_blockUpdates;
+};
+
+}; // namespace QtHandles
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libgui/graphics/TextControl.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,91 @@
+/*
+
+Copyright (C) 2011-2014 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 <QLabel>
+
+#include "Container.h"
+#include "TextControl.h"
+#include "QtHandlesUtils.h"
+
+namespace QtHandles
+{
+
+TextControl* TextControl::create (const graphics_object& go)
+{
+  Object* parent = Object::parentObject (go);
+
+  if (parent)
+    {
+      Container* container = parent->innerContainer ();
+
+      if (container)
+        return new TextControl (go, new QLabel (container));
+    }
+
+  return 0;
+}
+
+TextControl::TextControl (const graphics_object& go, QLabel* label)
+     : BaseControl (go, label)
+{
+  uicontrol::properties& up = properties<uicontrol> ();
+
+  label->setAutoFillBackground (true);
+  label->setTextFormat (Qt::PlainText);
+  label->setWordWrap (false);
+  label->setAlignment (Utils::fromHVAlign (up.get_horizontalalignment (),
+                                           up.get_verticalalignment ()));
+  // FIXME: support string_vector
+  label->setText (Utils::fromStdString (up.get_string_string ()));
+}
+
+TextControl::~TextControl (void)
+{
+}
+
+void TextControl::update (int pId)
+{
+  uicontrol::properties& up = properties<uicontrol> ();
+  QLabel* label = qWidget<QLabel> ();
+
+  switch (pId)
+    {
+    case uicontrol::properties::ID_STRING:
+      // FIXME: support string_vector
+      label->setText (Utils::fromStdString (up.get_string_string ()));
+      break;
+    case uicontrol::properties::ID_HORIZONTALALIGNMENT:
+    case uicontrol::properties::ID_VERTICALALIGNMENT:
+      label->setAlignment (Utils::fromHVAlign (up.get_horizontalalignment (),
+                                               up.get_verticalalignment ()));
+      break;
+    default:
+      BaseControl::update (pId);
+      break;
+    }
+}
+
+}; // namespace QtHandles
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libgui/graphics/TextControl.h	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,47 @@
+/*
+
+Copyright (C) 2011-2014 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/>.
+
+*/
+
+#ifndef __QtHandles_TextControl__
+#define __QtHandles_TextControl__ 1
+
+#include "BaseControl.h"
+
+class QLabel;
+
+namespace QtHandles
+{
+
+class TextControl : public BaseControl
+{
+public:
+  TextControl (const graphics_object& go, QLabel* label);
+  ~TextControl (void);
+
+  static TextControl* create (const graphics_object& go);
+
+protected:
+  void update (int pId);
+};
+
+}; // namespace QtHandles
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libgui/graphics/TextEdit.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,51 @@
+/*
+
+Copyright (C) 2011-2014 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 <QKeyEvent>
+
+#include "TextEdit.h"
+
+namespace QtHandles
+{
+
+void TextEdit::focusOutEvent (QFocusEvent* xevent)
+{
+  QTextEdit::focusOutEvent (xevent);
+
+  emit editingFinished ();
+}
+
+void TextEdit::keyPressEvent (QKeyEvent* xevent)
+{
+  QTextEdit::keyPressEvent (xevent);
+
+  if ((xevent->key () == Qt::Key_Return
+       || xevent->key () == Qt::Key_Enter)
+      && xevent->modifiers () == Qt::ControlModifier)
+    emit editingFinished ();
+}
+
+}; // namespace QtHandles
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libgui/graphics/TextEdit.h	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,49 @@
+/*
+
+Copyright (C) 2011-2014 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/>.
+
+*/
+
+#ifndef __QtHandles_TextEdit__
+#define __QtHandles_TextEdit__ 1
+
+#include <QTextEdit>
+
+namespace QtHandles
+{
+
+class TextEdit : public QTextEdit
+{
+  Q_OBJECT
+
+public:
+  TextEdit (QWidget* xparent) : QTextEdit(xparent) { }
+  ~TextEdit (void) { }
+
+signals:
+  void editingFinished (void);
+
+protected:
+  void focusOutEvent (QFocusEvent* event);
+  void keyPressEvent (QKeyEvent* event);
+};
+
+}; // namespace QtHandles
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libgui/graphics/ToggleButtonControl.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,63 @@
+/*
+
+Copyright (C) 2011-2014 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 <QPushButton>
+
+#include "ToggleButtonControl.h"
+#include "Container.h"
+#include "QtHandlesUtils.h"
+
+namespace QtHandles
+{
+
+ToggleButtonControl* ToggleButtonControl::create (const graphics_object& go)
+{
+  Object* parent = Object::parentObject (go);
+
+  if (parent)
+    {
+      Container* container = parent->innerContainer ();
+
+      if (container)
+        return new ToggleButtonControl (go, new QPushButton (container));
+    }
+
+  return 0;
+}
+
+ToggleButtonControl::ToggleButtonControl (const graphics_object& go,
+                                          QPushButton* btn)
+    : ButtonControl (go, btn)
+{
+  btn->setCheckable (true);
+  btn->setAutoFillBackground (true);
+}
+
+ToggleButtonControl::~ToggleButtonControl (void)
+{
+}
+
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libgui/graphics/ToggleButtonControl.h	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,44 @@
+/*
+
+Copyright (C) 2011-2014 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/>.
+
+*/
+
+#ifndef __QtHandles_ToggleButtonControl__
+#define __QtHandles_ToggleButtonControl__ 1
+
+#include "ButtonControl.h"
+
+class QPushButton;
+
+namespace QtHandles
+{
+
+class ToggleButtonControl : public ButtonControl
+{
+public:
+  ToggleButtonControl (const graphics_object& go, QPushButton* box);
+  ~ToggleButtonControl (void);
+
+  static ToggleButtonControl* create (const graphics_object& go);
+};
+
+}; // namespace QtHandles
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libgui/graphics/ToggleTool.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,91 @@
+/*
+
+Copyright (C) 2011-2014 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 "ToggleTool.h"
+
+#include "ToolBarButton.cc"
+
+namespace QtHandles
+{
+
+ToggleTool* ToggleTool::create (const graphics_object& go)
+{
+  Object* parent = Object::parentObject (go);
+
+  if (parent)
+    {
+      QWidget* parentWidget = parent->qWidget<QWidget> ();
+
+      if (parentWidget)
+        return new ToggleTool (go, new QAction (parentWidget));
+    }
+
+  return 0;
+}
+
+ToggleTool::ToggleTool (const graphics_object& go, QAction* action)
+    : ToolBarButton<uitoggletool> (go, action)
+{
+  uitoggletool::properties& tp = properties<uitoggletool> ();
+
+  action->setCheckable (true);
+  action->setChecked (tp.is_state ());
+
+  connect (action, SIGNAL (toggled (bool)),
+           this, SLOT (triggered (bool)));
+}
+
+ToggleTool::~ToggleTool (void)
+{
+}
+
+void ToggleTool::update (int pId)
+{
+  uitoggletool::properties& tp = properties<uitoggletool> ();
+  QAction* action = qWidget<QAction> ();
+
+  switch (pId)
+    {
+    case uitoggletool::properties::ID_STATE:
+      action->setChecked (tp.is_state ());
+      break;
+    default:
+      ToolBarButton<uitoggletool>::update (pId);
+      break;
+    }
+}
+
+void ToggleTool::triggered (bool checked)
+{
+  gh_manager::post_set (m_handle, "state", checked, false);
+  gh_manager::post_callback (m_handle,
+                             checked
+                             ? "oncallback"
+                             : "offcallback");
+  gh_manager::post_callback (m_handle, "clickedcallback");
+}
+
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libgui/graphics/ToggleTool.h	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,50 @@
+/*
+
+Copyright (C) 2011-2014 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/>.
+
+*/
+
+#ifndef __QtHandles_ToggleTool__
+#define __QtHandles_ToggleTool__ 1
+
+#include "ToolBarButton.h"
+
+namespace QtHandles
+{
+
+class ToggleTool : public ToolBarButton<uitoggletool>
+{
+  Q_OBJECT
+
+public:
+  ToggleTool (const graphics_object& go, QAction* action);
+  ~ToggleTool (void);
+
+  static ToggleTool* create (const graphics_object& go);
+
+protected:
+  void update (int pId);
+
+private slots:
+  void triggered (bool checked);
+};
+
+}; // namespace QtHandles
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libgui/graphics/ToolBar.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,172 @@
+/*
+
+Copyright (C) 2011-2014 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 <QAction>
+#include <QActionEvent>
+#include <QApplication>
+#include <QEvent>
+#include <QIcon>
+#include <QMainWindow>
+#include <QPixmap>
+#include <QTimer>
+#include <QToolBar>
+
+#include "Figure.h"
+#include "ToolBar.h"
+#include "QtHandlesUtils.h"
+
+namespace QtHandles
+{
+
+static QAction* addEmptyAction (QToolBar* bar)
+{
+  static QIcon _empty;
+
+  if (_empty.isNull ())
+    {
+      QPixmap pix (16, 16);
+
+      pix.fill (Qt::transparent);
+
+      _empty = QIcon (pix);
+    }
+
+  QAction* a = bar->addAction (_empty, "Empty Toolbar");
+
+  a->setEnabled (false);
+  a->setToolTip ("");
+
+  return a;
+}
+
+ToolBar* ToolBar::create (const graphics_object& go)
+{
+  Object* parent = Object::parentObject (go);
+
+  if (parent)
+    {
+      QWidget* parentWidget = parent->qWidget<QWidget> ();
+
+      if (parentWidget)
+        return new ToolBar (go, new QToolBar (parentWidget));
+    }
+
+  return 0;
+}
+
+ToolBar::ToolBar (const graphics_object& go, QToolBar* bar)
+     : Object (go, bar), m_empty (0), m_figure (0)
+{
+  uitoolbar::properties& tp = properties<uitoolbar> ();
+
+  bar->setFloatable (false);
+  bar->setMovable (false);
+  bar->setVisible (tp.is_visible ());
+
+  m_empty = addEmptyAction (bar);
+
+  m_figure =
+    dynamic_cast<Figure*> (Object::fromQObject (bar->parentWidget ()));
+
+  if (m_figure)
+    m_figure->addCustomToolBar (bar, tp.is_visible ());
+
+  bar->installEventFilter (this);
+}
+
+ToolBar::~ToolBar (void)
+{
+}
+
+void ToolBar::update (int pId)
+{
+  uitoolbar::properties& tp = properties<uitoolbar> ();
+  QToolBar* bar = qWidget<QToolBar> ();
+
+  switch (pId)
+    {
+    case base_properties::ID_VISIBLE:
+      if (m_figure)
+        m_figure->showCustomToolBar (bar, tp.is_visible ());
+      break;
+    default:
+      Object::update (pId);
+      break;
+    }
+}
+
+bool ToolBar::eventFilter (QObject* watched, QEvent* xevent)
+{
+  if (watched == qObject ())
+    {
+      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 (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;
+}
+
+void ToolBar::hideEmpty (void)
+{
+  m_empty->setVisible (false);
+}
+
+void ToolBar::beingDeleted (void)
+{
+  if (m_figure)
+    {
+      QToolBar* bar = qWidget<QToolBar> ();
+
+      if (bar)
+        m_figure->showCustomToolBar (bar, false);
+    }
+}
+
+}; // namespace QtHandles
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libgui/graphics/ToolBar.h	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,64 @@
+/*
+
+Copyright (C) 2011-2014 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/>.
+
+*/
+
+#ifndef __QtHandles_ToolBar__
+#define __QtHandles_ToolBar__ 1
+
+#include "Object.h"
+
+class QAction;
+class QToolBar;
+
+namespace QtHandles
+{
+
+class Figure;
+
+class ToolBar : public Object
+{
+  Q_OBJECT
+
+public:
+  ToolBar (const graphics_object& go, QToolBar* bar);
+  ~ToolBar (void);
+
+  static ToolBar* create (const graphics_object& go);
+
+  Container* innerContainer (void) { return 0; }
+
+  bool eventFilter (QObject* watched, QEvent* event);
+
+protected:
+  void update (int pId);
+  void beingDeleted (void);
+
+private slots:
+  void hideEmpty (void);
+
+private:
+  QAction* m_empty;
+  Figure* m_figure;
+};
+
+}; // namespace QtHandles
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libgui/graphics/ToolBarButton.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,119 @@
+/*
+
+Copyright (C) 2011-2014 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 <QAction>
+#include <QWidget>
+
+#include "ToolBarButton.h"
+#include "QtHandlesUtils.h"
+
+namespace QtHandles
+{
+
+template <class T>
+ToolBarButton<T>::ToolBarButton (const graphics_object& go, QAction* action)
+    : Object (go, action), m_separator (0)
+{
+  typename T::properties& tp = properties<T> ();
+
+  action->setToolTip (Utils::fromStdString (tp.get_tooltipstring ()));
+  action->setVisible (tp.is_visible ());
+  QImage img = Utils::makeImageFromCData (tp.get_cdata (), 16, 16);
+  action->setIcon (QIcon (QPixmap::fromImage (img)));
+  if (tp.is_separator ())
+    {
+      m_separator = new QAction (action);
+      m_separator->setSeparator (true);
+      m_separator->setVisible (tp.is_visible ());
+    }
+  action->setEnabled (tp.is_enable ());
+
+  QWidget* w = qobject_cast<QWidget*> (action->parent ());
+
+  w->insertAction (w->actions ().back (), action);
+  if (m_separator)
+    w->insertAction (action, m_separator);
+}
+
+template <class T>
+ToolBarButton<T>::~ToolBarButton (void)
+{
+}
+
+template <class T>
+void ToolBarButton<T>::update (int pId)
+{
+  typename T::properties& tp = properties<T> ();
+  QAction* action = qWidget<QAction> ();
+
+  switch (pId)
+    {
+    case base_properties::ID_VISIBLE:
+      action->setVisible (tp.is_visible ());
+      if (m_separator)
+        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);
+
+          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 ());
+
+              QWidget* w = qobject_cast<QWidget*> (action->parent ());
+
+              w->insertAction (action, m_separator);
+            }
+        }
+      else
+        {
+          if (m_separator)
+            delete m_separator;
+          m_separator = 0;
+        }
+      break;
+    case T::properties::ID_ENABLE:
+      action->setEnabled (tp.is_enable ());
+      break;
+    default:
+      Object::update (pId);
+      break;
+    }
+}
+
+}; // namespace QtHandles
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libgui/graphics/ToolBarButton.h	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,53 @@
+/*
+
+Copyright (C) 2011-2014 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/>.
+
+*/
+
+#ifndef __QtHandles_ToolBarButton__
+#define __QtHandles_ToolBarButton__ 1
+
+#include "Object.h"
+
+class QAction;
+
+namespace QtHandles
+{
+
+class Container;
+
+template <class T>
+class ToolBarButton : public Object
+{
+public:
+  ToolBarButton (const graphics_object& go, QAction* action);
+  ~ToolBarButton (void);
+
+  Container* innerContainer (void) { return 0; }
+
+protected:
+  void update (int pId);
+
+private:
+  QAction* m_separator;
+};
+
+};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libgui/graphics/__init_qt__.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,332 @@
+/*
+
+Copyright (C) 2011-2014 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 <QApplication>
+#include <QDir>
+#include <QFileDialog>
+#include <QMetaType>
+#include <QPalette>
+#include <QRegExp>
+
+#include "graphics.h"
+#include "toplev.h"
+#include "defun.h"
+
+#include "Backend.h"
+#include "QtHandlesUtils.h"
+
+namespace QtHandles
+{
+
+static bool qtHandlesInitialized = false;
+
+bool __init__ (void)
+{
+  if (! qtHandlesInitialized)
+    {
+      if (qApp)
+        {
+          qRegisterMetaType<graphics_object> ("graphics_object");
+
+          gh_manager::enable_event_processing (true);
+
+          graphics_toolkit tk (new Backend ());
+          gtk_manager::load_toolkit (tk);
+
+          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);
+
+          /*
+          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;
+
+          return true;
+        }
+      else
+        error ("__init_qt__: QApplication object must exist.");
+    }
+
+  return false;
+}
+
+bool __shutdown__ (void)
+{
+  if (qtHandlesInitialized)
+    {
+      octave_add_atexit_function ("__shutdown_qt__");
+
+      gtk_manager::unload_toolkit ("qt");
+
+      gh_manager::enable_event_processing (false);
+
+      qtHandlesInitialized = false;
+
+      return true;
+    }
+
+  return false;
+}
+
+}; // namespace QtHandles
+
+DEFUN (__init_qt__, , , "")
+{
+  QtHandles::__init__ ();
+
+  return octave_value ();
+}
+
+DEFUN (__shutdown_qt__, , , "")
+{
+  QtHandles::__shutdown__ ();
+
+  return octave_value ();
+}
+
+void
+install___init_qt___functions (void)
+{
+  install_builtin_function (F__init_qt__, "__init_qt__",
+                            "__init_qt__.cc", "");
+
+  install_builtin_function (F__shutdown_qt__, "__shutdown_qt__",
+                            "__init_qt__.cc", "");
+}
+
+#if 0
+
+static QStringList makeFilterSpecs (const Cell& filters)
+{
+  using namespace QtHandles::Utils;
+
+  QStringList filterSpecs;
+  QRegExp parenRe (" ?\\(.*\\)\\s*$");
+
+  for (int i = 0; i < filters.rows (); i++)
+    {
+      QStringList extList =
+        fromStdString (filters(i, 0).string_value ()).split (";");
+      QString desc = fromStdString (filters(i, 1).string_value ()).trimmed ();
+      QString specItem;
+
+      if (desc.contains (parenRe))
+        {
+          // We need to strip any existing parenthesis and recreate it.
+          // In case the format specified in the () section is not correct,
+          // the filters won't work as expected.
+          desc.remove (parenRe);
+        }
+
+      specItem = QString ("%1 (%2)").arg (desc).arg (extList.join (" "));
+
+      filterSpecs.append (specItem);
+    }
+
+  return filterSpecs;
+}
+
+static QString appendDirSep (const QString& d)
+{
+  if (! d.endsWith ("/") && ! d.endsWith (QDir::separator ()))
+    return (d + "/");
+  return d;
+}
+
+DEFUN (__uigetfile_qt__, args, , "")
+{
+  using namespace QtHandles::Utils;
+
+  // Expected arguments:
+  //   args(0) : File filter as a cell array {ext1, name1; ext2, name2; ...}
+  //   args(1) : Dialog title
+  //   args(2) : Default file name
+  //   args(3) : Dialog position [ignored]
+  //   args(4) : Multiselection "on"/"off"
+  //   args(5) : Default directory
+
+  octave_value_list retval (3);
+
+  QString caption = fromStdString (args(1).string_value ());
+  QString defaultDirectory = fromStdString (args(5).string_value ());
+  QString defaultFileName = fromStdString (args(2).string_value ());
+  bool isMultiSelect = (args(4).string_value () == "on");
+
+  if (isMultiSelect)
+    retval(0) = Cell ();
+  else
+    retval(0) = "";
+  retval(1) = "";
+  retval(2) = static_cast<double> (0);
+
+  if (defaultFileName.isEmpty ())
+    defaultFileName = defaultDirectory;
+  else
+    defaultFileName = defaultDirectory + "/" + defaultFileName;
+
+  QStringList filterSpecs = makeFilterSpecs (args(0).cell_value ());
+
+  if (isMultiSelect)
+    {
+      QString filter;
+      QStringList files =
+        QFileDialog::getOpenFileNames (0, caption, defaultFileName,
+                                       filterSpecs.join (";;"), &filter, 0);
+
+      if (! files.isEmpty ())
+        {
+          Cell cFiles (1, files.length ());
+          QString dirName;
+          int i = 0;
+
+          foreach (const QString& s, files)
+            {
+              QFileInfo fi (s);
+
+              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);
+        }
+    }
+  else
+    {
+      QString filter;
+      QString fileName =
+        QFileDialog::getOpenFileName (0, caption, defaultFileName,
+                                      filterSpecs.join (";;"), &filter, 0);
+
+      if (! fileName.isNull ())
+        {
+          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);
+        }
+    }
+
+  return retval;
+}
+
+DEFUN (__uiputfile_qt__, args, , "")
+{
+  using namespace QtHandles::Utils;
+
+  // Expected arguments:
+  //   args(0) : File filter as a cell array {ext1, name1; ext2, name2; ...}
+  //   args(1) : Dialog title
+  //   args(2) : Default file name
+  //   args(3) : Dialog position [ignored]
+  //   args(4) : Tag [ignored]
+  //   args(5) : Default directory
+
+  octave_value_list retval (3);
+
+  QString caption = fromStdString (args(1).string_value ());
+  QString defaultDirectory = fromStdString (args(5).string_value ());
+  QString defaultFileName = fromStdString (args(2).string_value ());
+
+  retval(0) = "";
+  retval(1) = "";
+  retval(2) = static_cast<double> (0);
+
+  if (defaultFileName.isEmpty ())
+    defaultFileName = defaultDirectory;
+  else
+    defaultFileName = defaultDirectory + "/" + defaultFileName;
+
+  QStringList filterSpecs = makeFilterSpecs (args(0).cell_value ());
+
+  QString filter;
+  QString fileName =
+    QFileDialog::getSaveFileName (0, caption, defaultFileName,
+                                  filterSpecs.join (";;"), &filter, 0);
+
+  if (! fileName.isNull ())
+    {
+      QFileInfo fi (fileName);
+
+      retval(0) = toStdString (fi.fileName ());
+      if (fi.exists ())
+        retval(1) = toStdString (appendDirSep (fi.canonicalPath ()));
+      else
+        retval(1) = toStdString (appendDirSep (fi.absolutePath ()));
+      if (! filter.isEmpty ())
+        retval(2) = static_cast<double> (filterSpecs.indexOf (filter) + 1);
+    }
+
+  return retval;
+}
+
+DEFUN (__uigetdir_qt__, args, , "")
+{
+  using namespace QtHandles::Utils;
+
+  // Expected arguments:
+  //   args(0) : Start directory
+  //   args(1) : Dialog title
+
+  octave_value retval ("");
+
+  QString caption = fromStdString (args(1).string_value ());
+  QString defaultDirectory = fromStdString (args(0).string_value ());
+
+  QString dirName = QFileDialog::getExistingDirectory (0, caption,
+                                                       defaultDirectory);
+
+  if (! dirName.isNull ())
+    retval = toStdString (dirName);
+
+  return retval;
+}
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libgui/graphics/__init_qt__.h	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,35 @@
+/*
+
+Copyright (C) 2011-2014 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/>.
+
+*/
+
+#ifndef __QtHandles_init_qt__
+#define __QtHandles_init_qt__ 1
+
+namespace QtHandles
+{
+
+bool __init__ (void);
+
+}; // namespace QtHandles
+
+extern void install___init_qt___functions (void);
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libgui/graphics/gl-select.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,203 @@
+/*
+
+Copyright (C) 2011-2014 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 "gl-select.h"
+
+#include <iostream>
+
+void
+opengl_selector::apply_pick_matrix (void)
+{
+  GLdouble p_matrix[16];
+  GLint viewport[4];
+
+  glGetDoublev (GL_PROJECTION_MATRIX, p_matrix);
+  glGetIntegerv (GL_VIEWPORT, viewport);
+  glMatrixMode (GL_PROJECTION);
+  glLoadIdentity ();
+  gluPickMatrix (xp, yp, size, size, viewport);
+  glMultMatrixd (p_matrix);
+  glMatrixMode (GL_MODELVIEW);
+}
+
+void
+opengl_selector::setup_opengl_transformation (const axes::properties& props)
+{
+  opengl_renderer::setup_opengl_transformation (props);
+  apply_pick_matrix ();
+}
+
+void
+opengl_selector::init_marker (const std::string& m, double sz, float width)
+{
+  opengl_renderer::init_marker (m, sz, width);
+  apply_pick_matrix ();
+}
+
+# define BUFFER_SIZE 128
+
+graphics_object
+opengl_selector::select (const graphics_object& ax, int x, int y, int flags)
+{
+  glEnable (GL_DEPTH_TEST);
+  glDepthFunc (GL_LEQUAL);
+
+  xp = x;
+  yp = y;
+
+  GLuint select_buffer[BUFFER_SIZE];
+
+  glSelectBuffer (BUFFER_SIZE, select_buffer);
+  glRenderMode (GL_SELECT);
+  glInitNames ();
+
+  object_map.clear ();
+
+  draw (ax);
+
+  int hits = glRenderMode (GL_RENDER);
+  graphics_object obj;
+
+  if (hits > 0)
+    {
+      GLuint current_minZ = 0xffffffff;
+      GLuint current_name = 0xffffffff;
+
+      for (int i = 0, j = 0; i < hits && j < BUFFER_SIZE-3; i++)
+        {
+          GLuint n = select_buffer[j++],
+                 minZ = select_buffer[j++];
+
+          j++; // skip maxZ
+          if (((flags & select_last) == 0 && (minZ <= current_minZ)) ||
+              ((flags & select_last) != 0 && (minZ >= current_minZ)))
+            {
+              bool candidate = true;
+              GLuint name =
+                select_buffer[std::min (j + n, GLuint (BUFFER_SIZE)) - 1];
+
+              if ((flags & select_ignore_hittest) == 0)
+                {
+                  graphics_object go = object_map[name];
+
+                  if (! go.get_properties ().is_hittest ())
+                    candidate = false;
+                }
+
+              if (candidate)
+                {
+                  current_minZ = minZ;
+                  current_name = name;
+                }
+
+              j += n;
+            }
+          else
+            j += n;
+        }
+
+      if (current_name != 0xffffffff)
+        obj = object_map[current_name];
+    }
+  else if (hits < 0)
+    warning ("opengl_selector::select: selection buffer overflow");
+
+  object_map.clear ();
+
+  return obj;
+}
+
+void
+opengl_selector::draw (const graphics_object& go, bool toplevel)
+{
+  GLuint name = object_map.size ();
+
+  object_map[name] = go;
+  glPushName (name);
+  opengl_renderer::draw (go, toplevel);
+  glPopName ();
+}
+
+void
+opengl_selector::fake_text (double x, double y, double z, const Matrix& bbox,
+                            bool use_scale)
+{
+  ColumnVector xpos, xp1, xp2;
+
+  xpos = get_transform ().transform (x, y, z, use_scale);
+
+  xp1 = xp2 = xpos;
+  xp1(0) += bbox(0);
+  xp1(1) -= bbox(1);
+  xp2(0) += (bbox(0) + bbox(2));
+  xp2(1) -= (bbox(1) + bbox(3));
+
+  ColumnVector p1, p2, p3, p4;
+
+  p1 = get_transform ().untransform (xp1(0), xp1(1), xp1(2), false);
+  p2 = get_transform ().untransform (xp2(0), xp1(1), xp1(2), false);
+  p3 = get_transform ().untransform (xp2(0), xp2(1), xp1(2), false);
+  p4 = get_transform ().untransform (xp1(0), xp2(1), xp1(2), false);
+
+  glBegin (GL_QUADS);
+  glVertex3dv (p1.data ());
+  glVertex3dv (p2.data ());
+  glVertex3dv (p3.data ());
+  glVertex3dv (p4.data ());
+  glEnd ();
+}
+
+void
+opengl_selector::draw_text (const text::properties& props)
+{
+  if (props.get_string ().is_empty ())
+    return;
+
+  Matrix pos = props.get_data_position ();
+  const Matrix bbox = props.get_extent_matrix ();
+
+  fake_text (pos(0), pos(1), pos.numel () > 2 ? pos(2) : 0.0, bbox);
+}
+
+Matrix
+opengl_selector::render_text (const std::string& txt,
+                              double x, double y, double z,
+                              int halign, int valign, double rotation)
+{
+#if HAVE_FREETYPE
+  uint8NDArray pixels;
+  Matrix bbox;
+
+  // FIXME: probably more efficient to only compute bbox instead
+  //        of doing full text rendering...
+  text_to_pixels (txt, pixels, bbox, halign, valign, rotation);
+  fake_text (x, y, z, bbox, false);
+
+  return bbox;
+#else
+  return Matrix (1, 4, 0.0);
+#endif
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libgui/graphics/gl-select.h	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,76 @@
+/*
+
+Copyright (C) 2011-2014 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/>.
+
+*/
+
+#ifndef __QtHandles_gl_selector__
+#define __QtHandles_gl_selector__ 1
+
+#include "gl-render.h"
+
+#include <map>
+
+enum select_flags
+{
+  select_ignore_hittest  = 0x01,
+  select_last            = 0x02
+};
+
+class opengl_selector : public opengl_renderer
+{
+public:
+  opengl_selector (void) : size (5) { }
+
+  virtual ~opengl_selector (void) { }
+
+  graphics_object select (const graphics_object& ax, int x, int y,
+                          int flags = 0);
+
+  virtual void draw (const graphics_object& go, bool toplevel = true);
+
+protected:
+  virtual void draw_text (const text::properties& props);
+
+  virtual void setup_opengl_transformation (const axes::properties& props);
+
+  virtual void init_marker (const std::string& m, double size, float width);
+
+  virtual Matrix render_text (const std::string& txt,
+                              double x, double y, double z,
+                              int halign, int valign, double rotation = 0.0);
+
+private:
+  void apply_pick_matrix (void);
+
+  void fake_text (double x, double y, double z, const Matrix& bbox,
+                  bool use_scale = true);
+
+private:
+  // The mouse coordinate of the selection/picking point
+  int xp, yp;
+
+  // The size (in pixels) of the picking window
+  int size;
+
+  // The OpenGL name mapping
+  std::map<GLuint, graphics_object> object_map;
+};
+
+#endif // __QtHandles_gl_selector__
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libgui/graphics/images/README	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,10 @@
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+This copyright and license notice covers the images in this directory.
+************************************************************************
+
+TITLE:	Crystal Project Icons
+AUTHOR:	Everaldo Coelho
+SITE:	http://www.everaldo.com
+CONTACT: everaldo@everaldo.com
+
+Copyright (c)  2006-2007  Everaldo Coelho.
Binary file libgui/graphics/images/pan.png has changed
Binary file libgui/graphics/images/rotate.png has changed
Binary file libgui/graphics/images/select.png has changed
Binary file libgui/graphics/images/zoom.png has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libgui/graphics/module.mk	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,138 @@
+EXTRA_DIST += \
+  graphics/module.mk \
+  graphics/qthandles.qrc \
+  graphics/images/README \
+  graphics/images/pan.png \
+  graphics/images/rotate.png \
+  graphics/images/select.png \
+  graphics/images/zoom.png
+
+octave_gui_MOC += \
+  graphics/moc-Backend.cc \
+  graphics/moc-ButtonControl.cc \
+  graphics/moc-ContextMenu.cc \
+  graphics/moc-EditControl.cc \
+  graphics/moc-Figure.cc \
+  graphics/moc-FigureWindow.cc \
+  graphics/moc-ListBoxControl.cc \
+  graphics/moc-Menu.cc \
+  graphics/moc-MouseModeActionGroup.cc \
+  graphics/moc-Object.cc \
+  graphics/moc-ObjectFactory.cc \
+  graphics/moc-ObjectProxy.cc \
+  graphics/moc-PopupMenuControl.cc \
+  graphics/moc-PushTool.cc \
+  graphics/moc-SliderControl.cc \
+  graphics/moc-TextEdit.cc \
+  graphics/moc-ToggleTool.cc \
+  graphics/moc-ToolBar.cc
+
+octave_gui_graphics_RC = graphics/qrc-qthandles.cc
+
+noinst_HEADERS += \
+  graphics/__init_qt__.h \
+  graphics/Backend.h \
+  graphics/BaseControl.h \
+  graphics/ButtonControl.h \
+  graphics/Canvas.h \
+  graphics/CheckBoxControl.h \
+  graphics/Container.h \
+  graphics/ContextMenu.h \
+  graphics/EditControl.h \
+  graphics/Figure.h \
+  graphics/FigureWindow.h \
+  graphics/GenericEventNotify.h \
+  graphics/GLCanvas.h \
+  graphics/KeyMap.h \
+  graphics/ListBoxControl.h \
+  graphics/Logger.h \
+  graphics/Menu.h \
+  graphics/MenuContainer.h \
+  graphics/MouseModeActionGroup.h \
+  graphics/Object.h \
+  graphics/ObjectFactory.h \
+  graphics/ObjectProxy.h \
+  graphics/Panel.h \
+  graphics/PopupMenuControl.h \
+  graphics/PushButtonControl.h \
+  graphics/PushTool.h \
+  graphics/QtHandlesUtils.h \
+  graphics/RadioButtonControl.h \
+  graphics/SliderControl.h \
+  graphics/TextControl.h \
+  graphics/TextEdit.h \
+  graphics/ToggleButtonControl.h \
+  graphics/ToggleTool.h \
+  graphics/ToolBar.h \
+  graphics/ToolBarButton.h \
+  graphics/gl-select.h \
+  $(TEMPLATE_SRC)
+
+graphics_libgui_graphics_la_SOURCES = \
+  graphics/__init_qt__.cc \
+  graphics/Backend.cc \
+  graphics/BaseControl.cc \
+  graphics/ButtonControl.cc \
+  graphics/Canvas.cc \
+  graphics/CheckBoxControl.cc \
+  graphics/Container.cc \
+  graphics/ContextMenu.cc \
+  graphics/EditControl.cc \
+  graphics/Figure.cc \
+  graphics/FigureWindow.cc \
+  graphics/GLCanvas.cc \
+  graphics/KeyMap.cc \
+  graphics/ListBoxControl.cc \
+  graphics/Logger.cc \
+  graphics/Menu.cc \
+  graphics/MouseModeActionGroup.cc \
+  graphics/Object.cc \
+  graphics/ObjectFactory.cc \
+  graphics/ObjectProxy.cc \
+  graphics/Panel.cc \
+  graphics/PopupMenuControl.cc \
+  graphics/PushButtonControl.cc \
+  graphics/PushTool.cc \
+  graphics/QtHandlesUtils.cc \
+  graphics/RadioButtonControl.cc \
+  graphics/SliderControl.cc \
+  graphics/TextControl.cc \
+  graphics/TextEdit.cc \
+  graphics/ToggleButtonControl.cc \
+  graphics/ToggleTool.cc \
+  graphics/ToolBar.cc \
+  graphics/gl-select.cc
+
+TEMPLATE_SRC = \
+  graphics/ToolBarButton.cc
+
+nodist_graphics_libgui_graphics_la_SOURCES = $(octave_gui_graphics_MOC) $(octave_gui_graphics_RC)
+
+graphics_libgui_graphics_la_CPPFLAGS = \
+  $(AM_CPPFLAGS) \
+  $(FT2_CPPFLAGS) \
+  $(FONTCONFIG_CPPFLAGS) \
+  $(HDF5_CPPFLAGS) \
+  @OCTGUI_DLL_DEFS@ \
+  @QT_CPPFLAGS@ \
+  -Igraphics -I$(srcdir)/graphics \
+  -I$(top_srcdir)/liboctave/cruft/misc \
+  -I$(top_srcdir)/liboctave/array \
+  -I$(top_builddir)/liboctave/numeric -I$(top_srcdir)/liboctave/numeric \
+  -I$(top_builddir)/liboctave/operators -I$(top_srcdir)/liboctave/operators \
+  -I$(top_srcdir)/liboctave/system \
+  -I$(top_srcdir)/liboctave/util \
+  -I$(top_builddir)/libinterp -I$(top_srcdir)/libinterp \
+  -I$(top_builddir)/libinterp/parse-tree -I$(top_srcdir)/libinterp/parse-tree \
+  -I$(top_builddir)/libinterp/corefcn -I$(top_srcdir)/libinterp/corefcn \
+  -I$(top_srcdir)/libinterp/octave-value
+
+graphics_libgui_graphics_la_CFLAGS = $(AM_CFLAGS) $(WARN_CFLAGS)
+
+graphics_libgui_graphics_la_CXXFLAGS = $(AM_CXXFLAGS) $(WARN_CXXFLAGS)
+
+noinst_LTLIBRARIES += graphics/libgui-graphics.la
+
+CLEANFILES += \
+  $(octave_gui_graphics_MOC) \
+  $(octave_gui_graphics_RC)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libgui/graphics/qthandles.qrc	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,8 @@
+<!DOCTYPE RCC><RCC version="1.0">
+<qresource>
+  <file>images/pan.png</file>
+  <file>images/rotate.png</file>
+  <file>images/select.png</file>
+  <file>images/zoom.png</file>
+</qresource>
+</RCC>
--- a/libgui/languages/be_BY.ts	Fri Feb 06 08:31:09 2015 -0800
+++ b/libgui/languages/be_BY.ts	Fri Feb 06 08:31:49 2015 -0800
@@ -475,7 +475,7 @@
         <translation>курсор</translation>
     </message>
     <message>
-        <location filename="../src/main-window.cc" line="+1900"/>
+        <location filename="../src/main-window.cc" line="+1963"/>
         <source>&lt;p&gt;&lt;strong&gt;A Note about Octave&apos;s New GUI&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;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.  But because it is not quite as polished as we would like, we have decided to wait until the 4.0.x release series before making the GUI the default interface.&lt;/p&gt;&lt;p&gt;Given the length of time and the number of bug fixes and improvements since the last major release, we also decided against delaying the release of all these new improvements any longer just to perfect the GUI.  So please enjoy the 3.8 release of Octave and the preview of the new GUI.  We believe it is working reasonably well, but we also know that there are some obvious rough spots and many things that could be improved.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;We Need Your Help&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;There are many ways that you can help us fix the remaining problems, complete the GUI, and improve the overall user experience for both novices and experts alike (links will open an external browser):&lt;/p&gt;&lt;p&gt;&lt;ul&gt;&lt;li&gt;If you are a skilled software developer, you can help by contributing your time to help &lt;a href=&quot;http://octave.org/get-involved.html&quot;&gt;develop Octave&lt;/a&gt;.&lt;/li&gt;&lt;li&gt;If Octave does not work properly, you are encouraged to &lt;a href=&quot;http://octave.org/bugs.html&quot;&gt;report problems &lt;/a&gt; that you find.&lt;/li&gt;&lt;li&gt;Whether you are a user or developer, you can &lt;a href=&quot;http://octave.org/donate.html&quot;&gt;help to fund the project&lt;/a&gt;.  Octave development takes a lot of time and expertise.  Your contributions help to ensure that Octave will continue to improve.&lt;/li&gt;&lt;/ul&gt;&lt;/p&gt;&lt;p&gt;We hope you find Octave to be useful.  Please help us make it even better for the future!&lt;/p&gt;</source>
         <translation>&lt;p&gt;&lt;strong&gt;Нататка пра новы GUI Octave&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;Адна з найбольшых адметнасцяў Octave 3.8 - графічны інтэрфэйс.  Карыстальнікі апошнімі гадамі прасілі яго найбольш часта, і нарэшце ён амаль гатовы.  Але ён пакуль не такі дасканалы, як бы мы жадалі, таму мы вырашылі пачакаць выпуску з серыі 4.0.x перад тым, як рабіць яго стандартным.&lt;/p&gt;&lt;p&gt;Да таго ж, улічваючы час і колькасць выпраўленняў і паляпшэнняў у параўнанні з апошнім буйным выпускам Octave, мы вырашылі затрымліваць новы выпуск толькі дзеля ўдасканалення GUI, не зважаючы на новыя магчымасці.  Таму прыемнага вам карстання выпускам 3.8 і першай версіяй новага інтэрфэйсу.  Нам здаецца, ён працуе даволі добра, але мы ведаем, што ёсць некаторыя відавочныя грубыя недарэчнасці і шмат чаго, што можна палепшыць.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Нам патрабуецца ваша дапамога&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;Ёсць шмат спосабаў, якімі вы можаце дапамагчы нам выправіць праблемы, што яшчэ засталіся, скончыць GUI і палепшыць агульнае уражанне як для новых карыстальнікаў, так і для экспертаў (спасылкі адкрыюцца ў знешнім браўзэры):&lt;/p&gt;&lt;p&gt;&lt;ul&gt;&lt;li&gt;Калі вы спрактыкаваны распрацоўнік праграм, то можаце выдаткаваць час, каб дапамагчы ў &lt;a href=&quot;http://octave.org/get-involved.html&quot;&gt;распрацоўцы Octave&lt;/a&gt;.&lt;/li&gt;&lt;li&gt;Калі Octave працуе з памылкамі, вы можаце &lt;a href=&quot;http://octave.org/bugs.html&quot;&gt;паведаміць пра праблемы&lt;/a&gt;, з якімі сутыкнуліся.&lt;/li&gt;&lt;li&gt;Няхай вы хоць карыстальнік, хоць распрацоўнік, вы можаце &lt;a href=&quot;http://octave.org/donate.html&quot;&gt;прафундаваць праект&lt;/a&gt;.  Распрацоўка Octave патрабуе шмат часу і навыкаў.  Ваш удзел дапаможа гарантаваць, што Octave і надалей будзе ўдасканальвацца.&lt;/li&gt;&lt;/ul&gt;&lt;/p&gt;&lt;p&gt;Спадзяемся, вы знойдзеце Octave карыснай.  Калі ласка, дапамажыце нам зрабіць яго лепшым для будучыні!&lt;/p&gt;</translation>
     </message>
@@ -963,7 +963,7 @@
 <context>
     <name>QWinTerminalImpl</name>
     <message>
-        <location filename="../qterminal/libqterminal/win32/QWinTerminalImpl.cpp" line="+1536"/>
+        <location filename="../qterminal/libqterminal/win32/QWinTerminalImpl.cpp" line="+1539"/>
         <source>copied selection to clipboard</source>
         <translation>вылучэнне скапіявана ў буфер абмену</translation>
     </message>
@@ -1684,17 +1684,12 @@
 ужо адкрыты ў рэдактары</translation>
     </message>
     <message>
-        <location line="+255"/>
+        <location line="+268"/>
         <source>&amp;%1 %2</source>
         <translation>&amp;%1 %2</translation>
     </message>
     <message>
-        <location line="+175"/>
-        <source>&amp;New File</source>
-        <translation>&amp;Новы файл</translation>
-    </message>
-    <message>
-        <location line="+6"/>
+        <location line="+207"/>
         <source>&amp;Save File</source>
         <translation>&amp;Захаваць файл</translation>
     </message>
@@ -1704,7 +1699,12 @@
         <translation>&amp;Адкрыць файл...</translation>
     </message>
     <message>
-        <location line="+6"/>
+        <location line="-3"/>
+        <source>&amp;New Script</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+9"/>
         <source>Save File &amp;As...</source>
         <translation>Захаваць файл &amp;як...</translation>
     </message>
@@ -1790,6 +1790,16 @@
     </message>
     <message>
         <location line="+3"/>
+        <source>&amp;Indent</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+2"/>
+        <source>&amp;Unindent</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+3"/>
         <source>&amp;Find and Replace...</source>
         <translation>&amp;Знайсці і замяніць...</translation>
     </message>
@@ -1804,7 +1814,7 @@
         <translation>П&amp;ерайсці да радка...</translation>
     </message>
     <message>
-        <location line="+55"/>
+        <location line="+57"/>
         <source>&amp;Recent Editor Files</source>
         <translation>&amp;Ранейшыя файлы</translation>
     </message>
@@ -1829,7 +1839,7 @@
         <translation>Закрыць іншыя файлы</translation>
     </message>
     <message>
-        <location line="+31"/>
+        <location line="+34"/>
         <source>&amp;Preferences...</source>
         <translation>&amp;Настаўленні...</translation>
     </message>
@@ -1859,7 +1869,7 @@
         <translation>&amp;Дакументацыя па ключавым слове</translation>
     </message>
     <message>
-        <location line="-741"/>
+        <location line="-790"/>
         <source>Could not open file
 %1
 for read: %2.</source>
@@ -1891,7 +1901,7 @@
         <translation>Асацыяваная картка рэдактара знікла.</translation>
     </message>
     <message>
-        <location line="+521"/>
+        <location line="+567"/>
         <source>&amp;File</source>
         <translation>&amp;Файл</translation>
     </message>
@@ -1906,7 +1916,7 @@
         <translation>&amp;Змяніць</translation>
     </message>
     <message>
-        <location line="+30"/>
+        <location line="+33"/>
         <source>&amp;Debug</source>
         <translation>&amp;Адладка</translation>
     </message>
@@ -1919,7 +1929,7 @@
 <context>
     <name>file_editor_tab</name>
     <message>
-        <location filename="../src/m-editor/file-editor-tab.cc" line="+803"/>
+        <location filename="../src/m-editor/file-editor-tab.cc" line="+824"/>
         <source>Goto line</source>
         <translation>Перайсці да радка</translation>
     </message>
@@ -1929,7 +1939,7 @@
         <translation>Нумар радка</translation>
     </message>
     <message>
-        <location line="+71"/>
+        <location line="+108"/>
         <location line="+69"/>
         <source>&lt;unnamed&gt;</source>
         <translation>&lt;без назвы&gt;</translation>
@@ -1946,14 +1956,15 @@
     </message>
     <message>
         <location line="+10"/>
-        <location line="+122"/>
-        <location line="+150"/>
+        <location line="+123"/>
+        <location line="+112"/>
+        <location line="+69"/>
         <location line="+22"/>
         <source>Octave Editor</source>
         <translation>Рэдактар Octave</translation>
     </message>
     <message>
-        <location line="-293"/>
+        <location line="-325"/>
         <source>The file
 %1
 is about to be closed but has been modified.
@@ -1964,12 +1975,12 @@
 %2</translation>
     </message>
     <message>
-        <location line="+201"/>
+        <location line="+203"/>
         <source>Octave Files (*.m);;All Files (*)</source>
         <translation>Файлы Octave (*.m);;Усе файлы (*)</translation>
     </message>
     <message>
-        <location line="+86"/>
+        <location line="+116"/>
         <source>
 
 Warning: The contents in the editor is modified!</source>
@@ -1987,14 +1998,14 @@
 быў выдалены або пераназваны. Можа, захаваць яго зараз?%2</translation>
     </message>
     <message>
-        <location line="-172"/>
+        <location line="-203"/>
         <source>Could not open file %1 for write:
 %2.</source>
         <translation>Не выйшла адкрыць файл %1 на запіс:
 %2.</translation>
     </message>
     <message>
-        <location line="-975"/>
+        <location line="-1032"/>
         <source>Line:</source>
         <translation>Радок:</translation>
     </message>
@@ -2004,7 +2015,18 @@
         <translation>Слупок:</translation>
     </message>
     <message>
-        <location line="+1122"/>
+        <location line="+1141"/>
+        <source>&quot;%1&quot;
+is not a valid identifier.
+
+If you keep this file name, you will not be able to
+call your script using its name as an Octave command.
+
+Do you want to choose another name?</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+69"/>
         <source>It seems that &apos;%1&apos; has been modified by another application. Do you want to reload it?</source>
         <translation>Выглядае на тое, што &apos;%1&apos; быў зменены іншай праграмай. Перачытаць яго?</translation>
     </message>
@@ -2037,7 +2059,12 @@
         <translation>Дзеянні з дзейным каталогам</translation>
     </message>
     <message>
-        <location line="+373"/>
+        <location line="+15"/>
+        <source>Set Browser Directory...</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+379"/>
         <source>Find Files...</source>
         <translation>Шукаць файлы...</translation>
     </message>
@@ -2048,16 +2075,17 @@
     </message>
     <message>
         <location line="+3"/>
+        <location line="+333"/>
         <source>New Directory</source>
         <translation>Новы каталог</translation>
     </message>
     <message>
-        <location line="-323"/>
+        <location line="-656"/>
         <source>Double-click a file to open it</source>
         <translation>Двойчы пстрыкніце па файле для адкрыцця</translation>
     </message>
     <message>
-        <location line="-79"/>
+        <location line="-100"/>
         <source>Show Octave directory</source>
         <translation>Перайсці да каталогу Octave</translation>
     </message>
@@ -2082,7 +2110,7 @@
         <translation>Перайсці да хатняга каталогу</translation>
     </message>
     <message>
-        <location line="+12"/>
+        <location line="+16"/>
         <source>Search Directory...</source>
         <translation>Шукаць каталог...</translation>
     </message>
@@ -2102,7 +2130,7 @@
         <translation>Новы каталог...</translation>
     </message>
     <message>
-        <location line="+276"/>
+        <location line="+297"/>
         <source>File size</source>
         <translation>Памер файла</translation>
     </message>
@@ -2215,7 +2243,12 @@
 </translation>
     </message>
     <message>
-        <location line="+17"/>
+        <location line="+1"/>
+        <source>New File.txt</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+16"/>
         <source>Create Directory</source>
         <translation>Стварыць каталог</translation>
     </message>
@@ -2294,7 +2327,12 @@
 <context>
     <name>find_dialog</name>
     <message>
-        <location filename="../src/m-editor/find-dialog.cc" line="+77"/>
+        <location filename="../src/m-editor/find-dialog.cc" line="+74"/>
+        <source>Find and Replace</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+3"/>
         <source>Find &amp;what:</source>
         <translation>Што &amp;шукаць:</translation>
     </message>
@@ -2364,7 +2402,7 @@
         <translation>Шукаць вы&amp;лучанае</translation>
     </message>
     <message>
-        <location line="+71"/>
+        <location line="+72"/>
         <source>Search from end</source>
         <translation>Шукаць ад канца</translation>
     </message>
@@ -2374,7 +2412,7 @@
         <translation>Шукаць ад пачатку</translation>
     </message>
     <message>
-        <location line="+121"/>
+        <location line="+119"/>
         <source>Replace Result</source>
         <translation>Вынік замены</translation>
     </message>
@@ -2384,7 +2422,7 @@
         <translation>%1 элементаў заменена</translation>
     </message>
     <message>
-        <location line="+10"/>
+        <location line="+12"/>
         <source>Find Result</source>
         <translation>Вынік пошуку</translation>
     </message>
@@ -2407,12 +2445,7 @@
         <translation>Маска назваў:</translation>
     </message>
     <message>
-        <location line="+2"/>
-        <source>Enter the filename expression</source>
-        <translation>Задайце выраз для назваў файлаў</translation>
-    </message>
-    <message>
-        <location line="+6"/>
+        <location line="+8"/>
         <source>Start in:</source>
         <translation>Пачынаць з:</translation>
     </message>
@@ -2432,22 +2465,12 @@
         <translation>Пазначыць каталог пачатку пошуку</translation>
     </message>
     <message>
-        <location line="+3"/>
-        <source>Recurse directories</source>
-        <translation>Рэкурсіўна</translation>
-    </message>
-    <message>
-        <location line="+4"/>
+        <location line="+7"/>
         <source>Search recursively through directories for matching files</source>
         <translation>Шукаць ува ўсіх падкаталогах</translation>
     </message>
     <message>
-        <location line="+2"/>
-        <source>Include directories</source>
-        <translation>Знаходзіць каталогі</translation>
-    </message>
-    <message>
-        <location line="+4"/>
+        <location line="+6"/>
         <source>Include matching directories in search results</source>
         <translation>Дадаваць пасавальныя каталогі ў вынікі пошуку</translation>
     </message>
@@ -2467,9 +2490,24 @@
         <translation>Змяшчае тэкст:</translation>
     </message>
     <message>
-        <location line="+1"/>
-        <source>Search must match text</source>
-        <translation>Улічваць файлы, што ўтрымліваюць пэўны тэкст</translation>
+        <location line="-35"/>
+        <source>Enter the filename search expression</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+18"/>
+        <source>Search subdirectories</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+6"/>
+        <source>Include directory names</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+12"/>
+        <source>Enter the file content search expression</source>
+        <translation type="unfinished"></translation>
     </message>
     <message>
         <location line="+5"/>
@@ -2532,7 +2570,12 @@
         <translation>Ідзе пошук...</translation>
     </message>
     <message>
-        <location line="+32"/>
+        <location line="+23"/>
+        <source>%1 match(es)</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+9"/>
         <source>Set search directory</source>
         <translation>Пазначыць каталог пошуку</translation>
     </message>
@@ -2622,13 +2665,13 @@
 <context>
     <name>main_window</name>
     <message>
-        <location filename="../src/main-window.cc" line="-1696"/>
+        <location filename="../src/main-window.cc" line="-1758"/>
         <source>Load Workspace</source>
         <translation>Загрузіць прастору зменных</translation>
     </message>
     <message>
-        <location line="+645"/>
-        <location line="+876"/>
+        <location line="+678"/>
+        <location line="+905"/>
         <source>About Octave</source>
         <translation>Пра Octave</translation>
     </message>
@@ -2643,12 +2686,7 @@
         <translation>Новы</translation>
     </message>
     <message>
-        <location line="+4"/>
-        <source>Script</source>
-        <translation>Новы сцэнар</translation>
-    </message>
-    <message>
-        <location line="+7"/>
+        <location line="+11"/>
         <source>Figure</source>
         <translation>Графік</translation>
     </message>
@@ -2688,12 +2726,23 @@
         <translation>Уставіць</translation>
     </message>
     <message>
-        <location line="-1265"/>
+        <location line="-1327"/>
         <source>Save Workspace As</source>
         <translation>Захаваць прастору зменных як</translation>
     </message>
     <message>
-        <location line="+124"/>
+        <location line="+84"/>
+        <source>The file %1
+can not be executed because its name
+is not a valid identifier.
+
+Do you want to execute
+%2
+instead?</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+73"/>
         <source>The release notes file &apos;%1&apos; is empty.</source>
         <translation>Файл заўваг да выпуску &apos;%1&apos; пусты.</translation>
     </message>
@@ -2713,7 +2762,7 @@
         <translation>Навіны супольнасці Octave</translation>
     </message>
     <message>
-        <location line="+939"/>
+        <location line="+968"/>
         <source>Clear Clipboard</source>
         <translation>Ачысціць буфер</translation>
     </message>
@@ -2778,7 +2827,12 @@
         <translation>Крок наперад</translation>
     </message>
     <message>
-        <location line="-151"/>
+        <location line="-1311"/>
+        <source>Octave</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+1160"/>
         <source>Load Workspace...</source>
         <translation>Загрузіць прастору зменных...</translation>
     </message>
@@ -2788,7 +2842,12 @@
         <translation>Захаваць прастору зменных як...</translation>
     </message>
     <message>
-        <location line="+41"/>
+        <location line="+38"/>
+        <source>New Script</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+3"/>
         <source>Function...</source>
         <translation>Функцыя...</translation>
     </message>
@@ -2879,8 +2938,8 @@
         <translation>Перайсці каталогам вышэй</translation>
     </message>
     <message>
-        <location line="-1283"/>
-        <location line="+1286"/>
+        <location line="-1312"/>
+        <location line="+1315"/>
         <source>Browse directories</source>
         <translation>Агляд каталогаў</translation>
     </message>
@@ -2954,7 +3013,7 @@
 <context>
     <name>news_reader</name>
     <message>
-        <location line="-1282"/>
+        <location line="-1311"/>
         <source>&lt;html&gt;
 &lt;body&gt;
 &lt;p&gt;
@@ -3013,18 +3072,18 @@
 <context>
     <name>octave_dock_widget</name>
     <message>
-        <location filename="../src/octave-dock-widget.cc" line="+61"/>
-        <location line="+163"/>
+        <location filename="../src/octave-dock-widget.cc" line="+60"/>
+        <location line="+170"/>
         <source>Undock widget</source>
         <translation>Адчапіць віджэт</translation>
     </message>
     <message>
-        <location line="-153"/>
+        <location line="-160"/>
         <source>Hide widget</source>
         <translation>Схаваць віджэт</translation>
     </message>
     <message>
-        <location line="+104"/>
+        <location line="+107"/>
         <source>Dock widget</source>
         <translation>Прычапіць віджэт</translation>
     </message>
@@ -3055,7 +3114,7 @@
 <context>
     <name>octave_qt_link</name>
     <message>
-        <location filename="../src/octave-qt-link.cc" line="+94"/>
+        <location filename="../src/octave-qt-link.cc" line="+97"/>
         <location line="+6"/>
         <location line="+7"/>
         <source>Yes</source>
@@ -3082,13 +3141,13 @@
     </message>
     <message>
         <location line="+211"/>
-        <source>The file %1 does not exist in the load path.  To debug the function you are editing, you must either change to the directory %2 or add that directory to the load path.</source>
-        <translation>Файл %1 не існуе ў дзейным шляху.  Для адладкі функцыі, якую вы рэдагуеце, трэба змяніць каталог на %2 або дадаць яго да дзейнага шляху.</translation>
+        <source>The file %1 does not exist in the load path.  To run or debug the function you are editing, you must either change to the directory %2 or add that directory to the load path.</source>
+        <translation type="unfinished"></translation>
     </message>
     <message>
         <location line="+1"/>
-        <source>The file %1 is shadowed by a file with the same name in the load path.  To debug the function you are editing, change to the directory %2.</source>
-        <translation>Файлу %1 замінае файл з такой самай назвай у дзейным шляху.  Для адладкі функцыі, якую вы рэдагуеце, змяніце каталог на %2.</translation>
+        <source>The file %1 is shadowed by a file with the same name in the load path. To run or debug the function you are editing, change to the directory %2.</source>
+        <translation type="unfinished"></translation>
     </message>
     <message>
         <location line="+2"/>
@@ -3139,17 +3198,17 @@
 <context>
     <name>settings_dialog</name>
     <message>
-        <location filename="../src/settings-dialog.ui" line="+29"/>
+        <location filename="../src/settings-dialog.ui" line="+23"/>
         <source>Settings</source>
         <translation>Настаўленні</translation>
     </message>
     <message>
-        <location line="+13"/>
+        <location line="+19"/>
         <source>General</source>
         <translation>Агульныя</translation>
     </message>
     <message>
-        <location line="+97"/>
+        <location line="+191"/>
         <source>Octave logo only</source>
         <translation>Толькі эмблема Octave</translation>
     </message>
@@ -3160,17 +3219,37 @@
         <translation>Літарныя значкі</translation>
     </message>
     <message>
-        <location line="+46"/>
+        <location line="-172"/>
+        <source>Dock widget title bar</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+40"/>
+        <source>Custom style</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+26"/>
+        <source>Background color</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+29"/>
+        <source>Text color</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+212"/>
         <source>Editor</source>
         <translation>Рэдактар</translation>
     </message>
     <message>
-        <location line="+71"/>
+        <location line="+102"/>
         <source>Color</source>
         <translation>Колер</translation>
     </message>
     <message>
-        <location line="+120"/>
+        <location line="+170"/>
         <source>Indent width</source>
         <translation>Даўжыня водступу</translation>
     </message>
@@ -3180,7 +3259,7 @@
         <translation>Табуляцыя робіць водступ</translation>
     </message>
     <message>
-        <location line="+7"/>
+        <location line="+23"/>
         <source>Auto indentation</source>
         <translation>Аўтаводступы</translation>
     </message>
@@ -3227,67 +3306,114 @@
         <translation>Памятаць карткі папярэдняга сеансу</translation>
     </message>
     <message>
-        <location line="+60"/>
+        <location line="+34"/>
         <source>Use custom file editor</source>
         <translation>Свой файлавы рэдактар</translation>
     </message>
     <message>
-        <location line="+32"/>
+        <location line="+20"/>
+        <source>emacs +%l %f </source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+35"/>
         <source>Editor Styles</source>
         <translation>Выгляд рэдактара</translation>
     </message>
     <message>
-        <location line="+24"/>
+        <location line="+17"/>
         <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Select font, font size (as a difference from the default size), font style (&lt;b&gt;b&lt;/b&gt;old, &lt;b&gt;i&lt;/b&gt;talic, &lt;b&gt;u&lt;/b&gt;nderline), text color and background color (for the latter, the color pink (255,0,255) is a placeholder for the default background color).&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
         <translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Пазначце шрыфт, ягоны памер (як розніцу ад стандартнага памеру), стыль шрыфту (&lt;b&gt;т&lt;/b&gt;оўсты, &lt;b&gt;к&lt;/b&gt;урсіўны, &lt;b&gt;п&lt;/b&gt;адкрэслены), колер тэксту і колер фону (для фону ружовы (255,0,255) азначае стандартны колер фону).&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
     </message>
     <message>
-        <location line="+108"/>
+        <location line="+191"/>
         <source>Terminal Colors</source>
         <translation>Колеры тэрміналу</translation>
     </message>
     <message>
-        <location line="+45"/>
+        <location line="-100"/>
         <source>Font</source>
         <translation>Шрыфт</translation>
     </message>
     <message>
-        <location line="-757"/>
+        <location line="-770"/>
         <source>Show line numbers</source>
         <translation>Паказваць нумары радкоў</translation>
     </message>
     <message>
-        <location line="+27"/>
+        <location line="+46"/>
         <source>Highlight current line</source>
         <translation>Фарбаваць дзейны радок</translation>
     </message>
     <message>
-        <location line="+262"/>
+        <location line="+328"/>
         <source>Code completion</source>
         <translation>Аўтадапаўненне</translation>
     </message>
     <message>
-        <location line="-282"/>
+        <location line="-361"/>
         <source>Show complete path in window title</source>
         <translation>Паказваць поўны шлях у загалоўку акна</translation>
     </message>
     <message>
-        <location line="-72"/>
+        <location line="-366"/>
+        <source>Interface</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+187"/>
         <source>Graphic icons</source>
         <translation>Графічныя значкі</translation>
     </message>
     <message>
-        <location line="+55"/>
+        <location line="+34"/>
+        <source>Octave Startup</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+6"/>
+        <source>These preferences are applied after the startup files like .octaverc.</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+35"/>
+        <location line="+1104"/>
+        <source>Startup path</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="-1091"/>
+        <location line="+1108"/>
+        <source>Browse</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="-1101"/>
+        <source>Restore last Octave directory of previous session</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+61"/>
         <source>Show whitespace</source>
         <translation>Паказваць прагальныя знакі</translation>
     </message>
     <message>
-        <location line="+27"/>
+        <location line="+33"/>
         <source>Do not show whitespace used for indentation</source>
         <translation>Не паказваць прагальныя знакі ў водступах</translation>
     </message>
     <message>
-        <location line="+290"/>
+        <location line="+120"/>
+        <source>Tab width min.</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+52"/>
+        <source>max.</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+197"/>
         <source># of characters typed before completion list displayed</source>
         <translation>Пасля ўводу колькі знакаў прапаноўваць дапаўненні</translation>
     </message>
@@ -3297,87 +3423,102 @@
         <translation>Ствараць няісныя файлы без пытанняў</translation>
     </message>
     <message>
-        <location line="+57"/>
+        <location line="+31"/>
         <source>command line (%f=file, %l=line):</source>
         <translation>Загад (%f=файл, %l-радок):</translation>
     </message>
     <message>
-        <location line="+10"/>
-        <source>emacs</source>
-        <translation>emacs</translation>
-    </message>
-    <message>
-        <location line="+67"/>
-        <source>Terminal</source>
-        <translation>Тэрмінал</translation>
-    </message>
-    <message>
-        <location line="+15"/>
-        <source>Cursor type:</source>
-        <translation>Тып курсора:</translation>
-    </message>
-    <message>
-        <location line="+23"/>
-        <source>Cursor blinking</source>
-        <translation>Мігценне курсора</translation>
-    </message>
-    <message>
-        <location line="+7"/>
-        <source>Use foreground color</source>
-        <translation>Выкар. колер пярэдняга плану</translation>
-    </message>
-    <message>
         <location line="+94"/>
+        <source>Terminal</source>
+        <translation>Тэрмінал</translation>
+    </message>
+    <message>
+        <location line="+45"/>
+        <source>Cursor type:</source>
+        <translation>Тып курсора:</translation>
+    </message>
+    <message>
+        <location line="-11"/>
+        <source>Cursor blinking</source>
+        <translation>Мігценне курсора</translation>
+    </message>
+    <message>
+        <location line="-7"/>
+        <source>Use foreground color</source>
+        <translation>Выкар. колер пярэдняга плану</translation>
+    </message>
+    <message>
+        <location line="+53"/>
         <source>Font size</source>
         <translation>Памер шрыфту</translation>
     </message>
     <message>
-        <location line="+35"/>
+        <location line="+99"/>
+        <source>Set focus to terminal when running a command from within another widget</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+34"/>
         <source>File Browser</source>
         <translation>Файлавы агляднік</translation>
     </message>
     <message>
-        <location line="+6"/>
+        <location line="+46"/>
         <source>Show file size</source>
         <translation>Паказваць памеры файлаў</translation>
     </message>
     <message>
-        <location line="+7"/>
+        <location line="-14"/>
         <source>Show file type</source>
         <translation>Паказваць тыпы файлаў</translation>
     </message>
     <message>
-        <location line="+7"/>
-        <source>Show date of last modification</source>
-        <translation>Паказваць дату апошняга змянення</translation>
-    </message>
-    <message>
-        <location line="+7"/>
-        <source>Show hidden files</source>
-        <translation>Паказваць схаваныя файлы</translation>
-    </message>
-    <message>
-        <location line="+14"/>
-        <source>Alternating row colors</source>
-        <translation>Колеры радкоў чаргуюцца</translation>
-    </message>
-    <message>
         <location line="+21"/>
+        <source>Show date of last modification</source>
+        <translation>Паказваць дату апошняга змянення</translation>
+    </message>
+    <message>
+        <location line="-14"/>
+        <source>Show hidden files</source>
+        <translation>Паказваць схаваныя файлы</translation>
+    </message>
+    <message>
+        <location line="-18"/>
+        <source>Display</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+39"/>
+        <source>Alternating row colors</source>
+        <translation>Колеры радкоў чаргуюцца</translation>
+    </message>
+    <message>
+        <location line="+12"/>
+        <source>Behavior</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+27"/>
+        <source>Restore last directory of previous session</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+65"/>
         <source>Workspace</source>
         <translation>Прастора зменных</translation>
     </message>
     <message>
-        <location line="+30"/>
+        <location line="+38"/>
         <source>Storage Class Colors</source>
         <translation>Колеры класаў памяці</translation>
     </message>
     <message>
-        <location line="+35"/>
+        <location line="+40"/>
         <source>Network</source>
         <translation>Сетка</translation>
     </message>
     <message>
-        <location line="+8"/>
+        <location line="+23"/>
         <source>Allow Octave to connect to the Octave web site to display current news and information</source>
         <translation>Дазволіць Octave злучацца з вэб-сайтам Octave для адлюстравання навінаў і свежай інфармацыі</translation>
     </message>
@@ -3392,27 +3533,27 @@
         <translation>HttpProxy</translation>
     </message>
     <message>
-        <location line="-1129"/>
+        <location line="-1356"/>
         <source>Icon set for dock widgets</source>
         <translation>Набор значкоў для віджэтаў</translation>
     </message>
     <message>
-        <location line="+7"/>
+        <location line="-48"/>
         <source>Language (requires restart)</source>
         <translation>Мова (патрэбны перазапуск)</translation>
     </message>
     <message>
-        <location line="+7"/>
+        <location line="-122"/>
         <source>Icon size</source>
         <translation>Памер значкоў</translation>
     </message>
     <message>
-        <location line="+991"/>
+        <location line="+1318"/>
         <source>Synchronize Octave working directory with file browser</source>
         <translation>Сінхранізаваць дзейны каталог Octave з файлавым агляднікам</translation>
     </message>
     <message>
-        <location line="+129"/>
+        <location line="+213"/>
         <source>Socks5Proxy</source>
         <translation>Socks5Proxy</translation>
     </message>
@@ -3442,9 +3583,9 @@
         <translation>Пароль:</translation>
     </message>
     <message>
-        <location filename="../src/settings-dialog.cc" line="+71"/>
+        <location filename="../src/settings-dialog.cc" line="+74"/>
         <location line="+4"/>
-        <location line="+389"/>
+        <location line="+437"/>
         <source>System setting</source>
         <translation>Сістэмная</translation>
     </message>
@@ -3491,6 +3632,16 @@
         <comment>short form for underlined</comment>
         <translation>п</translation>
     </message>
+    <message>
+        <location line="+419"/>
+        <source>Set Octave Startup Directory</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+6"/>
+        <source>Set File Browser Startup Directory</source>
+        <translation type="unfinished"></translation>
+    </message>
 </context>
 <context>
     <name>setup_community_news</name>
@@ -3558,7 +3709,7 @@
 <context>
     <name>webinfo</name>
     <message>
-        <location filename="../src/qtinfo/webinfo.cc" line="+80"/>
+        <location filename="../src/qtinfo/webinfo.cc" line="+83"/>
         <source>Type here and press &apos;Return&apos; to search</source>
         <translation>Для пошуку ўвядзіце тут штосьці і націсніце Enter</translation>
     </message>
@@ -3567,6 +3718,16 @@
         <source>Global search</source>
         <translation>Глабальны пошук</translation>
     </message>
+    <message>
+        <location line="+22"/>
+        <source>Error</source>
+        <translation type="unfinished">Памылкі</translation>
+    </message>
+    <message>
+        <location line="+3"/>
+        <source>The info file %1 does not exist</source>
+        <translation type="unfinished"></translation>
+    </message>
 </context>
 <context>
     <name>welcome_wizard</name>
@@ -3600,8 +3761,8 @@
     </message>
     <message>
         <location line="+1"/>
-        <source>Storage Class</source>
-        <translation>Клас памяці</translation>
+        <source>Attribute</source>
+        <translation type="unfinished"></translation>
     </message>
     <message>
         <location line="+109"/>
@@ -3649,8 +3810,8 @@
     </message>
     <message>
         <location line="+1"/>
-        <source>Colors for the storage class:</source>
-        <translation>Колеры для класаў памяці:</translation>
+        <source>Colors for variable attributes:</source>
+        <translation type="unfinished"></translation>
     </message>
 </context>
 </TS>
--- a/libgui/languages/de_DE.ts	Fri Feb 06 08:31:09 2015 -0800
+++ b/libgui/languages/de_DE.ts	Fri Feb 06 08:31:49 2015 -0800
@@ -62,7 +62,7 @@
         <translation>Cursor</translation>
     </message>
     <message>
-        <location filename="../src/main-window.cc" line="+1900"/>
+        <location filename="../src/main-window.cc" line="+1963"/>
         <source>&lt;p&gt;&lt;strong&gt;A Note about Octave&apos;s New GUI&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;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.  But because it is not quite as polished as we would like, we have decided to wait until the 4.0.x release series before making the GUI the default interface.&lt;/p&gt;&lt;p&gt;Given the length of time and the number of bug fixes and improvements since the last major release, we also decided against delaying the release of all these new improvements any longer just to perfect the GUI.  So please enjoy the 3.8 release of Octave and the preview of the new GUI.  We believe it is working reasonably well, but we also know that there are some obvious rough spots and many things that could be improved.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;We Need Your Help&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;There are many ways that you can help us fix the remaining problems, complete the GUI, and improve the overall user experience for both novices and experts alike (links will open an external browser):&lt;/p&gt;&lt;p&gt;&lt;ul&gt;&lt;li&gt;If you are a skilled software developer, you can help by contributing your time to help &lt;a href=&quot;http://octave.org/get-involved.html&quot;&gt;develop Octave&lt;/a&gt;.&lt;/li&gt;&lt;li&gt;If Octave does not work properly, you are encouraged to &lt;a href=&quot;http://octave.org/bugs.html&quot;&gt;report problems &lt;/a&gt; that you find.&lt;/li&gt;&lt;li&gt;Whether you are a user or developer, you can &lt;a href=&quot;http://octave.org/donate.html&quot;&gt;help to fund the project&lt;/a&gt;.  Octave development takes a lot of time and expertise.  Your contributions help to ensure that Octave will continue to improve.&lt;/li&gt;&lt;/ul&gt;&lt;/p&gt;&lt;p&gt;We hope you find Octave to be useful.  Please help us make it even better for the future!&lt;/p&gt;</source>
         <translation>&lt;p&gt;&lt;strong&gt;Einige Hinweise zur neuen Octave GUI&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;Eine der größten Neuerungen von Octave 3.8 ist die grafische Benutzerschnittstelle (GUI).  Sie ist das, worum die Nutzer in den letzten Jahren am häufigsten gebeten haben, und nun ist sie fast fertig.  Aber weil noch der Feinschliff fehlt, haben wir beschlossen, mit der GUI als Standard-Benutzerschnittstelle auf die 4.0.x Veröffentlichungen zu warten.&lt;/p&gt;&lt;p&gt;In Anbetracht der vergangenen Zeit, der Anzahl der behobenen Fehler und den Verbesserungen seit der letzten Veröffentlichung haben wir uns dazu entschieden, die nächste Veröffentlichung nicht weiter zu verzögern, nur um die GUI zu perfektionieren.  Daher wünschen wir viel Spaß mit der Version 3.8 von Octave und der Vorschau auf die neue GUI.  Wir sind der Meinung, dass sie schon ziemlich gut funktioniert, obwohl uns bewusst ist, dass es noch einige Ecken und Kanten sowie viele Dinge zu verbessern gibt.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Deshalb brauchen wir Deine Mithilfe!&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;Es gibt viele Möglichkeiten uns zu helfen die verbleibenden Probleme zu beheben, die GUI weiter zu entwickeln und die Benutzererfahrung für Neulinge und Experten gleichermaßen zu verbessern (Links öffnen im externen Browser):&lt;/p&gt;&lt;p&gt;&lt;ul&gt;&lt;li&gt;Falls Du ein geschickter Software-Entwickler bist, kannst du helfen, indem du dich an der &lt;a href=&quot;http://octave.org/get-involved.html&quot;&gt;Weiterentwicklung von Octave&lt;/a&gt; beteiligst.&lt;/li&gt;&lt;li&gt;Sollte Octave einmal nicht wie erwartet funktionieren, solltest Du das gefundene &lt;a href=&quot;http://octave.org/bugs.html&quot;&gt;Problem melden&lt;/a&gt;.&lt;/li&gt;&lt;li&gt;Egal, ob Du Anwender oder Entwickler bist, kannst du &lt;a href=&quot;http://octave.org/donate.html&quot;&gt;helfen, das Projekt zu finanzieren&lt;/a&gt;.  Die Weiterentwicklung von Octave braucht viel Zeit und Sachverstand.  Dein Beitrag hilft sicherzustellen, dass Octave weiter verbessert wird.&lt;/li&gt;&lt;/ul&gt;&lt;/p&gt;&lt;p&gt;Wir hoffen, dass du Octave nützlich findest.  Bitte hilf uns Octave zukünftig noch besser zu machen!&lt;/p&gt;</translation>
     </message>
@@ -88,7 +88,7 @@
 <context>
     <name>QWinTerminalImpl</name>
     <message>
-        <location filename="../qterminal/libqterminal/win32/QWinTerminalImpl.cpp" line="+1536"/>
+        <location filename="../qterminal/libqterminal/win32/QWinTerminalImpl.cpp" line="+1539"/>
         <source>copied selection to clipboard</source>
         <translation>Auswahl in die Zwischenablage kopiert</translation>
     </message>
@@ -144,17 +144,12 @@
 ist im Editor bereits geöffnet</translation>
     </message>
     <message>
-        <location line="+255"/>
+        <location line="+268"/>
         <source>&amp;%1 %2</source>
         <translation>&amp;%1 %2</translation>
     </message>
     <message>
-        <location line="+175"/>
-        <source>&amp;New File</source>
-        <translation>&amp;Neue Datei</translation>
-    </message>
-    <message>
-        <location line="+6"/>
+        <location line="+207"/>
         <source>&amp;Save File</source>
         <translation>Datei &amp;speichern</translation>
     </message>
@@ -164,7 +159,12 @@
         <translation>Datei &amp;Öffnen...</translation>
     </message>
     <message>
-        <location line="+6"/>
+        <location line="-3"/>
+        <source>&amp;New Script</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+9"/>
         <source>Save File &amp;As...</source>
         <translation>Datei speichern &amp;als...</translation>
     </message>
@@ -250,6 +250,16 @@
     </message>
     <message>
         <location line="+3"/>
+        <source>&amp;Indent</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+2"/>
+        <source>&amp;Unindent</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+3"/>
         <source>&amp;Find and Replace...</source>
         <translation>&amp;Suchen und Ersetzen...</translation>
     </message>
@@ -264,7 +274,7 @@
         <translation>&amp;Gehe zu Zeile...</translation>
     </message>
     <message>
-        <location line="+55"/>
+        <location line="+57"/>
         <source>&amp;Recent Editor Files</source>
         <translation>&amp;Zuletzt bearbeitete Dateien</translation>
     </message>
@@ -289,7 +299,7 @@
         <translation>Andere Dokumente schließen</translation>
     </message>
     <message>
-        <location line="+31"/>
+        <location line="+34"/>
         <source>&amp;Preferences...</source>
         <translation>&amp;Einstellungen...</translation>
     </message>
@@ -319,7 +329,7 @@
         <translation>&amp;Dokumentation zum Schlüsselwort</translation>
     </message>
     <message>
-        <location line="-741"/>
+        <location line="-790"/>
         <source>Could not open file
 %1
 for read: %2.</source>
@@ -353,7 +363,7 @@
         <translation>Der zugehörige Editor-Reiter ist nicht mehr vorhanden.</translation>
     </message>
     <message>
-        <location line="+521"/>
+        <location line="+567"/>
         <source>&amp;File</source>
         <translation>&amp;Datei</translation>
     </message>
@@ -368,7 +378,7 @@
         <translation>&amp;Bearbeiten</translation>
     </message>
     <message>
-        <location line="+30"/>
+        <location line="+33"/>
         <source>&amp;Debug</source>
         <translation>&amp;Debuggen</translation>
     </message>
@@ -381,7 +391,7 @@
 <context>
     <name>file_editor_tab</name>
     <message>
-        <location filename="../src/m-editor/file-editor-tab.cc" line="+803"/>
+        <location filename="../src/m-editor/file-editor-tab.cc" line="+824"/>
         <source>Goto line</source>
         <translation>Gehe zu Zeile</translation>
     </message>
@@ -391,7 +401,7 @@
         <translation>Zeilennummer</translation>
     </message>
     <message>
-        <location line="+71"/>
+        <location line="+108"/>
         <location line="+69"/>
         <source>&lt;unnamed&gt;</source>
         <translation>&lt;unbenannt&gt;</translation>
@@ -408,14 +418,15 @@
     </message>
     <message>
         <location line="+10"/>
-        <location line="+122"/>
-        <location line="+150"/>
+        <location line="+123"/>
+        <location line="+112"/>
+        <location line="+69"/>
         <location line="+22"/>
         <source>Octave Editor</source>
         <translation>Octave Editor</translation>
     </message>
     <message>
-        <location line="-293"/>
+        <location line="-325"/>
         <source>The file
 %1
 is about to be closed but has been modified.
@@ -426,12 +437,12 @@
 %2</translation>
     </message>
     <message>
-        <location line="+201"/>
+        <location line="+203"/>
         <source>Octave Files (*.m);;All Files (*)</source>
         <translation>Octave Dateien (*.m);;All Files (*)</translation>
     </message>
     <message>
-        <location line="+86"/>
+        <location line="+116"/>
         <source>
 
 Warning: The contents in the editor is modified!</source>
@@ -447,14 +458,14 @@
 wurde gelöscht oder umbenannt. Soll die Datei jetzt gespeichert werden?%2</translation>
     </message>
     <message>
-        <location line="-172"/>
+        <location line="-203"/>
         <source>Could not open file %1 for write:
 %2.</source>
         <translation>Die Datei %1  konnte nicht zum Schreiben geöffnet werden:
 %2.</translation>
     </message>
     <message>
-        <location line="-975"/>
+        <location line="-1032"/>
         <source>Line:</source>
         <translation>Zeile:</translation>
     </message>
@@ -464,7 +475,18 @@
         <translation>Spalte:</translation>
     </message>
     <message>
-        <location line="+1122"/>
+        <location line="+1141"/>
+        <source>&quot;%1&quot;
+is not a valid identifier.
+
+If you keep this file name, you will not be able to
+call your script using its name as an Octave command.
+
+Do you want to choose another name?</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+69"/>
         <source>It seems that &apos;%1&apos; has been modified by another application. Do you want to reload it?</source>
         <translation>Die Datei %1 wurde von einer anderen Anwendung verändert. Soll der neue Inhalt geladen werden?</translation>
     </message>
@@ -497,7 +519,12 @@
         <translation>Aktionen mit aktuellem Verzeichnis</translation>
     </message>
     <message>
-        <location line="+373"/>
+        <location line="+15"/>
+        <source>Set Browser Directory...</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+379"/>
         <source>Find Files...</source>
         <translation>Dateien suchen...</translation>
     </message>
@@ -508,16 +535,17 @@
     </message>
     <message>
         <location line="+3"/>
+        <location line="+333"/>
         <source>New Directory</source>
         <translation>Neues Verzeichnis</translation>
     </message>
     <message>
-        <location line="-323"/>
+        <location line="-656"/>
         <source>Double-click a file to open it</source>
         <translation>Doppelklick auf eine Datei um diese zu öffnen</translation>
     </message>
     <message>
-        <location line="-79"/>
+        <location line="-100"/>
         <source>Show Octave directory</source>
         <translation>Aktuelles Octave Verzeichnis anzeigen</translation>
     </message>
@@ -542,7 +570,7 @@
         <translation>Wechsle zum Heimatverzeichnis</translation>
     </message>
     <message>
-        <location line="+12"/>
+        <location line="+16"/>
         <source>Search Directory...</source>
         <translation>Verzeichnis suchen...</translation>
     </message>
@@ -563,7 +591,7 @@
         <translation>Neues Verzeichnis...</translation>
     </message>
     <message>
-        <location line="+276"/>
+        <location line="+297"/>
         <source>File size</source>
         <translation>Dateigröße</translation>
     </message>
@@ -677,7 +705,12 @@
 </translation>
     </message>
     <message>
-        <location line="+17"/>
+        <location line="+1"/>
+        <source>New File.txt</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+16"/>
         <source>Create Directory</source>
         <translation>Neues Verzeichnis</translation>
     </message>
@@ -756,7 +789,12 @@
 <context>
     <name>find_dialog</name>
     <message>
-        <location filename="../src/m-editor/find-dialog.cc" line="+77"/>
+        <location filename="../src/m-editor/find-dialog.cc" line="+74"/>
+        <source>Find and Replace</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+3"/>
         <source>Find &amp;what:</source>
         <translation>&amp;Suche:</translation>
     </message>
@@ -826,7 +864,7 @@
         <translation>In Auswah&amp;l suchen</translation>
     </message>
     <message>
-        <location line="+71"/>
+        <location line="+72"/>
         <source>Search from end</source>
         <translation>Vom Ende suchen</translation>
     </message>
@@ -836,7 +874,7 @@
         <translation>Suche vom Beginn</translation>
     </message>
     <message>
-        <location line="+121"/>
+        <location line="+119"/>
         <source>Replace Result</source>
         <translation>Ergebins der Ersetzungen</translation>
     </message>
@@ -846,7 +884,7 @@
         <translation>%1 Vorkommnisse ersetzt</translation>
     </message>
     <message>
-        <location line="+10"/>
+        <location line="+12"/>
         <source>Find Result</source>
         <translation>Suchergebnis</translation>
     </message>
@@ -869,12 +907,7 @@
         <translation>Name:</translation>
     </message>
     <message>
-        <location line="+2"/>
-        <source>Enter the filename expression</source>
-        <translation>Eingabe eines Ausdrucks für den Dateinamen</translation>
-    </message>
-    <message>
-        <location line="+6"/>
+        <location line="+8"/>
         <source>Start in:</source>
         <translation>Beginne in:</translation>
     </message>
@@ -894,22 +927,12 @@
         <translation>Suche Startverzeichnis</translation>
     </message>
     <message>
-        <location line="+3"/>
-        <source>Recurse directories</source>
-        <translation>Unterverzeichnisse durchsuchen</translation>
-    </message>
-    <message>
-        <location line="+4"/>
+        <location line="+7"/>
         <source>Search recursively through directories for matching files</source>
         <translation>Rekursive Dateisuche durch Unterverzeichnisse</translation>
     </message>
     <message>
-        <location line="+2"/>
-        <source>Include directories</source>
-        <translation>Verzeichnisse einbeziehen</translation>
-    </message>
-    <message>
-        <location line="+4"/>
+        <location line="+6"/>
         <source>Include matching directories in search results</source>
         <translation>Auch Verzeichnisse berücksichtigen, die die Suchanfrage erfüllen</translation>
     </message>
@@ -929,9 +952,24 @@
         <translation>In Datei vorkommender Text:</translation>
     </message>
     <message>
-        <location line="+1"/>
-        <source>Search must match text</source>
-        <translation>Suche Dateien mit übereinstimmendem Text</translation>
+        <location line="-35"/>
+        <source>Enter the filename search expression</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+18"/>
+        <source>Search subdirectories</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+6"/>
+        <source>Include directory names</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+12"/>
+        <source>Enter the file content search expression</source>
+        <translation type="unfinished"></translation>
     </message>
     <message>
         <location line="+5"/>
@@ -994,7 +1032,12 @@
         <translation>Suche...</translation>
     </message>
     <message>
-        <location line="+32"/>
+        <location line="+23"/>
+        <source>%1 match(es)</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+9"/>
         <source>Set search directory</source>
         <translation>Suchverzeichnis setzen</translation>
     </message>
@@ -1084,13 +1127,13 @@
 <context>
     <name>main_window</name>
     <message>
-        <location filename="../src/main-window.cc" line="-1696"/>
+        <location filename="../src/main-window.cc" line="-1758"/>
         <source>Load Workspace</source>
         <translation>Lade Arbeitsumgebung</translation>
     </message>
     <message>
-        <location line="+645"/>
-        <location line="+876"/>
+        <location line="+678"/>
+        <location line="+905"/>
         <source>About Octave</source>
         <translation>Über Octave</translation>
     </message>
@@ -1105,12 +1148,7 @@
         <translation>Neu</translation>
     </message>
     <message>
-        <location line="+4"/>
-        <source>Script</source>
-        <translation>Skript</translation>
-    </message>
-    <message>
-        <location line="+7"/>
+        <location line="+11"/>
         <source>Figure</source>
         <translation>Abbildung</translation>
     </message>
@@ -1150,12 +1188,23 @@
         <translation>Einfügen</translation>
     </message>
     <message>
-        <location line="-1265"/>
+        <location line="-1327"/>
         <source>Save Workspace As</source>
         <translation>Arbeitsumgebung speichern als</translation>
     </message>
     <message>
-        <location line="+124"/>
+        <location line="+84"/>
+        <source>The file %1
+can not be executed because its name
+is not a valid identifier.
+
+Do you want to execute
+%2
+instead?</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+73"/>
         <source>The release notes file &apos;%1&apos; is empty.</source>
         <translation>Die Datei &apos;%1&apos; mit Versionshinweisen ist leer.</translation>
     </message>
@@ -1175,7 +1224,7 @@
         <translation>Neuigkeiten aus der Octave Community</translation>
     </message>
     <message>
-        <location line="+939"/>
+        <location line="+968"/>
         <source>Clear Clipboard</source>
         <translation>Zwischenablage leeren</translation>
     </message>
@@ -1240,7 +1289,12 @@
         <translation>Hineinspringen</translation>
     </message>
     <message>
-        <location line="-151"/>
+        <location line="-1311"/>
+        <source>Octave</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+1160"/>
         <source>Load Workspace...</source>
         <translation>Lade Arbeitsumgebung...</translation>
     </message>
@@ -1250,7 +1304,12 @@
         <translation>Arbeitsumgebung speichern als...</translation>
     </message>
     <message>
-        <location line="+41"/>
+        <location line="+38"/>
+        <source>New Script</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+3"/>
         <source>Function...</source>
         <translation>Funktion...</translation>
     </message>
@@ -1341,8 +1400,8 @@
         <translation>Ein Verzeichnis höher</translation>
     </message>
     <message>
-        <location line="-1283"/>
-        <location line="+1286"/>
+        <location line="-1312"/>
+        <location line="+1315"/>
         <source>Browse directories</source>
         <translation>Verzeichnis suchen</translation>
     </message>
@@ -1416,7 +1475,7 @@
 <context>
     <name>news_reader</name>
     <message>
-        <location line="-1282"/>
+        <location line="-1311"/>
         <source>&lt;html&gt;
 &lt;body&gt;
 &lt;p&gt;
@@ -1475,18 +1534,18 @@
 <context>
     <name>octave_dock_widget</name>
     <message>
-        <location filename="../src/octave-dock-widget.cc" line="+61"/>
-        <location line="+163"/>
+        <location filename="../src/octave-dock-widget.cc" line="+60"/>
+        <location line="+170"/>
         <source>Undock widget</source>
         <translation>Fenster lösen</translation>
     </message>
     <message>
-        <location line="-153"/>
+        <location line="-160"/>
         <source>Hide widget</source>
         <translation>Fenster verbergen</translation>
     </message>
     <message>
-        <location line="+104"/>
+        <location line="+107"/>
         <source>Dock widget</source>
         <translation>Fenster andocken</translation>
     </message>
@@ -1517,7 +1576,7 @@
 <context>
     <name>octave_qt_link</name>
     <message>
-        <location filename="../src/octave-qt-link.cc" line="+94"/>
+        <location filename="../src/octave-qt-link.cc" line="+97"/>
         <location line="+6"/>
         <location line="+7"/>
         <source>Yes</source>
@@ -1544,13 +1603,13 @@
     </message>
     <message>
         <location line="+211"/>
-        <source>The file %1 does not exist in the load path.  To debug the function you are editing, you must either change to the directory %2 or add that directory to the load path.</source>
-        <translation>Die Datei %1 exisitiert nicht im Suchpfad. Um die editierte Funktion zu debuggen, muss entweder in das Verzeichnis %2 gewechselt werden oder dieses Verzeichnis dem Suchpfad hinzugefügt werden.</translation>
+        <source>The file %1 does not exist in the load path.  To run or debug the function you are editing, you must either change to the directory %2 or add that directory to the load path.</source>
+        <translation type="unfinished"></translation>
     </message>
     <message>
         <location line="+1"/>
-        <source>The file %1 is shadowed by a file with the same name in the load path.  To debug the function you are editing, change to the directory %2.</source>
-        <translation>Die Datei %1 wird von einer gleichnamigen Datei im Suchpfad überdeckt. Um die editierte Funktion zu debuggen, muss in das Verzeichnis %2 gewechselt werden.</translation>
+        <source>The file %1 is shadowed by a file with the same name in the load path. To run or debug the function you are editing, change to the directory %2.</source>
+        <translation type="unfinished"></translation>
     </message>
     <message>
         <location line="+2"/>
@@ -1601,17 +1660,17 @@
 <context>
     <name>settings_dialog</name>
     <message>
-        <location filename="../src/settings-dialog.ui" line="+29"/>
+        <location filename="../src/settings-dialog.ui" line="+23"/>
         <source>Settings</source>
         <translation>Einstellungen</translation>
     </message>
     <message>
-        <location line="+13"/>
+        <location line="+19"/>
         <source>General</source>
         <translation>Allgemein</translation>
     </message>
     <message>
-        <location line="+97"/>
+        <location line="+191"/>
         <source>Octave logo only</source>
         <translation>Nur Octave Logo</translation>
     </message>
@@ -1621,17 +1680,37 @@
         <translation>Icons mit Buchstaben</translation>
     </message>
     <message>
-        <location line="+46"/>
+        <location line="-172"/>
+        <source>Dock widget title bar</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+40"/>
+        <source>Custom style</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+26"/>
+        <source>Background color</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+29"/>
+        <source>Text color</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+212"/>
         <source>Editor</source>
         <translation>Editor</translation>
     </message>
     <message>
-        <location line="+71"/>
+        <location line="+102"/>
         <source>Color</source>
         <translation>Farbe</translation>
     </message>
     <message>
-        <location line="+120"/>
+        <location line="+170"/>
         <source>Indent width</source>
         <translation>Einrücken um</translation>
     </message>
@@ -1641,7 +1720,7 @@
         <translation>Tabulator rückt ein</translation>
     </message>
     <message>
-        <location line="+7"/>
+        <location line="+23"/>
         <source>Auto indentation</source>
         <translation>Auto Einrückung</translation>
     </message>
@@ -1686,67 +1765,114 @@
         <translation>Editor Dateien der letzten Sitzung wiederherstellen</translation>
     </message>
     <message>
-        <location line="+60"/>
+        <location line="+34"/>
         <source>Use custom file editor</source>
         <translation>Externen Editor verwenden</translation>
     </message>
     <message>
-        <location line="+32"/>
+        <location line="+20"/>
+        <source>emacs +%l %f </source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+35"/>
         <source>Editor Styles</source>
         <translation>Editor Stile</translation>
     </message>
     <message>
-        <location line="+24"/>
+        <location line="+17"/>
         <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Select font, font size (as a difference from the default size), font style (&lt;b&gt;b&lt;/b&gt;old, &lt;b&gt;i&lt;/b&gt;talic, &lt;b&gt;u&lt;/b&gt;nderline), text color and background color (for the latter, the color pink (255,0,255) is a placeholder for the default background color).&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
         <translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Auswahl von Schrift, Schriftgröße (als Differenz von der Standardgröße), Schriftstil (&lt;b&gt;f&lt;/b&gt;ett, &lt;b&gt;k&lt;/b&gt;ursiv, &lt;b&gt;u&lt;/b&gt;nterstrichen), Text- und Hintergrundfarbe (für den Hintergrund ist die Farbe Pink (255,0,255) ein Platzhalter für die Standardfarbe)&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
     </message>
     <message>
-        <location line="+108"/>
+        <location line="+191"/>
         <source>Terminal Colors</source>
         <translation>Farben des Befehlsfensters</translation>
     </message>
     <message>
-        <location line="+45"/>
+        <location line="-100"/>
         <source>Font</source>
         <translation>Schriftart</translation>
     </message>
     <message>
-        <location line="-757"/>
+        <location line="-770"/>
         <source>Show line numbers</source>
         <translation>Zeilennummern anzeigen</translation>
     </message>
     <message>
-        <location line="+27"/>
+        <location line="+46"/>
         <source>Highlight current line</source>
         <translation>Aktuelle Zeile hervorheben</translation>
     </message>
     <message>
-        <location line="+262"/>
+        <location line="+328"/>
         <source>Code completion</source>
         <translation>Vervollständigung</translation>
     </message>
     <message>
-        <location line="-282"/>
+        <location line="-361"/>
         <source>Show complete path in window title</source>
         <translation>Kompletten Pfad im Reiter anzeigen</translation>
     </message>
     <message>
-        <location line="-72"/>
+        <location line="-366"/>
+        <source>Interface</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+187"/>
         <source>Graphic icons</source>
         <translation>Grafische Icons</translation>
     </message>
     <message>
-        <location line="+55"/>
+        <location line="+34"/>
+        <source>Octave Startup</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+6"/>
+        <source>These preferences are applied after the startup files like .octaverc.</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+35"/>
+        <location line="+1104"/>
+        <source>Startup path</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="-1091"/>
+        <location line="+1108"/>
+        <source>Browse</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="-1101"/>
+        <source>Restore last Octave directory of previous session</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+61"/>
         <source>Show whitespace</source>
         <translation>Leerzeichen anzeigen</translation>
     </message>
     <message>
-        <location line="+27"/>
+        <location line="+33"/>
         <source>Do not show whitespace used for indentation</source>
         <translation>Leerzeichen der Einrückung nicht anzeigen</translation>
     </message>
     <message>
-        <location line="+290"/>
+        <location line="+120"/>
+        <source>Tab width min.</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+52"/>
+        <source>max.</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+197"/>
         <source># of characters typed before completion list displayed</source>
         <translation>Anzahl der eingegebenen Zeichen bis Vervollständigungsliste</translation>
     </message>
@@ -1756,87 +1882,102 @@
         <translation>Nicht existierende Dateien ohne Nachfrage anlegen</translation>
     </message>
     <message>
-        <location line="+57"/>
+        <location line="+31"/>
         <source>command line (%f=file, %l=line):</source>
         <translation>Kommandozeile (%f=Datei, %l=Zeile):</translation>
     </message>
     <message>
-        <location line="+10"/>
-        <source>emacs</source>
-        <translation>emacs</translation>
-    </message>
-    <message>
-        <location line="+67"/>
+        <location line="+94"/>
         <source>Terminal</source>
         <translation>Befehlsfenster</translation>
     </message>
     <message>
-        <location line="+15"/>
+        <location line="+45"/>
         <source>Cursor type:</source>
         <translation>Cursortyp:</translation>
     </message>
     <message>
-        <location line="+23"/>
+        <location line="-11"/>
         <source>Cursor blinking</source>
         <translation>Blinkender Cursor</translation>
     </message>
     <message>
-        <location line="+7"/>
+        <location line="-7"/>
         <source>Use foreground color</source>
         <translation>Vordergrundfarbe verwenden</translation>
     </message>
     <message>
-        <location line="+94"/>
+        <location line="+53"/>
         <source>Font size</source>
         <translation>Schriftgröße</translation>
     </message>
     <message>
-        <location line="+35"/>
+        <location line="+99"/>
+        <source>Set focus to terminal when running a command from within another widget</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+34"/>
         <source>File Browser</source>
         <translation>Dateibrowser</translation>
     </message>
     <message>
-        <location line="+6"/>
+        <location line="+46"/>
         <source>Show file size</source>
         <translation>Dateigröße anzeigen</translation>
     </message>
     <message>
-        <location line="+7"/>
+        <location line="-14"/>
         <source>Show file type</source>
         <translation>Dateityp anzeigen</translation>
     </message>
     <message>
-        <location line="+7"/>
+        <location line="+21"/>
         <source>Show date of last modification</source>
         <translation>Datum der letzten Änderung anzeigen</translation>
     </message>
     <message>
-        <location line="+7"/>
+        <location line="-14"/>
         <source>Show hidden files</source>
         <translation>Versteckte Dateien anzeigen</translation>
     </message>
     <message>
-        <location line="+14"/>
+        <location line="-18"/>
+        <source>Display</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+39"/>
         <source>Alternating row colors</source>
         <translation>Alternierende Farben für die Zeilen verwenden</translation>
     </message>
     <message>
-        <location line="+21"/>
+        <location line="+12"/>
+        <source>Behavior</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+27"/>
+        <source>Restore last directory of previous session</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+65"/>
         <source>Workspace</source>
         <translation>Arbeitsumgebung</translation>
     </message>
     <message>
-        <location line="+30"/>
+        <location line="+38"/>
         <source>Storage Class Colors</source>
         <translation>Farben der Speicherklassen festlegen</translation>
     </message>
     <message>
-        <location line="+35"/>
+        <location line="+40"/>
         <source>Network</source>
         <translation>Netzwerk</translation>
     </message>
     <message>
-        <location line="+8"/>
+        <location line="+23"/>
         <source>Allow Octave to connect to the Octave web site to display current news and information</source>
         <translation>Octave erlauben Neuigkeiten und Informationen von der Octave Webseite anzuzeigen</translation>
     </message>
@@ -1851,27 +1992,27 @@
         <translation>HTTP Proxy</translation>
     </message>
     <message>
-        <location line="-1129"/>
+        <location line="-1356"/>
         <source>Icon set for dock widgets</source>
         <translation>Icons der Unterfenster</translation>
     </message>
     <message>
-        <location line="+7"/>
+        <location line="-48"/>
         <source>Language (requires restart)</source>
         <translation>Sprache (Neustart erforderlich)</translation>
     </message>
     <message>
-        <location line="+7"/>
+        <location line="-122"/>
         <source>Icon size</source>
         <translation>Icongröße</translation>
     </message>
     <message>
-        <location line="+991"/>
+        <location line="+1318"/>
         <source>Synchronize Octave working directory with file browser</source>
         <translation>Octave Arbeitsverzeichnis und Dateibrowser synchronisieren</translation>
     </message>
     <message>
-        <location line="+129"/>
+        <location line="+213"/>
         <source>Socks5Proxy</source>
         <translation>Socks5Proxy</translation>
     </message>
@@ -1901,9 +2042,9 @@
         <translation>Passwort:</translation>
     </message>
     <message>
-        <location filename="../src/settings-dialog.cc" line="+71"/>
+        <location filename="../src/settings-dialog.cc" line="+74"/>
         <location line="+4"/>
-        <location line="+389"/>
+        <location line="+437"/>
         <source>System setting</source>
         <translation>Systemeinstellung</translation>
     </message>
@@ -1950,6 +2091,16 @@
         <comment>short form for underlined</comment>
         <translation>u</translation>
     </message>
+    <message>
+        <location line="+419"/>
+        <source>Set Octave Startup Directory</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+6"/>
+        <source>Set File Browser Startup Directory</source>
+        <translation type="unfinished"></translation>
+    </message>
 </context>
 <context>
     <name>setup_community_news</name>
@@ -2017,7 +2168,7 @@
 <context>
     <name>webinfo</name>
     <message>
-        <location filename="../src/qtinfo/webinfo.cc" line="+80"/>
+        <location filename="../src/qtinfo/webinfo.cc" line="+83"/>
         <source>Type here and press &apos;Return&apos; to search</source>
         <translation>Suchbegriff eingeben und mit &apos;Enter&apos; die Suche starten</translation>
     </message>
@@ -2026,6 +2177,16 @@
         <source>Global search</source>
         <translation>Globale Suche</translation>
     </message>
+    <message>
+        <location line="+22"/>
+        <source>Error</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+3"/>
+        <source>The info file %1 does not exist</source>
+        <translation type="unfinished"></translation>
+    </message>
 </context>
 <context>
     <name>welcome_wizard</name>
@@ -2059,8 +2220,8 @@
     </message>
     <message>
         <location line="+1"/>
-        <source>Storage Class</source>
-        <translation>Speicherklasse</translation>
+        <source>Attribute</source>
+        <translation type="unfinished"></translation>
     </message>
     <message>
         <location line="+109"/>
@@ -2108,8 +2269,8 @@
     </message>
     <message>
         <location line="+1"/>
-        <source>Colors for the storage class:</source>
-        <translation>Farben der Speicherklassen:</translation>
+        <source>Colors for variable attributes:</source>
+        <translation type="unfinished"></translation>
     </message>
 </context>
 </TS>
--- a/libgui/languages/en_US.ts	Fri Feb 06 08:31:09 2015 -0800
+++ b/libgui/languages/en_US.ts	Fri Feb 06 08:31:49 2015 -0800
@@ -62,7 +62,7 @@
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="../src/main-window.cc" line="+1900"/>
+        <location filename="../src/main-window.cc" line="+1963"/>
         <source>&lt;p&gt;&lt;strong&gt;A Note about Octave&apos;s New GUI&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;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.  But because it is not quite as polished as we would like, we have decided to wait until the 4.0.x release series before making the GUI the default interface.&lt;/p&gt;&lt;p&gt;Given the length of time and the number of bug fixes and improvements since the last major release, we also decided against delaying the release of all these new improvements any longer just to perfect the GUI.  So please enjoy the 3.8 release of Octave and the preview of the new GUI.  We believe it is working reasonably well, but we also know that there are some obvious rough spots and many things that could be improved.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;We Need Your Help&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;There are many ways that you can help us fix the remaining problems, complete the GUI, and improve the overall user experience for both novices and experts alike (links will open an external browser):&lt;/p&gt;&lt;p&gt;&lt;ul&gt;&lt;li&gt;If you are a skilled software developer, you can help by contributing your time to help &lt;a href=&quot;http://octave.org/get-involved.html&quot;&gt;develop Octave&lt;/a&gt;.&lt;/li&gt;&lt;li&gt;If Octave does not work properly, you are encouraged to &lt;a href=&quot;http://octave.org/bugs.html&quot;&gt;report problems &lt;/a&gt; that you find.&lt;/li&gt;&lt;li&gt;Whether you are a user or developer, you can &lt;a href=&quot;http://octave.org/donate.html&quot;&gt;help to fund the project&lt;/a&gt;.  Octave development takes a lot of time and expertise.  Your contributions help to ensure that Octave will continue to improve.&lt;/li&gt;&lt;/ul&gt;&lt;/p&gt;&lt;p&gt;We hope you find Octave to be useful.  Please help us make it even better for the future!&lt;/p&gt;</source>
         <translation type="unfinished"></translation>
     </message>
@@ -88,7 +88,7 @@
 <context>
     <name>QWinTerminalImpl</name>
     <message>
-        <location filename="../qterminal/libqterminal/win32/QWinTerminalImpl.cpp" line="+1536"/>
+        <location filename="../qterminal/libqterminal/win32/QWinTerminalImpl.cpp" line="+1539"/>
         <source>copied selection to clipboard</source>
         <translation type="unfinished"></translation>
     </message>
@@ -141,17 +141,12 @@
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location line="+255"/>
+        <location line="+268"/>
         <source>&amp;%1 %2</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location line="+175"/>
-        <source>&amp;New File</source>
-        <translation type="unfinished"></translation>
-    </message>
-    <message>
-        <location line="+6"/>
+        <location line="+207"/>
         <source>&amp;Save File</source>
         <translation type="unfinished"></translation>
     </message>
@@ -161,7 +156,12 @@
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location line="+6"/>
+        <location line="-3"/>
+        <source>&amp;New Script</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+9"/>
         <source>Save File &amp;As...</source>
         <translation type="unfinished"></translation>
     </message>
@@ -247,6 +247,16 @@
     </message>
     <message>
         <location line="+3"/>
+        <source>&amp;Indent</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+2"/>
+        <source>&amp;Unindent</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+3"/>
         <source>&amp;Find and Replace...</source>
         <translation type="unfinished"></translation>
     </message>
@@ -261,7 +271,7 @@
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location line="+55"/>
+        <location line="+57"/>
         <source>&amp;Recent Editor Files</source>
         <translation type="unfinished"></translation>
     </message>
@@ -286,7 +296,7 @@
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location line="+31"/>
+        <location line="+34"/>
         <source>&amp;Preferences...</source>
         <translation type="unfinished"></translation>
     </message>
@@ -316,7 +326,7 @@
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location line="-741"/>
+        <location line="-790"/>
         <source>Could not open file
 %1
 for read: %2.</source>
@@ -342,7 +352,7 @@
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location line="+521"/>
+        <location line="+567"/>
         <source>&amp;File</source>
         <translation type="unfinished"></translation>
     </message>
@@ -357,7 +367,7 @@
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location line="+30"/>
+        <location line="+33"/>
         <source>&amp;Debug</source>
         <translation type="unfinished"></translation>
     </message>
@@ -370,7 +380,7 @@
 <context>
     <name>file_editor_tab</name>
     <message>
-        <location filename="../src/m-editor/file-editor-tab.cc" line="+803"/>
+        <location filename="../src/m-editor/file-editor-tab.cc" line="+824"/>
         <source>Goto line</source>
         <translation type="unfinished"></translation>
     </message>
@@ -380,7 +390,7 @@
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location line="+71"/>
+        <location line="+108"/>
         <location line="+69"/>
         <source>&lt;unnamed&gt;</source>
         <translation type="unfinished"></translation>
@@ -397,14 +407,15 @@
     </message>
     <message>
         <location line="+10"/>
-        <location line="+122"/>
-        <location line="+150"/>
+        <location line="+123"/>
+        <location line="+112"/>
+        <location line="+69"/>
         <location line="+22"/>
         <source>Octave Editor</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location line="-293"/>
+        <location line="-325"/>
         <source>The file
 %1
 is about to be closed but has been modified.
@@ -412,12 +423,12 @@
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location line="+201"/>
+        <location line="+203"/>
         <source>Octave Files (*.m);;All Files (*)</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location line="+86"/>
+        <location line="+116"/>
         <source>
 
 Warning: The contents in the editor is modified!</source>
@@ -431,13 +442,13 @@
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location line="-172"/>
+        <location line="-203"/>
         <source>Could not open file %1 for write:
 %2.</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location line="-975"/>
+        <location line="-1032"/>
         <source>Line:</source>
         <translation type="unfinished"></translation>
     </message>
@@ -447,7 +458,18 @@
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location line="+1122"/>
+        <location line="+1141"/>
+        <source>&quot;%1&quot;
+is not a valid identifier.
+
+If you keep this file name, you will not be able to
+call your script using its name as an Octave command.
+
+Do you want to choose another name?</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+69"/>
         <source>It seems that &apos;%1&apos; has been modified by another application. Do you want to reload it?</source>
         <translation type="unfinished"></translation>
     </message>
@@ -480,7 +502,12 @@
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location line="+373"/>
+        <location line="+15"/>
+        <source>Set Browser Directory...</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+379"/>
         <source>Find Files...</source>
         <translation type="unfinished"></translation>
     </message>
@@ -491,16 +518,17 @@
     </message>
     <message>
         <location line="+3"/>
+        <location line="+333"/>
         <source>New Directory</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location line="-323"/>
+        <location line="-656"/>
         <source>Double-click a file to open it</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location line="-79"/>
+        <location line="-100"/>
         <source>Show Octave directory</source>
         <translation type="unfinished"></translation>
     </message>
@@ -525,7 +553,7 @@
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location line="+12"/>
+        <location line="+16"/>
         <source>Search Directory...</source>
         <translation type="unfinished"></translation>
     </message>
@@ -545,7 +573,7 @@
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location line="+276"/>
+        <location line="+297"/>
         <source>File size</source>
         <translation type="unfinished"></translation>
     </message>
@@ -656,7 +684,12 @@
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location line="+17"/>
+        <location line="+1"/>
+        <source>New File.txt</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+16"/>
         <source>Create Directory</source>
         <translation type="unfinished"></translation>
     </message>
@@ -719,7 +752,12 @@
 <context>
     <name>find_dialog</name>
     <message>
-        <location filename="../src/m-editor/find-dialog.cc" line="+77"/>
+        <location filename="../src/m-editor/find-dialog.cc" line="+74"/>
+        <source>Find and Replace</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+3"/>
         <source>Find &amp;what:</source>
         <translation type="unfinished"></translation>
     </message>
@@ -789,7 +827,7 @@
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location line="+71"/>
+        <location line="+72"/>
         <source>Search from end</source>
         <translation type="unfinished"></translation>
     </message>
@@ -799,7 +837,7 @@
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location line="+121"/>
+        <location line="+119"/>
         <source>Replace Result</source>
         <translation type="unfinished"></translation>
     </message>
@@ -809,7 +847,7 @@
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location line="+10"/>
+        <location line="+12"/>
         <source>Find Result</source>
         <translation type="unfinished"></translation>
     </message>
@@ -832,12 +870,7 @@
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location line="+2"/>
-        <source>Enter the filename expression</source>
-        <translation type="unfinished"></translation>
-    </message>
-    <message>
-        <location line="+6"/>
+        <location line="+8"/>
         <source>Start in:</source>
         <translation type="unfinished"></translation>
     </message>
@@ -857,22 +890,12 @@
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location line="+3"/>
-        <source>Recurse directories</source>
-        <translation type="unfinished"></translation>
-    </message>
-    <message>
-        <location line="+4"/>
+        <location line="+7"/>
         <source>Search recursively through directories for matching files</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location line="+2"/>
-        <source>Include directories</source>
-        <translation type="unfinished"></translation>
-    </message>
-    <message>
-        <location line="+4"/>
+        <location line="+6"/>
         <source>Include matching directories in search results</source>
         <translation type="unfinished"></translation>
     </message>
@@ -892,8 +915,23 @@
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location line="+1"/>
-        <source>Search must match text</source>
+        <location line="-35"/>
+        <source>Enter the filename search expression</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+18"/>
+        <source>Search subdirectories</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+6"/>
+        <source>Include directory names</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+12"/>
+        <source>Enter the file content search expression</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
@@ -957,7 +995,12 @@
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location line="+32"/>
+        <location line="+23"/>
+        <source>%1 match(es)</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+9"/>
         <source>Set search directory</source>
         <translation type="unfinished"></translation>
     </message>
@@ -1043,13 +1086,13 @@
 <context>
     <name>main_window</name>
     <message>
-        <location filename="../src/main-window.cc" line="-1696"/>
+        <location filename="../src/main-window.cc" line="-1758"/>
         <source>Load Workspace</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location line="+645"/>
-        <location line="+876"/>
+        <location line="+678"/>
+        <location line="+905"/>
         <source>About Octave</source>
         <translation type="unfinished"></translation>
     </message>
@@ -1064,12 +1107,7 @@
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location line="+4"/>
-        <source>Script</source>
-        <translation type="unfinished"></translation>
-    </message>
-    <message>
-        <location line="+7"/>
+        <location line="+11"/>
         <source>Figure</source>
         <translation type="unfinished"></translation>
     </message>
@@ -1109,12 +1147,23 @@
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location line="-1265"/>
+        <location line="-1327"/>
         <source>Save Workspace As</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location line="+124"/>
+        <location line="+84"/>
+        <source>The file %1
+can not be executed because its name
+is not a valid identifier.
+
+Do you want to execute
+%2
+instead?</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+73"/>
         <source>The release notes file &apos;%1&apos; is empty.</source>
         <translation type="unfinished"></translation>
     </message>
@@ -1134,7 +1183,7 @@
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location line="+939"/>
+        <location line="+968"/>
         <source>Clear Clipboard</source>
         <translation type="unfinished"></translation>
     </message>
@@ -1199,7 +1248,12 @@
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location line="-151"/>
+        <location line="-1311"/>
+        <source>Octave</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+1160"/>
         <source>Load Workspace...</source>
         <translation type="unfinished"></translation>
     </message>
@@ -1209,7 +1263,12 @@
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location line="+41"/>
+        <location line="+38"/>
+        <source>New Script</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+3"/>
         <source>Function...</source>
         <translation type="unfinished"></translation>
     </message>
@@ -1300,8 +1359,8 @@
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location line="-1283"/>
-        <location line="+1286"/>
+        <location line="-1312"/>
+        <location line="+1315"/>
         <source>Browse directories</source>
         <translation type="unfinished"></translation>
     </message>
@@ -1375,7 +1434,7 @@
 <context>
     <name>news_reader</name>
     <message>
-        <location line="-1282"/>
+        <location line="-1311"/>
         <source>&lt;html&gt;
 &lt;body&gt;
 &lt;p&gt;
@@ -1411,18 +1470,18 @@
 <context>
     <name>octave_dock_widget</name>
     <message>
-        <location filename="../src/octave-dock-widget.cc" line="+61"/>
-        <location line="+163"/>
+        <location filename="../src/octave-dock-widget.cc" line="+60"/>
+        <location line="+170"/>
         <source>Undock widget</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location line="-153"/>
+        <location line="-160"/>
         <source>Hide widget</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location line="+104"/>
+        <location line="+107"/>
         <source>Dock widget</source>
         <translation type="unfinished"></translation>
     </message>
@@ -1453,7 +1512,7 @@
 <context>
     <name>octave_qt_link</name>
     <message>
-        <location filename="../src/octave-qt-link.cc" line="+94"/>
+        <location filename="../src/octave-qt-link.cc" line="+97"/>
         <location line="+6"/>
         <location line="+7"/>
         <source>Yes</source>
@@ -1478,12 +1537,12 @@
     </message>
     <message>
         <location line="+211"/>
-        <source>The file %1 does not exist in the load path.  To debug the function you are editing, you must either change to the directory %2 or add that directory to the load path.</source>
+        <source>The file %1 does not exist in the load path.  To run or debug the function you are editing, you must either change to the directory %2 or add that directory to the load path.</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
         <location line="+1"/>
-        <source>The file %1 is shadowed by a file with the same name in the load path.  To debug the function you are editing, change to the directory %2.</source>
+        <source>The file %1 is shadowed by a file with the same name in the load path. To run or debug the function you are editing, change to the directory %2.</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
@@ -1529,17 +1588,17 @@
 <context>
     <name>settings_dialog</name>
     <message>
-        <location filename="../src/settings-dialog.ui" line="+29"/>
+        <location filename="../src/settings-dialog.ui" line="+23"/>
         <source>Settings</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location line="+13"/>
+        <location line="+19"/>
         <source>General</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location line="+97"/>
+        <location line="+191"/>
         <source>Octave logo only</source>
         <translation type="unfinished"></translation>
     </message>
@@ -1549,17 +1608,37 @@
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location line="+46"/>
+        <location line="-172"/>
+        <source>Dock widget title bar</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+40"/>
+        <source>Custom style</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+26"/>
+        <source>Background color</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+29"/>
+        <source>Text color</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+212"/>
         <source>Editor</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location line="+71"/>
+        <location line="+102"/>
         <source>Color</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location line="+120"/>
+        <location line="+170"/>
         <source>Indent width</source>
         <translation type="unfinished"></translation>
     </message>
@@ -1569,7 +1648,7 @@
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location line="+7"/>
+        <location line="+23"/>
         <source>Auto indentation</source>
         <translation type="unfinished"></translation>
     </message>
@@ -1614,67 +1693,114 @@
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location line="+60"/>
+        <location line="+34"/>
         <source>Use custom file editor</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location line="+32"/>
+        <location line="+20"/>
+        <source>emacs +%l %f </source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+35"/>
         <source>Editor Styles</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location line="+24"/>
+        <location line="+17"/>
         <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Select font, font size (as a difference from the default size), font style (&lt;b&gt;b&lt;/b&gt;old, &lt;b&gt;i&lt;/b&gt;talic, &lt;b&gt;u&lt;/b&gt;nderline), text color and background color (for the latter, the color pink (255,0,255) is a placeholder for the default background color).&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location line="+108"/>
+        <location line="+191"/>
         <source>Terminal Colors</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location line="+45"/>
+        <location line="-100"/>
         <source>Font</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location line="-757"/>
+        <location line="-770"/>
         <source>Show line numbers</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location line="+27"/>
+        <location line="+46"/>
         <source>Highlight current line</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location line="+262"/>
+        <location line="+328"/>
         <source>Code completion</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location line="-282"/>
+        <location line="-361"/>
         <source>Show complete path in window title</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location line="-72"/>
+        <location line="-366"/>
+        <source>Interface</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+187"/>
         <source>Graphic icons</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location line="+55"/>
+        <location line="+34"/>
+        <source>Octave Startup</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+6"/>
+        <source>These preferences are applied after the startup files like .octaverc.</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+35"/>
+        <location line="+1104"/>
+        <source>Startup path</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="-1091"/>
+        <location line="+1108"/>
+        <source>Browse</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="-1101"/>
+        <source>Restore last Octave directory of previous session</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+61"/>
         <source>Show whitespace</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location line="+27"/>
+        <location line="+33"/>
         <source>Do not show whitespace used for indentation</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location line="+290"/>
+        <location line="+120"/>
+        <source>Tab width min.</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+52"/>
+        <source>max.</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+197"/>
         <source># of characters typed before completion list displayed</source>
         <translation type="unfinished"></translation>
     </message>
@@ -1684,87 +1810,102 @@
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location line="+57"/>
+        <location line="+31"/>
         <source>command line (%f=file, %l=line):</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location line="+10"/>
-        <source>emacs</source>
-        <translation type="unfinished"></translation>
-    </message>
-    <message>
-        <location line="+67"/>
+        <location line="+94"/>
         <source>Terminal</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location line="+15"/>
+        <location line="+45"/>
         <source>Cursor type:</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location line="+23"/>
+        <location line="-11"/>
         <source>Cursor blinking</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location line="+7"/>
+        <location line="-7"/>
         <source>Use foreground color</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location line="+94"/>
+        <location line="+53"/>
         <source>Font size</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location line="+35"/>
+        <location line="+99"/>
+        <source>Set focus to terminal when running a command from within another widget</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+34"/>
         <source>File Browser</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location line="+6"/>
+        <location line="+46"/>
         <source>Show file size</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location line="+7"/>
+        <location line="-14"/>
         <source>Show file type</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location line="+7"/>
+        <location line="+21"/>
         <source>Show date of last modification</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location line="+7"/>
+        <location line="-14"/>
         <source>Show hidden files</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location line="+14"/>
+        <location line="-18"/>
+        <source>Display</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+39"/>
         <source>Alternating row colors</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location line="+21"/>
+        <location line="+12"/>
+        <source>Behavior</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+27"/>
+        <source>Restore last directory of previous session</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+65"/>
         <source>Workspace</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location line="+30"/>
+        <location line="+38"/>
         <source>Storage Class Colors</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location line="+35"/>
+        <location line="+40"/>
         <source>Network</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location line="+8"/>
+        <location line="+23"/>
         <source>Allow Octave to connect to the Octave web site to display current news and information</source>
         <translation type="unfinished"></translation>
     </message>
@@ -1779,27 +1920,27 @@
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location line="-1129"/>
+        <location line="-1356"/>
         <source>Icon set for dock widgets</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location line="+7"/>
+        <location line="-48"/>
         <source>Language (requires restart)</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location line="+7"/>
+        <location line="-122"/>
         <source>Icon size</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location line="+991"/>
+        <location line="+1318"/>
         <source>Synchronize Octave working directory with file browser</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location line="+129"/>
+        <location line="+213"/>
         <source>Socks5Proxy</source>
         <translation type="unfinished"></translation>
     </message>
@@ -1829,9 +1970,9 @@
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="../src/settings-dialog.cc" line="+71"/>
+        <location filename="../src/settings-dialog.cc" line="+74"/>
         <location line="+4"/>
-        <location line="+389"/>
+        <location line="+437"/>
         <source>System setting</source>
         <translation type="unfinished"></translation>
     </message>
@@ -1878,6 +2019,16 @@
         <comment>short form for underlined</comment>
         <translation type="unfinished"></translation>
     </message>
+    <message>
+        <location line="+419"/>
+        <source>Set Octave Startup Directory</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+6"/>
+        <source>Set File Browser Startup Directory</source>
+        <translation type="unfinished"></translation>
+    </message>
 </context>
 <context>
     <name>setup_community_news</name>
@@ -1934,7 +2085,7 @@
 <context>
     <name>webinfo</name>
     <message>
-        <location filename="../src/qtinfo/webinfo.cc" line="+80"/>
+        <location filename="../src/qtinfo/webinfo.cc" line="+83"/>
         <source>Type here and press &apos;Return&apos; to search</source>
         <translation type="unfinished"></translation>
     </message>
@@ -1943,6 +2094,16 @@
         <source>Global search</source>
         <translation type="unfinished"></translation>
     </message>
+    <message>
+        <location line="+22"/>
+        <source>Error</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+3"/>
+        <source>The info file %1 does not exist</source>
+        <translation type="unfinished"></translation>
+    </message>
 </context>
 <context>
     <name>welcome_wizard</name>
@@ -1976,7 +2137,7 @@
     </message>
     <message>
         <location line="+1"/>
-        <source>Storage Class</source>
+        <source>Attribute</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
@@ -2025,7 +2186,7 @@
     </message>
     <message>
         <location line="+1"/>
-        <source>Colors for the storage class:</source>
+        <source>Colors for variable attributes:</source>
         <translation type="unfinished"></translation>
     </message>
 </context>
--- a/libgui/languages/es_ES.ts	Fri Feb 06 08:31:09 2015 -0800
+++ b/libgui/languages/es_ES.ts	Fri Feb 06 08:31:49 2015 -0800
@@ -62,7 +62,7 @@
         <translation>cursor</translation>
     </message>
     <message>
-        <location filename="../src/main-window.cc" line="+1900"/>
+        <location filename="../src/main-window.cc" line="+1963"/>
         <source>&lt;p&gt;&lt;strong&gt;A Note about Octave&apos;s New GUI&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;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.  But because it is not quite as polished as we would like, we have decided to wait until the 4.0.x release series before making the GUI the default interface.&lt;/p&gt;&lt;p&gt;Given the length of time and the number of bug fixes and improvements since the last major release, we also decided against delaying the release of all these new improvements any longer just to perfect the GUI.  So please enjoy the 3.8 release of Octave and the preview of the new GUI.  We believe it is working reasonably well, but we also know that there are some obvious rough spots and many things that could be improved.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;We Need Your Help&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;There are many ways that you can help us fix the remaining problems, complete the GUI, and improve the overall user experience for both novices and experts alike (links will open an external browser):&lt;/p&gt;&lt;p&gt;&lt;ul&gt;&lt;li&gt;If you are a skilled software developer, you can help by contributing your time to help &lt;a href=&quot;http://octave.org/get-involved.html&quot;&gt;develop Octave&lt;/a&gt;.&lt;/li&gt;&lt;li&gt;If Octave does not work properly, you are encouraged to &lt;a href=&quot;http://octave.org/bugs.html&quot;&gt;report problems &lt;/a&gt; that you find.&lt;/li&gt;&lt;li&gt;Whether you are a user or developer, you can &lt;a href=&quot;http://octave.org/donate.html&quot;&gt;help to fund the project&lt;/a&gt;.  Octave development takes a lot of time and expertise.  Your contributions help to ensure that Octave will continue to improve.&lt;/li&gt;&lt;/ul&gt;&lt;/p&gt;&lt;p&gt;We hope you find Octave to be useful.  Please help us make it even better for the future!&lt;/p&gt;</source>
         <translation>&lt;p&gt;&lt;strong&gt;Nota acerca de la nueva GUI de Octave&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;Una de las novedades más grandes de Octave 3.8 es la interfaz gráfica de usuario.  Esto ha sido algo que los usuarios han solicitado frecuentemente durante los últimos años, y ahora está casi lista. Pero como esta interfaz aún no está tan pulida como a nosotros nos gustaría, hemos decidido esperar hasta la serie de versiones 4.0.x de Octave para hacer a la GUI la interfaz por defecto.&lt;/p&gt;&lt;p&gt;Dado el tiempo transcurrido, el número de correcciones de errores del software (bugs) y el número de mejoras desde la última versión mayor de Octave, también hemos decidido retrasar el lanzamiento de todas estas nuevas mejoras durante más tiempo con el fin de perfeccionar la GUI.  Disfrute de la versión 3.8 de Octave y la versión previa de la nueva GUI.  Creemos que está funcionando razonablemente bien, pero también somos conscientes de que existen muchas cosas que se pueden mejorar.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Necesitamos su ayuda&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;Hay varias maneras mediante las cuales usted nos puede ayudar a arreglar errores, completar la GUI y, en general, mejorar la experiencia del usuario, ya sean novatos o expertos (los enlaces se abrirán en un navegador externo):&lt;/p&gt;&lt;p&gt;&lt;ul&gt;&lt;li&gt;Si usted es un desarrollador de software experimentado, puede contribuir con su tiempo para ayudar &lt;a href=&quot;http://octave.org/get-involved.html&quot;&gt;Desarrollo de Octave&lt;/a&gt;.&lt;/li&gt;&lt;li&gt;Si Octave no funciona adecuadamente, se le invita a  &lt;a href=&quot;http://octave.org/bugs.html&quot;&gt;reportar problemas &lt;/a&gt; que haya encontrado.&lt;/li&gt;&lt;li&gt;Si usted es usuario o desarrollador, puede &lt;a href=&quot;http://octave.org/donate.html&quot;&gt;ayudar a financiar el proyecto&lt;/a&gt;.  El desarrollo de Octave necesita tiempo y conocimientos. Su contribución ayudaría en gran medida a asegurar que Octave continúe mejorando.&lt;/li&gt;&lt;/ul&gt;&lt;/p&gt;&lt;p&gt;Esperamos que haya encontrado Octave muy útil. Por favor, ¡ayúdenos a hacerlo aún mejor en el futuro!&lt;/p&gt;</translation>
     </message>
@@ -88,7 +88,7 @@
 <context>
     <name>QWinTerminalImpl</name>
     <message>
-        <location filename="../qterminal/libqterminal/win32/QWinTerminalImpl.cpp" line="+1536"/>
+        <location filename="../qterminal/libqterminal/win32/QWinTerminalImpl.cpp" line="+1539"/>
         <source>copied selection to clipboard</source>
         <translation>selección copiada al portapapeles</translation>
     </message>
@@ -134,17 +134,12 @@
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location line="+536"/>
+        <location line="+549"/>
         <source>&amp;%1 %2</source>
         <translation>&amp;%1 %2</translation>
     </message>
     <message>
-        <location line="+175"/>
-        <source>&amp;New File</source>
-        <translation>&amp;Nuevo archivo</translation>
-    </message>
-    <message>
-        <location line="+6"/>
+        <location line="+207"/>
         <source>&amp;Save File</source>
         <translation>&amp;Guardar archivo</translation>
     </message>
@@ -154,7 +149,12 @@
         <translation>&amp;Abrir archivo...</translation>
     </message>
     <message>
-        <location line="+6"/>
+        <location line="-3"/>
+        <source>&amp;New Script</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+9"/>
         <source>Save File &amp;As...</source>
         <translation>Guardar archivo &amp;como...</translation>
     </message>
@@ -240,6 +240,16 @@
     </message>
     <message>
         <location line="+3"/>
+        <source>&amp;Indent</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+2"/>
+        <source>&amp;Unindent</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+3"/>
         <source>&amp;Find and Replace...</source>
         <translation>&amp;Buscar y reemplazar...</translation>
     </message>
@@ -254,7 +264,7 @@
         <translation>&amp;Ir a línea...</translation>
     </message>
     <message>
-        <location line="+55"/>
+        <location line="+57"/>
         <source>&amp;Recent Editor Files</source>
         <translation>Archivos &amp;recientes</translation>
     </message>
@@ -279,7 +289,7 @@
         <translation>Cerrar otros archivos</translation>
     </message>
     <message>
-        <location line="+31"/>
+        <location line="+34"/>
         <source>&amp;Preferences...</source>
         <translation>&amp;Preferencias...</translation>
     </message>
@@ -309,7 +319,7 @@
         <translation>&amp;Documentación de palabras clave</translation>
     </message>
     <message>
-        <location line="-741"/>
+        <location line="-790"/>
         <source>Could not open file
 %1
 for read: %2.</source>
@@ -342,7 +352,7 @@
         <translation>La pestaña para la edición del archivo ha desaparecido.</translation>
     </message>
     <message>
-        <location line="+521"/>
+        <location line="+567"/>
         <source>&amp;File</source>
         <translation>&amp;Archivo</translation>
     </message>
@@ -357,7 +367,7 @@
         <translation>&amp;Editar</translation>
     </message>
     <message>
-        <location line="+30"/>
+        <location line="+33"/>
         <source>&amp;Debug</source>
         <translation>&amp;Depurar</translation>
     </message>
@@ -370,7 +380,7 @@
 <context>
     <name>file_editor_tab</name>
     <message>
-        <location filename="../src/m-editor/file-editor-tab.cc" line="+803"/>
+        <location filename="../src/m-editor/file-editor-tab.cc" line="+824"/>
         <source>Goto line</source>
         <translation>Ir a línea</translation>
     </message>
@@ -380,7 +390,7 @@
         <translation>Número de línea</translation>
     </message>
     <message>
-        <location line="+71"/>
+        <location line="+108"/>
         <location line="+69"/>
         <source>&lt;unnamed&gt;</source>
         <translation>&lt;sin nombre&gt;</translation>
@@ -397,14 +407,15 @@
     </message>
     <message>
         <location line="+10"/>
-        <location line="+122"/>
-        <location line="+150"/>
+        <location line="+123"/>
+        <location line="+112"/>
+        <location line="+69"/>
         <location line="+22"/>
         <source>Octave Editor</source>
         <translation>Editor de Octave</translation>
     </message>
     <message>
-        <location line="-293"/>
+        <location line="-325"/>
         <source>The file
 %1
 is about to be closed but has been modified.
@@ -412,12 +423,12 @@
         <translation>El archivo\n%1\nestá a punto de ser cerrado, pero ha sido modificado.\n%2</translation>
     </message>
     <message>
-        <location line="+201"/>
+        <location line="+203"/>
         <source>Octave Files (*.m);;All Files (*)</source>
         <translation>Archivos de Octave(*.m);;Todos los archivos(*)</translation>
     </message>
     <message>
-        <location line="+86"/>
+        <location line="+116"/>
         <source>
 
 Warning: The contents in the editor is modified!</source>
@@ -431,13 +442,13 @@
         <translation>Parece que el archivo\n%1\nha sido eliminado o renombrado.¿Desea guardarlo ahora?%2</translation>
     </message>
     <message>
-        <location line="-172"/>
+        <location line="-203"/>
         <source>Could not open file %1 for write:
 %2.</source>
         <translation>No se ha podido abrir el archivo %1 para escritura:\n%2.</translation>
     </message>
     <message>
-        <location line="-975"/>
+        <location line="-1032"/>
         <source>Line:</source>
         <translation>Línea:</translation>
     </message>
@@ -447,7 +458,18 @@
         <translation>Col:</translation>
     </message>
     <message>
-        <location line="+1122"/>
+        <location line="+1141"/>
+        <source>&quot;%1&quot;
+is not a valid identifier.
+
+If you keep this file name, you will not be able to
+call your script using its name as an Octave command.
+
+Do you want to choose another name?</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+69"/>
         <source>It seems that &apos;%1&apos; has been modified by another application. Do you want to reload it?</source>
         <translation>Parece que el archivo \&apos;%1\&apos; ha sido modificado por otra aplicación. ¿Desea recargarlo?</translation>
     </message>
@@ -480,7 +502,12 @@
         <translation>Acciones en el directorio actual</translation>
     </message>
     <message>
-        <location line="+373"/>
+        <location line="+15"/>
+        <source>Set Browser Directory...</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+379"/>
         <source>Find Files...</source>
         <translation>Buscar archivos...</translation>
     </message>
@@ -491,16 +518,17 @@
     </message>
     <message>
         <location line="+3"/>
+        <location line="+333"/>
         <source>New Directory</source>
         <translation>Nuevo directorio</translation>
     </message>
     <message>
-        <location line="-323"/>
+        <location line="-656"/>
         <source>Double-click a file to open it</source>
         <translation>Pulse dos veces en un archivo para abrirlo</translation>
     </message>
     <message>
-        <location line="-79"/>
+        <location line="-100"/>
         <source>Show Octave directory</source>
         <translation>Mostrar el directorio de Octave</translation>
     </message>
@@ -525,7 +553,7 @@
         <translation>Mostrar el directorio de inicio</translation>
     </message>
     <message>
-        <location line="+12"/>
+        <location line="+16"/>
         <source>Search Directory...</source>
         <translation>Buscar directorio...</translation>
     </message>
@@ -545,7 +573,7 @@
         <translation>Nuevo directorio...</translation>
     </message>
     <message>
-        <location line="+276"/>
+        <location line="+297"/>
         <source>File size</source>
         <translation>Tamaño del archivo</translation>
     </message>
@@ -657,7 +685,12 @@
 </translation>
     </message>
     <message>
-        <location line="+17"/>
+        <location line="+1"/>
+        <source>New File.txt</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+16"/>
         <source>Create Directory</source>
         <translation>Crear directorio</translation>
     </message>
@@ -739,7 +772,12 @@
 <context>
     <name>find_dialog</name>
     <message>
-        <location filename="../src/m-editor/find-dialog.cc" line="+77"/>
+        <location filename="../src/m-editor/find-dialog.cc" line="+74"/>
+        <source>Find and Replace</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+3"/>
         <source>Find &amp;what:</source>
         <translation>&amp;Buscar:</translation>
     </message>
@@ -809,7 +847,7 @@
         <translation>Buscar se&amp;lección</translation>
     </message>
     <message>
-        <location line="+71"/>
+        <location line="+72"/>
         <source>Search from end</source>
         <translation>Buscar desde el final</translation>
     </message>
@@ -819,7 +857,7 @@
         <translation>Buscar desde el inicio</translation>
     </message>
     <message>
-        <location line="+121"/>
+        <location line="+119"/>
         <source>Replace Result</source>
         <translation>Reemplazar resultado</translation>
     </message>
@@ -829,7 +867,7 @@
         <translation>%1 instancias reemplazadas</translation>
     </message>
     <message>
-        <location line="+10"/>
+        <location line="+12"/>
         <source>Find Result</source>
         <translation>Resultado de la búsqueda</translation>
     </message>
@@ -852,12 +890,7 @@
         <translation>Nombrado:</translation>
     </message>
     <message>
-        <location line="+2"/>
-        <source>Enter the filename expression</source>
-        <translation>Introducir la expresión del nombre de archivo</translation>
-    </message>
-    <message>
-        <location line="+6"/>
+        <location line="+8"/>
         <source>Start in:</source>
         <translation>Iniciar en:</translation>
     </message>
@@ -877,22 +910,12 @@
         <translation>Explorar para seleccionar el directorio de inicio</translation>
     </message>
     <message>
-        <location line="+3"/>
-        <source>Recurse directories</source>
-        <translation>Explorar directorios de forma recursiva</translation>
-    </message>
-    <message>
-        <location line="+4"/>
+        <location line="+7"/>
         <source>Search recursively through directories for matching files</source>
         <translation>Buscar archivos de forma recursiva en los directorios</translation>
     </message>
     <message>
-        <location line="+2"/>
-        <source>Include directories</source>
-        <translation>Incluir directorios</translation>
-    </message>
-    <message>
-        <location line="+4"/>
+        <location line="+6"/>
         <source>Include matching directories in search results</source>
         <translation>Incluir directorios que coicidan en los resultados de la búsqueda</translation>
     </message>
@@ -912,9 +935,24 @@
         <translation>Contiene el texto:</translation>
     </message>
     <message>
-        <location line="+1"/>
-        <source>Search must match text</source>
-        <translation>La búsqueda debe coincidir con el texto</translation>
+        <location line="-35"/>
+        <source>Enter the filename search expression</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+18"/>
+        <source>Search subdirectories</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+6"/>
+        <source>Include directory names</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+12"/>
+        <source>Enter the file content search expression</source>
+        <translation type="unfinished"></translation>
     </message>
     <message>
         <location line="+5"/>
@@ -977,7 +1015,12 @@
         <translation>Buscando...</translation>
     </message>
     <message>
-        <location line="+32"/>
+        <location line="+23"/>
+        <source>%1 match(es)</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+9"/>
         <source>Set search directory</source>
         <translation>Seleccionar directorio de búsqueda</translation>
     </message>
@@ -1068,13 +1111,13 @@
 <context>
     <name>main_window</name>
     <message>
-        <location filename="../src/main-window.cc" line="-1696"/>
+        <location filename="../src/main-window.cc" line="-1758"/>
         <source>Load Workspace</source>
         <translation>Cargar espacio de trabajo</translation>
     </message>
     <message>
-        <location line="+645"/>
-        <location line="+876"/>
+        <location line="+678"/>
+        <location line="+905"/>
         <source>About Octave</source>
         <translation>Acerca de Octave</translation>
     </message>
@@ -1089,13 +1132,7 @@
         <translation>Nuevo</translation>
     </message>
     <message>
-        <location line="+4"/>
-        <source>Script</source>
-        <translatorcomment>Guión/&quot;Script&quot;</translatorcomment>
-        <translation>Guión</translation>
-    </message>
-    <message>
-        <location line="+7"/>
+        <location line="+11"/>
         <source>Figure</source>
         <translation>Figura</translation>
     </message>
@@ -1135,12 +1172,23 @@
         <translation>Pegar</translation>
     </message>
     <message>
-        <location line="-1265"/>
+        <location line="-1327"/>
         <source>Save Workspace As</source>
         <translation>Guardar espacio de trabajo como</translation>
     </message>
     <message>
-        <location line="+124"/>
+        <location line="+84"/>
+        <source>The file %1
+can not be executed because its name
+is not a valid identifier.
+
+Do you want to execute
+%2
+instead?</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+73"/>
         <source>The release notes file &apos;%1&apos; is empty.</source>
         <translation>El archivo de las notas de versión %1 está vacío.</translation>
     </message>
@@ -1160,7 +1208,7 @@
         <translation>Noticas de la comunidad Octave</translation>
     </message>
     <message>
-        <location line="+939"/>
+        <location line="+968"/>
         <source>Clear Clipboard</source>
         <translation>Limpiar el portapapeles</translation>
     </message>
@@ -1225,7 +1273,12 @@
         <translation>Iniciar</translation>
     </message>
     <message>
-        <location line="-151"/>
+        <location line="-1311"/>
+        <source>Octave</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+1160"/>
         <source>Load Workspace...</source>
         <translation>Cargar espacio de trabajo...</translation>
     </message>
@@ -1235,7 +1288,12 @@
         <translation>Guardar espacio de trabajo como...</translation>
     </message>
     <message>
-        <location line="+41"/>
+        <location line="+38"/>
+        <source>New Script</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+3"/>
         <source>Function...</source>
         <translation>Función...</translation>
     </message>
@@ -1326,8 +1384,8 @@
         <translation>Directorio superior</translation>
     </message>
     <message>
-        <location line="-1283"/>
-        <location line="+1286"/>
+        <location line="-1312"/>
+        <location line="+1315"/>
         <source>Browse directories</source>
         <translation>Explorar directorios</translation>
     </message>
@@ -1401,7 +1459,7 @@
 <context>
     <name>news_reader</name>
     <message>
-        <location line="-1282"/>
+        <location line="-1311"/>
         <source>&lt;html&gt;
 &lt;body&gt;
 &lt;p&gt;
@@ -1461,20 +1519,20 @@
 <context>
     <name>octave_dock_widget</name>
     <message>
-        <location filename="../src/octave-dock-widget.cc" line="+61"/>
-        <location line="+163"/>
+        <location filename="../src/octave-dock-widget.cc" line="+60"/>
+        <location line="+170"/>
         <source>Undock widget</source>
         <translatorcomment>Uso &quot;widget&quot; por ser el término usual: http://es.wikipedia.org/wiki/Widget</translatorcomment>
         <translation>Desacoplar widget</translation>
     </message>
     <message>
-        <location line="-153"/>
+        <location line="-160"/>
         <source>Hide widget</source>
         <translatorcomment>Uso &quot;widget&quot; por ser el término usual: http://es.wikipedia.org/wiki/Widget</translatorcomment>
         <translation>Ocultar widget</translation>
     </message>
     <message>
-        <location line="+104"/>
+        <location line="+107"/>
         <source>Dock widget</source>
         <translatorcomment>Uso &quot;widget&quot; por ser el término usual: http://es.wikipedia.org/wiki/Widget</translatorcomment>
         <translation>Acoplar widget</translation>
@@ -1506,7 +1564,7 @@
 <context>
     <name>octave_qt_link</name>
     <message>
-        <location filename="../src/octave-qt-link.cc" line="+94"/>
+        <location filename="../src/octave-qt-link.cc" line="+97"/>
         <location line="+6"/>
         <location line="+7"/>
         <source>Yes</source>
@@ -1531,14 +1589,13 @@
     </message>
     <message>
         <location line="+211"/>
-        <source>The file %1 does not exist in the load path.  To debug the function you are editing, you must either change to the directory %2 or add that directory to the load path.</source>
-        <translatorcomment>Uso la traducción &quot;ruta&quot; para &quot;path&quot;: http://es.wikipedia.org/wiki/Ruta_(informática)</translatorcomment>
-        <translation>El archivo %1 no existe en la ruta de carga.  Para depurar la función que acualmente edita tiene que cambiar al directorio %2 o bien agregar ese directorio a la ruta de carga.</translation>
+        <source>The file %1 does not exist in the load path.  To run or debug the function you are editing, you must either change to the directory %2 or add that directory to the load path.</source>
+        <translation type="unfinished"></translation>
     </message>
     <message>
         <location line="+1"/>
-        <source>The file %1 is shadowed by a file with the same name in the load path.  To debug the function you are editing, change to the directory %2.</source>
-        <translation>El archivo %1 se solapa con un archivo con el mismo nombre en la ruta de carga.  Para depurar la función que edita, cambie al directorio %2.</translation>
+        <source>The file %1 is shadowed by a file with the same name in the load path. To run or debug the function you are editing, change to the directory %2.</source>
+        <translation type="unfinished"></translation>
     </message>
     <message>
         <location line="+2"/>
@@ -1585,17 +1642,17 @@
 <context>
     <name>settings_dialog</name>
     <message>
-        <location filename="../src/settings-dialog.ui" line="+29"/>
+        <location filename="../src/settings-dialog.ui" line="+23"/>
         <source>Settings</source>
         <translation>Configuración</translation>
     </message>
     <message>
-        <location line="+13"/>
+        <location line="+19"/>
         <source>General</source>
         <translation>General</translation>
     </message>
     <message>
-        <location line="+97"/>
+        <location line="+191"/>
         <source>Octave logo only</source>
         <translation>Sólo logo de Octave</translation>
     </message>
@@ -1610,17 +1667,37 @@
         <translation>Iconos gráficos</translation>
     </message>
     <message>
-        <location line="+39"/>
+        <location line="-179"/>
+        <source>Dock widget title bar</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+40"/>
+        <source>Custom style</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+26"/>
+        <source>Background color</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+29"/>
+        <source>Text color</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+212"/>
         <source>Editor</source>
         <translation>Editor</translation>
     </message>
     <message>
-        <location line="+71"/>
+        <location line="+102"/>
         <source>Color</source>
         <translation>Color</translation>
     </message>
     <message>
-        <location line="+120"/>
+        <location line="+170"/>
         <source>Indent width</source>
         <translation>Ancho de sangría</translation>
     </message>
@@ -1630,7 +1707,7 @@
         <translation>Sangrar con tabulación</translation>
     </message>
     <message>
-        <location line="+7"/>
+        <location line="+23"/>
         <source>Auto indentation</source>
         <translation>Sangría automática</translation>
     </message>
@@ -1675,63 +1752,68 @@
         <translation>Restaurar las pestañas del editor de la sesión anterior en el arranque </translation>
     </message>
     <message>
-        <location line="+60"/>
+        <location line="+34"/>
         <source>Use custom file editor</source>
         <translation>Utilizar editor de archivos personalizado</translation>
     </message>
     <message>
-        <location line="+32"/>
+        <location line="+20"/>
+        <source>emacs +%l %f </source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+35"/>
         <source>Editor Styles</source>
         <translation>Estilos del editor</translation>
     </message>
     <message>
-        <location line="+24"/>
+        <location line="+17"/>
         <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Select font, font size (as a difference from the default size), font style (&lt;b&gt;b&lt;/b&gt;old, &lt;b&gt;i&lt;/b&gt;talic, &lt;b&gt;u&lt;/b&gt;nderline), text color and background color (for the latter, the color pink (255,0,255) is a placeholder for the default background color).&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
         <translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Seleccione fuente, tamaño de fuente (como diferencia con el tamaño por defecto), estilo de fuente (&lt;b&gt;n&lt;/b&gt;egrita, &lt;b&gt;c&lt;/b&gt;ursiva, &lt;b&gt;s&lt;/b&gt;ubrayada), color de texto y color de fondo(para este último, el color rosa (255,0,255) es un marcador de posición para el color de fondo por defecto).&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
     </message>
     <message>
-        <location line="+108"/>
+        <location line="+191"/>
         <source>Terminal Colors</source>
         <translatorcomment>En es_ES, terminal suele ser masculino, aunque en el español iberoamericano suele adoptarse el femenino</translatorcomment>
         <translation>Colores del terminal</translation>
     </message>
     <message>
-        <location line="+45"/>
+        <location line="-100"/>
         <source>Font</source>
         <translation>Tipo de fuente</translation>
     </message>
     <message>
-        <location line="-757"/>
+        <location line="-770"/>
         <source>Show line numbers</source>
         <translation>Mostrar numeros de línea</translation>
     </message>
     <message>
-        <location line="+27"/>
+        <location line="+46"/>
         <source>Highlight current line</source>
         <translation>Resaltar línea actual</translation>
     </message>
     <message>
-        <location line="+262"/>
+        <location line="+328"/>
         <source>Code completion</source>
         <translation>Autocompletar código</translation>
     </message>
     <message>
-        <location line="-282"/>
+        <location line="-361"/>
         <source>Show complete path in window title</source>
         <translation>Mostrar ruta completa en el título de la ventana</translation>
     </message>
     <message>
-        <location line="-17"/>
+        <location line="-23"/>
         <source>Show whitespace</source>
         <translation>Mostrar espacios en blanco</translation>
     </message>
     <message>
-        <location line="+27"/>
+        <location line="+33"/>
         <source>Do not show whitespace used for indentation</source>
         <translation>No mostrar los espacios usados para la sangría</translation>
     </message>
     <message>
-        <location line="+290"/>
+        <location line="+369"/>
         <source># of characters typed before completion list displayed</source>
         <translation># de caracteres pulsados antes de completar la lista desplegada</translation>
     </message>
@@ -1741,87 +1823,144 @@
         <translation>Crear archivos no existentes sin consultar</translation>
     </message>
     <message>
-        <location line="+57"/>
+        <location line="+31"/>
         <source>command line (%f=file, %l=line):</source>
         <translation>línea de comando(%f=archivo, %l=linea):</translation>
     </message>
     <message>
-        <location line="+10"/>
-        <source>emacs</source>
-        <translation>emacs</translation>
-    </message>
-    <message>
-        <location line="+67"/>
+        <location line="+94"/>
         <source>Terminal</source>
         <translation>Terminal</translation>
     </message>
     <message>
-        <location line="+15"/>
+        <location line="+45"/>
         <source>Cursor type:</source>
         <translation>Tipo de cursor:</translation>
     </message>
     <message>
-        <location line="+23"/>
+        <location line="-11"/>
         <source>Cursor blinking</source>
         <translation>Cursor parpadeante</translation>
     </message>
     <message>
-        <location line="+7"/>
+        <location line="-7"/>
         <source>Use foreground color</source>
         <translation>Usar color de primer plano</translation>
     </message>
     <message>
-        <location line="+94"/>
+        <location line="+53"/>
         <source>Font size</source>
         <translation>Tamaño de fuente</translation>
     </message>
     <message>
-        <location line="+35"/>
+        <location line="+99"/>
+        <source>Set focus to terminal when running a command from within another widget</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+34"/>
         <source>File Browser</source>
         <translation>Explorador de archivos</translation>
     </message>
     <message>
-        <location line="+6"/>
+        <location line="+46"/>
         <source>Show file size</source>
         <translation>Mostrar tamaño de archivo</translation>
     </message>
     <message>
-        <location line="+7"/>
+        <location line="-14"/>
         <source>Show file type</source>
         <translation>Mostrar tipo de archivo</translation>
     </message>
     <message>
-        <location line="+7"/>
+        <location line="+21"/>
         <source>Show date of last modification</source>
         <translation>Mostrar fecha de la última modificación</translation>
     </message>
     <message>
-        <location line="+7"/>
+        <location line="-14"/>
         <source>Show hidden files</source>
         <translation>Mostrar archivos ocultos</translation>
     </message>
     <message>
-        <location line="+14"/>
+        <location line="-1316"/>
+        <source>Interface</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+221"/>
+        <source>Octave Startup</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+6"/>
+        <source>These preferences are applied after the startup files like .octaverc.</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+35"/>
+        <location line="+1104"/>
+        <source>Startup path</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="-1091"/>
+        <location line="+1108"/>
+        <source>Browse</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="-1101"/>
+        <source>Restore last Octave directory of previous session</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+214"/>
+        <source>Tab width min.</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+52"/>
+        <source>max.</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+750"/>
+        <source>Display</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+39"/>
         <source>Alternating row colors</source>
         <translation>Alternar colores de filas</translation>
     </message>
     <message>
-        <location line="+21"/>
+        <location line="+12"/>
+        <source>Behavior</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+27"/>
+        <source>Restore last directory of previous session</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+65"/>
         <source>Workspace</source>
         <translation>Espacio de trabajo</translation>
     </message>
     <message>
-        <location line="+30"/>
+        <location line="+38"/>
         <source>Storage Class Colors</source>
         <translation>Colores para las clases de almacenamiento</translation>
     </message>
     <message>
-        <location line="+35"/>
+        <location line="+40"/>
         <source>Network</source>
         <translation>Red</translation>
     </message>
     <message>
-        <location line="+8"/>
+        <location line="+23"/>
         <source>Allow Octave to connect to the Octave web site to display current news and information</source>
         <translation>Permitir a Octave la conexión al sitio web para desplegar las últimas noticias e información</translation>
     </message>
@@ -1836,27 +1975,27 @@
         <translation>HttpProxy</translation>
     </message>
     <message>
-        <location line="-1129"/>
+        <location line="-1356"/>
         <source>Icon set for dock widgets</source>
         <translation>Iconos para widget acoplados</translation>
     </message>
     <message>
-        <location line="+7"/>
+        <location line="-48"/>
         <source>Language (requires restart)</source>
         <translation>Lenguaje (reinicio requerido)</translation>
     </message>
     <message>
-        <location line="+7"/>
+        <location line="-122"/>
         <source>Icon size</source>
         <translation>Tamaño de icono</translation>
     </message>
     <message>
-        <location line="+991"/>
+        <location line="+1318"/>
         <source>Synchronize Octave working directory with file browser</source>
         <translation>Sincronizar el directorio de trabajo de Octave con el explorador de archivos</translation>
     </message>
     <message>
-        <location line="+129"/>
+        <location line="+213"/>
         <source>Socks5Proxy</source>
         <translation>&quot;Socks5Proxy&quot;</translation>
     </message>
@@ -1886,9 +2025,9 @@
         <translation>Contraseña:</translation>
     </message>
     <message>
-        <location filename="../src/settings-dialog.cc" line="+71"/>
+        <location filename="../src/settings-dialog.cc" line="+74"/>
         <location line="+4"/>
-        <location line="+389"/>
+        <location line="+437"/>
         <source>System setting</source>
         <translation>Configuración del sistema</translation>
     </message>
@@ -1935,6 +2074,16 @@
         <comment>short form for underlined</comment>
         <translation>u</translation>
     </message>
+    <message>
+        <location line="+419"/>
+        <source>Set Octave Startup Directory</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+6"/>
+        <source>Set File Browser Startup Directory</source>
+        <translation type="unfinished"></translation>
+    </message>
 </context>
 <context>
     <name>setup_community_news</name>
@@ -2002,7 +2151,7 @@
 <context>
     <name>webinfo</name>
     <message>
-        <location filename="../src/qtinfo/webinfo.cc" line="+80"/>
+        <location filename="../src/qtinfo/webinfo.cc" line="+83"/>
         <source>Type here and press &apos;Return&apos; to search</source>
         <translation>Escriba aquí y pulse la tecla &apos;Retorno&apos; para buscar</translation>
     </message>
@@ -2011,6 +2160,16 @@
         <source>Global search</source>
         <translation>Búsqueda global</translation>
     </message>
+    <message>
+        <location line="+22"/>
+        <source>Error</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+3"/>
+        <source>The info file %1 does not exist</source>
+        <translation type="unfinished"></translation>
+    </message>
 </context>
 <context>
     <name>welcome_wizard</name>
@@ -2044,8 +2203,8 @@
     </message>
     <message>
         <location line="+1"/>
-        <source>Storage Class</source>
-        <translation>Clase de almacenamiento</translation>
+        <source>Attribute</source>
+        <translation type="unfinished"></translation>
     </message>
     <message>
         <location line="+109"/>
@@ -2093,8 +2252,8 @@
     </message>
     <message>
         <location line="+1"/>
-        <source>Colors for the storage class:</source>
-        <translation>Colores para cada clase de almacenamiento:</translation>
+        <source>Colors for variable attributes:</source>
+        <translation type="unfinished"></translation>
     </message>
 </context>
 </TS>
--- a/libgui/languages/fr_FR.ts	Fri Feb 06 08:31:09 2015 -0800
+++ b/libgui/languages/fr_FR.ts	Fri Feb 06 08:31:49 2015 -0800
@@ -62,7 +62,7 @@
         <translation>curseur</translation>
     </message>
     <message>
-        <location filename="../src/main-window.cc" line="+1900"/>
+        <location filename="../src/main-window.cc" line="+1963"/>
         <source>&lt;p&gt;&lt;strong&gt;A Note about Octave&apos;s New GUI&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;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.  But because it is not quite as polished as we would like, we have decided to wait until the 4.0.x release series before making the GUI the default interface.&lt;/p&gt;&lt;p&gt;Given the length of time and the number of bug fixes and improvements since the last major release, we also decided against delaying the release of all these new improvements any longer just to perfect the GUI.  So please enjoy the 3.8 release of Octave and the preview of the new GUI.  We believe it is working reasonably well, but we also know that there are some obvious rough spots and many things that could be improved.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;We Need Your Help&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;There are many ways that you can help us fix the remaining problems, complete the GUI, and improve the overall user experience for both novices and experts alike (links will open an external browser):&lt;/p&gt;&lt;p&gt;&lt;ul&gt;&lt;li&gt;If you are a skilled software developer, you can help by contributing your time to help &lt;a href=&quot;http://octave.org/get-involved.html&quot;&gt;develop Octave&lt;/a&gt;.&lt;/li&gt;&lt;li&gt;If Octave does not work properly, you are encouraged to &lt;a href=&quot;http://octave.org/bugs.html&quot;&gt;report problems &lt;/a&gt; that you find.&lt;/li&gt;&lt;li&gt;Whether you are a user or developer, you can &lt;a href=&quot;http://octave.org/donate.html&quot;&gt;help to fund the project&lt;/a&gt;.  Octave development takes a lot of time and expertise.  Your contributions help to ensure that Octave will continue to improve.&lt;/li&gt;&lt;/ul&gt;&lt;/p&gt;&lt;p&gt;We hope you find Octave to be useful.  Please help us make it even better for the future!&lt;/p&gt;</source>
         <translation>&lt;p&gt;&lt;strong&gt;Note à propos du nouveau GUI d&apos;Octave&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;Parmi les nouvelles fonctionnalités d&apos;Ocatve 3.8, l&apos;interface graphique est une grande évolution. C&apos;est bien la fonctionnalité que les utilisateurs ont le plus réclamée durant les dernières années, et elle est maintenant presque prête. Elle n&apos;est pas aussi parfaite que nous le souhaiterions et c&apos;est pourquoi nous avons décidé d&apos;attendre la version 4.0 pour en faire l&apos;interface par défaut.&lt;/p&gt;&lt;p&gt;Au vu du nombre de bug résolus et des améliorations apportées depuis la dernière version majeure d&apos;Octave, nous avons décidé  de ne pas retarder plus la parution de ces améliorations pour perfectionner le GUI. Vous pouvez maintenant apprécier la version 3.8 et la version préliminaire de la nouvelle interface graphique. Nous pensons qu&apos;elle fonctionne raisonnablement bien, mais nous savons aussi qu&apos;il y a des points durs évidents et beaucoup d&apos;améliorations possibles.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Nous avons besoin de votre aide&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;Il y a de multiples manières d&apos;aider à résoudre les bogues restants, à terminer le GUI et à améliorer l&apos;expérience utilisateur aussi bien pour les novices que pour les experts (liens ouverts dans un navigateur externe):&lt;/p&gt;&lt;p&gt;&lt;ul&gt;&lt;li&gt;Si vous êtes un développeur  expérimenté, vous pouvez donner de votre temps et &lt;a href=&quot;http://octave.org/get-involved.html&quot;&gt;développer Octave&lt;/a&gt;.&lt;/li&gt;&lt;li&gt;Si Octave ne fonctionne pas correctement, vous êtes encouragés à &lt;a href=&quot;http://octave.org/bugs.html&quot;&gt;signaler les problèmes &lt;/a&gt; que vous trouvez.&lt;/li&gt;&lt;li&gt;Que vous soyez utilisateur ou développeur, vous pouvez &lt;a href=&quot;http://octave.org/donate.html&quot;&gt;aider à financer le projet&lt;/a&gt;. Le développement d&apos;Octave demande beaucoup de temps et d’expertise. Vos contributions permettent d&apos;assurer qu&apos;Octave continuera à s&apos;améliorer.&lt;/li&gt;&lt;/ul&gt;&lt;/p&gt;&lt;p&gt;Nous espérons que vous trouverez Octave utile. S&apos;il vous plaît, aidez nous à l&apos;améliorer encore dans le futur !&lt;/p&gt;</translation>
     </message>
@@ -88,7 +88,7 @@
 <context>
     <name>QWinTerminalImpl</name>
     <message>
-        <location filename="../qterminal/libqterminal/win32/QWinTerminalImpl.cpp" line="+1536"/>
+        <location filename="../qterminal/libqterminal/win32/QWinTerminalImpl.cpp" line="+1539"/>
         <source>copied selection to clipboard</source>
         <translation>sélection copiée vers le presse-papier</translation>
     </message>
@@ -143,17 +143,12 @@
 est déjà ouvert dans l&apos;éditeur</translation>
     </message>
     <message>
-        <location line="+255"/>
+        <location line="+268"/>
         <source>&amp;%1 %2</source>
         <translation>&amp;%1 %2</translation>
     </message>
     <message>
-        <location line="+175"/>
-        <source>&amp;New File</source>
-        <translation>&amp;Nouveau</translation>
-    </message>
-    <message>
-        <location line="+6"/>
+        <location line="+207"/>
         <source>&amp;Save File</source>
         <translation>&amp;Enregistrer</translation>
     </message>
@@ -163,7 +158,12 @@
         <translation>&amp;Ouvrir...</translation>
     </message>
     <message>
-        <location line="+6"/>
+        <location line="-3"/>
+        <source>&amp;New Script</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+9"/>
         <source>Save File &amp;As...</source>
         <translation>Enregistrer &amp;sous...</translation>
     </message>
@@ -249,6 +249,16 @@
     </message>
     <message>
         <location line="+3"/>
+        <source>&amp;Indent</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+2"/>
+        <source>&amp;Unindent</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+3"/>
         <source>&amp;Find and Replace...</source>
         <translation>&amp;Rechercher et remplacer...</translation>
     </message>
@@ -263,7 +273,7 @@
         <translation>&amp;Aller à la ligne...</translation>
     </message>
     <message>
-        <location line="+55"/>
+        <location line="+57"/>
         <source>&amp;Recent Editor Files</source>
         <translation>Fichiers &amp;récents</translation>
     </message>
@@ -288,7 +298,7 @@
         <translation>Fermer les autres fichiers</translation>
     </message>
     <message>
-        <location line="+31"/>
+        <location line="+34"/>
         <source>&amp;Preferences...</source>
         <translation>&amp;Préférences...</translation>
     </message>
@@ -318,7 +328,7 @@
         <translation>&amp;Documentation sur le mot de clés</translation>
     </message>
     <message>
-        <location line="-741"/>
+        <location line="-790"/>
         <source>Could not open file
 %1
 for read: %2.</source>
@@ -350,7 +360,7 @@
         <translation>L&apos;onglet éditeur de fichier associé a disparu.</translation>
     </message>
     <message>
-        <location line="+521"/>
+        <location line="+567"/>
         <source>&amp;File</source>
         <translation>&amp;Fichier</translation>
     </message>
@@ -365,7 +375,7 @@
         <translation>&amp;Editer</translation>
     </message>
     <message>
-        <location line="+30"/>
+        <location line="+33"/>
         <source>&amp;Debug</source>
         <translation>&amp;Déboguer</translation>
     </message>
@@ -378,7 +388,7 @@
 <context>
     <name>file_editor_tab</name>
     <message>
-        <location filename="../src/m-editor/file-editor-tab.cc" line="+803"/>
+        <location filename="../src/m-editor/file-editor-tab.cc" line="+824"/>
         <source>Goto line</source>
         <translation>Aller à la ligne</translation>
     </message>
@@ -388,7 +398,7 @@
         <translation>Numéro de ligne</translation>
     </message>
     <message>
-        <location line="+71"/>
+        <location line="+108"/>
         <location line="+69"/>
         <source>&lt;unnamed&gt;</source>
         <translation>&lt;sans nom&gt;</translation>
@@ -405,14 +415,15 @@
     </message>
     <message>
         <location line="+10"/>
-        <location line="+122"/>
-        <location line="+150"/>
+        <location line="+123"/>
+        <location line="+112"/>
+        <location line="+69"/>
         <location line="+22"/>
         <source>Octave Editor</source>
         <translation>Éditeur d&apos;Octave</translation>
     </message>
     <message>
-        <location line="-293"/>
+        <location line="-325"/>
         <source>The file
 %1
 is about to be closed but has been modified.
@@ -423,12 +434,12 @@
 %2</translation>
     </message>
     <message>
-        <location line="+201"/>
+        <location line="+203"/>
         <source>Octave Files (*.m);;All Files (*)</source>
         <translation>Fichiers d&apos;Octave (*.m);;Tous les fichiers (*)</translation>
     </message>
     <message>
-        <location line="+86"/>
+        <location line="+116"/>
         <source>
 
 Warning: The contents in the editor is modified!</source>
@@ -446,14 +457,14 @@
 a été supprimé ou rénommé. Voulez-vous l&apos;enregistrer maintenant ?%2</translation>
     </message>
     <message>
-        <location line="-172"/>
+        <location line="-203"/>
         <source>Could not open file %1 for write:
 %2.</source>
         <translation>Impossible d&apos;ouvrir le fichier %1 pour écrire :
 %2.</translation>
     </message>
     <message>
-        <location line="-975"/>
+        <location line="-1032"/>
         <source>Line:</source>
         <translation>Ligne :</translation>
     </message>
@@ -463,7 +474,18 @@
         <translation>Col :</translation>
     </message>
     <message>
-        <location line="+1122"/>
+        <location line="+1141"/>
+        <source>&quot;%1&quot;
+is not a valid identifier.
+
+If you keep this file name, you will not be able to
+call your script using its name as an Octave command.
+
+Do you want to choose another name?</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+69"/>
         <source>It seems that &apos;%1&apos; has been modified by another application. Do you want to reload it?</source>
         <translation>Il semblerait que &apos;%1&apos; a été modifié par une autre application. Voulez-vous le récharger ?</translation>
     </message>
@@ -496,7 +518,12 @@
         <translation>Actions sur le répertoire courant</translation>
     </message>
     <message>
-        <location line="+373"/>
+        <location line="+15"/>
+        <source>Set Browser Directory...</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+379"/>
         <source>Find Files...</source>
         <translation>Rechercher des fichiers...</translation>
     </message>
@@ -507,16 +534,17 @@
     </message>
     <message>
         <location line="+3"/>
+        <location line="+333"/>
         <source>New Directory</source>
         <translation>Nouveau répertoire</translation>
     </message>
     <message>
-        <location line="-323"/>
+        <location line="-656"/>
         <source>Double-click a file to open it</source>
         <translation>Double-cliquer sur un fichier pour l&apos;ouvrir</translation>
     </message>
     <message>
-        <location line="-79"/>
+        <location line="-100"/>
         <source>Show Octave directory</source>
         <translation>Revenir au répertoire d&apos;Octave</translation>
     </message>
@@ -541,7 +569,7 @@
         <translation>Aller au répertoire personnel</translation>
     </message>
     <message>
-        <location line="+12"/>
+        <location line="+16"/>
         <source>Search Directory...</source>
         <translation>Rechercher dans le répertoire...</translation>
     </message>
@@ -561,7 +589,7 @@
         <translation>Nouveau répertoire...</translation>
     </message>
     <message>
-        <location line="+276"/>
+        <location line="+297"/>
         <source>File size</source>
         <translation>Taille du fichier</translation>
     </message>
@@ -676,7 +704,12 @@
 </translation>
     </message>
     <message>
-        <location line="+17"/>
+        <location line="+1"/>
+        <source>New File.txt</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+16"/>
         <source>Create Directory</source>
         <translation>Créer un répertoire</translation>
     </message>
@@ -755,7 +788,12 @@
 <context>
     <name>find_dialog</name>
     <message>
-        <location filename="../src/m-editor/find-dialog.cc" line="+77"/>
+        <location filename="../src/m-editor/find-dialog.cc" line="+74"/>
+        <source>Find and Replace</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+3"/>
         <source>Find &amp;what:</source>
         <translation>Rechercher &amp;quoi :</translation>
     </message>
@@ -825,7 +863,7 @@
         <translation>Recherche dans la sé&amp;lection</translation>
     </message>
     <message>
-        <location line="+71"/>
+        <location line="+72"/>
         <source>Search from end</source>
         <translation>Rechercher depuis la fin</translation>
     </message>
@@ -835,7 +873,7 @@
         <translation>Rechercher depuis le début</translation>
     </message>
     <message>
-        <location line="+121"/>
+        <location line="+119"/>
         <source>Replace Result</source>
         <translation>Résultats du remplacement</translation>
     </message>
@@ -845,7 +883,7 @@
         <translation>%1 instances remplacées</translation>
     </message>
     <message>
-        <location line="+10"/>
+        <location line="+12"/>
         <source>Find Result</source>
         <translation>Résultats de la recherche</translation>
     </message>
@@ -868,12 +906,7 @@
         <translation>Nommé:</translation>
     </message>
     <message>
-        <location line="+2"/>
-        <source>Enter the filename expression</source>
-        <translation>Entrer le nom du fichier ou une expression</translation>
-    </message>
-    <message>
-        <location line="+6"/>
+        <location line="+8"/>
         <source>Start in:</source>
         <translation>Demarrer dans :</translation>
     </message>
@@ -893,22 +926,12 @@
         <translation>Choisir le répertoire de démarrage</translation>
     </message>
     <message>
-        <location line="+3"/>
-        <source>Recurse directories</source>
-        <translation>Parcourir récursivement les sous-répertoires</translation>
-    </message>
-    <message>
-        <location line="+4"/>
+        <location line="+7"/>
         <source>Search recursively through directories for matching files</source>
         <translation>Rechercher les fichiers recursivement dans les sous-répertoires</translation>
     </message>
     <message>
-        <location line="+2"/>
-        <source>Include directories</source>
-        <translation>Inclure les répertoires</translation>
-    </message>
-    <message>
-        <location line="+4"/>
+        <location line="+6"/>
         <source>Include matching directories in search results</source>
         <translation>Inclure les répertoires concordants dans des résultats de la recherche</translation>
     </message>
@@ -928,9 +951,24 @@
         <translation>Contenant le texte :</translation>
     </message>
     <message>
-        <location line="+1"/>
-        <source>Search must match text</source>
-        <translation>La recherche doit contenir le texte</translation>
+        <location line="-35"/>
+        <source>Enter the filename search expression</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+18"/>
+        <source>Search subdirectories</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+6"/>
+        <source>Include directory names</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+12"/>
+        <source>Enter the file content search expression</source>
+        <translation type="unfinished"></translation>
     </message>
     <message>
         <location line="+5"/>
@@ -993,7 +1031,12 @@
         <translation>Recherche en cours...</translation>
     </message>
     <message>
-        <location line="+32"/>
+        <location line="+23"/>
+        <source>%1 match(es)</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+9"/>
         <source>Set search directory</source>
         <translation>Définir le répertoire de recherche</translation>
     </message>
@@ -1083,13 +1126,13 @@
 <context>
     <name>main_window</name>
     <message>
-        <location filename="../src/main-window.cc" line="-1696"/>
+        <location filename="../src/main-window.cc" line="-1758"/>
         <source>Load Workspace</source>
         <translation>Charger l&apos;espace de travail</translation>
     </message>
     <message>
-        <location line="+645"/>
-        <location line="+876"/>
+        <location line="+678"/>
+        <location line="+905"/>
         <source>About Octave</source>
         <translation>À propos d&apos;Octave</translation>
     </message>
@@ -1104,12 +1147,7 @@
         <translation>Nouveau</translation>
     </message>
     <message>
-        <location line="+4"/>
-        <source>Script</source>
-        <translation>Fichier de script</translation>
-    </message>
-    <message>
-        <location line="+7"/>
+        <location line="+11"/>
         <source>Figure</source>
         <translation>Figure</translation>
     </message>
@@ -1149,12 +1187,23 @@
         <translation>Coller</translation>
     </message>
     <message>
-        <location line="-1265"/>
+        <location line="-1327"/>
         <source>Save Workspace As</source>
         <translation>Enregistrer l&apos;espace de travail sous</translation>
     </message>
     <message>
-        <location line="+124"/>
+        <location line="+84"/>
+        <source>The file %1
+can not be executed because its name
+is not a valid identifier.
+
+Do you want to execute
+%2
+instead?</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+73"/>
         <source>The release notes file &apos;%1&apos; is empty.</source>
         <translation>Le fichier de notes de version &apos;%1&apos; est vide.</translation>
     </message>
@@ -1174,7 +1223,7 @@
         <translation>Nouvelles de la communauté Octave</translation>
     </message>
     <message>
-        <location line="+939"/>
+        <location line="+968"/>
         <source>Clear Clipboard</source>
         <translation>Effacer le presse-papiers</translation>
     </message>
@@ -1239,7 +1288,12 @@
         <translation>Avancer d&apos;un pas avec entrée</translation>
     </message>
     <message>
-        <location line="-151"/>
+        <location line="-1311"/>
+        <source>Octave</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+1160"/>
         <source>Load Workspace...</source>
         <translation>Charger l&apos;espace de travail...</translation>
     </message>
@@ -1249,7 +1303,12 @@
         <translation>Enregistrer l&apos;espace de travail sous...</translation>
     </message>
     <message>
-        <location line="+41"/>
+        <location line="+38"/>
+        <source>New Script</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+3"/>
         <source>Function...</source>
         <translation>Fonction...</translation>
     </message>
@@ -1340,8 +1399,8 @@
         <translation>Monter au répertoire parent</translation>
     </message>
     <message>
-        <location line="-1283"/>
-        <location line="+1286"/>
+        <location line="-1312"/>
+        <location line="+1315"/>
         <source>Browse directories</source>
         <translation>Naviguer dans les répertoires</translation>
     </message>
@@ -1415,7 +1474,7 @@
 <context>
     <name>news_reader</name>
     <message>
-        <location line="-1282"/>
+        <location line="-1311"/>
         <source>&lt;html&gt;
 &lt;body&gt;
 &lt;p&gt;
@@ -1474,18 +1533,18 @@
 <context>
     <name>octave_dock_widget</name>
     <message>
-        <location filename="../src/octave-dock-widget.cc" line="+61"/>
-        <location line="+163"/>
+        <location filename="../src/octave-dock-widget.cc" line="+60"/>
+        <location line="+170"/>
         <source>Undock widget</source>
         <translation>Détacher le widget</translation>
     </message>
     <message>
-        <location line="-153"/>
+        <location line="-160"/>
         <source>Hide widget</source>
         <translation>Cacher le widget</translation>
     </message>
     <message>
-        <location line="+104"/>
+        <location line="+107"/>
         <source>Dock widget</source>
         <translation>Attacher le widget</translation>
     </message>
@@ -1516,7 +1575,7 @@
 <context>
     <name>octave_qt_link</name>
     <message>
-        <location filename="../src/octave-qt-link.cc" line="+94"/>
+        <location filename="../src/octave-qt-link.cc" line="+97"/>
         <location line="+6"/>
         <location line="+7"/>
         <source>Yes</source>
@@ -1543,13 +1602,13 @@
     </message>
     <message>
         <location line="+211"/>
-        <source>The file %1 does not exist in the load path.  To debug the function you are editing, you must either change to the directory %2 or add that directory to the load path.</source>
-        <translation>Le fichier %1 n&apos;existe pas dans les chemins accessibles. Pour déboguer la fonction que vous éditez, vous devez soit modifier le répertoire pour %2 ou ajouter le répertoire aux chemins accessibles.</translation>
+        <source>The file %1 does not exist in the load path.  To run or debug the function you are editing, you must either change to the directory %2 or add that directory to the load path.</source>
+        <translation type="unfinished"></translation>
     </message>
     <message>
         <location line="+1"/>
-        <source>The file %1 is shadowed by a file with the same name in the load path.  To debug the function you are editing, change to the directory %2.</source>
-        <translation>Le fichier %1 est occulté par un fichier du même nom dans les chemins accessibles. Pour déboguer la fonction que vous éditez, vous devez modifier le répertoire pour %2.</translation>
+        <source>The file %1 is shadowed by a file with the same name in the load path. To run or debug the function you are editing, change to the directory %2.</source>
+        <translation type="unfinished"></translation>
     </message>
     <message>
         <location line="+2"/>
@@ -1600,17 +1659,17 @@
 <context>
     <name>settings_dialog</name>
     <message>
-        <location filename="../src/settings-dialog.ui" line="+29"/>
+        <location filename="../src/settings-dialog.ui" line="+23"/>
         <source>Settings</source>
         <translation>Configuration</translation>
     </message>
     <message>
-        <location line="+13"/>
+        <location line="+19"/>
         <source>General</source>
         <translation>Général</translation>
     </message>
     <message>
-        <location line="+97"/>
+        <location line="+191"/>
         <source>Octave logo only</source>
         <translation>Logo d&apos;Octave seulement</translation>
     </message>
@@ -1625,17 +1684,37 @@
         <translation>Icones graphiques</translation>
     </message>
     <message>
-        <location line="+39"/>
+        <location line="-179"/>
+        <source>Dock widget title bar</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+40"/>
+        <source>Custom style</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+26"/>
+        <source>Background color</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+29"/>
+        <source>Text color</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+212"/>
         <source>Editor</source>
         <translation>Éditeur</translation>
     </message>
     <message>
-        <location line="+71"/>
+        <location line="+102"/>
         <source>Color</source>
         <translation>Couleur</translation>
     </message>
     <message>
-        <location line="+120"/>
+        <location line="+170"/>
         <source>Indent width</source>
         <translation>Largeur de l&apos;indentation</translation>
     </message>
@@ -1645,7 +1724,7 @@
         <translation>Indentation par tabulation</translation>
     </message>
     <message>
-        <location line="+7"/>
+        <location line="+23"/>
         <source>Auto indentation</source>
         <translation>Indentation automatique</translation>
     </message>
@@ -1690,62 +1769,67 @@
         <translation>Restaurer les onglets de la session précédente</translation>
     </message>
     <message>
-        <location line="+60"/>
+        <location line="+34"/>
         <source>Use custom file editor</source>
         <translation>Utiliser un éditeur externe</translation>
     </message>
     <message>
-        <location line="+32"/>
+        <location line="+20"/>
+        <source>emacs +%l %f </source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+35"/>
         <source>Editor Styles</source>
         <translation>Affichage</translation>
     </message>
     <message>
-        <location line="+24"/>
+        <location line="+17"/>
         <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Select font, font size (as a difference from the default size), font style (&lt;b&gt;b&lt;/b&gt;old, &lt;b&gt;i&lt;/b&gt;talic, &lt;b&gt;u&lt;/b&gt;nderline), text color and background color (for the latter, the color pink (255,0,255) is a placeholder for the default background color).&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
         <translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Sélectionnez la police, sa taille (différence par rapport à la taille par défaut), son style (&lt;b&gt;g&lt;/b&gt;ras, &lt;b&gt;i&lt;/b&gt;talique, &lt;b&gt;s&lt;/b&gt;ouligné), la couleur du texte et de l&apos;arrière plan (pour ce dernier, le rose (255,0,255) fait figure de défaut).&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
     </message>
     <message>
-        <location line="+108"/>
+        <location line="+191"/>
         <source>Terminal Colors</source>
         <translation>Couleurs de la fenetre de commandes</translation>
     </message>
     <message>
-        <location line="+45"/>
+        <location line="-100"/>
         <source>Font</source>
         <translation>Police</translation>
     </message>
     <message>
-        <location line="-757"/>
+        <location line="-770"/>
         <source>Show line numbers</source>
         <translation>Afficher les numéros des lignes</translation>
     </message>
     <message>
-        <location line="+27"/>
+        <location line="+46"/>
         <source>Highlight current line</source>
         <translation>Surligner la ligne courante</translation>
     </message>
     <message>
-        <location line="+262"/>
+        <location line="+328"/>
         <source>Code completion</source>
         <translation>Suggestions de saisie</translation>
     </message>
     <message>
-        <location line="-282"/>
+        <location line="-361"/>
         <source>Show complete path in window title</source>
         <translation>Afficher le chemin complet dans le titre de la fenetre</translation>
     </message>
     <message>
-        <location line="-17"/>
+        <location line="-23"/>
         <source>Show whitespace</source>
         <translation>Afficher les espaces</translation>
     </message>
     <message>
-        <location line="+27"/>
+        <location line="+33"/>
         <source>Do not show whitespace used for indentation</source>
         <translation>Ne pas afficher les espaces utilisés pour l&apos;indentation</translation>
     </message>
     <message>
-        <location line="+290"/>
+        <location line="+369"/>
         <source># of characters typed before completion list displayed</source>
         <translation>Nb. de caractères avant affichage de la liste de complétion</translation>
     </message>
@@ -1755,87 +1839,144 @@
         <translation>Créer les fichiers non-existants sans prévenir</translation>
     </message>
     <message>
-        <location line="+57"/>
+        <location line="+31"/>
         <source>command line (%f=file, %l=line):</source>
         <translation>ligne de commande (%f=fichier, %l=ligne) :</translation>
     </message>
     <message>
-        <location line="+10"/>
-        <source>emacs</source>
-        <translation>emacs</translation>
-    </message>
-    <message>
-        <location line="+67"/>
+        <location line="+94"/>
         <source>Terminal</source>
         <translation>Terminal</translation>
     </message>
     <message>
-        <location line="+15"/>
+        <location line="+45"/>
         <source>Cursor type:</source>
         <translation>Type de curseur :</translation>
     </message>
     <message>
-        <location line="+23"/>
+        <location line="-11"/>
         <source>Cursor blinking</source>
         <translation>Curseur clignotant</translation>
     </message>
     <message>
-        <location line="+7"/>
+        <location line="-7"/>
         <source>Use foreground color</source>
         <translation>Utiliser la couleur de l&apos;avant plan</translation>
     </message>
     <message>
-        <location line="+94"/>
+        <location line="+53"/>
         <source>Font size</source>
         <translation>Taille de police</translation>
     </message>
     <message>
-        <location line="+35"/>
+        <location line="+99"/>
+        <source>Set focus to terminal when running a command from within another widget</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+34"/>
         <source>File Browser</source>
         <translation>Explorateur de fichiers</translation>
     </message>
     <message>
-        <location line="+6"/>
+        <location line="+46"/>
         <source>Show file size</source>
         <translation>Afficher la taille des fichiers</translation>
     </message>
     <message>
-        <location line="+7"/>
+        <location line="-14"/>
         <source>Show file type</source>
         <translation>Afficher le type des fichiers</translation>
     </message>
     <message>
-        <location line="+7"/>
+        <location line="+21"/>
         <source>Show date of last modification</source>
         <translation>Afficher la date de la dernière modification</translation>
     </message>
     <message>
-        <location line="+7"/>
+        <location line="-14"/>
         <source>Show hidden files</source>
         <translation>Afficher les fichiers cachés</translation>
     </message>
     <message>
-        <location line="+14"/>
+        <location line="-1316"/>
+        <source>Interface</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+221"/>
+        <source>Octave Startup</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+6"/>
+        <source>These preferences are applied after the startup files like .octaverc.</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+35"/>
+        <location line="+1104"/>
+        <source>Startup path</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="-1091"/>
+        <location line="+1108"/>
+        <source>Browse</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="-1101"/>
+        <source>Restore last Octave directory of previous session</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+214"/>
+        <source>Tab width min.</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+52"/>
+        <source>max.</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+750"/>
+        <source>Display</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+39"/>
         <source>Alternating row colors</source>
         <translation>Alterner les couleurs des lignes</translation>
     </message>
     <message>
-        <location line="+21"/>
+        <location line="+12"/>
+        <source>Behavior</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+27"/>
+        <source>Restore last directory of previous session</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+65"/>
         <source>Workspace</source>
         <translation>Espace de travail</translation>
     </message>
     <message>
-        <location line="+30"/>
+        <location line="+38"/>
         <source>Storage Class Colors</source>
         <translation>Couleurs des variables</translation>
     </message>
     <message>
-        <location line="+35"/>
+        <location line="+40"/>
         <source>Network</source>
         <translation>Réseau</translation>
     </message>
     <message>
-        <location line="+8"/>
+        <location line="+23"/>
         <source>Allow Octave to connect to the Octave web site to display current news and information</source>
         <translation>Autoriser Octave à se connecter à son site internet afin d&apos;afficher les informations et nouvelle fraîches</translation>
     </message>
@@ -1850,27 +1991,27 @@
         <translation>Proxy HTTP</translation>
     </message>
     <message>
-        <location line="-1129"/>
+        <location line="-1356"/>
         <source>Icon set for dock widgets</source>
         <translation>Jeu d&apos;icones pour les widgets</translation>
     </message>
     <message>
-        <location line="+7"/>
+        <location line="-48"/>
         <source>Language (requires restart)</source>
         <translation>Langue (nécessite un redémarrage)</translation>
     </message>
     <message>
-        <location line="+7"/>
+        <location line="-122"/>
         <source>Icon size</source>
         <translation>Taille des icones</translation>
     </message>
     <message>
-        <location line="+991"/>
+        <location line="+1318"/>
         <source>Synchronize Octave working directory with file browser</source>
         <translation>Synchroniser le répertoire de travail d&apos;Octave et le navigateur de fichiers</translation>
     </message>
     <message>
-        <location line="+129"/>
+        <location line="+213"/>
         <source>Socks5Proxy</source>
         <translation>Proxy Socks5</translation>
     </message>
@@ -1900,9 +2041,9 @@
         <translation>Mot de passe :</translation>
     </message>
     <message>
-        <location filename="../src/settings-dialog.cc" line="+71"/>
+        <location filename="../src/settings-dialog.cc" line="+74"/>
         <location line="+4"/>
-        <location line="+389"/>
+        <location line="+437"/>
         <source>System setting</source>
         <translation>Reglages système</translation>
     </message>
@@ -1949,6 +2090,16 @@
         <comment>short form for underlined</comment>
         <translation>s</translation>
     </message>
+    <message>
+        <location line="+419"/>
+        <source>Set Octave Startup Directory</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+6"/>
+        <source>Set File Browser Startup Directory</source>
+        <translation type="unfinished"></translation>
+    </message>
 </context>
 <context>
     <name>setup_community_news</name>
@@ -2016,7 +2167,7 @@
 <context>
     <name>webinfo</name>
     <message>
-        <location filename="../src/qtinfo/webinfo.cc" line="+80"/>
+        <location filename="../src/qtinfo/webinfo.cc" line="+83"/>
         <source>Type here and press &apos;Return&apos; to search</source>
         <translation>Entrez le texte ici et appuyez sur &apos;Entrée&apos; pour lancer la recherche</translation>
     </message>
@@ -2025,6 +2176,16 @@
         <source>Global search</source>
         <translation>Recherche globale</translation>
     </message>
+    <message>
+        <location line="+22"/>
+        <source>Error</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+3"/>
+        <source>The info file %1 does not exist</source>
+        <translation type="unfinished"></translation>
+    </message>
 </context>
 <context>
     <name>welcome_wizard</name>
@@ -2058,8 +2219,8 @@
     </message>
     <message>
         <location line="+1"/>
-        <source>Storage Class</source>
-        <translation>Type de stockage</translation>
+        <source>Attribute</source>
+        <translation type="unfinished"></translation>
     </message>
     <message>
         <location line="+109"/>
@@ -2107,8 +2268,8 @@
     </message>
     <message>
         <location line="+1"/>
-        <source>Colors for the storage class:</source>
-        <translation>Couleurs pour le type de stockage :</translation>
+        <source>Colors for variable attributes:</source>
+        <translation type="unfinished"></translation>
     </message>
 </context>
 </TS>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libgui/languages/it_IT.ts	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,4868 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.0" language="it_IT">
+<context>
+    <name>ListDialog</name>
+    <message>
+        <location filename="../src/dialog.cc" line="+251"/>
+        <source>Select All</source>
+        <translation>Seleziona Tutto</translation>
+    </message>
+</context>
+<context>
+    <name>QColorDialog</name>
+    <message>
+        <source>Hu&amp;e:</source>
+        <translation type="obsolete">Tinta:</translation>
+    </message>
+    <message>
+        <source>&amp;Sat:</source>
+        <translation type="obsolete">Saturazione:</translation>
+    </message>
+    <message>
+        <source>&amp;Val:</source>
+        <translation type="obsolete">Luminosità:</translation>
+    </message>
+    <message>
+        <source>&amp;Red:</source>
+        <translation type="obsolete">Rosso:</translation>
+    </message>
+    <message>
+        <source>&amp;Green:</source>
+        <translation type="obsolete">Verde:</translation>
+    </message>
+    <message>
+        <source>Bl&amp;ue:</source>
+        <translation type="obsolete">Blu:</translation>
+    </message>
+    <message>
+        <source>A&amp;lpha channel:</source>
+        <translation type="obsolete">Canale alfa:</translation>
+    </message>
+    <message>
+        <source>Select Color</source>
+        <translation type="obsolete">Seleziona Colore</translation>
+    </message>
+    <message>
+        <source>&amp;Basic colors</source>
+        <translation type="obsolete">Colori di base</translation>
+    </message>
+    <message>
+        <source>&amp;Custom colors</source>
+        <translation type="obsolete">Colori personalizzati</translation>
+    </message>
+    <message>
+        <source>&amp;Add to Custom Colors</source>
+        <translation type="obsolete">Aggiungi ai Colori Personalizzati</translation>
+    </message>
+</context>
+<context>
+    <name>QDialog</name>
+    <message>
+        <source>Done</source>
+        <translation type="obsolete">Fatto</translation>
+    </message>
+    <message>
+        <source>What&apos;s This?</source>
+        <translation type="obsolete">Cos&apos;è questo?</translation>
+    </message>
+</context>
+<context>
+    <name>QDialogButtonBox</name>
+    <message>
+        <source>OK</source>
+        <translation type="obsolete">OK</translation>
+    </message>
+</context>
+<context>
+    <name>QErrorMessage</name>
+    <message>
+        <source>Debug Message:</source>
+        <translation type="obsolete">Messaggio di Debug:</translation>
+    </message>
+    <message>
+        <source>Warning:</source>
+        <translation type="obsolete">Avviso:</translation>
+    </message>
+    <message>
+        <source>Fatal Error:</source>
+        <translation type="obsolete">Errore Fatale:</translation>
+    </message>
+    <message>
+        <source>&amp;Show this message again</source>
+        <translation type="obsolete">Mostra di nuovo questo messaggio</translation>
+    </message>
+    <message>
+        <source>&amp;OK</source>
+        <translation type="obsolete">OK</translation>
+    </message>
+</context>
+<context>
+    <name>QFileDialog</name>
+    <message>
+        <source>Find Directory</source>
+        <translation type="obsolete">Trova Cartella</translation>
+    </message>
+    <message>
+        <source>Open</source>
+        <translation type="obsolete">Apri</translation>
+    </message>
+    <message>
+        <source>Save As</source>
+        <translation type="obsolete">Salva come</translation>
+    </message>
+    <message>
+        <source>All Files (*)</source>
+        <translation type="obsolete">Tutti i File (*)</translation>
+    </message>
+    <message>
+        <source>Show </source>
+        <translation type="obsolete">Mostra </translation>
+    </message>
+    <message>
+        <source>&amp;Rename</source>
+        <translation type="obsolete">&amp;Rinomina</translation>
+    </message>
+    <message>
+        <source>&amp;Delete</source>
+        <translation type="obsolete">&amp;Elimina</translation>
+    </message>
+    <message>
+        <source>Show &amp;hidden files</source>
+        <translation type="obsolete">Mostra &amp;file nascosti</translation>
+    </message>
+    <message>
+        <source>&amp;New Folder</source>
+        <translation type="obsolete">&amp;Nuova cartella</translation>
+    </message>
+    <message>
+        <source>Directory:</source>
+        <translation type="obsolete">Cartella:</translation>
+    </message>
+    <message>
+        <source>File &amp;name:</source>
+        <translation type="obsolete">Nome &amp;file:</translation>
+    </message>
+    <message>
+        <source>&amp;Open</source>
+        <translation type="obsolete">&amp;Apri</translation>
+    </message>
+    <message>
+        <source>&amp;Save</source>
+        <translation type="obsolete">&amp;Salva</translation>
+    </message>
+    <message>
+        <source>Directories</source>
+        <translation type="obsolete">Cartelle</translation>
+    </message>
+    <message>
+        <source>&amp;Choose</source>
+        <translation type="obsolete">&amp;Seleziona</translation>
+    </message>
+    <message>
+        <source>%1
+Directory not found.
+Please verify the correct directory name was given.</source>
+        <translation type="obsolete">%1
+Nessuna cartella trovata.
+Verificare la corretta ortografia del nome inserito.</translation>
+    </message>
+    <message>
+        <source>%1 already exists.
+Do you want to replace it?</source>
+        <translation type="obsolete">%1 esiste già.
+Si desidera sostituirlo?</translation>
+    </message>
+    <message>
+        <source>%1
+File not found.
+Please verify the correct file name was given.</source>
+        <translation type="obsolete">%1
+File non trovato.
+Verificare la corretta ortografia del nome inserito.</translation>
+    </message>
+    <message>
+        <source>New Folder</source>
+        <translation type="obsolete">Nuova Cartella</translation>
+    </message>
+    <message>
+        <source>&apos;%1&apos; is write protected.
+Do you want to delete it anyway?</source>
+        <translation type="obsolete">&apos;%1&apos; è protetto da scrittura.
+Si è certi di volerlo eliminare?</translation>
+    </message>
+    <message>
+        <source>Are sure you want to delete &apos;%1&apos;?</source>
+        <translation type="obsolete">Si è certi di voler eliminare &apos;%1&apos;?</translation>
+    </message>
+    <message>
+        <source>Could not delete directory.</source>
+        <translation type="obsolete">Impossibile eliminare la cartella.</translation>
+    </message>
+    <message>
+        <source>Recent Places</source>
+        <translation type="obsolete">Percorsi Recenti</translation>
+    </message>
+    <message>
+        <source>All Files (*.*)</source>
+        <translation type="obsolete">Tutti i File (*.*)</translation>
+    </message>
+</context>
+<context>
+    <name>QFileSystemModel</name>
+    <message>
+        <source>%1 TB</source>
+        <translation type="obsolete">%1 TB</translation>
+    </message>
+    <message>
+        <source>%1 GB</source>
+        <translation type="obsolete">%1 GB</translation>
+    </message>
+    <message>
+        <source>%1 MB</source>
+        <translation type="obsolete">%1 MB</translation>
+    </message>
+    <message>
+        <source>%1 KB</source>
+        <translation type="obsolete">%1 KB</translation>
+    </message>
+    <message>
+        <source>%1 bytes</source>
+        <translation type="obsolete">%1 byte</translation>
+    </message>
+    <message>
+        <source>Invalid filename</source>
+        <translation type="obsolete">Nome del file non valido</translation>
+    </message>
+    <message>
+        <source>&lt;b&gt;The name &quot;%1&quot; can not be used.&lt;/b&gt;&lt;p&gt;Try using another name, with fewer characters or no punctuations marks.</source>
+        <translation type="obsolete">&lt;b&gt;Il nome &quot;%1&quot; non può essere utilizzato.&lt;/b&gt;&lt;p&gt;Si consiglia di utilizzarne uno con meno caratteri o senza segni di punteggiatura.</translation>
+    </message>
+    <message>
+        <source>Name</source>
+        <translation type="obsolete">Nome</translation>
+    </message>
+    <message>
+        <source>Size</source>
+        <translation type="obsolete">Dimensione</translation>
+    </message>
+    <message>
+        <source>Kind</source>
+        <comment>Match OS X Finder</comment>
+        <translation type="obsolete">Tipo</translation>
+    </message>
+    <message>
+        <source>Type</source>
+        <comment>All other platforms</comment>
+        <translation type="obsolete">Tipo</translation>
+    </message>
+    <message>
+        <source>Date Modified</source>
+        <translation type="obsolete">Data Ultima Modifica</translation>
+    </message>
+</context>
+<context>
+    <name>QFontDialog</name>
+    <message>
+        <source>Select Font</source>
+        <translation type="obsolete">Seleziona Tipo di Carattere</translation>
+    </message>
+    <message>
+        <source>&amp;Font</source>
+        <translation type="obsolete">&amp;Tipo</translation>
+    </message>
+    <message>
+        <source>Font st&amp;yle</source>
+        <translation type="obsolete">&amp;Stile</translation>
+    </message>
+    <message>
+        <source>&amp;Size</source>
+        <translation type="obsolete">&amp;Dimensione</translation>
+    </message>
+    <message>
+        <source>Effects</source>
+        <translation type="obsolete">Effetti</translation>
+    </message>
+    <message>
+        <source>Stri&amp;keout</source>
+        <translation type="obsolete">Bar&amp;rato</translation>
+    </message>
+    <message>
+        <source>&amp;Underline</source>
+        <translation type="obsolete">&amp;Sottolineato</translation>
+    </message>
+    <message>
+        <source>Sample</source>
+        <translation type="obsolete">Colore</translation>
+    </message>
+    <message>
+        <source>Wr&amp;iting System</source>
+        <translation type="obsolete">Sistema di Scrittura</translation>
+    </message>
+</context>
+<context>
+    <name>QInputDialog</name>
+    <message>
+        <source>Enter a value:</source>
+        <translation type="obsolete">Inserire un valore:</translation>
+    </message>
+</context>
+<context>
+    <name>QMessageBox</name>
+    <message>
+        <source>Show Details...</source>
+        <translation type="obsolete">Mostra Dettagli...</translation>
+    </message>
+    <message>
+        <source>Hide Details...</source>
+        <translation type="obsolete">Nascondi Dettagli...</translation>
+    </message>
+    <message>
+        <source>OK</source>
+        <translation type="obsolete">OK</translation>
+    </message>
+    <message>
+        <source>Help</source>
+        <translation type="obsolete">Aiuto</translation>
+    </message>
+    <message>
+        <source>&lt;h3&gt;About Qt&lt;/h3&gt;&lt;p&gt;This program uses Qt version %1.&lt;/p&gt;</source>
+        <translation type="obsolete">&lt;h3&gt;A proposito Qt&lt;/h3&gt;&lt;p&gt;Questo programma utilizza Qt versione %1.&lt;/p&gt;</translation>
+    </message>
+    <message>
+        <source>&lt;p&gt;Qt is a C++ toolkit for cross-platform application development.&lt;/p&gt;&lt;p&gt;Qt provides single-source portability across MS&amp;nbsp;Windows, Mac&amp;nbsp;OS&amp;nbsp;X, Linux, and all major commercial Unix variants. Qt is also available for embedded devices as Qt for Embedded Linux and Qt for Windows CE.&lt;/p&gt;&lt;p&gt;Qt is available under three different licensing options designed to accommodate the needs of our various users.&lt;/p&gt;&lt;p&gt;Qt licensed under our commercial license agreement is appropriate for development of proprietary/commercial software where you do not want to share any source code with third parties or otherwise cannot comply with the terms of the GNU LGPL version 2.1 or GNU GPL version 3.0.&lt;/p&gt;&lt;p&gt;Qt licensed under the GNU LGPL version 2.1 is appropriate for the development of Qt applications (proprietary or open source) provided you can comply with the terms and conditions of the GNU LGPL version 2.1.&lt;/p&gt;&lt;p&gt;Qt licensed under the GNU General Public License version 3.0 is appropriate for the development of Qt applications where you wish to use such applications in combination with software subject to the terms of the GNU GPL version 3.0 or where you are otherwise willing to comply with the terms of the GNU GPL version 3.0.&lt;/p&gt;&lt;p&gt;Please see &lt;a href=&quot;http://qt.digia.com/product/licensing&quot;&gt;qt.digia.com/product/licensing&lt;/a&gt; for an overview of Qt licensing.&lt;/p&gt;&lt;p&gt;Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).&lt;/p&gt;&lt;p&gt;Qt is a Digia product. See &lt;a href=&quot;http://qt.digia.com/&quot;&gt;qt.digia.com&lt;/a&gt; for more information.&lt;/p&gt;</source>
+        <translation type="obsolete">&lt;p&gt;Qt è uno strumento per lo sviluppo di applicazioni multipiattaforma.&lt;/p&gt;&lt;p&gt;Fornisce portabilità completa fra MS&amp;nbsp;Windows, Mac&amp;nbsp;OS&amp;nbsp;X, Linux e tutte le principali varianti commerciali di Unix, ed è disponibile per dispositivi embedded come Qt for Embedded Linux e Qt for Windows CE.&lt;/p&gt;&lt;p&gt;Tre opzioni di liceza sono disponibili per rispondede alle esigenze eterogenee dei nostri utenti.&lt;/p&gt;&lt;p&gt;La licenza commerciale è adatta allo sviluppo di software proprietario e/o commerciale, quando non si desidera condividere codice sorgente con terze parti o si è in altro modo impossibilitati a rispettare i termini delle licenze GNU LGPL versione 2.1 o GNU GPL version 3.0.&lt;/p&gt;&lt;p&gt;La licenza GNU LGPL versione 2.1 si presta allo sviluppo di allpicazioni Qt (proprietarie o a sorgente aperto), qualora si sia in condizione di rispettare i termini e le condizioni della licenza GNU LGPL version 2.1.&lt;/p&gt;&lt;p&gt;La licenza GNU GPL versione 3.0 è adatta allo sviluppo di applicazioni Qt che si desidera utilizzare in combinazione con software soggetto ai termini della licenza GNU GPL version 3.0 o quando si desidera rispettare i termini della licenza GNU GPL version 3.0.&lt;/p&gt;&lt;p&gt;Si faccia riferimento a &lt;a href=&quot;http://qt.digia.com/product/licensing&quot;&gt;qt.digia.com/product/licensing&lt;/a&gt; per una panoramica delle opzioni di licenza di Qt. &lt;/p&gt;&lt;p&gt;Copyright (C) 2013 Digia Plc e/o sussidiarie.&lt;/p&gt;&lt;p&gt;Qt è un prodotto Digia. Si veda &lt;a href=&quot;http://qt.digia.com/&quot;&gt;qt.digia.com&lt;/a&gt; per maggiori informazioni.&lt;/p&gt;</translation>
+    </message>
+    <message>
+        <source>About Qt</source>
+        <translation type="obsolete">A proposito di Qt</translation>
+    </message>
+</context>
+<context>
+    <name>QObject</name>
+    <message>
+        <location filename="../src/workspace-model.cc" line="+75"/>
+        <source>automatic</source>
+        <translation>automatico</translation>
+    </message>
+    <message>
+        <location line="+1"/>
+        <source>function</source>
+        <translation>funzione</translation>
+    </message>
+    <message>
+        <location line="+1"/>
+        <source>global</source>
+        <translation>globale</translation>
+    </message>
+    <message>
+        <location line="+1"/>
+        <source>hidden</source>
+        <translation>nascosto</translation>
+    </message>
+    <message>
+        <location line="+1"/>
+        <source>inherited</source>
+        <translation>ereditato</translation>
+    </message>
+    <message>
+        <location line="+1"/>
+        <source>persistent</source>
+        <translation>persistente</translation>
+    </message>
+    <message>
+        <location filename="../qterminal/libqterminal/QTerminal.cc" line="+65"/>
+        <source>foreground</source>
+        <translation>primo piano</translation>
+    </message>
+    <message>
+        <location line="+1"/>
+        <source>background</source>
+        <translation>sfondo</translation>
+    </message>
+    <message>
+        <location line="+1"/>
+        <source>selection</source>
+        <translation>selezione</translation>
+    </message>
+    <message>
+        <location line="+1"/>
+        <source>cursor</source>
+        <translation>cursore</translation>
+    </message>
+    <message>
+        <source>&lt;p&gt;&lt;strong&gt;A Note about Octave&apos;s New GUI&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;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.  But because it is not quite as polished as we would like, we have decided to wait until the 4.0.x release series before making the GUI the default interface.&lt;/p&gt;&lt;p&gt;Given the length of time and the number of bug fixes and improvements since the last major release, we also decided against delaying the release of all these new improvements any longer just to perfect the GUI.  So please enjoy the 3.8 release of Octave and the preview of the new GUI.  We believe it is working reasonably well, but we also know that there are some obvious rough spots and many things that could be improved.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;We Need Your Help&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;There are many ways that you can help us fix the remaining problems, complete the GUI, and improve the overall user experience for both novices and experts alike (links will open an external browser):&lt;/p&gt;&lt;p&gt;&lt;ul&gt;&lt;li&gt;If you are a skilled software developer, you can help by contributing your time to help &lt;a href=&quot;http://octave.org/get-involved.html&quot;&gt;develop Octave&lt;/a&gt;.&lt;/li&gt;&lt;li&gt;If Octave does not work properly, you are encouraged to &lt;a href=&quot;http://octave.org/bugs.html&quot;&gt;report problems &lt;/a&gt; that you find.&lt;/li&gt;&lt;li&gt;Whether you are a user or developer, you can &lt;a href=&quot;http://octave.org/donate.html&quot;&gt;help to fund the project&lt;/a&gt;.  Octave development takes a lot of time and expertise.  Your contributions help to ensure that Octave will continue to improve.&lt;/li&gt;&lt;/ul&gt;&lt;/p&gt;&lt;p&gt;We hope you find Octave to be useful.  Please help us make it even better for the future!&lt;/p&gt;</source>
+        <translation type="obsolete">&lt;p&gt;&lt;strong&gt;Nota sulla nuova interfaccia grafica di Octave&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;Una delle maggiori novità di Octave 3.8 è l&apos;interfaccia grafica utente. Si tratta della caratteristica più richiesta dagli utenti negli ultimi anni, ed ora è quasi pronta. Tuttavia, poiché essa non è ancora rifinita come vorremmo, abbiamo deciso di attendere fino alle serie di rilascio 4.0.x prima di renderla l&apos;interfaccia predefinita.&lt;/p&gt;&lt;p&gt;D&apos;altro canto, considerato il lasso di tempo trascorso, i problemi risolti ed i miglioramenti dall&apos;ultima &apos;major release&apos;, abbiamo deciso di non ritardare ulteriormente un nuovo rilascio soltanto per perfezionare l&apos;interfaccia grafica ed è pertanto con piacere che presentiamo la versione 3.8 di Octave con un&apos;anteprima dell&apos;interfaccia grafica. Crediamo che funzioni sufficientemente bene, pur avendo ancora qualche problema ed aspetti che potrebbero essere migliorati.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Abbiamo bisogno del tuo aiuto&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;Sono molti i modi in cui puoi aiutare a risolvere i problemi restanti, a completare l&apos;interfaccia grafica e a migliorare in generale l&apos;esperienza di utilizzo, tanto per i principianti quanto per gli utenti esperti:&lt;/p&gt;&lt;p&gt;&lt;ul&gt;&lt;li&gt;Se sei un programmatore esperto, puoi aiutare contribuendo allo &lt;a href=&quot;http://octave.org/get-involved.html&quot;&gt;sviluppo di Octave&lt;/a&gt;.&lt;/li&gt;&lt;li&gt;Se Octave non funziona correttamente, ti incoraggiamo inoltre a &lt;a href=&quot;http://octave.org/bugs.html&quot;&gt;segnalare i problemi&lt;/a&gt; che incontri.&lt;/li&gt;&lt;li&gt;Che tu sia un utente o uno sviluppatore, puoi aiutare a &lt;a href=&quot;http://octave.org/donate.html&quot;&gt;finanziare il progetto&lt;/a&gt;. Lo sviluppo di questo software richiede molto tempo e molte competenze.  I tuoi contributi aiutano ad assicurare il continuo miglioramento del software.&lt;/li&gt;&lt;/ul&gt;&lt;/p&gt;&lt;p&gt;Speriamo che troverai Octave utile. Perfavore, aiutaci a renderlo ancora migliore per il futuro!&lt;/p&gt;</translation>
+    </message>
+</context>
+<context>
+    <name>QPPDOptionsModel</name>
+    <message>
+        <source>Name</source>
+        <translation type="obsolete">Nome</translation>
+    </message>
+    <message>
+        <source>Value</source>
+        <translation type="obsolete">Valore</translation>
+    </message>
+</context>
+<context>
+    <name>QPageSetupWidget</name>
+    <message>
+        <source>Centimeters (cm)</source>
+        <translation type="obsolete">Centimetri (cm)</translation>
+    </message>
+    <message>
+        <source>Millimeters (mm)</source>
+        <translation type="obsolete">Millimetri (mm)</translation>
+    </message>
+    <message>
+        <source>Inches (in)</source>
+        <translation type="obsolete">Pollici (in)</translation>
+    </message>
+    <message>
+        <source>Points (pt)</source>
+        <translation type="obsolete">Punti (pt)</translation>
+    </message>
+</context>
+<context>
+    <name>QPrintDialog</name>
+    <message>
+        <source>Print</source>
+        <translation type="obsolete">Stampa</translation>
+    </message>
+    <message>
+        <source>A0</source>
+        <translation type="obsolete">A0</translation>
+    </message>
+    <message>
+        <source>A1</source>
+        <translation type="obsolete">A1</translation>
+    </message>
+    <message>
+        <source>A2</source>
+        <translation type="obsolete">A2</translation>
+    </message>
+    <message>
+        <source>A3</source>
+        <translation type="obsolete">A3</translation>
+    </message>
+    <message>
+        <source>A4</source>
+        <translation type="obsolete">A4</translation>
+    </message>
+    <message>
+        <source>A5</source>
+        <translation type="obsolete">A5</translation>
+    </message>
+    <message>
+        <source>A6</source>
+        <translation type="obsolete">A6</translation>
+    </message>
+    <message>
+        <source>A7</source>
+        <translation type="obsolete">A7</translation>
+    </message>
+    <message>
+        <source>A8</source>
+        <translation type="obsolete">A8</translation>
+    </message>
+    <message>
+        <source>A9</source>
+        <translation type="obsolete">A9</translation>
+    </message>
+    <message>
+        <source>B0</source>
+        <translation type="obsolete">B0</translation>
+    </message>
+    <message>
+        <source>B1</source>
+        <translation type="obsolete">B1</translation>
+    </message>
+    <message>
+        <source>B2</source>
+        <translation type="obsolete">B2</translation>
+    </message>
+    <message>
+        <source>B3</source>
+        <translation type="obsolete">B3</translation>
+    </message>
+    <message>
+        <source>B4</source>
+        <translation type="obsolete">B4</translation>
+    </message>
+    <message>
+        <source>B5</source>
+        <translation type="obsolete">B5</translation>
+    </message>
+    <message>
+        <source>B6</source>
+        <translation type="obsolete">B6</translation>
+    </message>
+    <message>
+        <source>B7</source>
+        <translation type="obsolete">B7</translation>
+    </message>
+    <message>
+        <source>B8</source>
+        <translation type="obsolete">B8</translation>
+    </message>
+    <message>
+        <source>B9</source>
+        <translation type="obsolete">B9</translation>
+    </message>
+    <message>
+        <source>B10</source>
+        <translation type="obsolete">B10</translation>
+    </message>
+    <message>
+        <source>C5E</source>
+        <translation type="obsolete">C5E</translation>
+    </message>
+    <message>
+        <source>DLE</source>
+        <translation type="obsolete">DLE</translation>
+    </message>
+    <message>
+        <source>Executive</source>
+        <translation type="obsolete">Executive</translation>
+    </message>
+    <message>
+        <source>Folio</source>
+        <translation type="obsolete">Folio</translation>
+    </message>
+    <message>
+        <source>Ledger</source>
+        <translation type="obsolete">Ledger</translation>
+    </message>
+    <message>
+        <source>Legal</source>
+        <translation type="obsolete">Legal</translation>
+    </message>
+    <message>
+        <source>Letter</source>
+        <translation type="obsolete">Letter</translation>
+    </message>
+    <message>
+        <source>Tabloid</source>
+        <translation type="obsolete">Tabloid</translation>
+    </message>
+    <message>
+        <source>US Common #10 Envelope</source>
+        <translation type="obsolete">US Common #10 Envelope</translation>
+    </message>
+    <message>
+        <source>Custom</source>
+        <translation type="obsolete">Personalizzato</translation>
+    </message>
+    <message>
+        <source>File exists</source>
+        <translation type="obsolete">Il file esiste</translation>
+    </message>
+    <message>
+        <source>&lt;qt&gt;Do you want to overwrite it?&lt;/qt&gt;</source>
+        <translation type="obsolete">&lt;qt&gt;Si desidera sovrascriverlo?&lt;/qt&gt;</translation>
+    </message>
+    <message>
+        <source>A0 (841 x 1189 mm)</source>
+        <translation type="obsolete">A0 (841 x 1189 mm)</translation>
+    </message>
+    <message>
+        <source>A1 (594 x 841 mm)</source>
+        <translation type="obsolete">A1 (594 x 841 mm)</translation>
+    </message>
+    <message>
+        <source>A2 (420 x 594 mm)</source>
+        <translation type="obsolete">A2 (420 x 594 mm)</translation>
+    </message>
+    <message>
+        <source>A3 (297 x 420 mm)</source>
+        <translation type="obsolete">A3 (297 x 420 mm)</translation>
+    </message>
+    <message>
+        <source>A4 (210 x 297 mm, 8.26 x 11.7 inches)</source>
+        <translation type="obsolete">A4 (210 x 297 mm, 8.26 x 11.7 inches)</translation>
+    </message>
+    <message>
+        <source>A5 (148 x 210 mm)</source>
+        <translation type="obsolete">A5 (148 x 210 mm)&gt;A5 (148 x 210 mm)</translation>
+    </message>
+    <message>
+        <source>A6 (105 x 148 mm)</source>
+        <translation type="obsolete">A6 (105 x 148 mm)</translation>
+    </message>
+    <message>
+        <source>A7 (74 x 105 mm)</source>
+        <translation type="obsolete">A7 (74 x 105 mm)</translation>
+    </message>
+    <message>
+        <source>A8 (52 x 74 mm)</source>
+        <translation type="obsolete">A8 (52 x 74 mm)</translation>
+    </message>
+    <message>
+        <source>A9 (37 x 52 mm)</source>
+        <translation type="obsolete">A9 (37 x 52 mm)</translation>
+    </message>
+    <message>
+        <source>B0 (1000 x 1414 mm)</source>
+        <translation type="obsolete">B0 (1000 x 1414 mm)</translation>
+    </message>
+    <message>
+        <source>B1 (707 x 1000 mm)</source>
+        <translation type="obsolete">B1 (707 x 1000 mm)</translation>
+    </message>
+    <message>
+        <source>B2 (500 x 707 mm)</source>
+        <translation type="obsolete">B2 (500 x 707 mm)</translation>
+    </message>
+    <message>
+        <source>B3 (353 x 500 mm)</source>
+        <translation type="obsolete">B3 (353 x 500 mm)</translation>
+    </message>
+    <message>
+        <source>B4 (250 x 353 mm)</source>
+        <translation type="obsolete">B4 (250 x 353 mm)</translation>
+    </message>
+    <message>
+        <source>B5 (176 x 250 mm, 6.93 x 9.84 inches)</source>
+        <translation type="obsolete">B5 (176 x 250 mm, 6.93 x 9.84 pollici)</translation>
+    </message>
+    <message>
+        <source>B6 (125 x 176 mm)</source>
+        <translation type="obsolete">B6 (125 x 176 mm)</translation>
+    </message>
+    <message>
+        <source>B7 (88 x 125 mm)</source>
+        <translation type="obsolete">B7 (88 x 125 mm)</translation>
+    </message>
+    <message>
+        <source>B8 (62 x 88 mm)</source>
+        <translation type="obsolete">B8 (62 x 88 mm)</translation>
+    </message>
+    <message>
+        <source>B9 (44 x 62 mm)</source>
+        <translation type="obsolete">B9 (44 x 62 mm)</translation>
+    </message>
+    <message>
+        <source>B10 (31 x 44 mm)</source>
+        <translation type="obsolete">B10 (31 x 44 mm)</translation>
+    </message>
+    <message>
+        <source>C5E (163 x 229 mm)</source>
+        <translation type="obsolete">C5E (163 x 229 mm)</translation>
+    </message>
+    <message>
+        <source>DLE (110 x 220 mm)</source>
+        <translation type="obsolete">DLE (110 x 220 mm)</translation>
+    </message>
+    <message>
+        <source>Executive (7.5 x 10 inches, 191 x 254 mm)</source>
+        <translation type="obsolete">Executive (7.5 x 10 pollici, 191 x 254 mm)</translation>
+    </message>
+    <message>
+        <source>Folio (210 x 330 mm)</source>
+        <translation type="obsolete">Folio (210 x 330 mm)</translation>
+    </message>
+    <message>
+        <source>Ledger (432 x 279 mm)</source>
+        <translation type="obsolete">Ledger (432 x 279 mm)</translation>
+    </message>
+    <message>
+        <source>Legal (8.5 x 14 inches, 216 x 356 mm)</source>
+        <translation type="obsolete">Legal (8.5 x 14 pollici, 216 x 356 mm)</translation>
+    </message>
+    <message>
+        <source>Letter (8.5 x 11 inches, 216 x 279 mm)</source>
+        <translation type="obsolete">Letter (8.5 x 11 pollici, 216 x 279 mm)</translation>
+    </message>
+    <message>
+        <source>Tabloid (279 x 432 mm)</source>
+        <translation type="obsolete">Tabloid (279 x 432 mm)</translation>
+    </message>
+    <message>
+        <source>US Common #10 Envelope (105 x 241 mm)</source>
+        <translation type="obsolete">US Common #10 Busta (105 x 241 mm)</translation>
+    </message>
+    <message>
+        <source>Print all</source>
+        <translation type="obsolete">Stampa tutto</translation>
+    </message>
+    <message>
+        <source>Print selection</source>
+        <translation type="obsolete">Stampa selezione</translation>
+    </message>
+    <message>
+        <source>Print range</source>
+        <translation type="obsolete">Stampa intervallo</translation>
+    </message>
+    <message>
+        <source>Print current page</source>
+        <translation type="obsolete">Stampa la pagina corrente</translation>
+    </message>
+    <message>
+        <source>&amp;Options &gt;&gt;</source>
+        <translation type="obsolete">&amp;Opzioni&gt;&gt;</translation>
+    </message>
+    <message>
+        <source>&amp;Print</source>
+        <translation type="obsolete">&amp;Stampa</translation>
+    </message>
+    <message>
+        <source>&amp;Options &lt;&lt;</source>
+        <translation type="obsolete">&amp;Opzioni</translation>
+    </message>
+    <message>
+        <source>Print to File (PDF)</source>
+        <translation type="obsolete">Stampa su file (PDF)</translation>
+    </message>
+    <message>
+        <source>Print to File (Postscript)</source>
+        <translation type="obsolete">Stampa su file (Postscript)</translation>
+    </message>
+    <message>
+        <source>Local file</source>
+        <translation type="obsolete">File locale</translation>
+    </message>
+    <message>
+        <source>Write %1 file</source>
+        <translation type="obsolete">Scrivi %1 file</translation>
+    </message>
+    <message>
+        <source>Print To File...</source>
+        <translation type="obsolete">Stampa su file...</translation>
+    </message>
+    <message>
+        <source>%1 is a directory.
+Please choose a different file name.</source>
+        <translation type="obsolete">%1 è una cartella.
+Si prega di scegliere un altro nome.</translation>
+    </message>
+    <message>
+        <source>File %1 is not writable.
+Please choose a different file name.</source>
+        <translation type="obsolete">%1 non è scrivibile.
+Si prega di scegliere un altro nome.</translation>
+    </message>
+    <message>
+        <source>%1 already exists.
+Do you want to overwrite it?</source>
+        <translation type="obsolete">%1 esiste già.
+Si desidera sovrascriverlo?</translation>
+    </message>
+    <message>
+        <source>The &apos;From&apos; value cannot be greater than the &apos;To&apos; value.</source>
+        <translation type="obsolete">Il valore &apos;Da&apos; non può superare il valore &apos;A&apos;.</translation>
+    </message>
+    <message>
+        <source>OK</source>
+        <translation type="obsolete">OK</translation>
+    </message>
+</context>
+<context>
+    <name>QPrintPreviewDialog</name>
+    <message>
+        <source>Page Setup</source>
+        <translation type="obsolete">Formato Pagina</translation>
+    </message>
+</context>
+<context>
+    <name>QTerminal</name>
+    <message>
+        <location filename="../qterminal/libqterminal/QTerminal.h" line="+127"/>
+        <source>Copy</source>
+        <translation>Copia</translation>
+    </message>
+    <message>
+        <location line="+4"/>
+        <source>Paste</source>
+        <translation>Incolla</translation>
+    </message>
+    <message>
+        <location line="+5"/>
+        <source>Select All</source>
+        <translation>Seleziona Tutto</translation>
+    </message>
+    <message>
+        <location line="+5"/>
+        <source>Clear All</source>
+        <translation>Pulisci tutto</translation>
+    </message>
+</context>
+<context>
+    <name>QWinTerminalImpl</name>
+    <message>
+        <location filename="../qterminal/libqterminal/win32/QWinTerminalImpl.cpp" line="+1776"/>
+        <source>copied selection to clipboard</source>
+        <translation>selezione copiata negli appunti</translation>
+    </message>
+</context>
+<context>
+    <name>QsciLexerBash</name>
+    <message>
+        <source>Default</source>
+        <translation type="obsolete">Default</translation>
+    </message>
+    <message>
+        <source>Error</source>
+        <translation type="obsolete">Errore</translation>
+    </message>
+    <message>
+        <source>Comment</source>
+        <translation type="obsolete">Commento</translation>
+    </message>
+    <message>
+        <source>Number</source>
+        <translation type="obsolete">Numero</translation>
+    </message>
+    <message>
+        <source>Keyword</source>
+        <translation type="obsolete">Parola chiave</translation>
+    </message>
+    <message>
+        <source>Double-quoted string</source>
+        <translation type="obsolete">Stringa con doppi apici</translation>
+    </message>
+    <message>
+        <source>Single-quoted string</source>
+        <translation type="obsolete">Stringa con singoli apici</translation>
+    </message>
+    <message>
+        <source>Operator</source>
+        <translation type="obsolete">Operatore</translation>
+    </message>
+    <message>
+        <source>Identifier</source>
+        <translation type="obsolete">Identificatore</translation>
+    </message>
+    <message>
+        <source>Scalar</source>
+        <translation type="obsolete">Scalare</translation>
+    </message>
+    <message>
+        <source>Parameter expansion</source>
+        <translation type="obsolete">Espansione dei parametri</translation>
+    </message>
+    <message>
+        <source>Backticks</source>
+        <translation type="obsolete">Apici inversi</translation>
+    </message>
+    <message>
+        <source>Here document delimiter</source>
+        <translation type="obsolete">Delimitatore dello &quot;here document&quot;</translation>
+    </message>
+    <message>
+        <source>Single-quoted here document</source>
+        <translation type="obsolete">&quot;Here document&quot; delimitato da singoli apici</translation>
+    </message>
+</context>
+<context>
+    <name>QsciLexerBatch</name>
+    <message>
+        <source>Default</source>
+        <translation type="obsolete">Default</translation>
+    </message>
+    <message>
+        <source>Comment</source>
+        <translation type="obsolete">Commento</translation>
+    </message>
+    <message>
+        <source>Keyword</source>
+        <translation type="obsolete">Parola chiave</translation>
+    </message>
+    <message>
+        <source>Label</source>
+        <translation type="obsolete">Etichetta</translation>
+    </message>
+    <message>
+        <source>Hide command character</source>
+        <translation type="obsolete">Nascondi caratteri di comando</translation>
+    </message>
+    <message>
+        <source>External command</source>
+        <translation type="obsolete">Comando esterno</translation>
+    </message>
+    <message>
+        <source>Variable</source>
+        <translation type="obsolete">Variabile</translation>
+    </message>
+    <message>
+        <source>Operator</source>
+        <translation type="obsolete">Operatore</translation>
+    </message>
+</context>
+<context>
+    <name>QsciLexerCPP</name>
+    <message>
+        <source>Default</source>
+        <translation type="obsolete">Default</translation>
+    </message>
+    <message>
+        <source>Inactive default</source>
+        <translation type="obsolete">Default inattivo</translation>
+    </message>
+    <message>
+        <source>C comment</source>
+        <translation type="obsolete">Commento C</translation>
+    </message>
+    <message>
+        <source>Inactive C comment</source>
+        <translation type="obsolete">Commento C inattivo</translation>
+    </message>
+    <message>
+        <source>C++ comment</source>
+        <translation type="obsolete">Commento C++</translation>
+    </message>
+    <message>
+        <source>Inactive C++ comment</source>
+        <translation type="obsolete">Commento C++ inattivo</translation>
+    </message>
+    <message>
+        <source>JavaDoc style C comment</source>
+        <translation type="obsolete">Commento C in stile JavaDoc</translation>
+    </message>
+    <message>
+        <source>Inactive JavaDoc style C comment</source>
+        <translation type="obsolete">Commento C inattivo in stile JavaDoc</translation>
+    </message>
+    <message>
+        <source>Number</source>
+        <translation type="obsolete">Numero</translation>
+    </message>
+    <message>
+        <source>Inactive number</source>
+        <translation type="obsolete">Numero inattivo</translation>
+    </message>
+    <message>
+        <source>Keyword</source>
+        <translation type="obsolete">Parola chiave</translation>
+    </message>
+    <message>
+        <source>Inactive keyword</source>
+        <translation type="obsolete">Parola chiave inattiva</translation>
+    </message>
+    <message>
+        <source>Double-quoted string</source>
+        <translation type="obsolete">Stringa con doppi apici</translation>
+    </message>
+    <message>
+        <source>Inactive double-quoted string</source>
+        <translation type="obsolete">Stringa con doppi apici inattiva</translation>
+    </message>
+    <message>
+        <source>Single-quoted string</source>
+        <translation type="obsolete">Stringa con singoli apici</translation>
+    </message>
+    <message>
+        <source>Inactive single-quoted string</source>
+        <translation type="obsolete">Stringa con singoli apici inattiva</translation>
+    </message>
+    <message>
+        <source>IDL UUID</source>
+        <translation type="obsolete">UUID IDL</translation>
+    </message>
+    <message>
+        <source>Inactive IDL UUID</source>
+        <translation type="obsolete">UUID IDL inattivo</translation>
+    </message>
+    <message>
+        <source>Pre-processor block</source>
+        <translation type="obsolete">Blocco per il precompilatore</translation>
+    </message>
+    <message>
+        <source>Inactive pre-processor block</source>
+        <translation type="obsolete">Blocco inattivo per il precompilatore</translation>
+    </message>
+    <message>
+        <source>Operator</source>
+        <translation type="obsolete">Operatore</translation>
+    </message>
+    <message>
+        <source>Inactive operator</source>
+        <translation type="obsolete">Operatore inattivo</translation>
+    </message>
+    <message>
+        <source>Identifier</source>
+        <translation type="obsolete">Identificatore</translation>
+    </message>
+    <message>
+        <source>Inactive identifier</source>
+        <translation type="obsolete">Identificatore inattivo</translation>
+    </message>
+    <message>
+        <source>Unclosed string</source>
+        <translation type="obsolete">Stringa non terminata</translation>
+    </message>
+    <message>
+        <source>Inactive unclosed string</source>
+        <translation type="obsolete">Stringa non terminata inattiva</translation>
+    </message>
+    <message>
+        <source>C# verbatim string</source>
+        <translation type="obsolete">Stringa senza formattazione C#</translation>
+    </message>
+    <message>
+        <source>Inactive C# verbatim string</source>
+        <translation type="obsolete">Stringa senza formattazione C# inattiva</translation>
+    </message>
+    <message>
+        <source>JavaScript regular expression</source>
+        <translation type="obsolete">Espressione regolare JavaScript</translation>
+    </message>
+    <message>
+        <source>Inactive JavaScript regular expression</source>
+        <translation type="obsolete">Espressione regolare JavaScript inattiva</translation>
+    </message>
+    <message>
+        <source>JavaDoc style C++ comment</source>
+        <translation type="obsolete">Commento C++ in stile JavaDoc</translation>
+    </message>
+    <message>
+        <source>Inactive JavaDoc style C++ comment</source>
+        <translation type="obsolete">Commento C++ inattivo in stile JavaDoc</translation>
+    </message>
+    <message>
+        <source>Secondary keywords and identifiers</source>
+        <translation type="obsolete">Parole chiave ed identificatori secondari</translation>
+    </message>
+    <message>
+        <source>Inactive secondary keywords and identifiers</source>
+        <translation type="obsolete">Parole chiave ed identificatori secondari inattivi</translation>
+    </message>
+    <message>
+        <source>JavaDoc keyword</source>
+        <translation type="obsolete">Parola chiave JavaDoc</translation>
+    </message>
+    <message>
+        <source>Inactive JavaDoc keyword</source>
+        <translation type="obsolete">Parola chiave JavaDoc inattiva</translation>
+    </message>
+    <message>
+        <source>JavaDoc keyword error</source>
+        <translation type="obsolete">Errore in una parola chiave JavaDoc</translation>
+    </message>
+    <message>
+        <source>Inactive JavaDoc keyword error</source>
+        <translation type="obsolete">Errore in una parola chiave JavaDoc inattiva</translation>
+    </message>
+    <message>
+        <source>Global classes and typedefs</source>
+        <translation type="obsolete">Classi e typedef globali</translation>
+    </message>
+    <message>
+        <source>Inactive global classes and typedefs</source>
+        <translation type="obsolete">Classi e typedef globali inattivi</translation>
+    </message>
+    <message>
+        <source>Stringa C++ </source>
+        <translation type="obsolete">Stringa &quot;raw&quot; C++</translation>
+    </message>
+    <message>
+        <source>Inactive C++ raw string</source>
+        <translation type="obsolete">Stringa &quot;raw&quot; C++ inattiva</translation>
+    </message>
+</context>
+<context>
+    <name>QsciLexerDiff</name>
+    <message>
+        <source>Default</source>
+        <translation type="obsolete">Default</translation>
+    </message>
+    <message>
+        <source>Comment</source>
+        <translation type="obsolete">Commento</translation>
+    </message>
+    <message>
+        <source>Command</source>
+        <translation type="obsolete">Comando</translation>
+    </message>
+    <message>
+        <source>Header</source>
+        <translation type="obsolete">Intestazione</translation>
+    </message>
+    <message>
+        <source>Position</source>
+        <translation type="obsolete">Posizione</translation>
+    </message>
+    <message>
+        <source>Removed line</source>
+        <translation type="obsolete">Riga rimossa</translation>
+    </message>
+    <message>
+        <source>Added line</source>
+        <translation type="obsolete">Riga aggiunta</translation>
+    </message>
+    <message>
+        <source>Changed line</source>
+        <translation type="obsolete">Riga modificata</translation>
+    </message>
+</context>
+<context>
+    <name>QsciLexerMatlab</name>
+    <message>
+        <source>Default</source>
+        <translation type="obsolete">Default</translation>
+    </message>
+    <message>
+        <source>Comment</source>
+        <translation type="obsolete">Commento</translation>
+    </message>
+    <message>
+        <source>Command</source>
+        <translation type="obsolete">Comando</translation>
+    </message>
+    <message>
+        <source>Number</source>
+        <translation type="obsolete">Numero</translation>
+    </message>
+    <message>
+        <source>Keyword</source>
+        <translation type="obsolete">Parola chiave</translation>
+    </message>
+    <message>
+        <source>Single-quoted string</source>
+        <translation type="obsolete">Stringa con singoli apici</translation>
+    </message>
+    <message>
+        <source>Operator</source>
+        <translation type="obsolete">Operatore</translation>
+    </message>
+    <message>
+        <source>Identifier</source>
+        <translation type="obsolete">Identificatore</translation>
+    </message>
+    <message>
+        <source>Double-quoted string</source>
+        <translation type="obsolete">Stringa con doppi apici</translation>
+    </message>
+</context>
+<context>
+    <name>QsciLexerPerl</name>
+    <message>
+        <source>Default</source>
+        <translation type="obsolete">Default</translation>
+    </message>
+    <message>
+        <source>Error</source>
+        <translation type="obsolete">Errore</translation>
+    </message>
+    <message>
+        <source>Comment</source>
+        <translation type="obsolete">Commento</translation>
+    </message>
+    <message>
+        <source>POD</source>
+        <translation type="obsolete">POD</translation>
+    </message>
+    <message>
+        <source>Number</source>
+        <translation type="obsolete">Numero</translation>
+    </message>
+    <message>
+        <source>Keyword</source>
+        <translation type="obsolete">Parola chiave</translation>
+    </message>
+    <message>
+        <source>Double-quoted string</source>
+        <translation type="obsolete">Stringa con doppi apici</translation>
+    </message>
+    <message>
+        <source>Single-quoted string</source>
+        <translation type="obsolete">Stringa con apici singoli</translation>
+    </message>
+    <message>
+        <source>Operator</source>
+        <translation type="obsolete">Operatore</translation>
+    </message>
+    <message>
+        <source>Identifier</source>
+        <translation type="obsolete">Identificatore</translation>
+    </message>
+    <message>
+        <source>Scalar</source>
+        <translation type="obsolete">Scalare</translation>
+    </message>
+    <message>
+        <source>Array</source>
+        <translation type="obsolete">Vettore</translation>
+    </message>
+    <message>
+        <source>Hash</source>
+        <translation type="obsolete">Hash</translation>
+    </message>
+    <message>
+        <source>Symbol table</source>
+        <translation type="obsolete">Tabella dei simboli</translation>
+    </message>
+    <message>
+        <source>Regular expression</source>
+        <translation type="obsolete">Espressione regolare</translation>
+    </message>
+    <message>
+        <source>Substitution</source>
+        <translation type="obsolete">Sostituzione</translation>
+    </message>
+    <message>
+        <source>Backticks</source>
+        <translation type="obsolete">Apici inversi</translation>
+    </message>
+    <message>
+        <source>Data section</source>
+        <translation type="obsolete">Sezione dati</translation>
+    </message>
+    <message>
+        <source>Here document delimiter</source>
+        <translation type="obsolete">Delimitatore dello &quot;here document&quot;</translation>
+    </message>
+    <message>
+        <source>Single-quoted here document</source>
+        <translation type="obsolete">&quot;Here document&quot; delimitato da apici singoli</translation>
+    </message>
+    <message>
+        <source>Double-quoted here document</source>
+        <translation type="obsolete">&quot;Here document&quot; delimitato da doppi apici</translation>
+    </message>
+    <message>
+        <source>Backtick here document</source>
+        <translation type="obsolete">&quot;Here document&quot; delimitato da apici inversi</translation>
+    </message>
+    <message>
+        <source>Quoted string (q)</source>
+        <translation type="obsolete">Stringa delimitata da apici (q)</translation>
+    </message>
+    <message>
+        <source>Quoted string (qq)</source>
+        <translation type="obsolete">Stringa delimitata da apici (qq)</translation>
+    </message>
+    <message>
+        <source>Quoted string (qx)</source>
+        <translation type="obsolete">Stringa delimitata da apici (qx)</translation>
+    </message>
+    <message>
+        <source>Quoted string (qr)</source>
+        <translation type="obsolete">Stringa delimitata da apici (qr)</translation>
+    </message>
+    <message>
+        <source>Quoted string (qw)</source>
+        <translation type="obsolete">Stringa delimitata da apici (qw)</translation>
+    </message>
+    <message>
+        <source>POD verbatim</source>
+        <translation type="obsolete">POD senza formattazione</translation>
+    </message>
+    <message>
+        <source>Subroutine prototype</source>
+        <translation type="obsolete">Prototipo di subroutine</translation>
+    </message>
+    <message>
+        <source>Format identifier</source>
+        <translation type="obsolete">Identificatore del formato</translation>
+    </message>
+    <message>
+        <source>Format body</source>
+        <translation type="obsolete">Corpo del formato</translation>
+    </message>
+    <message>
+        <source>Double-quoted string (interpolated variable)</source>
+        <translation type="obsolete">Stringa con doppi apici (variabile interpolata)</translation>
+    </message>
+    <message>
+        <source>Translation</source>
+        <translation type="obsolete">Traduzione</translation>
+    </message>
+    <message>
+        <source>Regular expression (interpolated variable)</source>
+        <translation type="obsolete">Espressione regolare (variabile interpolata)</translation>
+    </message>
+    <message>
+        <source>Substitution (interpolated variable)</source>
+        <translation type="obsolete">Sostituzione (variabile interpolata)</translation>
+    </message>
+    <message>
+        <source>Backticks (interpolated variable)</source>
+        <translation type="obsolete">Apici inversi (variabile interpolata)</translation>
+    </message>
+    <message>
+        <source>Double-quoted here document (interpolated variable)</source>
+        <translation type="obsolete">&quot;Here document&quot; delimitato da doppi apici (variabile interpolata)</translation>
+    </message>
+    <message>
+        <source>Backtick here document (interpolated variable)</source>
+        <translation type="obsolete">Here document&quot; delimitato da apici inversi (variabile interpolata)</translation>
+    </message>
+    <message>
+        <source>Quoted string (qq, interpolated variable)</source>
+        <translation type="obsolete">Stringa delimitata da apici (qq, variabile interpolata)</translation>
+    </message>
+    <message>
+        <source>Quoted string (qx, interpolated variable)</source>
+        <translation type="obsolete">Stringa delimitata da apici (qx, variabile interpolata)</translation>
+    </message>
+    <message>
+        <source>Quoted string (qr, interpolated variable)</source>
+        <translation type="obsolete">Stringa delimitata da apici (qr, variabile interpolata)</translation>
+    </message>
+</context>
+<context>
+    <name>QsciScintilla</name>
+    <message>
+        <source>&amp;Undo</source>
+        <translation type="obsolete">&amp;Annulla</translation>
+    </message>
+    <message>
+        <source>&amp;Redo</source>
+        <translation type="obsolete">&amp;Ripeti</translation>
+    </message>
+    <message>
+        <source>Cu&amp;t</source>
+        <translation type="obsolete">&amp;Taglia</translation>
+    </message>
+    <message>
+        <source>&amp;Copy</source>
+        <translation type="obsolete">&amp;Copia</translation>
+    </message>
+    <message>
+        <source>&amp;Paste</source>
+        <translation type="obsolete">&amp;Incolla</translation>
+    </message>
+    <message>
+        <source>Delete</source>
+        <translation type="obsolete">&amp;Cancella</translation>
+    </message>
+    <message>
+        <source>Select All</source>
+        <translation type="obsolete">Seleziona Tutto</translation>
+    </message>
+</context>
+<context>
+    <name>QtHandles::Figure</name>
+    <message>
+        <location filename="../graphics/Figure.cc" line="+170"/>
+        <source>Figure ToolBar</source>
+        <translation>Barra degli strumenti delle figure</translation>
+    </message>
+    <message>
+        <location line="+12"/>
+        <source>&amp;File</source>
+        <translation>&amp;File</translation>
+    </message>
+    <message>
+        <location line="+2"/>
+        <source>&amp;New Figure</source>
+        <translation>&amp;Nuova Figura</translation>
+    </message>
+    <message>
+        <location line="+1"/>
+        <source>&amp;Open...</source>
+        <translation>&amp;Apri...</translation>
+    </message>
+    <message>
+        <location line="+2"/>
+        <source>&amp;Save</source>
+        <translation>&amp;Salva</translation>
+    </message>
+    <message>
+        <location line="+1"/>
+        <source>Save &amp;As</source>
+        <translation>Salva &amp;Come</translation>
+    </message>
+    <message>
+        <location line="+2"/>
+        <source>&amp;Close Figure</source>
+        <translation>&amp;Chiudi Figura</translation>
+    </message>
+    <message>
+        <location line="+3"/>
+        <source>&amp;Edit</source>
+        <translation>&amp;Modifica</translation>
+    </message>
+    <message>
+        <location line="+2"/>
+        <source>Cop&amp;y</source>
+        <translation>Co&amp;pia</translation>
+    </message>
+    <message>
+        <location line="+2"/>
+        <source>Cu&amp;t</source>
+        <translation>&amp;Taglia</translation>
+    </message>
+    <message>
+        <location line="+2"/>
+        <source>&amp;Paste</source>
+        <translation>&amp;Incolla</translation>
+    </message>
+    <message>
+        <location line="+5"/>
+        <source>&amp;Help</source>
+        <translation>Ai&amp;uto</translation>
+    </message>
+    <message>
+        <location line="+2"/>
+        <source>&amp;About QtHandles</source>
+        <translation>A Proposito di Qt&amp;Handles</translation>
+    </message>
+    <message>
+        <location line="+2"/>
+        <source>About &amp;Qt</source>
+        <translation>A Proposito di &amp;Qt</translation>
+    </message>
+    <message>
+        <location line="+391"/>
+        <source>About QtHandles</source>
+        <translation>A Proposito di QtHandles</translation>
+    </message>
+</context>
+<context>
+    <name>QtHandles::MouseModeActionGroup</name>
+    <message>
+        <location filename="../graphics/MouseModeActionGroup.cc" line="+40"/>
+        <source>Rotate</source>
+        <translation>Ruota</translation>
+    </message>
+    <message>
+        <location line="+2"/>
+        <source>Zoom</source>
+        <translation>Zoom</translation>
+    </message>
+    <message>
+        <location line="+2"/>
+        <source>Pan</source>
+        <translation>Panoramica</translation>
+    </message>
+    <message>
+        <location line="+2"/>
+        <source>Select</source>
+        <translation>Seleziona</translation>
+    </message>
+</context>
+<context>
+    <name>S:</name>
+    <message>
+        <location filename="../../gnulib-hg/lib/quotearg.c" line="+291"/>
+        <source></source>
+        <comment>The placeholder indicates the bug-reporting address for this package. Please add _another line_ saying &quot;Report translation bugs to &lt;...&gt;
+&quot; with the address for translation bugs (typically your translation team&apos;s web or email address).</comment>
+        <translatorcomment>TODO</translatorcomment>
+        <translation></translation>
+    </message>
+</context>
+<context>
+    <name>documentation_dock_widget</name>
+    <message>
+        <location filename="../src/documentation-dock-widget.cc" line="+34"/>
+        <source>Documentation</source>
+        <translation>Documentazione</translation>
+    </message>
+    <message>
+        <location line="+1"/>
+        <source>See the documentation for help.</source>
+        <translation>Si faccia riferimento alla documentazione per maggiori informazioni.</translation>
+    </message>
+</context>
+<context>
+    <name>file_editor</name>
+    <message>
+        <location filename="../src/m-editor/file-editor.cc" line="+282"/>
+        <location line="+125"/>
+        <location line="+19"/>
+        <location line="+25"/>
+        <location line="+62"/>
+        <location line="+28"/>
+        <source>Octave Editor</source>
+        <translation>Editor di Octave</translation>
+    </message>
+    <message>
+        <location line="-318"/>
+        <source>Octave Files (*.m);;All Files (*)</source>
+        <translation>File di Octave (*.m);;Tutti i File (*)</translation>
+    </message>
+    <message>
+        <location line="-40"/>
+        <source>New Function</source>
+        <translation>Nuova Funzione</translation>
+    </message>
+    <message>
+        <location line="+1"/>
+        <source>New function name:
+</source>
+        <translation>Nome della nuova funzione:</translation>
+    </message>
+    <message>
+        <location line="+330"/>
+        <source>File not saved! A file with the selected name
+%1
+is already open in the editor</source>
+        <translation>File non salvato! Un file chiamato
+%1
+è già aperto nell&apos;editor</translation>
+    </message>
+    <message>
+        <location line="+387"/>
+        <source>&amp;%1 %2</source>
+        <translation>&amp;%1 %2</translation>
+    </message>
+    <message>
+        <location line="+390"/>
+        <source>&amp;Save File</source>
+        <translation>&amp;Salva File</translation>
+    </message>
+    <message>
+        <source>&amp;Open File...</source>
+        <translation type="obsolete">&amp;Apri...</translation>
+    </message>
+    <message>
+        <source>&amp;New Script</source>
+        <translation type="obsolete">&amp;Nuovo Script</translation>
+    </message>
+    <message>
+        <location line="+2"/>
+        <source>Save File &amp;As...</source>
+        <translation>Salva &amp;Come...</translation>
+    </message>
+    <message>
+        <location line="+17"/>
+        <source>Print...</source>
+        <translation>Stampa...</translation>
+    </message>
+    <message>
+        <location line="+7"/>
+        <source>&amp;Undo</source>
+        <translation>Annu&amp;lla</translation>
+    </message>
+    <message>
+        <location line="+3"/>
+        <source>&amp;Redo</source>
+        <translation>&amp;Ripeti</translation>
+    </message>
+    <message>
+        <location line="+6"/>
+        <source>&amp;Copy</source>
+        <translation>&amp;Copia</translation>
+    </message>
+    <message>
+        <location line="+3"/>
+        <source>Cu&amp;t</source>
+        <translation>&amp;Taglia</translation>
+    </message>
+    <message>
+        <location line="+3"/>
+        <source>Paste</source>
+        <translation>Incolla</translation>
+    </message>
+    <message>
+        <location line="+4"/>
+        <source>Select All</source>
+        <translation>Seleziona Tutto</translation>
+    </message>
+    <message>
+        <location line="+10"/>
+        <source>&amp;Commands</source>
+        <translation>Co&amp;mandi</translation>
+    </message>
+    <message>
+        <location line="+3"/>
+        <source>Delete Line</source>
+        <translation>Cancella riga</translation>
+    </message>
+    <message>
+        <location line="+2"/>
+        <source>Copy Line</source>
+        <translation>Copia riga</translation>
+    </message>
+    <message>
+        <location line="+2"/>
+        <source>Cut Line</source>
+        <translation>Taglia riga</translation>
+    </message>
+    <message>
+        <location line="+5"/>
+        <source>Delete to Start of Word</source>
+        <translation>Cancella fino a inizio parola</translation>
+    </message>
+    <message>
+        <location line="+2"/>
+        <source>Delete to End of Word</source>
+        <translation>Cancella fino a fine parola</translation>
+    </message>
+    <message>
+        <location line="+2"/>
+        <source>Delete to Start of Line</source>
+        <translation>Cancella fino a inizio riga</translation>
+    </message>
+    <message>
+        <location line="+2"/>
+        <source>Delete to End of Line</source>
+        <translation>Cancella fino a fine riga</translation>
+    </message>
+    <message>
+        <location line="+5"/>
+        <source>Duplicate Selection/Line</source>
+        <translation>Duplica selezion/riga</translation>
+    </message>
+    <message>
+        <location line="+2"/>
+        <source>Transpose Line</source>
+        <translation>Trasponi riga</translation>
+    </message>
+    <message>
+        <location line="+5"/>
+        <source>&amp;Show Completion List</source>
+        <translation>Mostra &amp;lista di completamento</translation>
+    </message>
+    <message>
+        <location line="+2"/>
+        <source>&amp;Format</source>
+        <translation>&amp;Formatta</translation>
+    </message>
+    <message>
+        <location line="+3"/>
+        <source>&amp;Uppercase Selection</source>
+        <translation>Rendi &amp;Maiuscola la selezione</translation>
+    </message>
+    <message>
+        <location line="+2"/>
+        <source>&amp;Lowercase Selection</source>
+        <translation>Rendi Mi&amp;nuscola la selezione</translation>
+    </message>
+    <message>
+        <location line="+19"/>
+        <source>Convert Line Endings to &amp;Windows (CRLF)</source>
+        <translation>A Capo in Stile &amp;Windows (CRLF)</translation>
+    </message>
+    <message>
+        <location line="+3"/>
+        <source>Convert Line Endings to &amp;Unix (LF)</source>
+        <translation>A Capo in Stile &amp;Unix (LF)</translation>
+    </message>
+    <message>
+        <location line="+3"/>
+        <source>Convert Line Endings to &amp;Mac (CR)</source>
+        <translation>A Capo in Stile &amp;Mac (CR)</translation>
+    </message>
+    <message>
+        <location line="+3"/>
+        <source>Navi&amp;gation</source>
+        <translation>Navi&amp;gazione</translation>
+    </message>
+    <message>
+        <location line="+8"/>
+        <source>Move to Matching Brace</source>
+        <translation>Vai alla Parentesi Corrispondente</translation>
+    </message>
+    <message>
+        <location line="+2"/>
+        <source>Select to Matching Brace</source>
+        <translation>Seleziona fino alla Parentesi Corrispondente</translation>
+    </message>
+    <message>
+        <location line="+5"/>
+        <source>&amp;Next Bookmark</source>
+        <translation>Segnalibro &amp;Successivo</translation>
+    </message>
+    <message>
+        <location line="+2"/>
+        <source>Pre&amp;vious Bookmark</source>
+        <translation>Segnalibro &amp;Precedente</translation>
+    </message>
+    <message>
+        <location line="+2"/>
+        <source>Toggle &amp;Bookmark</source>
+        <translation>Attiva/disattiva &amp;Segnalibro</translation>
+    </message>
+    <message>
+        <location line="+2"/>
+        <source>&amp;Remove All Bookmarks</source>
+        <translation>&amp;Elimina Tutti i Segnalibri</translation>
+    </message>
+    <message>
+        <location line="+13"/>
+        <source>&amp;View</source>
+        <translation>&amp;Vista</translation>
+    </message>
+    <message>
+        <location line="+2"/>
+        <source>&amp;Editor</source>
+        <translation>&amp;Editor</translation>
+    </message>
+    <message>
+        <location line="+3"/>
+        <source>Show &amp;Line Numbers</source>
+        <translation>Mostra Numeri di &amp;Riga</translation>
+    </message>
+    <message>
+        <location line="+4"/>
+        <source>Show &amp;White Spaces</source>
+        <translation>Mostra &amp;Spazi</translation>
+    </message>
+    <message>
+        <location line="+4"/>
+        <source>Show Line &amp;Endings</source>
+        <translation>Mostra a &amp;Capo</translation>
+    </message>
+    <message>
+        <location line="+4"/>
+        <source>Show &amp;Indentation Guides</source>
+        <translation>Mostre Guide &amp;Indentazione</translation>
+    </message>
+    <message>
+        <location line="+4"/>
+        <source>Show Long Line &amp;Marker</source>
+        <translation>Mostra &amp;Marcatori di Linea Lunga</translation>
+    </message>
+    <message>
+        <location line="+6"/>
+        <source>Zoom &amp;In</source>
+        <translation>&amp;Ingrandisci</translation>
+    </message>
+    <message>
+        <location line="+2"/>
+        <source>Zoom &amp;Out</source>
+        <translation>&amp;Riduci</translation>
+    </message>
+    <message>
+        <location line="+2"/>
+        <source>&amp;Normal Size</source>
+        <translation>Dimensione &amp;Normale</translation>
+    </message>
+    <message>
+        <location line="+12"/>
+        <source>&amp;Next Breakpoint</source>
+        <translation>&amp;Breakpoint Successivo</translation>
+    </message>
+    <message>
+        <location line="+3"/>
+        <source>Pre&amp;vious Breakpoint</source>
+        <translation>&amp;Breakpoint Precedente</translation>
+    </message>
+    <message>
+        <location line="-6"/>
+        <source>Toggle &amp;Breakpoint</source>
+        <translation>Attiva/Disattiva &amp;Breakpoint</translation>
+    </message>
+    <message>
+        <location line="+9"/>
+        <source>&amp;Remove All Breakpoints</source>
+        <translation>&amp;Rimuovi Tutti i Breakpoint</translation>
+    </message>
+    <message>
+        <location line="-106"/>
+        <source>&amp;Comment</source>
+        <translation>&amp;Commenta</translation>
+    </message>
+    <message>
+        <location line="+2"/>
+        <source>&amp;Uncomment</source>
+        <translation>&amp;Decommenta</translation>
+    </message>
+    <message>
+        <location line="+5"/>
+        <source>&amp;Indent</source>
+        <translation>&amp;Indenta</translation>
+    </message>
+    <message>
+        <location line="+2"/>
+        <source>&amp;Unindent</source>
+        <translation>&amp;Rimuovi Indentazione</translation>
+    </message>
+    <message>
+        <location line="-55"/>
+        <source>&amp;Find and Replace...</source>
+        <translation>&amp;Trova e Sostituisci...</translation>
+    </message>
+    <message>
+        <location line="+164"/>
+        <source>Save File and Run</source>
+        <translation>Salva ed Esegui</translation>
+    </message>
+    <message>
+        <location line="-92"/>
+        <source>Go &amp;to Line...</source>
+        <translation>Vai &amp;alla Riga...</translation>
+    </message>
+    <message>
+        <location line="-1131"/>
+        <source>Could not start custom file editor
+%1</source>
+        <translation>Impossibile avviare l&apos;editor di file personalizzato
+%1</translation>
+    </message>
+    <message>
+        <location line="+148"/>
+        <source>Create</source>
+        <translation>Crea</translation>
+    </message>
+    <message>
+        <location line="+1"/>
+        <source>Cancel</source>
+        <translation>Annulla</translation>
+    </message>
+    <message>
+        <location line="+846"/>
+        <source>&amp;Recent Editor Files</source>
+        <translation>&amp;Documenti Recenti</translation>
+    </message>
+    <message>
+        <location line="+8"/>
+        <source>&amp;Edit Function</source>
+        <translation>&amp;Modifica Funzione</translation>
+    </message>
+    <message>
+        <location line="+13"/>
+        <source>&amp;Close</source>
+        <translation>&amp;Chiudi</translation>
+    </message>
+    <message>
+        <location line="+3"/>
+        <source>Close All</source>
+        <translation>Chiudi Tutto</translation>
+    </message>
+    <message>
+        <location line="+3"/>
+        <source>Close Other Files</source>
+        <translation>Chiudi gli Altri File</translation>
+    </message>
+    <message>
+        <location line="+133"/>
+        <source>&amp;Preferences...</source>
+        <translation>&amp;Preferenze...</translation>
+    </message>
+    <message>
+        <location line="+3"/>
+        <source>&amp;Styles Preferences...</source>
+        <translation>&amp;Preferenze di stile...</translation>
+    </message>
+    <message>
+        <location line="+67"/>
+        <source>Run &amp;Selection</source>
+        <translation>Esegui &amp;Selezione</translation>
+    </message>
+    <message>
+        <location line="+5"/>
+        <source>&amp;Help</source>
+        <translation>&amp;Aiuto</translation>
+    </message>
+    <message>
+        <location line="+3"/>
+        <source>&amp;Help on Keyword</source>
+        <translation>&amp;Aiuto su Parola Chiave</translation>
+    </message>
+    <message>
+        <location line="+2"/>
+        <source>&amp;Documentation on Keyword</source>
+        <translation>&amp;Documentazione sulla Parola Chiave</translation>
+    </message>
+    <message>
+        <location line="-1110"/>
+        <source>Could not open file
+%1
+for read: %2.</source>
+        <translation>Impossibile aprire
+%1
+in lettura: %2.</translation>
+    </message>
+    <message>
+        <location line="+19"/>
+        <source>File
+%1
+does not exist. Do you want to create it?</source>
+        <translation>Il file
+%1
+non esiste. Si desidera crearlo?</translation>
+    </message>
+    <message>
+        <location line="+25"/>
+        <source>Could not open file
+%1
+for write: %2.</source>
+        <translation>Impossibile aprire
+%1
+in scrittura: %2.</translation>
+    </message>
+    <message>
+        <location line="+90"/>
+        <source>The associated file editor tab has disappeared.</source>
+        <translation>La scheda corrispondente nell&apos;editor è scomparsa.</translation>
+    </message>
+    <message>
+        <location line="+733"/>
+        <source>&amp;File</source>
+        <translation>&amp;File</translation>
+    </message>
+    <message>
+        <source>New &amp;Function...</source>
+        <translation type="obsolete">Nuova &amp;Funzione...</translation>
+    </message>
+    <message>
+        <location line="+39"/>
+        <source>&amp;Edit</source>
+        <translation>&amp;Modifica</translation>
+    </message>
+    <message>
+        <location line="+168"/>
+        <source>&amp;Debug</source>
+        <translation>&amp;Debug</translation>
+    </message>
+    <message>
+        <location line="+21"/>
+        <source>&amp;Run</source>
+        <translation>&amp;Esegui</translation>
+    </message>
+</context>
+<context>
+    <name>file_editor_tab</name>
+    <message>
+        <location filename="../src/m-editor/file-editor-tab.cc" line="+96"/>
+        <source>eol:</source>
+        <translation>fine della riga:</translation>
+    </message>
+    <message>
+        <location line="+9"/>
+        <source>line:</source>
+        <translation>riga:</translation>
+    </message>
+    <message>
+        <location line="+3"/>
+        <source>col:</source>
+        <translation>riga:</translation>
+    </message>
+    <message>
+        <location line="+142"/>
+        <source>%1 is a built-in function</source>
+        <translation>%1 è una funzione built-in</translation>
+    </message>
+    <message>
+        <location line="+24"/>
+        <source>Can not find function %1</source>
+        <translation>Impossibile trovare la funzione %1</translation>
+    </message>
+    <message>
+        <location line="+9"/>
+        <location line="+985"/>
+        <location line="+228"/>
+        <location line="+185"/>
+        <location line="+85"/>
+        <location line="+23"/>
+        <source>Octave Editor</source>
+        <translation>Editor di Octave</translation>
+    </message>
+    <message>
+        <location line="-752"/>
+        <source>Goto line</source>
+        <translation>Vai alla riga</translation>
+    </message>
+    <message>
+        <location line="+1"/>
+        <source>Line number</source>
+        <translation>Numero riga</translation>
+    </message>
+    <message>
+        <location line="+146"/>
+        <location line="+81"/>
+        <source>&lt;unnamed&gt;</source>
+        <translation>&lt;senza nome&gt;</translation>
+    </message>
+    <message>
+        <location line="-20"/>
+        <source>Do you want to save or discard the changes?</source>
+        <translation>Si desidera salvare o annullare le modifiche?</translation>
+    </message>
+    <message>
+        <location line="+5"/>
+        <source>Do you want to cancel exiting octave, save or discard the changes?</source>
+        <translation>Si desidera annullare l&apos;operazione di chiusura, salvare o annullare le modifiche?</translation>
+    </message>
+    <message>
+        <location line="+6"/>
+        <source>Do you want to cancel closing, save or discard the changes?</source>
+        <translation>Si desidera annullare l&apos;operazione di chiusura, salvare o annullare le modifiche?</translation>
+    </message>
+    <message>
+        <location line="+13"/>
+        <source>The file
+%1
+is about to be closed but has been modified.
+%2</source>
+        <translation>Il file
+%1
+sta per essere chiuso ma è stato modificato.
+%2</translation>
+    </message>
+    <message>
+        <location line="+303"/>
+        <source>Line Endings:</source>
+        <translation>Terminatori di Riga:</translation>
+    </message>
+    <message>
+        <location line="+23"/>
+        <source>Octave Files (*.m)</source>
+        <translation>File di Octave (*.m)</translation>
+    </message>
+    <message>
+        <location line="+1"/>
+        <source>All Files (*)</source>
+        <translation>Tutti i File (*)</translation>
+    </message>
+    <message>
+        <source>Octave Files (*.m);;All Files (*)</source>
+        <translation type="obsolete">File di Octave (*.m);;Tutti i File (*)</translation>
+    </message>
+    <message>
+        <location line="+187"/>
+        <source>
+
+Warning: The contents in the editor is modified!</source>
+        <translation>
+
+Attenzione: il contenuto nell&apos;editor è modificato!</translation>
+    </message>
+    <message>
+        <location line="+7"/>
+        <source>It seems that the file
+%1
+has been deleted or renamed. Do you want to save it now?%2</source>
+        <translation>Sembra che il file
+%1
+sia stato rinominato o rimosso. Si desidera salvarlo ora?%2</translation>
+    </message>
+    <message>
+        <location line="-293"/>
+        <source>Could not open file %1 for write:
+%2.</source>
+        <translation>Impossibile aprire  %1 in scrittura:
+%2.</translation>
+    </message>
+    <message>
+        <source>Line:</source>
+        <translation type="obsolete">Riga:</translation>
+    </message>
+    <message>
+        <source>Col:</source>
+        <translation type="obsolete">Car:</translation>
+    </message>
+    <message>
+        <location line="+185"/>
+        <source>&quot;%1&quot;
+is not a valid identifier.
+
+If you keep this file name, you will not be able to
+call your script using its name as an Octave command.
+
+Do you want to choose another name?</source>
+        <translation>&quot;%1&quot;
+non è un nome valido.
+
+Se lo si mantiene, non si potrà invocare
+lo script come comando Octave.
+
+Si desidera scegliere un altro nome?</translation>
+    </message>
+    <message>
+        <location line="+85"/>
+        <source>It seems that &apos;%1&apos; has been modified by another application. Do you want to reload it?</source>
+        <translation>Sembra che &apos;%1&apos; sia stato modificato da un&apos;altra applicazione. Si desidera ricaricarlo?</translation>
+    </message>
+</context>
+<context>
+    <name>files_dock_widget</name>
+    <message>
+        <location filename="../src/files-dock-widget.cc" line="+68"/>
+        <source>File Browser</source>
+        <translation>Gestore dei File</translation>
+    </message>
+    <message>
+        <location line="+1"/>
+        <source>Browse your files.</source>
+        <translation>Esplorare i prorpi file.</translation>
+    </message>
+    <message>
+        <location line="+18"/>
+        <source>Enter the path or filename</source>
+        <translation>Inserire il percorso o il nome del file</translation>
+    </message>
+    <message>
+        <location line="+11"/>
+        <source>Move up one directory</source>
+        <translation>Cartella precedente</translation>
+    </message>
+    <message>
+        <location line="+17"/>
+        <source>Actions on current directory</source>
+        <translation>Azioni sulla cartella corrente</translation>
+    </message>
+    <message>
+        <location line="+15"/>
+        <source>Set Browser Directory...</source>
+        <translation>Scegliere la Cartella del Gestore...</translation>
+    </message>
+    <message>
+        <location line="+4"/>
+        <location line="+387"/>
+        <source>Find Files...</source>
+        <translation>Cerca File...</translation>
+    </message>
+    <message>
+        <source>New File</source>
+        <translation type="obsolete">Nuovo File</translation>
+    </message>
+    <message>
+        <location line="+357"/>
+        <source>New Directory</source>
+        <translation>Nuova Cartella</translation>
+    </message>
+    <message>
+        <location line="-676"/>
+        <source>Double-click a file to open it</source>
+        <translation>Fare doppio click su un file per aprirlo</translation>
+    </message>
+    <message>
+        <location line="-100"/>
+        <source>Show Octave directory</source>
+        <translation>Mostra la cartella di Octave</translation>
+    </message>
+    <message>
+        <location line="+2"/>
+        <source>Go to current Octave directory</source>
+        <translation>Vai alla directory corrente di Octave</translation>
+    </message>
+    <message>
+        <location line="+5"/>
+        <source>Set Octave directory</source>
+        <translation>Scegli la cartella di Octave</translation>
+    </message>
+    <message>
+        <location line="+2"/>
+        <source>Set Octave directroy to current browser directory</source>
+        <translation>Scegli la directory corrente come directory di Octave</translation>
+    </message>
+    <message>
+        <location line="+7"/>
+        <source>Show Home Directory</source>
+        <translation>Mostra la Cartella Personale</translation>
+    </message>
+    <message>
+        <source>Search Directory...</source>
+        <translation type="obsolete">Cerca Cartella...</translation>
+    </message>
+    <message>
+        <location line="+20"/>
+        <location line="+396"/>
+        <source>New File...</source>
+        <translation>Nuovo File...</translation>
+    </message>
+    <message>
+        <location line="-393"/>
+        <location line="+396"/>
+        <source>New Directory...</source>
+        <translation>Nuova Cartella...</translation>
+    </message>
+    <message>
+        <location line="-99"/>
+        <source>File size</source>
+        <translation>Dimensione</translation>
+    </message>
+    <message>
+        <location line="+8"/>
+        <source>File type</source>
+        <translation>Tipo</translation>
+    </message>
+    <message>
+        <location line="+8"/>
+        <source>Date modified</source>
+        <translation>Data ultima modifica</translation>
+    </message>
+    <message>
+        <location line="+8"/>
+        <source>Show hidden</source>
+        <translation>Mostra file nascosti</translation>
+    </message>
+    <message>
+        <location line="+35"/>
+        <source>Open</source>
+        <translation>Apri</translation>
+    </message>
+    <message>
+        <location line="+3"/>
+        <source>Open in Default Application</source>
+        <translation>Apri con l&apos;Applicazione Predefinita</translation>
+    </message>
+    <message>
+        <location line="+3"/>
+        <source>Copy Selection to Clipboard</source>
+        <translation>Copia Selezione negli Appunti</translation>
+    </message>
+    <message>
+        <location line="+5"/>
+        <source>Run</source>
+        <translation>Esegui</translation>
+    </message>
+    <message>
+        <location line="+3"/>
+        <source>Load Data</source>
+        <translation>Carica Dati</translation>
+    </message>
+    <message>
+        <location line="+6"/>
+        <source>Set Current Directory</source>
+        <translation>Seleziona la Cartella Corrente</translation>
+    </message>
+    <message>
+        <location line="+9"/>
+        <source>Rename...</source>
+        <translation>Rinomina...</translation>
+    </message>
+    <message>
+        <location line="+2"/>
+        <source>Delete...</source>
+        <translation>Elimina...</translation>
+    </message>
+    <message>
+        <source>Rename</source>
+        <translation type="obsolete">Rinomina</translation>
+    </message>
+    <message>
+        <source>Delete</source>
+        <translation type="obsolete">Elimina</translation>
+    </message>
+    <message>
+        <location line="+115"/>
+        <source>Rename file/directory</source>
+        <translation>Rinomina file/cartella</translation>
+    </message>
+    <message>
+        <location line="+1"/>
+        <source>Rename file/directory:
+</source>
+        <translation>Rinomina file/cartella:
+</translation>
+    </message>
+    <message>
+        <location line="+1"/>
+        <source>
+ to: </source>
+        <translation>
+ a: </translation>
+    </message>
+    <message>
+        <location line="+25"/>
+        <location line="+14"/>
+        <source>Delete file/directory</source>
+        <translation>Elimina file/cartella</translation>
+    </message>
+    <message>
+        <location line="-13"/>
+        <source>Are you sure you want to delete
+</source>
+        <translation>Si è sicuri di voler eliminare
+</translation>
+    </message>
+    <message>
+        <location line="+14"/>
+        <source>Can not delete a directory that is not empty</source>
+        <translation>Impossibile eliminare una cartella non vuota</translation>
+    </message>
+    <message>
+        <location line="+144"/>
+        <source>Set directory of file browser</source>
+        <translation>Seleziona la cartella del gestore di file</translation>
+    </message>
+    <message>
+        <location line="+29"/>
+        <source>Create File</source>
+        <translation>Nuovo File</translation>
+    </message>
+    <message>
+        <location line="+1"/>
+        <source>Create file in
+</source>
+        <comment>String ends with \n!</comment>
+        <translation>Nuovo file in
+</translation>
+    </message>
+    <message>
+        <location line="+1"/>
+        <source>New File.txt</source>
+        <translation>Nuovo.txt</translation>
+    </message>
+    <message>
+        <location line="+16"/>
+        <source>Create Directory</source>
+        <translation>Nuova Cartella</translation>
+    </message>
+    <message>
+        <location line="+1"/>
+        <source>Create folder in
+</source>
+        <comment>String ends with \n!</comment>
+        <translation>Nuova cartella in
+</translation>
+    </message>
+</context>
+<context>
+    <name>final_page</name>
+    <message>
+        <location filename="../src/welcome-wizard.cc" line="+194"/>
+        <source>Enjoy!</source>
+        <translation>Buon lavoro!</translation>
+    </message>
+    <message>
+        <location line="+4"/>
+        <source>Previous</source>
+        <translation>Precedente</translation>
+    </message>
+    <message>
+        <location line="+1"/>
+        <source>Finish</source>
+        <translation>Finito</translation>
+    </message>
+    <message>
+        <location line="+1"/>
+        <source>Cancel</source>
+        <translation>Annulla</translation>
+    </message>
+    <message>
+        <location line="+7"/>
+        <source>&lt;html&gt;&lt;body&gt;
+&lt;p&gt;We hope you find Octave to be a useful tool.&lt;/p&gt;
+&lt;p&gt;If you encounter problems, there are a number of ways to get help, including commercial support options, a mailing list, a wiki, and other commnity-based support channels.
+You can find more information about each of these by visiting &lt;a href=&quot;http://octave.org/support.html&quot;&gt;http://octave.org/support.html&lt;/a&gt; (opens in external browser).&lt;/p&gt;
+&lt;/body&gt;&lt;/html&gt;</source>
+        <translation>&lt;html&gt;&lt;body&gt;
+&lt;p&gt;Speriamo che troverai Octave un programma utile.&lt;/p&gt;
+&lt;p&gt;Se incontri dei problemi, ci sono molto modi per ottenere aiuto, incluse possibilità di supporto commerciale, una mailing list, una wiki ed altri canali di supporto basati sulla comunità.
+Puoi trovare maggiori informazioni su ciascuno di essi visitando &lt;a href=&quot;http://octave.org/support.html&quot;&gt;http://octave.org/support.html&lt;/a&gt; (utilizza un browser esterno).&lt;/p&gt;
+&lt;/body&gt;&lt;/html&gt;</translation>
+    </message>
+    <message>
+        <location line="+21"/>
+        <source>&lt;html&gt;&lt;head&gt;
+&lt;style&gt;
+a:link { text-decoration: underline; color: #0000ff; }
+&lt;/style&gt;
+&lt;head/&gt;&lt;body&gt;
+&lt;p&gt;For more information about Octave:&lt;/p&gt;
+&lt;ul&gt;
+&lt;li&gt;Visit &lt;a href=&quot;http://octave.org&quot;&gt;http://octave.org&lt;/a&gt; (opens in external browser)&lt;/li&gt;
+&lt;li&gt;Get the documentation online as &lt;a href=&quot;http://www.gnu.org/software/octave/doc/interpreter/index.html&quot;&gt;html&lt;/a&gt;- or &lt;a href=&quot;http://www.gnu.org/software/octave/octave.pdf&quot;&gt;pdf&lt;/span&gt;&lt;/a&gt;-document (opens in external browser)&lt;/li&gt;
+&lt;li&gt;Open the documentation browser of the Octave GUI with the help menu&lt;/li&gt;
+&lt;/ul&gt;
+&lt;/body&gt;&lt;/html&gt;</source>
+        <translation>&lt;html&gt;&lt;head&gt;
+&lt;style&gt;
+a:link { text-decoration: underline; color: #0000ff; }
+&lt;/style&gt;
+&lt;head/&gt;&lt;body&gt;
+&lt;p&gt;Per maggiori informazioni su Octave:&lt;/p&gt;
+&lt;ul&gt;
+&lt;li&gt;visita &lt;a href=&quot;http://octave.org&quot;&gt;http://octave.org&lt;/a&gt; (utilizza un browser esterno)&lt;/li&gt;
+&lt;li&gt;Puoi trovare la documentazione online agli indirizzi &lt;a href=&quot;http://www.gnu.org/software/octave/doc/interpreter/index.html&quot;&gt;html&lt;/a&gt;- o &lt;a href=&quot;http://www.gnu.org/software/octave/octave.pdf&quot;&gt;pdf&lt;/span&gt;&lt;/a&gt; (utilizza un browser esterno)&lt;/li&gt;
+&lt;li&gt;Apri la documentazione dell&apos;interfaccia grafica di Octave utilizzando il menu help&lt;/li&gt;
+&lt;/ul&gt;
+&lt;/body&gt;&lt;/html&gt;</translation>
+    </message>
+</context>
+<context>
+    <name>find_dialog</name>
+    <message>
+        <location filename="../src/m-editor/find-dialog.cc" line="+74"/>
+        <source>Find and Replace</source>
+        <translation>Trova e Sostituisci</translation>
+    </message>
+    <message>
+        <location line="+3"/>
+        <source>Find &amp;what:</source>
+        <translation>T&amp;rova:</translation>
+    </message>
+    <message>
+        <location line="+3"/>
+        <source>Re&amp;place with:</source>
+        <translation>Sos&amp;tituisci con:</translation>
+    </message>
+    <message>
+        <location line="+4"/>
+        <source>Match &amp;case</source>
+        <translation>Maiuscole/&amp;minuscole</translation>
+    </message>
+    <message>
+        <location line="+1"/>
+        <source>Search from &amp;start</source>
+        <translation>Cerca dall&apos;i&amp;nizio</translation>
+    </message>
+    <message>
+        <location line="+1"/>
+        <source>&amp;Wrap while searching</source>
+        <translation>&amp;Evidenzia durante la ricerca</translation>
+    </message>
+    <message>
+        <location line="+2"/>
+        <source>&amp;Find Next</source>
+        <translation>&amp;Trova Successivo</translation>
+    </message>
+    <message>
+        <location line="+1"/>
+        <source>Find &amp;Previous</source>
+        <translation>Trova &amp;Precedente</translation>
+    </message>
+    <message>
+        <location line="+1"/>
+        <source>&amp;Replace</source>
+        <translation>&amp;Sostituisci</translation>
+    </message>
+    <message>
+        <location line="+1"/>
+        <source>Replace &amp;All</source>
+        <translation>S&amp;ostituisci Tutto</translation>
+    </message>
+    <message>
+        <location line="+2"/>
+        <source>&amp;More...</source>
+        <translation>&amp;Avanzate...</translation>
+    </message>
+    <message>
+        <location line="+13"/>
+        <source>&amp;Whole words</source>
+        <translation>Paro&amp;le intere</translation>
+    </message>
+    <message>
+        <location line="+1"/>
+        <source>Regular E&amp;xpressions</source>
+        <translation>Espressioni Re&amp;golari</translation>
+    </message>
+    <message>
+        <location line="+1"/>
+        <source>Search &amp;backward</source>
+        <translation>Cerca &amp;indietro</translation>
+    </message>
+    <message>
+        <location line="+1"/>
+        <source>Search se&amp;lection</source>
+        <translation>Cerca nella sele&amp;zione</translation>
+    </message>
+    <message>
+        <location line="+84"/>
+        <source>Search from end</source>
+        <translation>Cerca dalla fine</translation>
+    </message>
+    <message>
+        <location line="+2"/>
+        <source>Search from start</source>
+        <translation>Cerca dall&apos;inizio</translation>
+    </message>
+    <message>
+        <location line="+199"/>
+        <source>Replace Result</source>
+        <translation>Sostituisci Risultato</translation>
+    </message>
+    <message>
+        <location line="+1"/>
+        <source>%1 items replaced</source>
+        <translation>%1 occorrenze sostituite</translation>
+    </message>
+    <message>
+        <location line="+15"/>
+        <source>Find Result</source>
+        <translation>Trova Risultato</translation>
+    </message>
+    <message>
+        <location line="+1"/>
+        <source>No more matches found</source>
+        <translation>Nessun&apos;altra corrispondenza trovata</translation>
+    </message>
+</context>
+<context>
+    <name>find_files_dialog</name>
+    <message>
+        <location filename="../src/find-files-dialog.cc" line="+52"/>
+        <source>Find Files</source>
+        <translation>Cerca File</translation>
+    </message>
+    <message>
+        <location line="+10"/>
+        <source>Named:</source>
+        <translation>Chiamato:</translation>
+    </message>
+    <message>
+        <location line="+8"/>
+        <source>Start in:</source>
+        <translation>Comincia da:</translation>
+    </message>
+    <message>
+        <location line="+5"/>
+        <source>Enter the start directory</source>
+        <translation>Inserire la cartella di partenza</translation>
+    </message>
+    <message>
+        <location line="+3"/>
+        <source>Browse...</source>
+        <translation>Esplora...</translation>
+    </message>
+    <message>
+        <location line="+1"/>
+        <source>Browse for start directory</source>
+        <translation>Seleziona la cartella di partenza</translation>
+    </message>
+    <message>
+        <location line="+7"/>
+        <source>Search recursively through directories for matching files</source>
+        <translation>Cerca ricorsivamente nella gerarchia di cartelle</translation>
+    </message>
+    <message>
+        <location line="+6"/>
+        <source>Include matching directories in search results</source>
+        <translation>Includi cartelle nei risultati di ricerca</translation>
+    </message>
+    <message>
+        <location line="+2"/>
+        <source>Name case insensitive</source>
+        <translation>Nessuna distinzione maiuscole/minuscole nel nome</translation>
+    </message>
+    <message>
+        <location line="+3"/>
+        <source>Set matching name is case insensitive</source>
+        <translation>Nessuna distinzione maiuscole/minuscole per le corrispendenze fra nomi</translation>
+    </message>
+    <message>
+        <location line="+2"/>
+        <source>Contains text:</source>
+        <translation>Contiene il testo:</translation>
+    </message>
+    <message>
+        <location line="-35"/>
+        <source>Enter the filename search expression</source>
+        <translation>Inserire una espressione da ricercare nel nome del file</translation>
+    </message>
+    <message>
+        <location line="+18"/>
+        <source>Search subdirectories</source>
+        <translation>Ricerca nelle sottocartelle</translation>
+    </message>
+    <message>
+        <location line="+6"/>
+        <source>Include directory names</source>
+        <translation>Includi i nomi di cartelle</translation>
+    </message>
+    <message>
+        <location line="+12"/>
+        <source>Enter the file content search expression</source>
+        <translation>Inserisci un&apos;espressione da ricercare nel contenuto del file</translation>
+    </message>
+    <message>
+        <location line="+5"/>
+        <source>Text to match</source>
+        <translation>Testo da trovare</translation>
+    </message>
+    <message>
+        <location line="+4"/>
+        <source>Text case insensitive</source>
+        <translation>Testo senza distinzione maisucole/minuscole</translation>
+    </message>
+    <message>
+        <location line="+3"/>
+        <source>Set text content is case insensitive</source>
+        <translation>Nessuna distinzione maiuscole/minuscole nel contenuto del testo</translation>
+    </message>
+    <message>
+        <location line="+11"/>
+        <source>Search results</source>
+        <translation>Risultati della ricerca</translation>
+    </message>
+    <message>
+        <location line="+17"/>
+        <source>Idle.</source>
+        <translation>Inattivo.</translation>
+    </message>
+    <message>
+        <location line="+2"/>
+        <source>Find</source>
+        <translation>Cerca</translation>
+    </message>
+    <message>
+        <location line="+1"/>
+        <source>Start search for matching files</source>
+        <translation>Inizia la ricerca</translation>
+    </message>
+    <message>
+        <location line="+3"/>
+        <source>Stop</source>
+        <translation>Interrompi</translation>
+    </message>
+    <message>
+        <location line="+1"/>
+        <source>Stop searching</source>
+        <translation>Interrompi la ricerca</translation>
+    </message>
+    <message>
+        <location line="+15"/>
+        <source>File name/location</source>
+        <translation>Nome del file/posizione</translation>
+    </message>
+    <message>
+        <location line="+17"/>
+        <source>File contents</source>
+        <translation>Contenuti</translation>
+    </message>
+    <message>
+        <location line="+105"/>
+        <source>Searching...</source>
+        <translation>Ricerca in corso...</translation>
+    </message>
+    <message>
+        <location line="+23"/>
+        <source>%1 match(es)</source>
+        <translation>%1 corrispondenze</translation>
+    </message>
+    <message>
+        <location line="+9"/>
+        <source>Set search directory</source>
+        <translation>Scegli la cartella di ricerca</translation>
+    </message>
+</context>
+<context>
+    <name>find_files_model</name>
+    <message>
+        <location filename="../src/find-files-model.cc" line="+82"/>
+        <source>Filename</source>
+        <translation>Nome del file</translation>
+    </message>
+    <message>
+        <location line="+1"/>
+        <source>Directory</source>
+        <translation>Cartella</translation>
+    </message>
+</context>
+<context>
+    <name>history_dock_widget</name>
+    <message>
+        <location filename="../src/history-dock-widget.cc" line="+47"/>
+        <source>Browse and search the command history.</source>
+        <translation>Naviga nello storico dei comandi.</translation>
+    </message>
+    <message>
+        <location line="+24"/>
+        <source>Double-click a command to transfer it to the terminal.</source>
+        <translation>Fare doppio click su un comando per trasferirlo nel termianle.</translation>
+    </message>
+    <message>
+        <source>Enter text to filter the command history.</source>
+        <translation type="obsolete">Inserire del testo per filtrare lo storico dei comandi.</translation>
+    </message>
+    <message>
+        <location line="+8"/>
+        <source>Enter text to filter the command history</source>
+        <translation>Inserire del testo per filtrare lo storico dei comandi</translation>
+    </message>
+    <message>
+        <location line="+10"/>
+        <source>Filter</source>
+        <translation>Filtra</translation>
+    </message>
+    <message>
+        <location line="+5"/>
+        <source>Command History</source>
+        <translation>Storico dei comandi</translation>
+    </message>
+    <message>
+        <location line="+88"/>
+        <source>Copy</source>
+        <translation>Copia</translation>
+    </message>
+    <message>
+        <location line="+1"/>
+        <source>Evaluate</source>
+        <translation>Valuta</translation>
+    </message>
+    <message>
+        <location line="+2"/>
+        <source>Create script</source>
+        <translation>Crea script</translation>
+    </message>
+</context>
+<context>
+    <name>initial_page</name>
+    <message>
+        <location filename="../src/welcome-wizard.cc" line="-179"/>
+        <source>Welcome to Octave!</source>
+        <translation>Benvenuto in Octave!</translation>
+    </message>
+    <message>
+        <location line="+3"/>
+        <source>Next</source>
+        <translation>Successivo</translation>
+    </message>
+    <message>
+        <location line="+1"/>
+        <source>Cancel</source>
+        <translation>Annulla</translation>
+    </message>
+    <message>
+        <location line="+7"/>
+        <source>&lt;html&gt;&lt;body&gt;
+&lt;p&gt;You seem to be using the Octave graphical interface for the first time on this computer.
+Click &apos;Next&apos; to create a configuration file and launch Octave.&lt;/p&gt;
+&lt;p&gt;The configuration file is stored in&lt;br&gt;%1.&lt;/p&gt;
+&lt;/body&gt;&lt;/html&gt;</source>
+        <translation>&lt;html&gt;&lt;body&gt;
+&lt;p&gt;Sembra che si stia utilizzando l&apos;interfaccia grafica di Octave per la prima volta su questo computer.
+Fare click su &apos;Successivo&apos; per creare un file di configurazione e lanciare Octave.&lt;/p&gt;
+&lt;p&gt;Il file di configurazione verrà salvato in&lt;br&gt;%1.&lt;/p&gt;
+&lt;/body&gt;&lt;/html&gt;</translation>
+    </message>
+</context>
+<context>
+    <name>main_window</name>
+    <message>
+        <location filename="../src/main-window.cc" line="+265"/>
+        <source>Load Workspace</source>
+        <translation>Carica lo Spazio di Lavoro</translation>
+    </message>
+    <message>
+        <location line="+715"/>
+        <location line="+910"/>
+        <source>About Octave</source>
+        <translation>A proposito di Octave</translation>
+    </message>
+    <message>
+        <location line="-297"/>
+        <source>&amp;File</source>
+        <translation>&amp;File</translation>
+    </message>
+    <message>
+        <location line="+58"/>
+        <source>New</source>
+        <translation>Nuovo</translation>
+    </message>
+    <message>
+        <source>Figure</source>
+        <translation type="obsolete">Figura</translation>
+    </message>
+    <message>
+        <location line="-52"/>
+        <source>Open...</source>
+        <translation>Apri...</translation>
+    </message>
+    <message>
+        <location line="+24"/>
+        <source>Preferences...</source>
+        <translation>Preferenze...</translation>
+    </message>
+    <message>
+        <location line="+4"/>
+        <source>Exit</source>
+        <translation>Esci</translation>
+    </message>
+    <message>
+        <location line="+53"/>
+        <source>&amp;Edit</source>
+        <translation>&amp;Modifica</translation>
+    </message>
+    <message>
+        <location line="+5"/>
+        <source>Undo</source>
+        <translation>Annulla</translation>
+    </message>
+    <message>
+        <location line="+6"/>
+        <source>Copy</source>
+        <translation>Copia</translation>
+    </message>
+    <message>
+        <location line="+4"/>
+        <source>Paste</source>
+        <translation>Incolla</translation>
+    </message>
+    <message>
+        <location line="-1444"/>
+        <source>Save Workspace As</source>
+        <translation>Salva lo Spazio di Lavoro Come</translation>
+    </message>
+    <message>
+        <location line="+84"/>
+        <source>The file %1
+can not be executed because its name
+is not a valid identifier.
+
+Do you want to execute
+%2
+instead?</source>
+        <translation>Il file %1
+non può essere eseguito perché il suo
+nome non è un identificatore valido.
+
+Si desidera eseguire
+%2
+invece?</translation>
+    </message>
+    <message>
+        <location line="+73"/>
+        <source>The release notes file &apos;%1&apos; is empty.</source>
+        <translation>Il file delle note di rilascio &apos;%1&apos; è vuoto.</translation>
+    </message>
+    <message>
+        <location line="+4"/>
+        <source>The release notes file &apos;%1&apos; cannot be read.</source>
+        <translation>Il file delle note di rilascio &apos;%1&apos; non può essere letto.</translation>
+    </message>
+    <message>
+        <location line="+13"/>
+        <source>Octave Release Notes</source>
+        <translation>Note di Rilascio di Octave</translation>
+    </message>
+    <message>
+        <location line="+192"/>
+        <source>Octave Community News</source>
+        <translation>Notizie dalla Comunità di Octave</translation>
+    </message>
+    <message>
+        <location line="+984"/>
+        <source>Open an existing file in editor</source>
+        <translation>Apri file esistente nell&apos;editor</translation>
+    </message>
+    <message>
+        <location line="+57"/>
+        <source>New Function...</source>
+        <translation>Nuova Funzione...</translation>
+    </message>
+    <message>
+        <location line="+4"/>
+        <source>New Figure</source>
+        <translation>Nuova Figura</translation>
+    </message>
+    <message>
+        <location line="+36"/>
+        <source>Select All</source>
+        <translation>Seleziona Tutto</translation>
+    </message>
+    <message>
+        <location line="+3"/>
+        <source>Clear Clipboard</source>
+        <translation>Pulisci Appunti</translation>
+    </message>
+    <message>
+        <location line="+5"/>
+        <source>Find Files...</source>
+        <translation>Trova File...</translation>
+    </message>
+    <message>
+        <location line="+5"/>
+        <source>Clear Command Window</source>
+        <translation>Pulisci la Finestra dei Comandi</translation>
+    </message>
+    <message>
+        <location line="+3"/>
+        <source>Clear Command History</source>
+        <translation>Pulisci lo Storico dei Comandi</translation>
+    </message>
+    <message>
+        <location line="+3"/>
+        <source>Clear Workspace</source>
+        <translation>Pulisci lo Spazio di Lavoro</translation>
+    </message>
+    <message>
+        <location line="+38"/>
+        <source>De&amp;bug</source>
+        <translation>De&amp;bug</translation>
+    </message>
+    <message>
+        <location line="+3"/>
+        <source>Step</source>
+        <translation>Un&apos;istruzione alla volta</translation>
+    </message>
+    <message>
+        <location line="+12"/>
+        <source>Continue</source>
+        <translation>Continua</translation>
+    </message>
+    <message>
+        <location line="+601"/>
+        <source>Are you sure you want to exit Octave?</source>
+        <translation>Si è sicuri di voler uscire da Octave?</translation>
+    </message>
+    <message>
+        <source>Exit Debug Mode</source>
+        <translation type="obsolete">Abbandona la Modalità di Debug</translation>
+    </message>
+    <message>
+        <location line="-545"/>
+        <source>Show File Browser</source>
+        <translation>Nostra l&apos;Esploratore di Risorse</translation>
+    </message>
+    <message>
+        <location line="+20"/>
+        <source>File Browser</source>
+        <translation>Esploratore di Risorse</translation>
+    </message>
+    <message>
+        <source>&lt;strong&gt;You are using a release candidate of Octave&apos;s experimental GUI.&lt;/strong&gt;  Octave is under continuous improvement and the GUI will be the default interface for the 4.0 release.  For more information, select the &quot;Release Notes&quot; item in the &quot;News&quot; menu of the GUI, or visit &lt;a href=&quot;http://octave.org&quot;&gt;http://octave.org&lt;/a&gt;.</source>
+        <translation type="obsolete">&lt;strong&gt;Stai utilizzando un &apos;candidato al rilascio&apos; dell&apos;interfaccia grafica sperimentale.&lt;/strong&gt; Octave è in continuo miglioramento e l&apos;interfaccia grafica sarà l&apos;interfaccia di default per la versione 4.0. Per maggiori informazioni, seleziona la voce &quot;Note di Rilascio&quot; nel menu &quot;Notizie&quot; dell&apos;interfaccia grafica o visita &lt;a href=&quot;http://octave.org&quot;&gt;http://octave.org&lt;/a&gt;.</translation>
+    </message>
+    <message>
+        <location line="-84"/>
+        <source>Step In</source>
+        <translation>Entra</translation>
+    </message>
+    <message>
+        <location line="-1428"/>
+        <location line="+2036"/>
+        <source>Octave</source>
+        <translation>Octave</translation>
+    </message>
+    <message>
+        <location line="-756"/>
+        <source>Load Workspace...</source>
+        <translation>Apri Spazio di Lavoro...</translation>
+    </message>
+    <message>
+        <location line="+3"/>
+        <source>Save Workspace As...</source>
+        <translation>Salva Spazio di Lavoro Come...</translation>
+    </message>
+    <message>
+        <location line="+38"/>
+        <source>New Script</source>
+        <translation>Nuovo Script</translation>
+    </message>
+    <message>
+        <source>Function...</source>
+        <translation type="obsolete">Funzione...</translation>
+    </message>
+    <message>
+        <location line="+111"/>
+        <source>Step Out</source>
+        <translation>Esci</translation>
+    </message>
+    <message>
+        <location line="+13"/>
+        <source>Quit Debug Mode</source>
+        <translation>Esci dalla modalità di Debug</translation>
+    </message>
+    <message>
+        <location line="+81"/>
+        <source>Reset Default Window Layout</source>
+        <translation>Ripristina il Layout della Finestra</translation>
+    </message>
+    <message>
+        <location line="+16"/>
+        <source>Octave Packages</source>
+        <translation>Octave Packages</translation>
+    </message>
+    <message>
+        <location line="+3"/>
+        <source>Share Code</source>
+        <translation>Condividi Codice (Agorà)</translation>
+    </message>
+    <message>
+        <location line="+3"/>
+        <source>Contribute to Octave</source>
+        <translation>Contribuisci</translation>
+    </message>
+    <message>
+        <location line="+3"/>
+        <source>Octave Developer Resources</source>
+        <translation>Risorse per Sviluppatori</translation>
+    </message>
+    <message>
+        <location line="+14"/>
+        <source>On Disk</source>
+        <translation>Su Disco</translation>
+    </message>
+    <message>
+        <location line="+3"/>
+        <source>Online</source>
+        <translation>In Linea</translation>
+    </message>
+    <message>
+        <location line="+6"/>
+        <source>&amp;News</source>
+        <translation>&amp;Notizie</translation>
+    </message>
+    <message>
+        <location line="+3"/>
+        <source>Release Notes</source>
+        <translation>Note di Rilascio</translation>
+    </message>
+    <message>
+        <location line="+3"/>
+        <source>Community News</source>
+        <translation>Notizie dalla Comunità</translation>
+    </message>
+    <message>
+        <source>More Info</source>
+        <translation type="obsolete">Maggiori Informazioni</translation>
+    </message>
+    <message>
+        <source>Hide</source>
+        <translation type="obsolete">Nascondi</translation>
+    </message>
+    <message>
+        <source>Experimental GUI Info</source>
+        <translation type="obsolete">Informazioni sull&apos;Interfaccia Grafica Sperimentale</translation>
+    </message>
+    <message>
+        <location line="+24"/>
+        <source>Enter directory name</source>
+        <translation>Inserisci nome cartella</translation>
+    </message>
+    <message>
+        <location line="+9"/>
+        <source>Current Directory: </source>
+        <translation>Cartella Corrente:</translation>
+    </message>
+    <message>
+        <location line="+4"/>
+        <source>One directory up</source>
+        <translation>Livello precedente</translation>
+    </message>
+    <message>
+        <location line="-1127"/>
+        <location line="+1130"/>
+        <source>Browse directories</source>
+        <translation>Naviga cartelle</translation>
+    </message>
+    <message>
+        <location line="-137"/>
+        <source>&amp;Window</source>
+        <translation>&amp;Finestra</translation>
+    </message>
+    <message>
+        <location line="+3"/>
+        <source>Show Command Window</source>
+        <translation>Mostra la Finestra dei Comandi</translation>
+    </message>
+    <message>
+        <location line="+3"/>
+        <source>Show Command History</source>
+        <translation>Mostra lo Storico dei Comandi</translation>
+    </message>
+    <message>
+        <location line="+6"/>
+        <source>Show Workspace</source>
+        <translation>Mostra lo Spazio di Lavoro</translation>
+    </message>
+    <message>
+        <location line="+3"/>
+        <source>Show Editor</source>
+        <translation>Mostra l&apos;Editor</translation>
+    </message>
+    <message>
+        <location line="+3"/>
+        <source>Show Documentation</source>
+        <translation>Mostra la Documentazione</translation>
+    </message>
+    <message>
+        <location line="+5"/>
+        <source>Command Window</source>
+        <translation>Finestra dei Comandi</translation>
+    </message>
+    <message>
+        <location line="+3"/>
+        <source>Command History</source>
+        <translation>Storico dei Comandi</translation>
+    </message>
+    <message>
+        <location line="+6"/>
+        <source>Workspace</source>
+        <translation>Spazio di lavoro</translation>
+    </message>
+    <message>
+        <location line="+3"/>
+        <source>Editor</source>
+        <translation>Editor</translation>
+    </message>
+    <message>
+        <location line="+3"/>
+        <location line="+41"/>
+        <source>Documentation</source>
+        <translation>Documentazione</translation>
+    </message>
+    <message>
+        <location line="-30"/>
+        <source>&amp;Help</source>
+        <translation>&amp;Aiuto</translation>
+    </message>
+    <message>
+        <location line="+7"/>
+        <source>Report Bug</source>
+        <translation>Segnala un Problema</translation>
+    </message>
+</context>
+<context>
+    <name>news_reader</name>
+    <message>
+        <location line="-1350"/>
+        <source>&lt;html&gt;
+&lt;body&gt;
+&lt;p&gt;
+Octave&apos;s community news source seems to be unavailable.
+&lt;/p&gt;
+&lt;p&gt;
+For the latest news, please check
+&lt;a href=&quot;http://octave.org/community-news.html&quot;&gt;http://octave.org/community-news.html&lt;/a&gt;
+when you have a connection to the web (link opens in an external browser).
+&lt;/p&gt;
+&lt;p&gt;
+&lt;small&gt;&lt;em&gt;&amp;mdash; The Octave Developers, </source>
+        <translation>&lt;html&gt;
+&lt;body&gt;
+&lt;p&gt;
+Le notizie dalla comunità di Octave non sembrano essere disponibili.
+&lt;/p&gt;
+&lt;p&gt;
+Per le ultime novità, si prega di controllare
+&lt;a href=&quot;http://octave.org/community-news.html&quot;&gt;http://octave.org/community-news.html&lt;/a&gt;
+avendo a disposizione una connesione ad internet (utilizza un browser esterno).
+&lt;/p&gt;
+&lt;p&gt;
+&lt;small&gt;&lt;em&gt;&amp;mdash; Gli Sviluppatori di Octave, </translation>
+    </message>
+    <message>
+        <location line="+18"/>
+        <source>&lt;html&gt;
+&lt;body&gt;
+&lt;p&gt;
+Connecting to the web to display the latest Octave Community news has been disabled.
+&lt;/p&gt;
+&lt;p&gt;
+For the latest news, please check
+&lt;a href=&quot;http://octave.org/community-news.html&quot;&gt;http://octave.org/community-news.html&lt;/a&gt;
+when you have a connection to the web (link opens in an external browser)
+or enable web connections for news in Octave&apos;s network settings dialog.
+&lt;/p&gt;
+&lt;p&gt;
+&lt;small&gt;&lt;em&gt;&amp;mdash; The Octave Developers, </source>
+        <translation>&lt;html&gt;
+&lt;body&gt;
+&lt;p&gt;
+La connessione ad internet per mostrare le ultime notizie dalla comunità di Octave non è abilitata.
+&lt;/p&gt;
+&lt;p&gt;
+Per le ultime novità, si prega di controllare
+&lt;a href=&quot;http://octave.org/community-news.html&quot;&gt;http://octave.org/community-news.html&lt;/a&gt;
+avendo a disposizione una connesione ad internet (utilizza un browser esterno)
+o di abilitare, nella finestra delle impostazioni di rete di Octave, la connessione ad internet per le notizie.
+&lt;/p&gt;
+&lt;p&gt;
+&lt;small&gt;&lt;em&gt;&amp;mdash; Gli Sviluppatori di Octave, </translation>
+    </message>
+</context>
+<context>
+    <name>octave_dock_widget</name>
+    <message>
+        <location filename="../src/octave-dock-widget.cc" line="+63"/>
+        <location line="+175"/>
+        <source>Undock widget</source>
+        <translation>Rimuovi widget dal lanciatore</translation>
+    </message>
+    <message>
+        <location line="-165"/>
+        <source>Hide widget</source>
+        <translation>Nascondi widget</translation>
+    </message>
+    <message>
+        <location line="+112"/>
+        <source>Dock widget</source>
+        <translation>Ancora widget al lanciatore</translation>
+    </message>
+</context>
+<context>
+    <name>octave_qscintilla</name>
+    <message>
+        <location filename="../src/m-editor/octave-qscintilla.cc" line="+226"/>
+        <source>Help on</source>
+        <translation>Aiuto su</translation>
+    </message>
+    <message>
+        <location line="+2"/>
+        <source>Documentation on</source>
+        <translation>Documentazione su</translation>
+    </message>
+    <message>
+        <location line="+3"/>
+        <source>Edit</source>
+        <translation>Modifica</translation>
+    </message>
+    <message>
+        <source>&amp;Run Selection</source>
+        <translation type="obsolete">&amp;Esegui Selezione</translation>
+    </message>
+</context>
+<context>
+    <name>octave_qt_link</name>
+    <message>
+        <source>Yes</source>
+        <translation type="obsolete">Sì</translation>
+    </message>
+    <message>
+        <source>No</source>
+        <translation type="obsolete">No</translation>
+    </message>
+    <message>
+        <location filename="../src/octave-qt-link.cc" line="+97"/>
+        <location line="+6"/>
+        <location line="+7"/>
+        <source>Create</source>
+        <translation>Crea</translation>
+    </message>
+    <message>
+        <location line="-10"/>
+        <source>File
+%1
+does not exist. Do you want to create it?</source>
+        <translation>Il file
+%1
+non esiste. Si desidera crearlo?</translation>
+    </message>
+    <message>
+        <location line="+3"/>
+        <source>Octave Editor</source>
+        <translation>Editor di octave</translation>
+    </message>
+    <message>
+        <location line="+211"/>
+        <source>The file %1 does not exist in the load path.  To run or debug the function you are editing, you must either change to the directory %2 or add that directory to the load path.</source>
+        <translation>Il file %1 non esiste nelle cartelle di esecuzione. Per lanciare o eseguire il debug della funzione in corso di modifica, è necessario passare alla cartella %2 o aggiungere tale cartella alle cartelle di esecuzione.</translation>
+    </message>
+    <message>
+        <location line="+1"/>
+        <source>The file %1 is shadowed by a file with the same name in the load path. To run or debug the function you are editing, change to the directory %2.</source>
+        <translation>Il file %1 è nascosto da un file con lo stesso nome presente nelle cartelle di esecuzione. Per lanciare o esguire il debug del file in corso di modifica, passare alla directory %2.</translation>
+    </message>
+    <message>
+        <location line="+2"/>
+        <source>Change Directory or Add Directory to Load Path</source>
+        <translation>Cambia Cartella o Aggiungi Cartella alle Cartelle di Esecuzione</translation>
+    </message>
+    <message>
+        <location line="+2"/>
+        <source>Change Directory</source>
+        <translation>Cambia Cartella</translation>
+    </message>
+    <message>
+        <location line="+1"/>
+        <source>Add Directory to Load Path</source>
+        <translation>Aggiungi Cartella alle Cartelle di esecuzione</translation>
+    </message>
+    <message>
+        <location line="-223"/>
+        <location line="+224"/>
+        <source>Cancel</source>
+        <translation>Annulla</translation>
+    </message>
+</context>
+<context>
+    <name>octave_txt_lexer</name>
+    <message>
+        <location filename="../src/m-editor/octave-txt-lexer.cc" line="+39"/>
+        <source>Default</source>
+        <translation>Default</translation>
+    </message>
+</context>
+<context>
+    <name>resource_manager</name>
+    <message>
+        <location filename="../src/resource-manager.cc" line="+235"/>
+        <source>The settings file
+%1
+does not exist and can not be created.
+Make sure you have read and write permissions to
+%2
+
+Octave GUI must be closed now.</source>
+        <translation>Il file di configurazione
+%1
+non esiste e non può essere creato.
+Assicurasi di avere permesso di lettura e scrittura in
+%2
+
+L&apos;inerfaccia grafica verrà chiusa.</translation>
+    </message>
+    <message>
+        <location line="+4"/>
+        <source>Octave Critical Error</source>
+        <translation>Errore Critico di Octave</translation>
+    </message>
+</context>
+<context>
+    <name>settings_dialog</name>
+    <message>
+        <location filename="../src/settings-dialog.ui" line="+23"/>
+        <location filename="../../build/libgui/src/ui-settings-dialog.h" line="+1685"/>
+        <source>Settings</source>
+        <translation>Impostazioni</translation>
+    </message>
+    <message>
+        <location line="+19"/>
+        <location filename="../../build/libgui/src/ui-settings-dialog.h" line="+21"/>
+        <source>General</source>
+        <translation>Genrale</translation>
+    </message>
+    <message>
+        <location line="+122"/>
+        <location filename="../../build/libgui/src/ui-settings-dialog.h" line="-15"/>
+        <source>Octave logo only</source>
+        <translation>Logo di Octave solamente</translation>
+    </message>
+    <message>
+        <location line="+10"/>
+        <location filename="../../build/libgui/src/ui-settings-dialog.h" line="+1"/>
+        <source>Letter icons</source>
+        <translation>Icone testuali</translation>
+    </message>
+    <message>
+        <location line="+7"/>
+        <location filename="../../build/libgui/src/ui-settings-dialog.h" line="+1"/>
+        <source>Graphic icons</source>
+        <translation>Icone grafiche</translation>
+    </message>
+    <message>
+        <location line="-110"/>
+        <location filename="../../build/libgui/src/ui-settings-dialog.h" line="-6"/>
+        <source>Dock widget title bar</source>
+        <translation>Barra del titolo del lanciatore di widget</translation>
+    </message>
+    <message>
+        <location line="+44"/>
+        <location filename="../../build/libgui/src/ui-settings-dialog.h" line="+2"/>
+        <source>Confirm before exiting</source>
+        <translation>Conferma prima di uscire</translation>
+    </message>
+    <message>
+        <location line="+135"/>
+        <location filename="../../build/libgui/src/ui-settings-dialog.h" line="+9"/>
+        <source>Custom style</source>
+        <translation>Stile personalizzato</translation>
+    </message>
+    <message>
+        <source>Background color</source>
+        <translation type="obsolete">Colore dello sfondo</translation>
+    </message>
+    <message>
+        <source>Text color</source>
+        <translation type="obsolete">Colore del testo</translation>
+    </message>
+    <message>
+        <location line="-40"/>
+        <location line="+512"/>
+        <location filename="../../build/libgui/src/ui-settings-dialog.h" line="-3"/>
+        <location line="+26"/>
+        <source>Show status bar</source>
+        <translation>Mostra barra di stato</translation>
+    </message>
+    <message>
+        <location line="-495"/>
+        <location filename="../../build/libgui/src/ui-settings-dialog.h" line="-25"/>
+        <source>Text inactive</source>
+        <translation>Testo inattivo</translation>
+    </message>
+    <message>
+        <location line="+13"/>
+        <location line="+52"/>
+        <location filename="../../build/libgui/src/ui-settings-dialog.h" line="+1"/>
+        <location line="+2"/>
+        <source>Active</source>
+        <translation>Attiva</translation>
+    </message>
+    <message>
+        <location line="+19"/>
+        <location filename="../../build/libgui/src/ui-settings-dialog.h" line="+1"/>
+        <source>Background inactive</source>
+        <translation>Sfondo inattivo</translation>
+    </message>
+    <message>
+        <location line="+132"/>
+        <location filename="../../build/libgui/src/ui-settings-dialog.h" line="+60"/>
+        <source>Editor</source>
+        <translation>Editor</translation>
+    </message>
+    <message>
+        <location line="+30"/>
+        <location filename="../../build/libgui/src/ui-settings-dialog.h" line="-53"/>
+        <source>After Column</source>
+        <translation>Numero di colonne</translation>
+    </message>
+    <message>
+        <location line="+96"/>
+        <location filename="../../build/libgui/src/ui-settings-dialog.h" line="+6"/>
+        <source>Color</source>
+        <translation>Colore</translation>
+    </message>
+    <message>
+        <location line="+130"/>
+        <location filename="../../build/libgui/src/ui-settings-dialog.h" line="+4"/>
+        <source>This works well for monospaced fonts. The line is drawn at a position based on the width of a space character in the default font. It may not work very well if styles use proportional fonts or if varied font sizes or bold, italic and normal texts are used.</source>
+        <translation>Questa impostazione è adatta a tipi di caratteri monospaced. La linea è posta in una posizione basata sulla larghezza di uno spazio bianco del tipo di carattere predefinito. Può non funzionare bene se gli stili usano stili di caratteri proporzionali o se diverse dimensioni di carattere, grassetto, corsivo sono utilizzati.</translation>
+    </message>
+    <message>
+        <location line="+3"/>
+        <location filename="../../build/libgui/src/ui-settings-dialog.h" line="+2"/>
+        <source>Draw a long  line marker</source>
+        <translation>Disegna un marcatore di linea lungo</translation>
+    </message>
+    <message>
+        <location line="+10"/>
+        <location filename="../../build/libgui/src/ui-settings-dialog.h" line="+1"/>
+        <source>Enable Code Folding</source>
+        <translation>Attiva espansione del codice</translation>
+    </message>
+    <message>
+        <location line="+20"/>
+        <location filename="../../build/libgui/src/ui-settings-dialog.h" line="+2"/>
+        <source>Show eol characters</source>
+        <translation>Mostra terminatore di riga</translation>
+    </message>
+    <message>
+        <location line="+9"/>
+        <location filename="../../build/libgui/src/ui-settings-dialog.h" line="+1"/>
+        <source>Default eol mode</source>
+        <translation>Terminatore predefinito</translation>
+    </message>
+    <message>
+        <location line="+14"/>
+        <location filename="../../build/libgui/src/ui-settings-dialog.h" line="+3"/>
+        <source>Windows (CRLF)</source>
+        <translation>Windows (CRLF)</translation>
+    </message>
+    <message>
+        <location line="+5"/>
+        <location filename="../../build/libgui/src/ui-settings-dialog.h" line="+1"/>
+        <source>Mac (CR)</source>
+        <translation>Mac (CR)</translation>
+    </message>
+    <message>
+        <location line="+5"/>
+        <location filename="../../build/libgui/src/ui-settings-dialog.h" line="+1"/>
+        <source>Unix (LF)</source>
+        <translation>Unix (LF)</translation>
+    </message>
+    <message>
+        <location line="+26"/>
+        <location filename="../../build/libgui/src/ui-settings-dialog.h" line="+2"/>
+        <source>Show horizontal scroll bar</source>
+        <translation>Mostra barra di scorrimento orizzontale</translation>
+    </message>
+    <message>
+        <location line="+24"/>
+        <location filename="../../build/libgui/src/ui-settings-dialog.h" line="+1"/>
+        <source>Indent width</source>
+        <translation>Ampiezza indentazione</translation>
+    </message>
+    <message>
+        <location line="+23"/>
+        <location filename="../../build/libgui/src/ui-settings-dialog.h" line="+1"/>
+        <source>Tab indents line</source>
+        <translation>Tasto Tab per l&apos;indentazione</translation>
+    </message>
+    <message>
+        <location line="+7"/>
+        <location filename="../../build/libgui/src/ui-settings-dialog.h" line="+1"/>
+        <source>Auto indentation</source>
+        <translation>Indentazione automatica</translation>
+    </message>
+    <message>
+        <location line="+20"/>
+        <location filename="../../build/libgui/src/ui-settings-dialog.h" line="+1"/>
+        <source>Tab width</source>
+        <translation>Ampiezza tabulazione</translation>
+    </message>
+    <message>
+        <location line="+7"/>
+        <location filename="../../build/libgui/src/ui-settings-dialog.h" line="+1"/>
+        <source>Show indentation guides</source>
+        <translation>Mostra guide per l&apos;indentazione</translation>
+    </message>
+    <message>
+        <location line="+17"/>
+        <location filename="../../build/libgui/src/ui-settings-dialog.h" line="+1"/>
+        <source>Backspace unindents line</source>
+        <translation>Tasto Backspace per rimuove l&apos;indentazione</translation>
+    </message>
+    <message>
+        <location line="+49"/>
+        <location filename="../../build/libgui/src/ui-settings-dialog.h" line="+1"/>
+        <source>Indentation uses tabs</source>
+        <translation>Indenta con tabulazioni</translation>
+    </message>
+    <message>
+        <location line="+26"/>
+        <location filename="../../build/libgui/src/ui-settings-dialog.h" line="+1"/>
+        <source>Auto completion</source>
+        <translation>Completamento automatico</translation>
+    </message>
+    <message>
+        <location line="+30"/>
+        <location filename="../../build/libgui/src/ui-settings-dialog.h" line="+1"/>
+        <source>Match keywords</source>
+        <translation>Abbina parole chiave</translation>
+    </message>
+    <message>
+        <location line="+13"/>
+        <location filename="../../build/libgui/src/ui-settings-dialog.h" line="+1"/>
+        <source>Case sensitive</source>
+        <translation>Distinzione maiuscole/minuscole</translation>
+    </message>
+    <message>
+        <location line="+23"/>
+        <location filename="../../build/libgui/src/ui-settings-dialog.h" line="+2"/>
+        <source>Replace word by suggested one</source>
+        <translation>Sostituisci una parola con quella suggerita</translation>
+    </message>
+    <message>
+        <location line="-10"/>
+        <location filename="../../build/libgui/src/ui-settings-dialog.h" line="-1"/>
+        <source>Match words in document</source>
+        <translation>Abbina parole nel documento</translation>
+    </message>
+    <message>
+        <location line="+173"/>
+        <location filename="../../build/libgui/src/ui-settings-dialog.h" line="+13"/>
+        <source>Restore editor tabs from previous session on startup</source>
+        <translation>Ripristina le schede dell&apos;editor dalla sessione precedente all&apos;avvio</translation>
+    </message>
+    <message>
+        <location line="+41"/>
+        <location filename="../../build/libgui/src/ui-settings-dialog.h" line="+3"/>
+        <source>Use custom file editor</source>
+        <translation>Utilizza editor personalizzato</translation>
+    </message>
+    <message>
+        <location line="+20"/>
+        <location filename="../../build/libgui/src/ui-settings-dialog.h" line="+2"/>
+        <source>emacs +%l %f </source>
+        <translation>emacs +%l %f</translation>
+    </message>
+    <message>
+        <location line="+35"/>
+        <location filename="../../build/libgui/src/ui-settings-dialog.h" line="+3"/>
+        <source>Editor Styles</source>
+        <translation>Stili dell&apos;Editor</translation>
+    </message>
+    <message>
+        <location line="+17"/>
+        <location filename="../../build/libgui/src/ui-settings-dialog.h" line="-1"/>
+        <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Select font, font size (as a difference from the default size), font style (&lt;b&gt;b&lt;/b&gt;old, &lt;b&gt;i&lt;/b&gt;talic, &lt;b&gt;u&lt;/b&gt;nderline), text color and background color (for the latter, the color pink (255,0,255) is a placeholder for the default background color).&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+        <translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Seleziona stile di carattere, dimensione carattere (come differenza dalla dimensione iniziale), stile del carattere (&lt;b&gt;g&lt;/b&gt;rassetto, &lt;b&gt;c&lt;/b&gt;orsivo, &lt;b&gt;s&lt;/b&gt;ottolinea), colore del testo e colore dello sfondo (per il quale il colore rosa (255, 0, 255) indica il colore di default).&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
+    </message>
+    <message>
+        <location line="+258"/>
+        <location filename="../../build/libgui/src/ui-settings-dialog.h" line="+11"/>
+        <source>Terminal Colors</source>
+        <translation>Colori del Terminale</translation>
+    </message>
+    <message>
+        <location line="-161"/>
+        <location filename="../../build/libgui/src/ui-settings-dialog.h" line="-6"/>
+        <source>Font</source>
+        <translation>Stile di carattere</translation>
+    </message>
+    <message>
+        <location line="-885"/>
+        <location filename="../../build/libgui/src/ui-settings-dialog.h" line="-57"/>
+        <source>Show line numbers</source>
+        <translation>Mostra numero di riga</translation>
+    </message>
+    <message>
+        <location line="+33"/>
+        <location filename="../../build/libgui/src/ui-settings-dialog.h" line="+3"/>
+        <source>Highlight current line</source>
+        <translation>Evidenzia la riga corrente</translation>
+    </message>
+    <message>
+        <source>Code completion</source>
+        <translation type="obsolete">Completamento del codice</translation>
+    </message>
+    <message>
+        <location line="-20"/>
+        <location filename="../../build/libgui/src/ui-settings-dialog.h" line="-2"/>
+        <source>Show complete path in window title</source>
+        <translation>Mostra il percorso completo nel titolo della finestra</translation>
+    </message>
+    <message>
+        <location line="-23"/>
+        <location filename="../../build/libgui/src/ui-settings-dialog.h" line="-2"/>
+        <source>Show whitespace</source>
+        <translation>Mostra spazi</translation>
+    </message>
+    <message>
+        <location line="+33"/>
+        <location filename="../../build/libgui/src/ui-settings-dialog.h" line="+3"/>
+        <source>Do not show whitespace used for indentation</source>
+        <translation>Non mostrare gli spazi utilizzati per l&apos;indentazione</translation>
+    </message>
+    <message>
+        <source># of characters typed before completion list displayed</source>
+        <translation type="obsolete">Numero i caratteri da digitare prima che la lista di completamento appaia</translation>
+    </message>
+    <message>
+        <location line="+665"/>
+        <location filename="../../build/libgui/src/ui-settings-dialog.h" line="+44"/>
+        <source>Create nonexistent files without prompting</source>
+        <translation>Crea file inesistenti senza chiedere conferma</translation>
+    </message>
+    <message>
+        <location line="+38"/>
+        <location filename="../../build/libgui/src/ui-settings-dialog.h" line="+3"/>
+        <source>command line (%f=file, %l=line):</source>
+        <translation>linea di comando (%f=file, %l=riga):</translation>
+    </message>
+    <message>
+        <location line="+94"/>
+        <location filename="../../build/libgui/src/ui-settings-dialog.h" line="+15"/>
+        <source>Terminal</source>
+        <translation>Terminale</translation>
+    </message>
+    <message>
+        <location line="+51"/>
+        <location filename="../../build/libgui/src/ui-settings-dialog.h" line="-8"/>
+        <source>Cursor type:</source>
+        <translation>Tipo di cursore:</translation>
+    </message>
+    <message>
+        <location line="-11"/>
+        <location filename="../../build/libgui/src/ui-settings-dialog.h" line="-1"/>
+        <source>Cursor blinking</source>
+        <translation>Lampeggiamento del cursore</translation>
+    </message>
+    <message>
+        <location line="-7"/>
+        <location filename="../../build/libgui/src/ui-settings-dialog.h" line="-1"/>
+        <source>Use foreground color</source>
+        <translation>Usa colore di primo piano</translation>
+    </message>
+    <message>
+        <location line="+53"/>
+        <location filename="../../build/libgui/src/ui-settings-dialog.h" line="+4"/>
+        <source>Font size</source>
+        <translation>Dimensione carattere</translation>
+    </message>
+    <message>
+        <location line="+111"/>
+        <location filename="../../build/libgui/src/ui-settings-dialog.h" line="+3"/>
+        <source>Set focus to terminal when running a command from within another widget</source>
+        <translation>Rendi il terminale la finestra attiva quando un comando è eseguito da uno widget</translation>
+    </message>
+    <message>
+        <location line="+79"/>
+        <location filename="../../build/libgui/src/ui-settings-dialog.h" line="+15"/>
+        <source>File Browser</source>
+        <translation>Gestore dei file</translation>
+    </message>
+    <message>
+        <location line="+46"/>
+        <location filename="../../build/libgui/src/ui-settings-dialog.h" line="-8"/>
+        <source>Show file size</source>
+        <translation>Mostra dimensione del file</translation>
+    </message>
+    <message>
+        <location line="-14"/>
+        <location filename="../../build/libgui/src/ui-settings-dialog.h" line="-2"/>
+        <source>Show file type</source>
+        <translation>Mostra tipo del file</translation>
+    </message>
+    <message>
+        <location line="+21"/>
+        <location filename="../../build/libgui/src/ui-settings-dialog.h" line="+3"/>
+        <source>Show date of last modification</source>
+        <translation>Mostra la data di ultima modifica</translation>
+    </message>
+    <message>
+        <location line="-14"/>
+        <location filename="../../build/libgui/src/ui-settings-dialog.h" line="-2"/>
+        <source>Show hidden files</source>
+        <translation>Mostra i file nascosti</translation>
+    </message>
+    <message>
+        <location line="-1590"/>
+        <location filename="../../build/libgui/src/ui-settings-dialog.h" line="-90"/>
+        <source>Interface</source>
+        <translation>Interfaccia</translation>
+    </message>
+    <message>
+        <location line="+286"/>
+        <location filename="../../build/libgui/src/ui-settings-dialog.h" line="+15"/>
+        <source>Octave Startup</source>
+        <translation>Avvio di Octave</translation>
+    </message>
+    <message>
+        <location line="+6"/>
+        <location filename="../../build/libgui/src/ui-settings-dialog.h" line="+1"/>
+        <source>These preferences are applied after the startup files like .octaverc.</source>
+        <translation>Queste preferenze sono applicate dopo l&apos;esecuzione del file di avvio .octaverc.</translation>
+    </message>
+    <message>
+        <location line="+35"/>
+        <location line="+1313"/>
+        <location filename="../../build/libgui/src/ui-settings-dialog.h" line="+1"/>
+        <location line="+79"/>
+        <source>Startup path</source>
+        <translation>Percorso di avvio</translation>
+    </message>
+    <message>
+        <location line="-1300"/>
+        <location line="+1317"/>
+        <location filename="../../build/libgui/src/ui-settings-dialog.h" line="-78"/>
+        <location line="+80"/>
+        <source>Browse</source>
+        <translation>Naviga</translation>
+    </message>
+    <message>
+        <location line="-1310"/>
+        <location filename="../../build/libgui/src/ui-settings-dialog.h" line="-79"/>
+        <source>Restore last Octave directory of previous session</source>
+        <translation>Ripristina la cartella Octave della sessione precedente</translation>
+    </message>
+    <message>
+        <location line="+212"/>
+        <location filename="../../build/libgui/src/ui-settings-dialog.h" line="+9"/>
+        <source>Tab width min.</source>
+        <translation>Ampiezza tabulazione min.</translation>
+    </message>
+    <message>
+        <location line="+52"/>
+        <location filename="../../build/libgui/src/ui-settings-dialog.h" line="+1"/>
+        <source>max.</source>
+        <translation>max.</translation>
+    </message>
+    <message>
+        <location line="+394"/>
+        <location filename="../../build/libgui/src/ui-settings-dialog.h" line="+28"/>
+        <source>With Octave builtins</source>
+        <translation>Con built-in di Octave</translation>
+    </message>
+    <message>
+        <location line="+10"/>
+        <location filename="../../build/libgui/src/ui-settings-dialog.h" line="+1"/>
+        <source>With Octave functions</source>
+        <translation>Con funzioni di Octave</translation>
+    </message>
+    <message>
+        <location line="+16"/>
+        <location filename="../../build/libgui/src/ui-settings-dialog.h" line="+1"/>
+        <source>Number of characters before list is shwon: </source>
+        <translation>Numero di caratteri da digitare prima che la lista appaia: </translation>
+    </message>
+    <message>
+        <location line="+48"/>
+        <location filename="../../build/libgui/src/ui-settings-dialog.h" line="+8"/>
+        <source>Show completion list automatically</source>
+        <translation>Mostra lista di completamento automaticamente</translation>
+    </message>
+    <message>
+        <location line="+71"/>
+        <location filename="../../build/libgui/src/ui-settings-dialog.h" line="+3"/>
+        <source>Reload externally changed files without prompt</source>
+        <translation>Ricarica file modificati esternamente senza chiedere</translation>
+    </message>
+    <message>
+        <location line="+267"/>
+        <location filename="../../build/libgui/src/ui-settings-dialog.h" line="+12"/>
+        <source>(Changing buffer size clears history)</source>
+        <translation>(Il cambio della dimensione della lista svuota lo storico comandi)</translation>
+    </message>
+    <message>
+        <location line="+28"/>
+        <location filename="../../build/libgui/src/ui-settings-dialog.h" line="+1"/>
+        <source>History buffer Size</source>
+        <translation>Dimensione storico comandi</translation>
+    </message>
+    <message>
+        <location line="+34"/>
+        <location filename="../../build/libgui/src/ui-settings-dialog.h" line="+2"/>
+        <source>Print debug location in terminal window in addition to the marker in the editor</source>
+        <translation>Stampa la posizione di debug nella finestra del terminale oltre al marcatore nell&apos;editor</translation>
+    </message>
+    <message>
+        <location line="+93"/>
+        <location filename="../../build/libgui/src/ui-settings-dialog.h" line="+3"/>
+        <source>Display</source>
+        <translation>Mostra</translation>
+    </message>
+    <message>
+        <location line="+39"/>
+        <location filename="../../build/libgui/src/ui-settings-dialog.h" line="+5"/>
+        <source>Alternating row colors</source>
+        <translation>Colori alternati per le righe</translation>
+    </message>
+    <message>
+        <location line="+12"/>
+        <location filename="../../build/libgui/src/ui-settings-dialog.h" line="+1"/>
+        <source>Behavior</source>
+        <translation>Comportamento</translation>
+    </message>
+    <message>
+        <location line="+27"/>
+        <location filename="../../build/libgui/src/ui-settings-dialog.h" line="+3"/>
+        <source>Restore last directory of previous session</source>
+        <translation>Ripristina l&apos;ultima cartella della sessione precedente</translation>
+    </message>
+    <message>
+        <location line="+65"/>
+        <location filename="../../build/libgui/src/ui-settings-dialog.h" line="+5"/>
+        <source>Workspace</source>
+        <translation>Spazio di lavoro</translation>
+    </message>
+    <message>
+        <source>Storage Class Colors</source>
+        <translation type="obsolete">Colori della Storage Class</translation>
+    </message>
+    <message>
+        <location line="+338"/>
+        <location filename="../../build/libgui/src/ui-settings-dialog.h" line="+33"/>
+        <source>Network</source>
+        <translation>Rete</translation>
+    </message>
+    <message>
+        <location line="+23"/>
+        <location filename="../../build/libgui/src/ui-settings-dialog.h" line="-12"/>
+        <source>Allow Octave to connect to the Octave web site to display current news and information</source>
+        <translation>Pemetti ad Octave di connettersi al sito web di Octave per mostrare notizie ed informazioni aggiornate</translation>
+    </message>
+    <message>
+        <location line="+46"/>
+        <location filename="../../build/libgui/src/ui-settings-dialog.h" line="+8"/>
+        <source>Use proxy server</source>
+        <translation>Usa server proxy</translation>
+    </message>
+    <message>
+        <location line="-23"/>
+        <location filename="../../build/libgui/src/ui-settings-dialog.h" line="-4"/>
+        <source>HttpProxy</source>
+        <translation>HttpProxy</translation>
+    </message>
+    <message>
+        <location line="-1959"/>
+        <location filename="../../build/libgui/src/ui-settings-dialog.h" line="-119"/>
+        <source>Icon set for dock widgets</source>
+        <translation>Icone per il lanciatore degli widget</translation>
+    </message>
+    <message>
+        <location line="-48"/>
+        <location filename="../../build/libgui/src/ui-settings-dialog.h" line="-4"/>
+        <source>Language (requires restart)</source>
+        <translation>Lingua (richiede riavvio)</translation>
+    </message>
+    <message>
+        <location line="-50"/>
+        <location filename="../../build/libgui/src/ui-settings-dialog.h" line="-2"/>
+        <source>Icon size</source>
+        <translation>Dimensione icona</translation>
+    </message>
+    <message>
+        <location line="+1589"/>
+        <location filename="../../build/libgui/src/ui-settings-dialog.h" line="+93"/>
+        <source>Synchronize Octave working directory with file browser</source>
+        <translation>Sincronizza la cartella di lavoro di Octave con il gestore dei file</translation>
+    </message>
+    <message>
+        <location line="+125"/>
+        <location filename="../../build/libgui/src/ui-settings-dialog.h" line="+5"/>
+        <source>Colors for variable attributes </source>
+        <translation>Colori per attributi variabili </translation>
+    </message>
+    <message>
+        <location line="+7"/>
+        <location filename="../../build/libgui/src/ui-settings-dialog.h" line="+1"/>
+        <source>Hide tool tip</source>
+        <translation>Nascondi tooltip</translation>
+    </message>
+    <message>
+        <location line="+27"/>
+        <location filename="../../build/libgui/src/ui-settings-dialog.h" line="+21"/>
+        <source>Shortcuts</source>
+        <translation>Scorciatoie</translation>
+    </message>
+    <message>
+        <location line="+31"/>
+        <location filename="../../build/libgui/src/ui-settings-dialog.h" line="-18"/>
+        <source>Select this option to prevent conflicts with readline shortcuts</source>
+        <translation>Seleziona questa opzione per evitrare conflitti con le scorciatoie readline</translation>
+    </message>
+    <message>
+        <location line="+3"/>
+        <location filename="../../build/libgui/src/ui-settings-dialog.h" line="+2"/>
+        <source>Disable global shortcuts when terminal window has focus</source>
+        <translation>Disabilita le scorciatoie globali quando il terminale è selezionato</translation>
+    </message>
+    <message>
+        <location line="+31"/>
+        <location line="+28"/>
+        <location filename="../../build/libgui/src/ui-settings-dialog.h" line="+1"/>
+        <location line="+4"/>
+        <source>Use this set</source>
+        <translation>Utilizza questo insieme</translation>
+    </message>
+    <message>
+        <location line="-21"/>
+        <location filename="../../build/libgui/src/ui-settings-dialog.h" line="-3"/>
+        <source>Set 1:</source>
+        <translation>Insieme 1:</translation>
+    </message>
+    <message>
+        <location line="+7"/>
+        <location line="+37"/>
+        <location filename="../../build/libgui/src/ui-settings-dialog.h" line="+1"/>
+        <location line="+3"/>
+        <source>Export</source>
+        <translation>Esporta</translation>
+    </message>
+    <message>
+        <location line="-30"/>
+        <location line="+37"/>
+        <location filename="../../build/libgui/src/ui-settings-dialog.h" line="-2"/>
+        <location line="+3"/>
+        <source>Import</source>
+        <translation>Importa</translation>
+    </message>
+    <message>
+        <location line="+7"/>
+        <location filename="../../build/libgui/src/ui-settings-dialog.h" line="+1"/>
+        <source>Set 2:</source>
+        <translation>Insieme 2:</translation>
+    </message>
+    <message>
+        <location line="+25"/>
+        <location filename="../../build/libgui/src/ui-settings-dialog.h" line="+1"/>
+        <source>Edit an actual shortcut by double clicking into the related cell</source>
+        <translation>Modifica una scorciatoia facendo doppio click nella relativa cella</translation>
+    </message>
+    <message>
+        <location line="+61"/>
+        <location filename="../../build/libgui/src/ui-settings-dialog.h" line="+6"/>
+        <source>Action</source>
+        <translation>Azione</translation>
+    </message>
+    <message>
+        <location line="+10"/>
+        <location filename="../../build/libgui/src/ui-settings-dialog.h" line="-1"/>
+        <source>Set 1 Default</source>
+        <translation>Insieme 1 predefinito</translation>
+    </message>
+    <message>
+        <location line="+5"/>
+        <location filename="../../build/libgui/src/ui-settings-dialog.h" line="-1"/>
+        <source>Set 1 Actual</source>
+        <translation>Ineieme 1 attuale</translation>
+    </message>
+    <message>
+        <location line="+5"/>
+        <location filename="../../build/libgui/src/ui-settings-dialog.h" line="-1"/>
+        <source>Set 2 Default</source>
+        <translation>Insieme 2 predefinito</translation>
+    </message>
+    <message>
+        <location line="+10"/>
+        <location filename="../../build/libgui/src/ui-settings-dialog.h" line="-1"/>
+        <source>Set 2 Actual</source>
+        <translation>Insieme 2 attuale</translation>
+    </message>
+    <message>
+        <location line="+68"/>
+        <location filename="../../build/libgui/src/ui-settings-dialog.h" line="+11"/>
+        <source>Socks5Proxy</source>
+        <translation>Socks5Proxy</translation>
+    </message>
+    <message>
+        <location line="-16"/>
+        <location filename="../../build/libgui/src/ui-settings-dialog.h" line="-4"/>
+        <source>Hostname:</source>
+        <translation>Nome host:</translation>
+    </message>
+    <message>
+        <location line="+44"/>
+        <location filename="../../build/libgui/src/ui-settings-dialog.h" line="+8"/>
+        <source>Proxy type:</source>
+        <translation>Tipo di proxy:</translation>
+    </message>
+    <message>
+        <location line="+10"/>
+        <location filename="../../build/libgui/src/ui-settings-dialog.h" line="+1"/>
+        <source>Port:</source>
+        <translation>Porta:</translation>
+    </message>
+    <message>
+        <location line="-27"/>
+        <location filename="../../build/libgui/src/ui-settings-dialog.h" line="-3"/>
+        <source>Username:</source>
+        <translation>Nome utente:</translation>
+    </message>
+    <message>
+        <location line="+37"/>
+        <location filename="../../build/libgui/src/ui-settings-dialog.h" line="+4"/>
+        <source>Password:</source>
+        <translation>Password:</translation>
+    </message>
+    <message>
+        <location filename="../src/settings-dialog.cc" line="+77"/>
+        <location line="+4"/>
+        <location line="+546"/>
+        <source>System setting</source>
+        <translation>Parametri di sistema</translation>
+    </message>
+    <message>
+        <location line="-353"/>
+        <source>IBeam Cursor</source>
+        <translation>Cursore IBeam</translation>
+    </message>
+    <message>
+        <location line="+1"/>
+        <source>Block Cursor</source>
+        <translation>Cursore blocco</translation>
+    </message>
+    <message>
+        <location line="+1"/>
+        <source>Underline Cursor</source>
+        <translation>Cursore testo sottolineato</translation>
+    </message>
+    <message>
+        <location line="+211"/>
+        <source>Difference to the default size</source>
+        <translation>Differenza rispetto alla dimensione di default</translation>
+    </message>
+    <message>
+        <location line="+6"/>
+        <source>Background color, pink (255,0,255) means default</source>
+        <translation>Colore dello sfondo; rosa (255,0,255) indica default</translation>
+    </message>
+    <message>
+        <location line="+2"/>
+        <source>b</source>
+        <comment>short form for bold</comment>
+        <translation>g</translation>
+    </message>
+    <message>
+        <location line="+1"/>
+        <source>i</source>
+        <comment>short form for italic</comment>
+        <translation>c</translation>
+    </message>
+    <message>
+        <location line="+1"/>
+        <source>u</source>
+        <comment>short form for underlined</comment>
+        <translation>s</translation>
+    </message>
+    <message>
+        <location line="+490"/>
+        <source>Set Octave Startup Directory</source>
+        <translation>Scegli la Cartella di Avvio di Octave</translation>
+    </message>
+    <message>
+        <location line="+6"/>
+        <source>Set File Browser Startup Directory</source>
+        <translation>Scegli la Cartella di Avvio del Gestore di File</translation>
+    </message>
+</context>
+<context>
+    <name>setup_community_news</name>
+    <message>
+        <location filename="../src/welcome-wizard.cc" line="+44"/>
+        <source>Community News</source>
+        <translation>Notizie dalla Comunità</translation>
+    </message>
+    <message>
+        <location line="+5"/>
+        <source>Previous</source>
+        <translation>Precedente</translation>
+    </message>
+    <message>
+        <location line="+1"/>
+        <source>Next</source>
+        <translation>Successivo</translation>
+    </message>
+    <message>
+        <location line="+1"/>
+        <source>Cancel</source>
+        <translation>Chiudi</translation>
+    </message>
+    <message>
+        <location line="+7"/>
+        <source>&lt;html&gt;&lt;body&gt;
+&lt;p&gt;When the Octave GUI starts, it will check the Octave web site for current news and information about the Octave community.
+The check will happen at most once each day and news will only be displayed if there is something new since the last time you viewed the news.&lt;/p&gt;
+&lt;p&gt;You may also view the news by selecting the &quot;Community News&quot; item in the &quot;Help&quot; menu in the GUI, or by visiting
+&lt;a href=&quot;http://octave.org/community-news.html&quot;&gt;http://octave.org/community-news.html&lt;/a&gt;.&lt;/p&gt;
+&lt;/body&gt;&lt;/html&gt;</source>
+        <translation>&lt;html&gt;&lt;body&gt;
+&lt;p&gt;Ad ogni avvio dell&apos;interfaccia grafica, l&apos;applicazione controllerà il sito web di Octave per ottenere notizie ed informazioni recenti dalla comunità. Tale controllo averrà non più di una volta al giorno e la finestra delle notizie verrà aperta soltanto nel caso in cui ci sia qualcosa di nuovo rispetto all&apos;ultima consultazione&lt;/p&gt;
+&lt;p&gt;Le notizie possono essere raggiunte anche selezionando &quot;Notizie dalla Comunità&quot; nel menu &quot;Aiuto&quot; dell&apos;interfaccia grafica, o visitando
+&lt;a href=&quot;http://octave.org/community-news.html&quot;&gt;http://octave.org/community-news.html&lt;/a&gt;.&lt;/p&gt;
+&lt;/body&gt;&lt;/html&gt;</translation>
+    </message>
+    <message>
+        <location line="+26"/>
+        <source>&lt;html&gt;&lt;head&gt;
+&lt;style&gt;
+a:link { text-decoration: underline; color: #0000ff; }
+&lt;/style&gt;
+&lt;head/&gt;&lt;body&gt;
+&lt;p&gt;Allow Octave to connect to the Octave web site when it starts to display current news and information about the Octave community.&lt;/p&gt;
+&lt;/body&gt;&lt;/html&gt;</source>
+        <translation>&lt;html&gt;&lt;head&gt;
+&lt;style&gt;
+a:link { text-decoration: underline; color: #0000ff; }
+&lt;/style&gt;
+&lt;head/&gt;&lt;body&gt;
+&lt;p&gt;Permetti all&apos;applicazione di connettersi all&apos;avvio al sito web di Octave per mostrare notizie ed informazione recenti dalla comunità.&lt;/p&gt;
+&lt;/body&gt;&lt;/html&gt;</translation>
+    </message>
+</context>
+<context>
+    <name>shortcut_manager</name>
+    <message>
+        <location filename="../src/shortcut-manager.cc" line="+109"/>
+        <source>New File</source>
+        <translation>Nuovo File</translation>
+    </message>
+    <message>
+        <location line="+1"/>
+        <source>New Function</source>
+        <translation>Nuova Funzione</translation>
+    </message>
+    <message>
+        <location line="+2"/>
+        <source>New Figure</source>
+        <translation>Nuova Figura</translation>
+    </message>
+    <message>
+        <location line="+1"/>
+        <source>Open File</source>
+        <translation>Apri File</translation>
+    </message>
+    <message>
+        <location line="+1"/>
+        <source>Load Workspace</source>
+        <translation>Carica lo Spazio di Lavoro</translation>
+    </message>
+    <message>
+        <location line="+1"/>
+        <source>Save Workspace As</source>
+        <translation>Salva lo Spazio di Lavoro Come</translation>
+    </message>
+    <message>
+        <location line="+1"/>
+        <location line="+155"/>
+        <source>Preferences</source>
+        <translation>Preferenze</translation>
+    </message>
+    <message>
+        <location line="-154"/>
+        <source>Exit Octave</source>
+        <translation>Esci da Octave</translation>
+    </message>
+    <message>
+        <location line="+3"/>
+        <location line="+81"/>
+        <source>Copy</source>
+        <translation>Copia</translation>
+    </message>
+    <message>
+        <location line="-80"/>
+        <location line="+82"/>
+        <source>Paste</source>
+        <translation>Incolla</translation>
+    </message>
+    <message>
+        <location line="-81"/>
+        <location line="+77"/>
+        <source>Undo</source>
+        <translation>Annulla</translation>
+    </message>
+    <message>
+        <location line="-76"/>
+        <location line="+81"/>
+        <source>Select All</source>
+        <translation>Seleziona Tutto</translation>
+    </message>
+    <message>
+        <location line="-80"/>
+        <source>Clear Clipboard</source>
+        <translation>Pulisci Appunti</translation>
+    </message>
+    <message>
+        <location line="+1"/>
+        <source>Find in Files</source>
+        <translation>Cerca nei file</translation>
+    </message>
+    <message>
+        <location line="+2"/>
+        <source>Clear Command Window</source>
+        <translation>Pulisci la Finestra dei Comandi</translation>
+    </message>
+    <message>
+        <location line="+2"/>
+        <source>Clear Command History</source>
+        <translation>Pulisci lo Storico dei Comandi</translation>
+    </message>
+    <message>
+        <location line="+2"/>
+        <source>Clear Workspace</source>
+        <translation>Pulisci lo Spazio di Lavoro</translation>
+    </message>
+    <message>
+        <location line="+3"/>
+        <source>Step Over</source>
+        <translation>Scavalca</translation>
+    </message>
+    <message>
+        <location line="+2"/>
+        <source>Step Into</source>
+        <translation>Livello Successivo</translation>
+    </message>
+    <message>
+        <location line="+2"/>
+        <source>Step Out</source>
+        <translation>Livello Precedente</translation>
+    </message>
+    <message>
+        <location line="+2"/>
+        <source>Continue</source>
+        <translation>Continua</translation>
+    </message>
+    <message>
+        <location line="+2"/>
+        <source>Quit Debug Mode</source>
+        <translation>Esci dalla modalità di Debug</translation>
+    </message>
+    <message>
+        <location line="+4"/>
+        <source>Show Command Window</source>
+        <translation>Mostra la Finestra dei Comandi</translation>
+    </message>
+    <message>
+        <location line="+2"/>
+        <source>Show Command History</source>
+        <translation>Mostra lo Storico dei Comandi</translation>
+    </message>
+    <message>
+        <location line="+2"/>
+        <source>Show File Browser</source>
+        <translation>Nostra l&apos;Esploratore di Risorse</translation>
+    </message>
+    <message>
+        <location line="+2"/>
+        <source>Show Workspace</source>
+        <translation>Mostra lo Spazio di Lavoro</translation>
+    </message>
+    <message>
+        <location line="+2"/>
+        <source>Show Editor</source>
+        <translation>Mostra l&apos;Editor</translation>
+    </message>
+    <message>
+        <location line="+2"/>
+        <source>Show Documentation</source>
+        <translation>Mostra la Documentazione</translation>
+    </message>
+    <message>
+        <location line="+2"/>
+        <source>Command Window</source>
+        <translation>Finestra dei Comandi</translation>
+    </message>
+    <message>
+        <location line="+2"/>
+        <source>Command History</source>
+        <translation>Storico dei comandi</translation>
+    </message>
+    <message>
+        <location line="+2"/>
+        <source>File Browser</source>
+        <translation>Gestore dei File</translation>
+    </message>
+    <message>
+        <location line="+2"/>
+        <source>Workspace</source>
+        <translation>Spazio di lavoro</translation>
+    </message>
+    <message>
+        <location line="+2"/>
+        <location line="+203"/>
+        <source>Editor</source>
+        <translation>Editor</translation>
+    </message>
+    <message>
+        <location line="-201"/>
+        <source>Documentation</source>
+        <translation>Documentazione</translation>
+    </message>
+    <message>
+        <location line="+2"/>
+        <source>Reset Window Layout</source>
+        <translation>Ripristina il Layout della Finestra</translation>
+    </message>
+    <message>
+        <location line="+3"/>
+        <source>Show Ondisk Documentation</source>
+        <translation>Mostra la Documentazione su Disco</translation>
+    </message>
+    <message>
+        <location line="+1"/>
+        <source>Show Online Documentation</source>
+        <translation>Mostra la Documentazione in Linea</translation>
+    </message>
+    <message>
+        <location line="+1"/>
+        <source>Report a Bug</source>
+        <translation>Segnala un Problema</translation>
+    </message>
+    <message>
+        <location line="+1"/>
+        <source>Octave Packages</source>
+        <translation>Octave Packages</translation>
+    </message>
+    <message>
+        <location line="+1"/>
+        <source>Share Code</source>
+        <translation>Condividi Codice</translation>
+    </message>
+    <message>
+        <location line="+1"/>
+        <source>Contribute to Octave</source>
+        <translation>Contribuisci</translation>
+    </message>
+    <message>
+        <location line="+1"/>
+        <source>Octave Developer Resources</source>
+        <translation>Risorse per Sviluppatori</translation>
+    </message>
+    <message>
+        <location line="+1"/>
+        <source>About Octave</source>
+        <translation>A proposito di Octave</translation>
+    </message>
+    <message>
+        <location line="+3"/>
+        <source>Release Notes</source>
+        <translation>Note di Rilascio</translation>
+    </message>
+    <message>
+        <location line="+1"/>
+        <source>Community News</source>
+        <translation>Notizie dalla Comunità</translation>
+    </message>
+    <message>
+        <location line="+5"/>
+        <source>Edit Function</source>
+        <translation>Modifica Funzione</translation>
+    </message>
+    <message>
+        <location line="+2"/>
+        <source>Save File</source>
+        <translation>Salva File</translation>
+    </message>
+    <message>
+        <location line="+1"/>
+        <source>Save File As</source>
+        <translation>Salva File Come</translation>
+    </message>
+    <message>
+        <location line="+1"/>
+        <source>Close</source>
+        <translation>Chiudi</translation>
+    </message>
+    <message>
+        <location line="+1"/>
+        <source>Close All</source>
+        <translation>Chiudi Tutto</translation>
+    </message>
+    <message>
+        <location line="+1"/>
+        <source>Close Other</source>
+        <translation>Chiudi Altro</translation>
+    </message>
+    <message>
+        <location line="+1"/>
+        <source>Print</source>
+        <translation>Stampa</translation>
+    </message>
+    <message>
+        <location line="+4"/>
+        <source>Redo</source>
+        <translation>Ripeti</translation>
+    </message>
+    <message>
+        <source>Cuy</source>
+        <translation type="obsolete">Taglia</translation>
+    </message>
+    <message>
+        <location line="+2"/>
+        <source>Cut</source>
+        <translation>Taglia</translation>
+    </message>
+    <message>
+        <location line="+3"/>
+        <source>Find and Replace</source>
+        <translation>Trova e Sostituisci</translation>
+    </message>
+    <message>
+        <location line="+2"/>
+        <source>Delete to Start of Word</source>
+        <translation>Cancella fino a inizio parola</translation>
+    </message>
+    <message>
+        <location line="+2"/>
+        <source>Delete to End of Word</source>
+        <translation>Cancella fino a fine parola</translation>
+    </message>
+    <message>
+        <location line="+2"/>
+        <source>Delete to Start of Line</source>
+        <translation>Cancella fino a inizio riga</translation>
+    </message>
+    <message>
+        <location line="+2"/>
+        <source>Delete to End of Line</source>
+        <translation>Cancella fino a fine riga</translation>
+    </message>
+    <message>
+        <location line="+2"/>
+        <source>Delete Line</source>
+        <translation>Cancella riga</translation>
+    </message>
+    <message>
+        <location line="+2"/>
+        <source>Copy Line</source>
+        <translation>Copia riga</translation>
+    </message>
+    <message>
+        <location line="+2"/>
+        <source>Cut Line</source>
+        <translation>Taglia riga</translation>
+    </message>
+    <message>
+        <location line="+2"/>
+        <source>Duplicate Selection/Line</source>
+        <translation>Duplica selezione/riga</translation>
+    </message>
+    <message>
+        <location line="+2"/>
+        <source>Transpose Line</source>
+        <translation>Trasponi riga</translation>
+    </message>
+    <message>
+        <location line="+2"/>
+        <source>Completion List</source>
+        <translation>Lista di completamento</translation>
+    </message>
+    <message>
+        <location line="+3"/>
+        <source>Comment Selection</source>
+        <translation>Commenta selezione</translation>
+    </message>
+    <message>
+        <location line="+2"/>
+        <source>Uncomment Selection</source>
+        <translation>Decommenta selezione</translation>
+    </message>
+    <message>
+        <location line="+2"/>
+        <source>Uppercase Selection</source>
+        <translation>Rendi la selezione in maisucolo</translation>
+    </message>
+    <message>
+        <location line="+2"/>
+        <source>Lowercase Selection</source>
+        <translation>Rendi la selezione in minuscolo</translation>
+    </message>
+    <message>
+        <location line="+4"/>
+        <location line="+5"/>
+        <source>Indent Selection</source>
+        <translation>Indenta selezione</translation>
+    </message>
+    <message>
+        <location line="-3"/>
+        <location line="+5"/>
+        <source>Unindent Selection</source>
+        <translation>Deindenta selezione</translation>
+    </message>
+    <message>
+        <location line="+4"/>
+        <source>Convert Line Ednings to Windows</source>
+        <translation>Converti terminatore di riga a Windows</translation>
+    </message>
+    <message>
+        <location line="+2"/>
+        <source>Convert Line Ednings to Unix</source>
+        <translation>Converti terminatore di riga a Unix</translation>
+    </message>
+    <message>
+        <location line="+2"/>
+        <source>Convert Line Ednings to Mac</source>
+        <translation>Converti terminatore di riga a Mac</translation>
+    </message>
+    <message>
+        <location line="+3"/>
+        <source>Goto Line</source>
+        <translation>Vai alla riga</translation>
+    </message>
+    <message>
+        <location line="+2"/>
+        <source>Move to Matching Brace</source>
+        <translation>Vai alla Parentesi Corrispondente</translation>
+    </message>
+    <message>
+        <location line="+2"/>
+        <source>Select to Matching Brace</source>
+        <translation>Seleziona fino alla Parentesi Corrispondente</translation>
+    </message>
+    <message>
+        <location line="+2"/>
+        <source>Toggle Bookmark</source>
+        <translation>Attiva/disattiva Segnalibro</translation>
+    </message>
+    <message>
+        <location line="+2"/>
+        <source>Next Bookmark</source>
+        <translation>Segnalibro Successivo</translation>
+    </message>
+    <message>
+        <location line="+2"/>
+        <source>Previous Bookmark</source>
+        <translation>Segnalibro Precedente</translation>
+    </message>
+    <message>
+        <location line="+2"/>
+        <source>Remove All Bookmark</source>
+        <translation>Elimina Tutti i Segnalibri</translation>
+    </message>
+    <message>
+        <location line="+4"/>
+        <source>Styles Preferences</source>
+        <translation>Preferenze di stile</translation>
+    </message>
+    <message>
+        <location line="+4"/>
+        <source>Show Line Numbers</source>
+        <translation>Mostra numeri di riga</translation>
+    </message>
+    <message>
+        <location line="+1"/>
+        <source>Show White Spaces</source>
+        <translation>Mostra spazi</translation>
+    </message>
+    <message>
+        <location line="+1"/>
+        <source>Show Line Endings</source>
+        <translation>Mostra terminatori di riga</translation>
+    </message>
+    <message>
+        <location line="+1"/>
+        <source>Show Indentation Guides</source>
+        <translation>Mostra guide per l&apos;indentazione</translation>
+    </message>
+    <message>
+        <location line="+1"/>
+        <source>Show Long Line Marker</source>
+        <translation>Mostra marcatori linea lunga</translation>
+    </message>
+    <message>
+        <location line="+1"/>
+        <source>Zoom In</source>
+        <translation>Ingrandisci</translation>
+    </message>
+    <message>
+        <location line="+1"/>
+        <source>Zoom Out</source>
+        <translation>Riduci</translation>
+    </message>
+    <message>
+        <location line="+2"/>
+        <location line="+3"/>
+        <source>Zoom Normal</source>
+        <translation>Dimensione normale</translation>
+    </message>
+    <message>
+        <location line="+5"/>
+        <source>Toggle Breakpoint</source>
+        <translation>Attiva/disattiva Breakpoint</translation>
+    </message>
+    <message>
+        <location line="+2"/>
+        <source>Next Breakpoint</source>
+        <translation>Breakpoint Successivo</translation>
+    </message>
+    <message>
+        <location line="+2"/>
+        <source>Previous Breakpoint</source>
+        <translation>Breakpoint Precedente</translation>
+    </message>
+    <message>
+        <location line="+2"/>
+        <source>Remove All Breakpoints</source>
+        <translation>Rimuovi Tutti i Breakpoint</translation>
+    </message>
+    <message>
+        <location line="+4"/>
+        <source>Run File</source>
+        <translation>Esegui File</translation>
+    </message>
+    <message>
+        <location line="+2"/>
+        <source>Run Selection</source>
+        <translation>Esegui Selezione</translation>
+    </message>
+    <message>
+        <location line="+4"/>
+        <source>Help on Keyword</source>
+        <translation>Aiuto su Parola Chiave</translation>
+    </message>
+    <message>
+        <location line="+1"/>
+        <source>Document on Keyword</source>
+        <translation>Documentazione sulla Parola Chiave</translation>
+    </message>
+    <message>
+        <location line="+37"/>
+        <source>Main</source>
+        <translation>Principale</translation>
+    </message>
+    <message>
+        <location line="+3"/>
+        <location line="+23"/>
+        <source>File</source>
+        <translation>File</translation>
+    </message>
+    <message>
+        <location line="-21"/>
+        <location line="+23"/>
+        <source>Edit</source>
+        <translation>Modifica</translation>
+    </message>
+    <message>
+        <location line="-21"/>
+        <location line="+25"/>
+        <source>Debug</source>
+        <translation>Debug</translation>
+    </message>
+    <message>
+        <location line="-23"/>
+        <source>Window</source>
+        <translation>Finestra</translation>
+    </message>
+    <message>
+        <location line="+2"/>
+        <location line="+25"/>
+        <source>Help</source>
+        <translation>Aiuto</translation>
+    </message>
+    <message>
+        <location line="-23"/>
+        <source>News</source>
+        <translation>Novità</translation>
+    </message>
+    <message>
+        <location line="+17"/>
+        <source>View</source>
+        <translation>Vista</translation>
+    </message>
+    <message>
+        <location line="+4"/>
+        <source>Run</source>
+        <translation>Esegui</translation>
+    </message>
+    <message>
+        <location line="+118"/>
+        <source>Enter new Shortcut for Set %1</source>
+        <translation>Inserisci nuova Scorciatoia per l&apos;Insieme %1</translation>
+    </message>
+    <message>
+        <location line="+5"/>
+        <source>Apply the desired shortcut or click on the right button to reset the shortcut to its default.</source>
+        <translation>Applica la scorciatoia desiderata o clicca con il tasto destro del mouse per ripristinare la scorciatoia predefinita.</translation>
+    </message>
+    <message>
+        <location line="+6"/>
+        <source>Enter shortcut directly by performing it</source>
+        <translation>Inserici una scorciatoia eseguendola direttamente</translation>
+    </message>
+    <message>
+        <location line="+6"/>
+        <source>Actual shortcut</source>
+        <translation>Scorciatoia attuale</translation>
+    </message>
+    <message>
+        <location line="+6"/>
+        <source>Default shortcut</source>
+        <translation>Scorciatoia predefinita</translation>
+    </message>
+    <message>
+        <location line="+6"/>
+        <source>Set to default</source>
+        <translation>Imposta al valore predefinito</translation>
+    </message>
+    <message>
+        <location line="+53"/>
+        <source>Double Shortcut</source>
+        <translation>Doppia Scorciatoia</translation>
+    </message>
+    <message>
+        <location line="+1"/>
+        <source>The chosen shortcut
+  &quot;%1&quot;
+is already used for the action
+  &quot;%2&quot;.
+Do you want to use the shortcut anyhow removing it from the previous action?</source>
+        <translation>La scorciatoia
+&quot;%1&quot;
+è già utilizzata per un l&apos;azione
+&quot;%2&quot;
+Si desidera utilizzare comunque la scorciatoia rimuovendola dall&apos;azione cui era precedentemente associata?</translation>
+    </message>
+    <message>
+        <location line="+70"/>
+        <source>Import shortcut set %1 from file ...</source>
+        <translation>Importa l&apos;insieme di  scorciatoie %1 dal file...</translation>
+    </message>
+    <message>
+        <location line="+1"/>
+        <location line="+6"/>
+        <source>Octave Shortcut Files (*.osc);;All Files (*)</source>
+        <translation>File Scorciatoia di Octave (*.osc);;Tutti i File (*)</translation>
+    </message>
+    <message>
+        <location line="-1"/>
+        <source>Export shortcut set %1 into file ...</source>
+        <translation>Esporta l&apos;insieme di  scorciatoie %1 nel file...</translation>
+    </message>
+    <message>
+        <location line="+15"/>
+        <source>Failed to open %1 as octave shortcut file</source>
+        <translation>Impossibile aprire il file %1 come file di scorciatoie di Octave</translation>
+    </message>
+</context>
+<context>
+    <name>terminal_dock_widget</name>
+    <message>
+        <location filename="../src/terminal-dock-widget.cc" line="+38"/>
+        <source>Command Window</source>
+        <translation>Finestra dei Comandi</translation>
+    </message>
+</context>
+<context>
+    <name>webinfo</name>
+    <message>
+        <location filename="../src/qtinfo/webinfo.cc" line="+82"/>
+        <source>Type here and press &apos;Return&apos; to search</source>
+        <translation>Scrivi qui e premi &apos;Invio&apos; per cercare</translation>
+    </message>
+    <message>
+        <location line="+4"/>
+        <source>Global search</source>
+        <translation>Ricerca globale</translation>
+    </message>
+    <message>
+        <location line="+18"/>
+        <source>Error</source>
+        <translation>Errore</translation>
+    </message>
+    <message>
+        <location line="+3"/>
+        <source>The info file&lt;p&gt;%1&lt;p&gt;or compressed versions do not exist</source>
+        <translation>Né file di informazione %1 né una sua versione compressa esistono</translation>
+    </message>
+    <message>
+        <source>The info file %1 does not exist</source>
+        <translation type="obsolete">Il file di informazione %1 non esiste</translation>
+    </message>
+</context>
+<context>
+    <name>welcome_wizard</name>
+    <message>
+        <location filename="../src/welcome-wizard.cc" line="+135"/>
+        <source>Welcome to GNU Octave</source>
+        <translation>Benvenuto in GNU Octave</translation>
+    </message>
+</context>
+<context>
+    <name>workspace_model</name>
+    <message>
+        <location filename="../src/workspace-model.cc" line="-42"/>
+        <source>Name</source>
+        <translation>Nome</translation>
+    </message>
+    <message>
+        <location line="+1"/>
+        <source>Class</source>
+        <translation>Classe</translation>
+    </message>
+    <message>
+        <location line="+1"/>
+        <source>Dimension</source>
+        <translation>Dimensione</translation>
+    </message>
+    <message>
+        <location line="+1"/>
+        <source>Value</source>
+        <translation>Valore</translation>
+    </message>
+    <message>
+        <location line="+1"/>
+        <source>Attribute</source>
+        <translation>Attributo</translation>
+    </message>
+    <message>
+        <location line="+109"/>
+        <source>Right click to copy, rename, or display</source>
+        <translation>Cliccare con il tasto destro del mouse per copiare, rinominare o mostrare</translation>
+    </message>
+    <message>
+        <location line="+37"/>
+        <location line="+2"/>
+        <source>complex</source>
+        <translation>complesso</translation>
+    </message>
+</context>
+<context>
+    <name>workspace_view</name>
+    <message>
+        <location filename="../src/workspace-view.cc" line="+50"/>
+        <source>Workspace</source>
+        <translation>Spazio di lavoro</translation>
+    </message>
+    <message>
+        <location line="+1"/>
+        <source>View the variables in the active workspace.</source>
+        <translation>Mostra le variabili nello spazio di lavoro attivo.</translation>
+    </message>
+    <message>
+        <source>Copy</source>
+        <translation type="obsolete">Copia</translation>
+    </message>
+    <message>
+        <location line="+3"/>
+        <source>Enter text to filter the workspace</source>
+        <translation>Inserire del testo per filtrare l&apos;area di lavoro</translation>
+    </message>
+    <message>
+        <location line="+10"/>
+        <source>Filter</source>
+        <translation>Filtra</translation>
+    </message>
+    <message>
+        <location line="+147"/>
+        <source>Copy name</source>
+        <translation>Copia nome</translation>
+    </message>
+    <message>
+        <location line="+3"/>
+        <source>Copy value</source>
+        <translation>Copia valore</translation>
+    </message>
+    <message>
+        <location line="+3"/>
+        <source>Rename</source>
+        <translation>Rinomina</translation>
+    </message>
+    <message>
+        <location line="+9"/>
+        <source>Only top-level symbols may be renamed.</source>
+        <translation>Solamente i simboli di primo livello possono essere rinominati.</translation>
+    </message>
+    <message>
+        <location line="+132"/>
+        <source>View the variables in the active workspace.&lt;br&gt;</source>
+        <translation>Mostra le variabili nello spazio di lavoro attivo.&lt;br&gt;</translation>
+    </message>
+    <message>
+        <location line="+1"/>
+        <source>Colors for variable attributes:</source>
+        <translation>Colori per gli attributi variabili:</translation>
+    </message>
+</context>
+</TS>
--- a/libgui/languages/nl_NL.ts	Fri Feb 06 08:31:09 2015 -0800
+++ b/libgui/languages/nl_NL.ts	Fri Feb 06 08:31:49 2015 -0800
@@ -474,7 +474,7 @@
         <translation>Aanwijzer</translation>
     </message>
     <message>
-        <location filename="../src/main-window.cc" line="+1900"/>
+        <location filename="../src/main-window.cc" line="+1963"/>
         <source>&lt;p&gt;&lt;strong&gt;A Note about Octave&apos;s New GUI&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;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.  But because it is not quite as polished as we would like, we have decided to wait until the 4.0.x release series before making the GUI the default interface.&lt;/p&gt;&lt;p&gt;Given the length of time and the number of bug fixes and improvements since the last major release, we also decided against delaying the release of all these new improvements any longer just to perfect the GUI.  So please enjoy the 3.8 release of Octave and the preview of the new GUI.  We believe it is working reasonably well, but we also know that there are some obvious rough spots and many things that could be improved.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;We Need Your Help&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;There are many ways that you can help us fix the remaining problems, complete the GUI, and improve the overall user experience for both novices and experts alike (links will open an external browser):&lt;/p&gt;&lt;p&gt;&lt;ul&gt;&lt;li&gt;If you are a skilled software developer, you can help by contributing your time to help &lt;a href=&quot;http://octave.org/get-involved.html&quot;&gt;develop Octave&lt;/a&gt;.&lt;/li&gt;&lt;li&gt;If Octave does not work properly, you are encouraged to &lt;a href=&quot;http://octave.org/bugs.html&quot;&gt;report problems &lt;/a&gt; that you find.&lt;/li&gt;&lt;li&gt;Whether you are a user or developer, you can &lt;a href=&quot;http://octave.org/donate.html&quot;&gt;help to fund the project&lt;/a&gt;.  Octave development takes a lot of time and expertise.  Your contributions help to ensure that Octave will continue to improve.&lt;/li&gt;&lt;/ul&gt;&lt;/p&gt;&lt;p&gt;We hope you find Octave to be useful.  Please help us make it even better for the future!&lt;/p&gt;</source>
         <translation>&lt;p&gt;&lt;strong&gt;Een opmerking over Octave&apos;s Nieuwe GUI&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;Een van de belangrijkste nieuwe kenmerken van Octave 3.8 is een grafische user interface (GUI).  Dat is waar de gebruikers de afgelopen jaren het meest om gevraagd hebben en hij is bijna af.  Maar omdat hij nog niet zo gepolijst is als we zouden willen hebben we besloten te wachten tot de versie 4.0 serie voordat we hem de standaard interface maken.&lt;/p&gt;&lt;p&gt;Vanwege de lange tijd en het aantal bug fixes en verbeteringen sinds de laatste major release versie hebben we ook besloten om niet langer meer te wachten op de GUI om al die verbeteringen door te voeren.  Dus geniet van Octave versie 3.8 en de preview van de nieuwe GUI.  We denken dat hij redelijk goed werkt, maar natuurlijk weten we dat er nog ruwe kantjes aan zitten en ruimte voor verbeteringen.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;We hebben je hulp nodig&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;Er zijn veel manieren waarop je ons kunt helpen de overgebleven problemen te verhelpen, de GUI te completeren, en de gebruikerservaring voor nieuwelingen en experts (de URLs openen een nieuwe browser):&lt;/p&gt;&lt;p&gt;&lt;ul&gt;&lt;li&gt;Als je een bekwame ontwikkelaar bent kun je ons helpen door bij te dragen &lt;a href=&quot;http://octave.org/get-involved.html&quot;&gt;develop Octave&lt;/a&gt;.&lt;/li&gt;&lt;li&gt;Als Octave niet goed wekt raden we je aan om &lt;a href=&quot;http://octave.org/bugs.html&quot;&gt;de problemen te rapporteren &lt;/a&gt; die je tegen komt.&lt;/li&gt;&lt;li&gt;Of je nu gebruiker of ontwikkelaar bent, je kunt ook &lt;a href=&quot;http://octave.org/donate.html&quot;&gt;een bijdrage geven&lt;/a&gt;.  De ontwikkeling van Octave vraagt een hoop tijd en expertise.  Je bijdrage helpt er aan mee dat Octave verbeterd blijft worden.&lt;/li&gt;&lt;/ul&gt;&lt;/p&gt;&lt;p&gt;We hopen dat je Octave nuttig vindt.  Help alsjeblieft om het in de toekomst nog beter te maken!&lt;/p&gt;</translation>
     </message>
@@ -962,7 +962,7 @@
 <context>
     <name>QWinTerminalImpl</name>
     <message>
-        <location filename="../qterminal/libqterminal/win32/QWinTerminalImpl.cpp" line="+1536"/>
+        <location filename="../qterminal/libqterminal/win32/QWinTerminalImpl.cpp" line="+1539"/>
         <source>copied selection to clipboard</source>
         <translation>selectie is naar klembord gekopieerd</translation>
     </message>
@@ -1683,17 +1683,12 @@
 is reeds geopend in de editor</translation>
     </message>
     <message>
-        <location line="+255"/>
+        <location line="+268"/>
         <source>&amp;%1 %2</source>
         <translation></translation>
     </message>
     <message>
-        <location line="+175"/>
-        <source>&amp;New File</source>
-        <translation>&amp;Nieuw Bestand</translation>
-    </message>
-    <message>
-        <location line="+6"/>
+        <location line="+207"/>
         <source>&amp;Save File</source>
         <translation>Op&amp;slaan</translation>
     </message>
@@ -1703,7 +1698,12 @@
         <translation>&amp;Openen...</translation>
     </message>
     <message>
-        <location line="+6"/>
+        <location line="-3"/>
+        <source>&amp;New Script</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+9"/>
         <source>Save File &amp;As...</source>
         <translation>Opslaan &amp;als...</translation>
     </message>
@@ -1789,6 +1789,16 @@
     </message>
     <message>
         <location line="+3"/>
+        <source>&amp;Indent</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+2"/>
+        <source>&amp;Unindent</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+3"/>
         <source>&amp;Find and Replace...</source>
         <translation>Zoek en Vervang...</translation>
     </message>
@@ -1803,7 +1813,7 @@
         <translation>Ga naar regel...</translation>
     </message>
     <message>
-        <location line="+55"/>
+        <location line="+57"/>
         <source>&amp;Recent Editor Files</source>
         <translation>&amp;Recent geopend</translation>
     </message>
@@ -1828,7 +1838,7 @@
         <translation>Andere bestanden sluiten</translation>
     </message>
     <message>
-        <location line="+31"/>
+        <location line="+34"/>
         <source>&amp;Preferences...</source>
         <translation>Voorkeuren...</translation>
     </message>
@@ -1858,7 +1868,7 @@
         <translation>&amp;Documentatie bij sleutelwoord</translation>
     </message>
     <message>
-        <location line="-741"/>
+        <location line="-790"/>
         <source>Could not open file
 %1
 for read: %2.</source>
@@ -1890,7 +1900,7 @@
         <translation>Het bijbehorende tabblad in de editor is verdwenen.</translation>
     </message>
     <message>
-        <location line="+521"/>
+        <location line="+567"/>
         <source>&amp;File</source>
         <translation>Bestand</translation>
     </message>
@@ -1905,7 +1915,7 @@
         <translation>B&amp;ewerken</translation>
     </message>
     <message>
-        <location line="+30"/>
+        <location line="+33"/>
         <source>&amp;Debug</source>
         <translation>&amp;Debuggen</translation>
     </message>
@@ -1918,7 +1928,7 @@
 <context>
     <name>file_editor_tab</name>
     <message>
-        <location filename="../src/m-editor/file-editor-tab.cc" line="+803"/>
+        <location filename="../src/m-editor/file-editor-tab.cc" line="+824"/>
         <source>Goto line</source>
         <translation>Ga naar regel</translation>
     </message>
@@ -1928,7 +1938,7 @@
         <translation>Regelnummer</translation>
     </message>
     <message>
-        <location line="+71"/>
+        <location line="+108"/>
         <location line="+69"/>
         <source>&lt;unnamed&gt;</source>
         <translation>naamloos</translation>
@@ -1945,14 +1955,15 @@
     </message>
     <message>
         <location line="+10"/>
-        <location line="+122"/>
-        <location line="+150"/>
+        <location line="+123"/>
+        <location line="+112"/>
+        <location line="+69"/>
         <location line="+22"/>
         <source>Octave Editor</source>
         <translation></translation>
     </message>
     <message>
-        <location line="-293"/>
+        <location line="-325"/>
         <source>The file
 %1
 is about to be closed but has been modified.
@@ -1963,12 +1974,12 @@
 %2</translation>
     </message>
     <message>
-        <location line="+201"/>
+        <location line="+203"/>
         <source>Octave Files (*.m);;All Files (*)</source>
         <translation>Octave bestanden (*.m);;Alle bestanden (*)</translation>
     </message>
     <message>
-        <location line="+86"/>
+        <location line="+116"/>
         <source>
 
 Warning: The contents in the editor is modified!</source>
@@ -1985,14 +1996,14 @@
 is gewist of hernoemd. Wil je het nu opslaan?%2</translation>
     </message>
     <message>
-        <location line="-172"/>
+        <location line="-203"/>
         <source>Could not open file %1 for write:
 %2.</source>
         <translation>Kon bestand %1 niet openen om te schrijven:
 %2.</translation>
     </message>
     <message>
-        <location line="-975"/>
+        <location line="-1032"/>
         <source>Line:</source>
         <translation>Regel:</translation>
     </message>
@@ -2002,7 +2013,18 @@
         <translation>Kolom:</translation>
     </message>
     <message>
-        <location line="+1122"/>
+        <location line="+1141"/>
+        <source>&quot;%1&quot;
+is not a valid identifier.
+
+If you keep this file name, you will not be able to
+call your script using its name as an Octave command.
+
+Do you want to choose another name?</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+69"/>
         <source>It seems that &apos;%1&apos; has been modified by another application. Do you want to reload it?</source>
         <translation>Het lijkt erop dat &apos;%1&apos; is gewijzigd door een ander programma. Wil je het opnieuw laden?</translation>
     </message>
@@ -2035,7 +2057,12 @@
         <translation>Bewerkingen op huidige map</translation>
     </message>
     <message>
-        <location line="+373"/>
+        <location line="+15"/>
+        <source>Set Browser Directory...</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+379"/>
         <source>Find Files...</source>
         <translation>Zoek bestanden...</translation>
     </message>
@@ -2046,16 +2073,17 @@
     </message>
     <message>
         <location line="+3"/>
+        <location line="+333"/>
         <source>New Directory</source>
         <translation>Nieuwe map</translation>
     </message>
     <message>
-        <location line="-323"/>
+        <location line="-656"/>
         <source>Double-click a file to open it</source>
         <translation>Dubbelklik een bestand om te openen</translation>
     </message>
     <message>
-        <location line="-79"/>
+        <location line="-100"/>
         <source>Show Octave directory</source>
         <translation>Laat Octave map zien</translation>
     </message>
@@ -2080,7 +2108,7 @@
         <translation>Laat home map zien</translation>
     </message>
     <message>
-        <location line="+12"/>
+        <location line="+16"/>
         <source>Search Directory...</source>
         <translation>Zoek in map...</translation>
     </message>
@@ -2100,7 +2128,7 @@
         <translation>Nieuwe map...</translation>
     </message>
     <message>
-        <location line="+276"/>
+        <location line="+297"/>
         <source>File size</source>
         <translation>Bestandsgrootte</translation>
     </message>
@@ -2215,7 +2243,12 @@
 </translation>
     </message>
     <message>
-        <location line="+17"/>
+        <location line="+1"/>
+        <source>New File.txt</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+16"/>
         <source>Create Directory</source>
         <translation>Maak nieuwe map</translation>
     </message>
@@ -2295,7 +2328,12 @@
 <context>
     <name>find_dialog</name>
     <message>
-        <location filename="../src/m-editor/find-dialog.cc" line="+77"/>
+        <location filename="../src/m-editor/find-dialog.cc" line="+74"/>
+        <source>Find and Replace</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+3"/>
         <source>Find &amp;what:</source>
         <translation>Zoek naar:</translation>
     </message>
@@ -2365,7 +2403,7 @@
         <translation>In se&amp;lectie zoeken</translation>
     </message>
     <message>
-        <location line="+71"/>
+        <location line="+72"/>
         <source>Search from end</source>
         <translation>vanaf einde terug zoeken</translation>
     </message>
@@ -2375,7 +2413,7 @@
         <translation>Zoeken vanaf begin</translation>
     </message>
     <message>
-        <location line="+121"/>
+        <location line="+119"/>
         <source>Replace Result</source>
         <translation>Resultaat vervangen</translation>
     </message>
@@ -2385,7 +2423,7 @@
         <translation>%1 vervangingen</translation>
     </message>
     <message>
-        <location line="+10"/>
+        <location line="+12"/>
         <source>Find Result</source>
         <translation>Zoek resultaat</translation>
     </message>
@@ -2408,12 +2446,7 @@
         <translation>Genaamd:</translation>
     </message>
     <message>
-        <location line="+2"/>
-        <source>Enter the filename expression</source>
-        <translation>Voer de bestandnaam-expressie in</translation>
-    </message>
-    <message>
-        <location line="+6"/>
+        <location line="+8"/>
         <source>Start in:</source>
         <translation>Begin in:</translation>
     </message>
@@ -2433,22 +2466,12 @@
         <translation>Blader naar begin map</translation>
     </message>
     <message>
-        <location line="+3"/>
-        <source>Recurse directories</source>
-        <translation>Ook in onderliggende mappen</translation>
-    </message>
-    <message>
-        <location line="+4"/>
+        <location line="+7"/>
         <source>Search recursively through directories for matching files</source>
         <translation>Zoek ook in onderliggende mappen naar overeenkomende bestanden</translation>
     </message>
     <message>
-        <location line="+2"/>
-        <source>Include directories</source>
-        <translation>Neem mappen ook mee</translation>
-    </message>
-    <message>
-        <location line="+4"/>
+        <location line="+6"/>
         <source>Include matching directories in search results</source>
         <translation>Neem overeenkomende mappen mee in zoekresultaten</translation>
     </message>
@@ -2468,9 +2491,24 @@
         <translation>Met tekst:</translation>
     </message>
     <message>
-        <location line="+1"/>
-        <source>Search must match text</source>
-        <translation>Zoeken naar overeenkomende tekst</translation>
+        <location line="-35"/>
+        <source>Enter the filename search expression</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+18"/>
+        <source>Search subdirectories</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+6"/>
+        <source>Include directory names</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+12"/>
+        <source>Enter the file content search expression</source>
+        <translation type="unfinished"></translation>
     </message>
     <message>
         <location line="+5"/>
@@ -2533,7 +2571,12 @@
         <translation>Bezig met zoeken...</translation>
     </message>
     <message>
-        <location line="+32"/>
+        <location line="+23"/>
+        <source>%1 match(es)</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+9"/>
         <source>Set search directory</source>
         <translation>Stel zoekmap in</translation>
     </message>
@@ -2623,13 +2666,13 @@
 <context>
     <name>main_window</name>
     <message>
-        <location filename="../src/main-window.cc" line="-1696"/>
+        <location filename="../src/main-window.cc" line="-1758"/>
         <source>Load Workspace</source>
         <translation>Werkruimte laden</translation>
     </message>
     <message>
-        <location line="+645"/>
-        <location line="+876"/>
+        <location line="+678"/>
+        <location line="+905"/>
         <source>About Octave</source>
         <translation>Over Octave</translation>
     </message>
@@ -2644,12 +2687,7 @@
         <translation>Nieuw</translation>
     </message>
     <message>
-        <location line="+4"/>
-        <source>Script</source>
-        <translation>Script</translation>
-    </message>
-    <message>
-        <location line="+7"/>
+        <location line="+11"/>
         <source>Figure</source>
         <translation>Figuur</translation>
     </message>
@@ -2689,12 +2727,23 @@
         <translation>Plakken</translation>
     </message>
     <message>
-        <location line="-1265"/>
+        <location line="-1327"/>
         <source>Save Workspace As</source>
         <translation>Sla Werkruimte Op Als</translation>
     </message>
     <message>
-        <location line="+124"/>
+        <location line="+84"/>
+        <source>The file %1
+can not be executed because its name
+is not a valid identifier.
+
+Do you want to execute
+%2
+instead?</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+73"/>
         <source>The release notes file &apos;%1&apos; is empty.</source>
         <translation>Bestand met Release Notes &apos;%1&apos; is leeg.</translation>
     </message>
@@ -2714,7 +2763,7 @@
         <translation>Octave Community Nieuws</translation>
     </message>
     <message>
-        <location line="+939"/>
+        <location line="+968"/>
         <source>Clear Clipboard</source>
         <translation>Wis klembord</translation>
     </message>
@@ -2779,7 +2828,12 @@
         <translation>Stap In</translation>
     </message>
     <message>
-        <location line="-151"/>
+        <location line="-1311"/>
+        <source>Octave</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+1160"/>
         <source>Load Workspace...</source>
         <translation>Werkruimte laden...</translation>
     </message>
@@ -2789,7 +2843,12 @@
         <translation>Sla Werkruimte Op Als...</translation>
     </message>
     <message>
-        <location line="+41"/>
+        <location line="+38"/>
+        <source>New Script</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+3"/>
         <source>Function...</source>
         <translation>Functie...</translation>
     </message>
@@ -2880,8 +2939,8 @@
         <translation>Eén mapniveau omhoog</translation>
     </message>
     <message>
-        <location line="-1283"/>
-        <location line="+1286"/>
+        <location line="-1312"/>
+        <location line="+1315"/>
         <source>Browse directories</source>
         <translation>Blader door mappen</translation>
     </message>
@@ -2955,7 +3014,7 @@
 <context>
     <name>news_reader</name>
     <message>
-        <location line="-1282"/>
+        <location line="-1311"/>
         <source>&lt;html&gt;
 &lt;body&gt;
 &lt;p&gt;
@@ -3014,18 +3073,18 @@
 <context>
     <name>octave_dock_widget</name>
     <message>
-        <location filename="../src/octave-dock-widget.cc" line="+61"/>
-        <location line="+163"/>
+        <location filename="../src/octave-dock-widget.cc" line="+60"/>
+        <location line="+170"/>
         <source>Undock widget</source>
         <translation>Widget laten zweven</translation>
     </message>
     <message>
-        <location line="-153"/>
+        <location line="-160"/>
         <source>Hide widget</source>
         <translation>Widget verbergen</translation>
     </message>
     <message>
-        <location line="+104"/>
+        <location line="+107"/>
         <source>Dock widget</source>
         <translation>Widget in venster opnemen</translation>
     </message>
@@ -3056,7 +3115,7 @@
 <context>
     <name>octave_qt_link</name>
     <message>
-        <location filename="../src/octave-qt-link.cc" line="+94"/>
+        <location filename="../src/octave-qt-link.cc" line="+97"/>
         <location line="+6"/>
         <location line="+7"/>
         <source>Yes</source>
@@ -3083,13 +3142,13 @@
     </message>
     <message>
         <location line="+211"/>
-        <source>The file %1 does not exist in the load path.  To debug the function you are editing, you must either change to the directory %2 or add that directory to the load path.</source>
-        <translation>Het bestand %1 is niet in zoekpad.  Om de functie die je edit te debuggen moet je òf naar debetreffende map %2 gaan, of die map aan het zoekpad toevoegen.</translation>
+        <source>The file %1 does not exist in the load path.  To run or debug the function you are editing, you must either change to the directory %2 or add that directory to the load path.</source>
+        <translation type="unfinished"></translation>
     </message>
     <message>
         <location line="+1"/>
-        <source>The file %1 is shadowed by a file with the same name in the load path.  To debug the function you are editing, change to the directory %2.</source>
-        <translation>Het bestand %1 is overschaduwd door een bestand met dezelfde naam in het zoekpad.  Ga naar de map %2 om de functie de je edit te kunnen debuggen.</translation>
+        <source>The file %1 is shadowed by a file with the same name in the load path. To run or debug the function you are editing, change to the directory %2.</source>
+        <translation type="unfinished"></translation>
     </message>
     <message>
         <location line="+2"/>
@@ -3140,17 +3199,17 @@
 <context>
     <name>settings_dialog</name>
     <message>
-        <location filename="../src/settings-dialog.ui" line="+29"/>
+        <location filename="../src/settings-dialog.ui" line="+23"/>
         <source>Settings</source>
         <translation>Instellingen</translation>
     </message>
     <message>
-        <location line="+13"/>
+        <location line="+19"/>
         <source>General</source>
         <translation>Algemeen</translation>
     </message>
     <message>
-        <location line="+97"/>
+        <location line="+191"/>
         <source>Octave logo only</source>
         <translation>Alleen Octave logo</translation>
     </message>
@@ -3165,17 +3224,37 @@
         <translation>Grafische iconen</translation>
     </message>
     <message>
-        <location line="+39"/>
+        <location line="-179"/>
+        <source>Dock widget title bar</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+40"/>
+        <source>Custom style</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+26"/>
+        <source>Background color</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+29"/>
+        <source>Text color</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+212"/>
         <source>Editor</source>
         <translation>Editor</translation>
     </message>
     <message>
-        <location line="+71"/>
+        <location line="+102"/>
         <source>Color</source>
         <translation>Kleur</translation>
     </message>
     <message>
-        <location line="+120"/>
+        <location line="+170"/>
         <source>Indent width</source>
         <translation>Inspringafstand</translation>
     </message>
@@ -3185,7 +3264,7 @@
         <translation>Inspringen met tab</translation>
     </message>
     <message>
-        <location line="+7"/>
+        <location line="+23"/>
         <source>Auto indentation</source>
         <translation>Automatisch inspringen</translation>
     </message>
@@ -3230,62 +3309,67 @@
         <translation>Herstel bij opstarten de editor tabs uit de vorige sessie</translation>
     </message>
     <message>
-        <location line="+60"/>
+        <location line="+34"/>
         <source>Use custom file editor</source>
         <translation>Gebruik een andere editor</translation>
     </message>
     <message>
-        <location line="+32"/>
+        <location line="+20"/>
+        <source>emacs +%l %f </source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+35"/>
         <source>Editor Styles</source>
         <translation>Editorstijlen</translation>
     </message>
     <message>
-        <location line="+24"/>
+        <location line="+17"/>
         <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Select font, font size (as a difference from the default size), font style (&lt;b&gt;b&lt;/b&gt;old, &lt;b&gt;i&lt;/b&gt;talic, &lt;b&gt;u&lt;/b&gt;nderline), text color and background color (for the latter, the color pink (255,0,255) is a placeholder for the default background color).&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
         <translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Selecteer font, font grootte (als een verschil van de standaard grootte), font stijl (&lt;b&gt;d&lt;/b&gt;ik, &lt;b&gt;s&lt;/b&gt;chuin, &lt;b&gt;o&lt;/b&gt;nderstreept), tekstkleur en achtergrondkleur (wat betreft de laatste, de kleur roze (255,0,255) is een plaatsvervanger voor de standaard achtergrondkleur).&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
     </message>
     <message>
-        <location line="+108"/>
+        <location line="+191"/>
         <source>Terminal Colors</source>
         <translation>Terminalkleuren</translation>
     </message>
     <message>
-        <location line="+45"/>
+        <location line="-100"/>
         <source>Font</source>
         <translation>Lettertype</translation>
     </message>
     <message>
-        <location line="-757"/>
+        <location line="-770"/>
         <source>Show line numbers</source>
         <translation>Regelnummers weergeven</translation>
     </message>
     <message>
-        <location line="+27"/>
+        <location line="+46"/>
         <source>Highlight current line</source>
         <translation>Markeer huidige regel</translation>
     </message>
     <message>
-        <location line="+262"/>
+        <location line="+328"/>
         <source>Code completion</source>
         <translation>Automatisch aanvullen</translation>
     </message>
     <message>
-        <location line="-282"/>
+        <location line="-361"/>
         <source>Show complete path in window title</source>
         <translation>Hele pad in schermtitel weergeven</translation>
     </message>
     <message>
-        <location line="-17"/>
+        <location line="-23"/>
         <source>Show whitespace</source>
         <translation>Laat witruimte zien</translation>
     </message>
     <message>
-        <location line="+27"/>
+        <location line="+33"/>
         <source>Do not show whitespace used for indentation</source>
         <translation>Laat geen voor inspringen gebruikte witruimte zien</translation>
     </message>
     <message>
-        <location line="+290"/>
+        <location line="+369"/>
         <source># of characters typed before completion list displayed</source>
         <translation>Getypt aantal karakters voordat de aanvullijst verschijnt</translation>
     </message>
@@ -3295,87 +3379,144 @@
         <translation>Maak niet bestaande bestanden aan zonder te vragen</translation>
     </message>
     <message>
-        <location line="+57"/>
+        <location line="+31"/>
         <source>command line (%f=file, %l=line):</source>
         <translation>command line (%f=bestand, %l=regel):</translation>
     </message>
     <message>
-        <location line="+10"/>
-        <source>emacs</source>
-        <translation></translation>
-    </message>
-    <message>
-        <location line="+67"/>
-        <source>Terminal</source>
-        <translation>Opdrachtvenster</translation>
-    </message>
-    <message>
-        <location line="+15"/>
-        <source>Cursor type:</source>
-        <translation>Type aanwijzer:</translation>
-    </message>
-    <message>
-        <location line="+23"/>
-        <source>Cursor blinking</source>
-        <translation>Knipperende aanwijzer</translation>
-    </message>
-    <message>
-        <location line="+7"/>
-        <source>Use foreground color</source>
-        <translation>Gebruik voorgrondkleur</translation>
-    </message>
-    <message>
         <location line="+94"/>
+        <source>Terminal</source>
+        <translation>Opdrachtvenster</translation>
+    </message>
+    <message>
+        <location line="+45"/>
+        <source>Cursor type:</source>
+        <translation>Type aanwijzer:</translation>
+    </message>
+    <message>
+        <location line="-11"/>
+        <source>Cursor blinking</source>
+        <translation>Knipperende aanwijzer</translation>
+    </message>
+    <message>
+        <location line="-7"/>
+        <source>Use foreground color</source>
+        <translation>Gebruik voorgrondkleur</translation>
+    </message>
+    <message>
+        <location line="+53"/>
         <source>Font size</source>
         <translation>Lettergrootte</translation>
     </message>
     <message>
-        <location line="+35"/>
+        <location line="+99"/>
+        <source>Set focus to terminal when running a command from within another widget</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+34"/>
         <source>File Browser</source>
         <translation>Bestandsbrowser</translation>
     </message>
     <message>
+        <location line="+46"/>
+        <source>Show file size</source>
+        <translation>Bestandsgrootte weergeven</translation>
+    </message>
+    <message>
+        <location line="-14"/>
+        <source>Show file type</source>
+        <translation>Bestandstype weergeven</translation>
+    </message>
+    <message>
+        <location line="+21"/>
+        <source>Show date of last modification</source>
+        <translation>Datum van laatste wijziging weergeven</translation>
+    </message>
+    <message>
+        <location line="-14"/>
+        <source>Show hidden files</source>
+        <translation>Verborgen bestanden weergeven</translation>
+    </message>
+    <message>
+        <location line="-1316"/>
+        <source>Interface</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+221"/>
+        <source>Octave Startup</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
         <location line="+6"/>
-        <source>Show file size</source>
-        <translation>Bestandsgrootte weergeven</translation>
-    </message>
-    <message>
-        <location line="+7"/>
-        <source>Show file type</source>
-        <translation>Bestandstype weergeven</translation>
-    </message>
-    <message>
-        <location line="+7"/>
-        <source>Show date of last modification</source>
-        <translation>Datum van laatste wijziging weergeven</translation>
-    </message>
-    <message>
-        <location line="+7"/>
-        <source>Show hidden files</source>
-        <translation>Verborgen bestanden weergeven</translation>
-    </message>
-    <message>
-        <location line="+14"/>
-        <source>Alternating row colors</source>
-        <translation>Om en om andere regelkleuren</translation>
-    </message>
-    <message>
-        <location line="+21"/>
-        <source>Workspace</source>
-        <translation>Werkruimte</translation>
-    </message>
-    <message>
-        <location line="+30"/>
-        <source>Storage Class Colors</source>
-        <translation>Kleuren voor klasse</translation>
+        <source>These preferences are applied after the startup files like .octaverc.</source>
+        <translation type="unfinished"></translation>
     </message>
     <message>
         <location line="+35"/>
+        <location line="+1104"/>
+        <source>Startup path</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="-1091"/>
+        <location line="+1108"/>
+        <source>Browse</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="-1101"/>
+        <source>Restore last Octave directory of previous session</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+214"/>
+        <source>Tab width min.</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+52"/>
+        <source>max.</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+750"/>
+        <source>Display</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+39"/>
+        <source>Alternating row colors</source>
+        <translation>Om en om andere regelkleuren</translation>
+    </message>
+    <message>
+        <location line="+12"/>
+        <source>Behavior</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+27"/>
+        <source>Restore last directory of previous session</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+65"/>
+        <source>Workspace</source>
+        <translation>Werkruimte</translation>
+    </message>
+    <message>
+        <location line="+38"/>
+        <source>Storage Class Colors</source>
+        <translation>Kleuren voor klasse</translation>
+    </message>
+    <message>
+        <location line="+40"/>
         <source>Network</source>
         <translation>Netwerk</translation>
     </message>
     <message>
-        <location line="+8"/>
+        <location line="+23"/>
         <source>Allow Octave to connect to the Octave web site to display current news and information</source>
         <translation>Sta Octave toe om te verbinden met de Octave website om recent nieuws en informatie weer te geven</translation>
     </message>
@@ -3390,27 +3531,27 @@
         <translation>http proxy</translation>
     </message>
     <message>
-        <location line="-1129"/>
+        <location line="-1356"/>
         <source>Icon set for dock widgets</source>
         <translation>Iconenset voor dock widgets</translation>
     </message>
     <message>
-        <location line="+7"/>
+        <location line="-48"/>
         <source>Language (requires restart)</source>
         <translation>Taal instellen (vereist herstart)</translation>
     </message>
     <message>
-        <location line="+7"/>
+        <location line="-122"/>
         <source>Icon size</source>
         <translation>Icoongrootte</translation>
     </message>
     <message>
-        <location line="+991"/>
+        <location line="+1318"/>
         <source>Synchronize Octave working directory with file browser</source>
         <translation>Synchroniseer Octave werkmap met bestandsverkenner</translation>
     </message>
     <message>
-        <location line="+129"/>
+        <location line="+213"/>
         <source>Socks5Proxy</source>
         <translation></translation>
     </message>
@@ -3440,9 +3581,9 @@
         <translation>Wachtwoord:</translation>
     </message>
     <message>
-        <location filename="../src/settings-dialog.cc" line="+71"/>
+        <location filename="../src/settings-dialog.cc" line="+74"/>
         <location line="+4"/>
-        <location line="+389"/>
+        <location line="+437"/>
         <source>System setting</source>
         <translation>Systeeminstelling</translation>
     </message>
@@ -3489,6 +3630,16 @@
         <comment>short form for underlined</comment>
         <translation>o</translation>
     </message>
+    <message>
+        <location line="+419"/>
+        <source>Set Octave Startup Directory</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+6"/>
+        <source>Set File Browser Startup Directory</source>
+        <translation type="unfinished"></translation>
+    </message>
 </context>
 <context>
     <name>setup_community_news</name>
@@ -3556,7 +3707,7 @@
 <context>
     <name>webinfo</name>
     <message>
-        <location filename="../src/qtinfo/webinfo.cc" line="+80"/>
+        <location filename="../src/qtinfo/webinfo.cc" line="+83"/>
         <source>Type here and press &apos;Return&apos; to search</source>
         <translation>Typ hier en druk op &apos;Enter&apos; om te zoeken</translation>
     </message>
@@ -3565,6 +3716,16 @@
         <source>Global search</source>
         <translation>Globaal zoeken</translation>
     </message>
+    <message>
+        <location line="+22"/>
+        <source>Error</source>
+        <translation type="unfinished">Fout</translation>
+    </message>
+    <message>
+        <location line="+3"/>
+        <source>The info file %1 does not exist</source>
+        <translation type="unfinished"></translation>
+    </message>
 </context>
 <context>
     <name>welcome_wizard</name>
@@ -3598,8 +3759,8 @@
     </message>
     <message>
         <location line="+1"/>
-        <source>Storage Class</source>
-        <translation>Klasse</translation>
+        <source>Attribute</source>
+        <translation type="unfinished"></translation>
     </message>
     <message>
         <location line="+109"/>
@@ -3647,8 +3808,8 @@
     </message>
     <message>
         <location line="+1"/>
-        <source>Colors for the storage class:</source>
-        <translation>Kleuren voor klasse:</translation>
+        <source>Colors for variable attributes:</source>
+        <translation type="unfinished"></translation>
     </message>
 </context>
 </TS>
--- a/libgui/languages/pt_BR.ts	Fri Feb 06 08:31:09 2015 -0800
+++ b/libgui/languages/pt_BR.ts	Fri Feb 06 08:31:49 2015 -0800
@@ -62,7 +62,7 @@
         <translation>indicador</translation>
     </message>
     <message>
-        <location filename="../src/main-window.cc" line="+1900"/>
+        <location filename="../src/main-window.cc" line="+1963"/>
         <source>&lt;p&gt;&lt;strong&gt;A Note about Octave&apos;s New GUI&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;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.  But because it is not quite as polished as we would like, we have decided to wait until the 4.0.x release series before making the GUI the default interface.&lt;/p&gt;&lt;p&gt;Given the length of time and the number of bug fixes and improvements since the last major release, we also decided against delaying the release of all these new improvements any longer just to perfect the GUI.  So please enjoy the 3.8 release of Octave and the preview of the new GUI.  We believe it is working reasonably well, but we also know that there are some obvious rough spots and many things that could be improved.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;We Need Your Help&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;There are many ways that you can help us fix the remaining problems, complete the GUI, and improve the overall user experience for both novices and experts alike (links will open an external browser):&lt;/p&gt;&lt;p&gt;&lt;ul&gt;&lt;li&gt;If you are a skilled software developer, you can help by contributing your time to help &lt;a href=&quot;http://octave.org/get-involved.html&quot;&gt;develop Octave&lt;/a&gt;.&lt;/li&gt;&lt;li&gt;If Octave does not work properly, you are encouraged to &lt;a href=&quot;http://octave.org/bugs.html&quot;&gt;report problems &lt;/a&gt; that you find.&lt;/li&gt;&lt;li&gt;Whether you are a user or developer, you can &lt;a href=&quot;http://octave.org/donate.html&quot;&gt;help to fund the project&lt;/a&gt;.  Octave development takes a lot of time and expertise.  Your contributions help to ensure that Octave will continue to improve.&lt;/li&gt;&lt;/ul&gt;&lt;/p&gt;&lt;p&gt;We hope you find Octave to be useful.  Please help us make it even better for the future!&lt;/p&gt;</source>
         <translation>&lt;p&gt;&lt;strong&gt;Um aviso sobre a nova interface gráfica do Octave&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;Uma das funcionalidades novas mais importantes no Octave versão 3.8 é a interface gráfica (GUI).  É uma coisa que os usuários solicitaram muito frequentemente nos últimos anos, e agora ela está quase pronta.  Mas como ela não está tão bem acabada quanto gostaríamos, decidimos esperar até a próxima versão 4.0 antes de tornar a GUI a interface padrão.&lt;/p&gt;&lt;p&gt;Dado o tempo transcorrido e o número de correções e melhorias desde a última versão, também decidimos não adiar mais o lançamento de todas essas novidades, ao invés ficar aperfeiçoando a GUI.  Portanto, aproveite a versão 3.8 do Octave e a prévia da nova GUI!  Acreditamos que ela está funcionando razoavelmente bem, apesar de alguns aspectos obviamente inacabados, além de muitas melhorias possíveis.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Ajude-nos&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;Há muitas formas de você nos ajudar a corrigir os problemas que persistirem, a finalizar a GUI e a melhorar a usabilidade do Octave em geral, tanto para usuários iniciantes quanto para aqueles mais experientes (os links abaixo serão abertos no seu navegador padrão do sistema; o conteúdo poderá estar em inglês):&lt;/p&gt;&lt;p&gt;&lt;ul&gt;&lt;li&gt;Se você for um desenvolvedor de software talentoso, ajude-nos contribuindo com o seu tempo, auxiliando no &lt;a href=&quot;http://octave.org/get-involved.html&quot;&gt;desenvolvimento do Octave&lt;/a&gt;.&lt;/li&gt;&lt;li&gt;Se o Octave não estiver funcionando corretamente, convidamos-lhe a &lt;a href=&quot;http://octave.org/bugs.html&quot;&gt;relatar os problemas&lt;/a&gt; que você vier a encontrar.&lt;/li&gt;&lt;li&gt;Quer você seja um usuário ou um desenvolvedor, você poderia &lt;a href=&quot;http://octave.org/donate.html&quot;&gt;fazer uma doação&lt;/a&gt; para auxiliar no financiamento do projeto.  Afinal, o desenvolvimento do Octave demanda tempo e conhecimento consideráveis.  A sua generosidade contribui para assegurar a melhoria contínua do Octave.&lt;/li&gt;&lt;/ul&gt;&lt;/p&gt;&lt;p&gt;Esperamos que você goste do Octave.  Ajude-nos a torná-lo ainda melhor no futuro!&lt;/p&gt;</translation>
     </message>
@@ -88,7 +88,7 @@
 <context>
     <name>QWinTerminalImpl</name>
     <message>
-        <location filename="../qterminal/libqterminal/win32/QWinTerminalImpl.cpp" line="+1536"/>
+        <location filename="../qterminal/libqterminal/win32/QWinTerminalImpl.cpp" line="+1539"/>
         <source>copied selection to clipboard</source>
         <translation>seleção copiada para a área de transferência</translation>
     </message>
@@ -141,17 +141,12 @@
         <translation>Arquivo não foi salvo! Um arquivo com o nome selecionado %1 já está aberto no editor</translation>
     </message>
     <message>
-        <location line="+255"/>
+        <location line="+268"/>
         <source>&amp;%1 %2</source>
         <translation>&amp;%1 %2</translation>
     </message>
     <message>
-        <location line="+175"/>
-        <source>&amp;New File</source>
-        <translation>&amp;Novo Script</translation>
-    </message>
-    <message>
-        <location line="+6"/>
+        <location line="+207"/>
         <source>&amp;Save File</source>
         <translation>&amp;Salvar Arquivo</translation>
     </message>
@@ -161,7 +156,12 @@
         <translation>&amp;Abrir Arquivo...</translation>
     </message>
     <message>
-        <location line="+6"/>
+        <location line="-3"/>
+        <source>&amp;New Script</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+9"/>
         <source>Save File &amp;As...</source>
         <translation>Salvar Arquivo &amp;Como...</translation>
     </message>
@@ -247,6 +247,16 @@
     </message>
     <message>
         <location line="+3"/>
+        <source>&amp;Indent</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+2"/>
+        <source>&amp;Unindent</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+3"/>
         <source>&amp;Find and Replace...</source>
         <translation>&amp;Buscar e Substituir...</translation>
     </message>
@@ -261,7 +271,7 @@
         <translation>Vá para &amp;Linha...</translation>
     </message>
     <message>
-        <location line="+55"/>
+        <location line="+57"/>
         <source>&amp;Recent Editor Files</source>
         <translation>Arquivos &amp;Recentes</translation>
     </message>
@@ -286,7 +296,7 @@
         <translation>Fechar Demais Arquivos</translation>
     </message>
     <message>
-        <location line="+31"/>
+        <location line="+34"/>
         <source>&amp;Preferences...</source>
         <translation>&amp;Preferências...</translation>
     </message>
@@ -316,7 +326,7 @@
         <translation>&amp;Documentação da Palavra-chave</translation>
     </message>
     <message>
-        <location line="-741"/>
+        <location line="-790"/>
         <source>Could not open file
 %1
 for read: %2.</source>
@@ -348,7 +358,7 @@
         <translation>A aba do editor associada ao arquivo desapareceu.</translation>
     </message>
     <message>
-        <location line="+521"/>
+        <location line="+567"/>
         <source>&amp;File</source>
         <translation>&amp;Arquivo</translation>
     </message>
@@ -363,7 +373,7 @@
         <translation>&amp;Editar</translation>
     </message>
     <message>
-        <location line="+30"/>
+        <location line="+33"/>
         <source>&amp;Debug</source>
         <translation>&amp;Depurar</translation>
     </message>
@@ -376,7 +386,7 @@
 <context>
     <name>file_editor_tab</name>
     <message>
-        <location filename="../src/m-editor/file-editor-tab.cc" line="+803"/>
+        <location filename="../src/m-editor/file-editor-tab.cc" line="+824"/>
         <source>Goto line</source>
         <translation>Vá para linha</translation>
     </message>
@@ -386,7 +396,7 @@
         <translation>Número da linha</translation>
     </message>
     <message>
-        <location line="+71"/>
+        <location line="+108"/>
         <location line="+69"/>
         <source>&lt;unnamed&gt;</source>
         <translation>&lt;sem_nome&gt;</translation>
@@ -403,14 +413,15 @@
     </message>
     <message>
         <location line="+10"/>
-        <location line="+122"/>
-        <location line="+150"/>
+        <location line="+123"/>
+        <location line="+112"/>
+        <location line="+69"/>
         <location line="+22"/>
         <source>Octave Editor</source>
         <translation>Editor do Octave</translation>
     </message>
     <message>
-        <location line="-293"/>
+        <location line="-325"/>
         <source>The file
 %1
 is about to be closed but has been modified.
@@ -421,12 +432,12 @@
 %2</translation>
     </message>
     <message>
-        <location line="+201"/>
+        <location line="+203"/>
         <source>Octave Files (*.m);;All Files (*)</source>
         <translation>Arquivos do Octave (*.m);; Todos os Arquivos (*)</translation>
     </message>
     <message>
-        <location line="+86"/>
+        <location line="+116"/>
         <source>
 
 Warning: The contents in the editor is modified!</source>
@@ -444,14 +455,14 @@
 foi removido ou renomeado. Gostaria de salvá-lo agora?%2</translation>
     </message>
     <message>
-        <location line="-172"/>
+        <location line="-203"/>
         <source>Could not open file %1 for write:
 %2.</source>
         <translation>Não foi possível abrir arquivo %1 para escrita:
 %2.</translation>
     </message>
     <message>
-        <location line="-975"/>
+        <location line="-1032"/>
         <source>Line:</source>
         <translation>Linha:</translation>
     </message>
@@ -461,7 +472,18 @@
         <translation>Coluna:</translation>
     </message>
     <message>
-        <location line="+1122"/>
+        <location line="+1141"/>
+        <source>&quot;%1&quot;
+is not a valid identifier.
+
+If you keep this file name, you will not be able to
+call your script using its name as an Octave command.
+
+Do you want to choose another name?</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+69"/>
         <source>It seems that &apos;%1&apos; has been modified by another application. Do you want to reload it?</source>
         <translation>Parece que o arquivo &apos;%1&apos; foi modificado por outra aplicação. Deseja recarregá-lo?</translation>
     </message>
@@ -494,7 +516,12 @@
         <translation>Ações no diretório atual</translation>
     </message>
     <message>
-        <location line="+373"/>
+        <location line="+15"/>
+        <source>Set Browser Directory...</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+379"/>
         <source>Find Files...</source>
         <translation>Buscar Arquivos...</translation>
     </message>
@@ -505,16 +532,17 @@
     </message>
     <message>
         <location line="+3"/>
+        <location line="+333"/>
         <source>New Directory</source>
         <translation>Novo Diretório</translation>
     </message>
     <message>
-        <location line="-323"/>
+        <location line="-656"/>
         <source>Double-click a file to open it</source>
         <translation>Clique duas vezes em um arquivo para abrí-lo</translation>
     </message>
     <message>
-        <location line="-79"/>
+        <location line="-100"/>
         <source>Show Octave directory</source>
         <translation>Exibir o diretório do Octave</translation>
     </message>
@@ -539,7 +567,7 @@
         <translation>Exibir Diretório Pessoal</translation>
     </message>
     <message>
-        <location line="+12"/>
+        <location line="+16"/>
         <source>Search Directory...</source>
         <translation>Buscar no Diretório...</translation>
     </message>
@@ -559,7 +587,7 @@
         <translation>Novo Diretório...</translation>
     </message>
     <message>
-        <location line="+276"/>
+        <location line="+297"/>
         <source>File size</source>
         <translation>Tamanho do arquivo</translation>
     </message>
@@ -672,7 +700,12 @@
 </translation>
     </message>
     <message>
-        <location line="+17"/>
+        <location line="+1"/>
+        <source>New File.txt</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+16"/>
         <source>Create Directory</source>
         <translation>Criar Diretório</translation>
     </message>
@@ -751,7 +784,12 @@
 <context>
     <name>find_dialog</name>
     <message>
-        <location filename="../src/m-editor/find-dialog.cc" line="+77"/>
+        <location filename="../src/m-editor/find-dialog.cc" line="+74"/>
+        <source>Find and Replace</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+3"/>
         <source>Find &amp;what:</source>
         <translation>&amp;Buscar por:</translation>
     </message>
@@ -821,7 +859,7 @@
         <translation>Buscar dentro do texto &amp;selecionado</translation>
     </message>
     <message>
-        <location line="+71"/>
+        <location line="+72"/>
         <source>Search from end</source>
         <translation>Buscar do final para o começo</translation>
     </message>
@@ -831,7 +869,7 @@
         <translation>Buscar do começo para o final</translation>
     </message>
     <message>
-        <location line="+121"/>
+        <location line="+119"/>
         <source>Replace Result</source>
         <translation>Substituir Resultado</translation>
     </message>
@@ -841,7 +879,7 @@
         <translation>%1 itens substituidos</translation>
     </message>
     <message>
-        <location line="+10"/>
+        <location line="+12"/>
         <source>Find Result</source>
         <translation>Buscar Resultado</translation>
     </message>
@@ -864,12 +902,7 @@
         <translation>Nome de arquivo:</translation>
     </message>
     <message>
-        <location line="+2"/>
-        <source>Enter the filename expression</source>
-        <translation>Digite a expressão de busca para os nomes de arquivo</translation>
-    </message>
-    <message>
-        <location line="+6"/>
+        <location line="+8"/>
         <source>Start in:</source>
         <translation>Diretório inicial:</translation>
     </message>
@@ -889,22 +922,12 @@
         <translation>Escolha o diretório inicial</translation>
     </message>
     <message>
-        <location line="+3"/>
-        <source>Recurse directories</source>
-        <translation>Buscar em sub-diretórios</translation>
-    </message>
-    <message>
-        <location line="+4"/>
+        <location line="+7"/>
         <source>Search recursively through directories for matching files</source>
         <translation>Buscar recursivamente nos sub-diretórios</translation>
     </message>
     <message>
-        <location line="+2"/>
-        <source>Include directories</source>
-        <translation>Inclur nomes de diretórios</translation>
-    </message>
-    <message>
-        <location line="+4"/>
+        <location line="+6"/>
         <source>Include matching directories in search results</source>
         <translation>Incluir diretórios no resultado da busca</translation>
     </message>
@@ -924,9 +947,24 @@
         <translation>Contém texto:</translation>
     </message>
     <message>
-        <location line="+1"/>
-        <source>Search must match text</source>
-        <translation>Digite a expressão de busca para conteúdo dos arquivos</translation>
+        <location line="-35"/>
+        <source>Enter the filename search expression</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+18"/>
+        <source>Search subdirectories</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+6"/>
+        <source>Include directory names</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+12"/>
+        <source>Enter the file content search expression</source>
+        <translation type="unfinished"></translation>
     </message>
     <message>
         <location line="+5"/>
@@ -989,7 +1027,12 @@
         <translation>Buscando...</translation>
     </message>
     <message>
-        <location line="+32"/>
+        <location line="+23"/>
+        <source>%1 match(es)</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+9"/>
         <source>Set search directory</source>
         <translation>Alterar diretório de busca</translation>
     </message>
@@ -1079,13 +1122,13 @@
 <context>
     <name>main_window</name>
     <message>
-        <location filename="../src/main-window.cc" line="-1696"/>
+        <location filename="../src/main-window.cc" line="-1758"/>
         <source>Load Workspace</source>
         <translation>Carregar Ambiente de Trabalho</translation>
     </message>
     <message>
-        <location line="+645"/>
-        <location line="+876"/>
+        <location line="+678"/>
+        <location line="+905"/>
         <source>About Octave</source>
         <translation>Sobre o Octave</translation>
     </message>
@@ -1100,12 +1143,7 @@
         <translation>Novo</translation>
     </message>
     <message>
-        <location line="+4"/>
-        <source>Script</source>
-        <translation>Script</translation>
-    </message>
-    <message>
-        <location line="+7"/>
+        <location line="+11"/>
         <source>Figure</source>
         <translation>Figura</translation>
     </message>
@@ -1145,12 +1183,23 @@
         <translation>Colar</translation>
     </message>
     <message>
-        <location line="-1265"/>
+        <location line="-1327"/>
         <source>Save Workspace As</source>
         <translation>Salvar Ambiente de Trabalho Como</translation>
     </message>
     <message>
-        <location line="+124"/>
+        <location line="+84"/>
+        <source>The file %1
+can not be executed because its name
+is not a valid identifier.
+
+Do you want to execute
+%2
+instead?</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+73"/>
         <source>The release notes file &apos;%1&apos; is empty.</source>
         <translation>O arquivo de notas da versão &apos;%1&apos; está vazio.</translation>
     </message>
@@ -1170,7 +1219,7 @@
         <translation>Novidades da Comunidade</translation>
     </message>
     <message>
-        <location line="+939"/>
+        <location line="+968"/>
         <source>Clear Clipboard</source>
         <translation>Limpar Área de Transferência</translation>
     </message>
@@ -1235,7 +1284,12 @@
         <translation>Passo adentro</translation>
     </message>
     <message>
-        <location line="-151"/>
+        <location line="-1311"/>
+        <source>Octave</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+1160"/>
         <source>Load Workspace...</source>
         <translation>Carregar Ambiente de Trabalho...</translation>
     </message>
@@ -1245,7 +1299,12 @@
         <translation>Salvar Ambiente de Trabalho Como...</translation>
     </message>
     <message>
-        <location line="+41"/>
+        <location line="+38"/>
+        <source>New Script</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+3"/>
         <source>Function...</source>
         <translation>Função...</translation>
     </message>
@@ -1336,8 +1395,8 @@
         <translation>Diretório um nível acima</translation>
     </message>
     <message>
-        <location line="-1283"/>
-        <location line="+1286"/>
+        <location line="-1312"/>
+        <location line="+1315"/>
         <source>Browse directories</source>
         <translation>Escolher diretório</translation>
     </message>
@@ -1411,7 +1470,7 @@
 <context>
     <name>news_reader</name>
     <message>
-        <location line="-1282"/>
+        <location line="-1311"/>
         <source>&lt;html&gt;
 &lt;body&gt;
 &lt;p&gt;
@@ -1470,18 +1529,18 @@
 <context>
     <name>octave_dock_widget</name>
     <message>
-        <location filename="../src/octave-dock-widget.cc" line="+61"/>
-        <location line="+163"/>
+        <location filename="../src/octave-dock-widget.cc" line="+60"/>
+        <location line="+170"/>
         <source>Undock widget</source>
         <translation>Desacoplar painel</translation>
     </message>
     <message>
-        <location line="-153"/>
+        <location line="-160"/>
         <source>Hide widget</source>
         <translation>Esconder painel</translation>
     </message>
     <message>
-        <location line="+104"/>
+        <location line="+107"/>
         <source>Dock widget</source>
         <translation>Acoplar painel</translation>
     </message>
@@ -1512,7 +1571,7 @@
 <context>
     <name>octave_qt_link</name>
     <message>
-        <location filename="../src/octave-qt-link.cc" line="+94"/>
+        <location filename="../src/octave-qt-link.cc" line="+97"/>
         <location line="+6"/>
         <location line="+7"/>
         <source>Yes</source>
@@ -1539,13 +1598,13 @@
     </message>
     <message>
         <location line="+211"/>
-        <source>The file %1 does not exist in the load path.  To debug the function you are editing, you must either change to the directory %2 or add that directory to the load path.</source>
-        <translation>O arquivo %1 não existe no caminho de pesquisa.  Para depurar a função que você está editando, é preciso ou mudar para o diretório %2 ou adicionar esse diretório ao caminho de pesquisa.</translation>
+        <source>The file %1 does not exist in the load path.  To run or debug the function you are editing, you must either change to the directory %2 or add that directory to the load path.</source>
+        <translation type="unfinished"></translation>
     </message>
     <message>
         <location line="+1"/>
-        <source>The file %1 is shadowed by a file with the same name in the load path.  To debug the function you are editing, change to the directory %2.</source>
-        <translation>Existe um arquivo com o mesmo nome %1 no caminho de pesquisa. Para depurar a função que você está editando, é preciso mudar para o diretório %2.</translation>
+        <source>The file %1 is shadowed by a file with the same name in the load path. To run or debug the function you are editing, change to the directory %2.</source>
+        <translation type="unfinished"></translation>
     </message>
     <message>
         <location line="+2"/>
@@ -1596,17 +1655,17 @@
 <context>
     <name>settings_dialog</name>
     <message>
-        <location filename="../src/settings-dialog.ui" line="+29"/>
+        <location filename="../src/settings-dialog.ui" line="+23"/>
         <source>Settings</source>
         <translation>Configurações</translation>
     </message>
     <message>
-        <location line="+13"/>
+        <location line="+19"/>
         <source>General</source>
         <translation>Geral</translation>
     </message>
     <message>
-        <location line="+97"/>
+        <location line="+191"/>
         <source>Octave logo only</source>
         <translation>Apenas logotipo do Octave</translation>
     </message>
@@ -1621,17 +1680,37 @@
         <translation>Ícones gráficos</translation>
     </message>
     <message>
-        <location line="+39"/>
+        <location line="-179"/>
+        <source>Dock widget title bar</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+40"/>
+        <source>Custom style</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+26"/>
+        <source>Background color</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+29"/>
+        <source>Text color</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+212"/>
         <source>Editor</source>
         <translation>Editor</translation>
     </message>
     <message>
-        <location line="+71"/>
+        <location line="+102"/>
         <source>Color</source>
         <translation>Cor</translation>
     </message>
     <message>
-        <location line="+120"/>
+        <location line="+170"/>
         <source>Indent width</source>
         <translation>Largura de identação</translation>
     </message>
@@ -1641,7 +1720,7 @@
         <translation>Tecla Tab causa identação na linha</translation>
     </message>
     <message>
-        <location line="+7"/>
+        <location line="+23"/>
         <source>Auto indentation</source>
         <translation>Auto-identação</translation>
     </message>
@@ -1686,62 +1765,67 @@
         <translation>Restaurar abas de edição da sessão anterior durante inicialização</translation>
     </message>
     <message>
-        <location line="+60"/>
+        <location line="+34"/>
         <source>Use custom file editor</source>
         <translation>Usar editor de texto externo</translation>
     </message>
     <message>
-        <location line="+32"/>
+        <location line="+20"/>
+        <source>emacs +%l %f </source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+35"/>
         <source>Editor Styles</source>
         <translation>Apresentação</translation>
     </message>
     <message>
-        <location line="+24"/>
+        <location line="+17"/>
         <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Select font, font size (as a difference from the default size), font style (&lt;b&gt;b&lt;/b&gt;old, &lt;b&gt;i&lt;/b&gt;talic, &lt;b&gt;u&lt;/b&gt;nderline), text color and background color (for the latter, the color pink (255,0,255) is a placeholder for the default background color).&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
         <translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Selecionar fonte, tamanho da fonte (variacão com relacão ao tamanho padrão), estilo da fonte (&lt;b&gt;n&lt;/b&gt;egrito, &lt;b&gt;i&lt;/b&gt;tálico, &lt;b&gt;s&lt;/b&gt;ublinhado), cor da fonte e cor de fundo (a cor rosa (255,0,255) é a cor de fundo padrão).&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
     </message>
     <message>
-        <location line="+108"/>
+        <location line="+191"/>
         <source>Terminal Colors</source>
         <translation>Cores do Terminal</translation>
     </message>
     <message>
-        <location line="+45"/>
+        <location line="-100"/>
         <source>Font</source>
         <translation>Fonte</translation>
     </message>
     <message>
-        <location line="-757"/>
+        <location line="-770"/>
         <source>Show line numbers</source>
         <translation>Exibir números de linha</translation>
     </message>
     <message>
-        <location line="+27"/>
+        <location line="+46"/>
         <source>Highlight current line</source>
         <translation>Destacar linha atual</translation>
     </message>
     <message>
-        <location line="+262"/>
+        <location line="+328"/>
         <source>Code completion</source>
         <translation>Oferecer sugestões de preenchimento</translation>
     </message>
     <message>
-        <location line="-282"/>
+        <location line="-361"/>
         <source>Show complete path in window title</source>
         <translation>Exibir caminho completo no título da janela</translation>
     </message>
     <message>
-        <location line="-17"/>
+        <location line="-23"/>
         <source>Show whitespace</source>
         <translation>Exibir espaços em branco</translation>
     </message>
     <message>
-        <location line="+27"/>
+        <location line="+33"/>
         <source>Do not show whitespace used for indentation</source>
         <translation>Não exibir espaços em branco usados para identação</translation>
     </message>
     <message>
-        <location line="+290"/>
+        <location line="+369"/>
         <source># of characters typed before completion list displayed</source>
         <translation>Número de caracteres digitados antes da apresentar sugestões de preenchimento</translation>
     </message>
@@ -1751,87 +1835,144 @@
         <translation>Criar arquivos não existentes sem confirmar</translation>
     </message>
     <message>
-        <location line="+57"/>
+        <location line="+31"/>
         <source>command line (%f=file, %l=line):</source>
         <translation>linha de comando (%f=arquivo, %l=linha):</translation>
     </message>
     <message>
-        <location line="+10"/>
-        <source>emacs</source>
-        <translation>emacs</translation>
-    </message>
-    <message>
-        <location line="+67"/>
+        <location line="+94"/>
         <source>Terminal</source>
         <translation>Terminal</translation>
     </message>
     <message>
-        <location line="+15"/>
+        <location line="+45"/>
         <source>Cursor type:</source>
         <translation>Tipo do Indicador:</translation>
     </message>
     <message>
-        <location line="+23"/>
+        <location line="-11"/>
         <source>Cursor blinking</source>
         <translation>Indicador piscante</translation>
     </message>
     <message>
-        <location line="+7"/>
+        <location line="-7"/>
         <source>Use foreground color</source>
         <translation>Usar cor de primeiro plano</translation>
     </message>
     <message>
-        <location line="+94"/>
+        <location line="+53"/>
         <source>Font size</source>
         <translation>Tamanho de fonte</translation>
     </message>
     <message>
-        <location line="+35"/>
+        <location line="+99"/>
+        <source>Set focus to terminal when running a command from within another widget</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+34"/>
         <source>File Browser</source>
         <translation>Navegador de Arquivos</translation>
     </message>
     <message>
-        <location line="+6"/>
+        <location line="+46"/>
         <source>Show file size</source>
         <translation>Exibir tamanho do arquivo</translation>
     </message>
     <message>
-        <location line="+7"/>
+        <location line="-14"/>
         <source>Show file type</source>
         <translation>Exibir tipo do arquivo</translation>
     </message>
     <message>
-        <location line="+7"/>
+        <location line="+21"/>
         <source>Show date of last modification</source>
         <translation>Exibir data de última modificação</translation>
     </message>
     <message>
-        <location line="+7"/>
+        <location line="-14"/>
         <source>Show hidden files</source>
         <translation>Exibir arquivos ocultos</translation>
     </message>
     <message>
-        <location line="+14"/>
+        <location line="-1316"/>
+        <source>Interface</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+221"/>
+        <source>Octave Startup</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+6"/>
+        <source>These preferences are applied after the startup files like .octaverc.</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+35"/>
+        <location line="+1104"/>
+        <source>Startup path</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="-1091"/>
+        <location line="+1108"/>
+        <source>Browse</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="-1101"/>
+        <source>Restore last Octave directory of previous session</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+214"/>
+        <source>Tab width min.</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+52"/>
+        <source>max.</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+750"/>
+        <source>Display</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+39"/>
         <source>Alternating row colors</source>
         <translation>Cores de linhas alternantes</translation>
     </message>
     <message>
-        <location line="+21"/>
+        <location line="+12"/>
+        <source>Behavior</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+27"/>
+        <source>Restore last directory of previous session</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+65"/>
         <source>Workspace</source>
         <translation>Ambiente de Trabalho</translation>
     </message>
     <message>
-        <location line="+30"/>
+        <location line="+38"/>
         <source>Storage Class Colors</source>
         <translation>Cores das Categorias</translation>
     </message>
     <message>
-        <location line="+35"/>
+        <location line="+40"/>
         <source>Network</source>
         <translation>Rede</translation>
     </message>
     <message>
-        <location line="+8"/>
+        <location line="+23"/>
         <source>Allow Octave to connect to the Octave web site to display current news and information</source>
         <translation>Permitir Octave se conectar à Internet para mostrar notícias e informações recentes</translation>
     </message>
@@ -1846,27 +1987,27 @@
         <translation>Proxy HTTP</translation>
     </message>
     <message>
-        <location line="-1129"/>
+        <location line="-1356"/>
         <source>Icon set for dock widgets</source>
         <translation>Conjunto de ícones para painéis</translation>
     </message>
     <message>
-        <location line="+7"/>
+        <location line="-48"/>
         <source>Language (requires restart)</source>
         <translation>Idioma (alteração exige reinicialização do Octave)</translation>
     </message>
     <message>
-        <location line="+7"/>
+        <location line="-122"/>
         <source>Icon size</source>
         <translation>Tamanho dos ícones</translation>
     </message>
     <message>
-        <location line="+991"/>
+        <location line="+1318"/>
         <source>Synchronize Octave working directory with file browser</source>
         <translation>Sincronizar diretório atual do Octave com o Navegador de Arquivos</translation>
     </message>
     <message>
-        <location line="+129"/>
+        <location line="+213"/>
         <source>Socks5Proxy</source>
         <translation>Proxy Socks 5</translation>
     </message>
@@ -1896,9 +2037,9 @@
         <translation>Senha:</translation>
     </message>
     <message>
-        <location filename="../src/settings-dialog.cc" line="+71"/>
+        <location filename="../src/settings-dialog.cc" line="+74"/>
         <location line="+4"/>
-        <location line="+389"/>
+        <location line="+437"/>
         <source>System setting</source>
         <translation>Configuração do sistema</translation>
     </message>
@@ -1945,6 +2086,16 @@
         <comment>short form for underlined</comment>
         <translation>s</translation>
     </message>
+    <message>
+        <location line="+419"/>
+        <source>Set Octave Startup Directory</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+6"/>
+        <source>Set File Browser Startup Directory</source>
+        <translation type="unfinished"></translation>
+    </message>
 </context>
 <context>
     <name>setup_community_news</name>
@@ -2012,7 +2163,7 @@
 <context>
     <name>webinfo</name>
     <message>
-        <location filename="../src/qtinfo/webinfo.cc" line="+80"/>
+        <location filename="../src/qtinfo/webinfo.cc" line="+83"/>
         <source>Type here and press &apos;Return&apos; to search</source>
         <translation>Digite aqui e pressione &apos;Enter&apos; para buscar</translation>
     </message>
@@ -2021,6 +2172,16 @@
         <source>Global search</source>
         <translation>Busca global</translation>
     </message>
+    <message>
+        <location line="+22"/>
+        <source>Error</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+3"/>
+        <source>The info file %1 does not exist</source>
+        <translation type="unfinished"></translation>
+    </message>
 </context>
 <context>
     <name>welcome_wizard</name>
@@ -2054,8 +2215,8 @@
     </message>
     <message>
         <location line="+1"/>
-        <source>Storage Class</source>
-        <translation>Categoria</translation>
+        <source>Attribute</source>
+        <translation type="unfinished"></translation>
     </message>
     <message>
         <location line="+109"/>
@@ -2103,8 +2264,8 @@
     </message>
     <message>
         <location line="+1"/>
-        <source>Colors for the storage class:</source>
-        <translation>Cores das categorias:</translation>
+        <source>Colors for variable attributes:</source>
+        <translation type="unfinished"></translation>
     </message>
 </context>
 </TS>
--- a/libgui/languages/pt_PT.ts	Fri Feb 06 08:31:09 2015 -0800
+++ b/libgui/languages/pt_PT.ts	Fri Feb 06 08:31:49 2015 -0800
@@ -62,7 +62,7 @@
         <translation>indicador</translation>
     </message>
     <message>
-        <location filename="../src/main-window.cc" line="+1900"/>
+        <location filename="../src/main-window.cc" line="+1963"/>
         <source>&lt;p&gt;&lt;strong&gt;A Note about Octave&apos;s New GUI&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;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.  But because it is not quite as polished as we would like, we have decided to wait until the 4.0.x release series before making the GUI the default interface.&lt;/p&gt;&lt;p&gt;Given the length of time and the number of bug fixes and improvements since the last major release, we also decided against delaying the release of all these new improvements any longer just to perfect the GUI.  So please enjoy the 3.8 release of Octave and the preview of the new GUI.  We believe it is working reasonably well, but we also know that there are some obvious rough spots and many things that could be improved.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;We Need Your Help&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;There are many ways that you can help us fix the remaining problems, complete the GUI, and improve the overall user experience for both novices and experts alike (links will open an external browser):&lt;/p&gt;&lt;p&gt;&lt;ul&gt;&lt;li&gt;If you are a skilled software developer, you can help by contributing your time to help &lt;a href=&quot;http://octave.org/get-involved.html&quot;&gt;develop Octave&lt;/a&gt;.&lt;/li&gt;&lt;li&gt;If Octave does not work properly, you are encouraged to &lt;a href=&quot;http://octave.org/bugs.html&quot;&gt;report problems &lt;/a&gt; that you find.&lt;/li&gt;&lt;li&gt;Whether you are a user or developer, you can &lt;a href=&quot;http://octave.org/donate.html&quot;&gt;help to fund the project&lt;/a&gt;.  Octave development takes a lot of time and expertise.  Your contributions help to ensure that Octave will continue to improve.&lt;/li&gt;&lt;/ul&gt;&lt;/p&gt;&lt;p&gt;We hope you find Octave to be useful.  Please help us make it even better for the future!&lt;/p&gt;</source>
         <translation type="unfinished"></translation>
     </message>
@@ -88,7 +88,7 @@
 <context>
     <name>QWinTerminalImpl</name>
     <message>
-        <location filename="../qterminal/libqterminal/win32/QWinTerminalImpl.cpp" line="+1536"/>
+        <location filename="../qterminal/libqterminal/win32/QWinTerminalImpl.cpp" line="+1539"/>
         <source>copied selection to clipboard</source>
         <translation>selecçao copiada para a área de transferência</translation>
     </message>
@@ -810,17 +810,12 @@
 já está aberto no editor</translation>
     </message>
     <message>
-        <location line="+255"/>
+        <location line="+268"/>
         <source>&amp;%1 %2</source>
         <translation>&amp;%1 %2</translation>
     </message>
     <message>
-        <location line="+175"/>
-        <source>&amp;New File</source>
-        <translation>&amp;Novo Ficheiro</translation>
-    </message>
-    <message>
-        <location line="+6"/>
+        <location line="+207"/>
         <source>&amp;Save File</source>
         <translation>&amp;Guardar Ficheiro</translation>
     </message>
@@ -830,7 +825,12 @@
         <translation>&amp;Abrir Ficheiro...</translation>
     </message>
     <message>
-        <location line="+6"/>
+        <location line="-3"/>
+        <source>&amp;New Script</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+9"/>
         <source>Save File &amp;As...</source>
         <translation>Guardar Ficheiro &amp;Como...</translation>
     </message>
@@ -916,6 +916,16 @@
     </message>
     <message>
         <location line="+3"/>
+        <source>&amp;Indent</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+2"/>
+        <source>&amp;Unindent</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+3"/>
         <source>&amp;Find and Replace...</source>
         <translation>&amp;Buscar e Substituir...</translation>
     </message>
@@ -930,7 +940,7 @@
         <translation>Ir para &amp;Linha...</translation>
     </message>
     <message>
-        <location line="+55"/>
+        <location line="+57"/>
         <source>&amp;Recent Editor Files</source>
         <translation>Ficheiros &amp;recentes</translation>
     </message>
@@ -955,7 +965,7 @@
         <translation>Fechar os Outros Ficheiros</translation>
     </message>
     <message>
-        <location line="+31"/>
+        <location line="+34"/>
         <source>&amp;Preferences...</source>
         <translation>&amp;Preferências...</translation>
     </message>
@@ -985,7 +995,7 @@
         <translation>&amp;Documentação da Palavra-chave</translation>
     </message>
     <message>
-        <location line="-741"/>
+        <location line="-790"/>
         <source>Could not open file
 %1
 for read: %2.</source>
@@ -1017,7 +1027,7 @@
         <translation>A aba do editor associada ao ficheiro desapareceu.</translation>
     </message>
     <message>
-        <location line="+521"/>
+        <location line="+567"/>
         <source>&amp;File</source>
         <translation>&amp;Ficheiro</translation>
     </message>
@@ -1032,7 +1042,7 @@
         <translation>&amp;Editar</translation>
     </message>
     <message>
-        <location line="+30"/>
+        <location line="+33"/>
         <source>&amp;Debug</source>
         <translation>&amp;Depurar</translation>
     </message>
@@ -1045,7 +1055,7 @@
 <context>
     <name>file_editor_tab</name>
     <message>
-        <location filename="../src/m-editor/file-editor-tab.cc" line="+803"/>
+        <location filename="../src/m-editor/file-editor-tab.cc" line="+824"/>
         <source>Goto line</source>
         <translation>Ir para linha</translation>
     </message>
@@ -1055,7 +1065,7 @@
         <translation>Número da linha</translation>
     </message>
     <message>
-        <location line="+71"/>
+        <location line="+108"/>
         <location line="+69"/>
         <source>&lt;unnamed&gt;</source>
         <translation>&lt;sem_nome&gt;</translation>
@@ -1072,14 +1082,15 @@
     </message>
     <message>
         <location line="+10"/>
-        <location line="+122"/>
-        <location line="+150"/>
+        <location line="+123"/>
+        <location line="+112"/>
+        <location line="+69"/>
         <location line="+22"/>
         <source>Octave Editor</source>
         <translation>Editor do Octave</translation>
     </message>
     <message>
-        <location line="-293"/>
+        <location line="-325"/>
         <source>The file
 %1
 is about to be closed but has been modified.
@@ -1090,12 +1101,12 @@
 %2</translation>
     </message>
     <message>
-        <location line="+201"/>
+        <location line="+203"/>
         <source>Octave Files (*.m);;All Files (*)</source>
         <translation>Ficheiros de Octave (*.m);; Todos os Ficheiros (*)</translation>
     </message>
     <message>
-        <location line="+86"/>
+        <location line="+116"/>
         <source>
 
 Warning: The contents in the editor is modified!</source>
@@ -1113,14 +1124,14 @@
 foi removido ou renomeado. Pretende guardá-lo agora?%2</translation>
     </message>
     <message>
-        <location line="-172"/>
+        <location line="-203"/>
         <source>Could not open file %1 for write:
 %2.</source>
         <translation>Não foi possível abrir o ficheiro %1 para escrita:
 %2.</translation>
     </message>
     <message>
-        <location line="-975"/>
+        <location line="-1032"/>
         <source>Line:</source>
         <translation>Linha:</translation>
     </message>
@@ -1130,7 +1141,18 @@
         <translation>Col:</translation>
     </message>
     <message>
-        <location line="+1122"/>
+        <location line="+1141"/>
+        <source>&quot;%1&quot;
+is not a valid identifier.
+
+If you keep this file name, you will not be able to
+call your script using its name as an Octave command.
+
+Do you want to choose another name?</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+69"/>
         <source>It seems that &apos;%1&apos; has been modified by another application. Do you want to reload it?</source>
         <translation>Parece que o ficheiro &apos;%1&apos; foi modificado por outro aplicativo. Deseja recarregá-lo?</translation>
     </message>
@@ -1163,7 +1185,12 @@
         <translation>Acções no directório actual</translation>
     </message>
     <message>
-        <location line="+373"/>
+        <location line="+15"/>
+        <source>Set Browser Directory...</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+379"/>
         <source>Find Files...</source>
         <translation>Procurar Ficheiros...</translation>
     </message>
@@ -1174,16 +1201,17 @@
     </message>
     <message>
         <location line="+3"/>
+        <location line="+333"/>
         <source>New Directory</source>
         <translation>Novo Directório</translation>
     </message>
     <message>
-        <location line="-323"/>
+        <location line="-656"/>
         <source>Double-click a file to open it</source>
         <translation>Clicar duas vezes num ficheiro para o abrir</translation>
     </message>
     <message>
-        <location line="-79"/>
+        <location line="-100"/>
         <source>Show Octave directory</source>
         <translation>Mostrar o directório actual do Octave</translation>
     </message>
@@ -1208,7 +1236,7 @@
         <translation>Mostrar directório pessoal</translation>
     </message>
     <message>
-        <location line="+12"/>
+        <location line="+16"/>
         <source>Search Directory...</source>
         <translation>Procurar no directório...</translation>
     </message>
@@ -1228,7 +1256,7 @@
         <translation>Novo Directório...</translation>
     </message>
     <message>
-        <location line="+276"/>
+        <location line="+297"/>
         <source>File size</source>
         <translation>Tamanho de ficheiro</translation>
     </message>
@@ -1343,7 +1371,12 @@
 </translation>
     </message>
     <message>
-        <location line="+17"/>
+        <location line="+1"/>
+        <source>New File.txt</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+16"/>
         <source>Create Directory</source>
         <translation>Criar Directório</translation>
     </message>
@@ -1422,7 +1455,12 @@
 <context>
     <name>find_dialog</name>
     <message>
-        <location filename="../src/m-editor/find-dialog.cc" line="+77"/>
+        <location filename="../src/m-editor/find-dialog.cc" line="+74"/>
+        <source>Find and Replace</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+3"/>
         <source>Find &amp;what:</source>
         <translation>Procurar por:</translation>
     </message>
@@ -1492,7 +1530,7 @@
         <translation>Procurar dentro da selecção</translation>
     </message>
     <message>
-        <location line="+71"/>
+        <location line="+72"/>
         <source>Search from end</source>
         <translation>Procurar a partir do fim</translation>
     </message>
@@ -1502,7 +1540,7 @@
         <translation>Procurar a partir do início</translation>
     </message>
     <message>
-        <location line="+121"/>
+        <location line="+119"/>
         <source>Replace Result</source>
         <translation>Substituir Resultado</translation>
     </message>
@@ -1512,7 +1550,7 @@
         <translation>%1 itens substituidos</translation>
     </message>
     <message>
-        <location line="+10"/>
+        <location line="+12"/>
         <source>Find Result</source>
         <translation>Buscar Resultado</translation>
     </message>
@@ -1535,12 +1573,7 @@
         <translation>Chamados:</translation>
     </message>
     <message>
-        <location line="+2"/>
-        <source>Enter the filename expression</source>
-        <translation>Introduza a expressão para o nome do ficheiro</translation>
-    </message>
-    <message>
-        <location line="+6"/>
+        <location line="+8"/>
         <source>Start in:</source>
         <translation>Iniciar em:</translation>
     </message>
@@ -1560,22 +1593,12 @@
         <translation>Navegar por directório inicial</translation>
     </message>
     <message>
-        <location line="+3"/>
-        <source>Recurse directories</source>
-        <translation>Entrar em sub-directórios</translation>
-    </message>
-    <message>
-        <location line="+4"/>
+        <location line="+7"/>
         <source>Search recursively through directories for matching files</source>
         <translation>Procurar recursivamente pelos directórios por ficheiros correspondentes</translation>
     </message>
     <message>
-        <location line="+2"/>
-        <source>Include directories</source>
-        <translation>Incluir directórios</translation>
-    </message>
-    <message>
-        <location line="+4"/>
+        <location line="+6"/>
         <source>Include matching directories in search results</source>
         <translation>Incluir directórios correspondentes nos resultado da pesquisa</translation>
     </message>
@@ -1595,9 +1618,24 @@
         <translation>Contém texto:</translation>
     </message>
     <message>
-        <location line="+1"/>
-        <source>Search must match text</source>
-        <translation>Pesquisa precisa corresponder ao texto</translation>
+        <location line="-35"/>
+        <source>Enter the filename search expression</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+18"/>
+        <source>Search subdirectories</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+6"/>
+        <source>Include directory names</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+12"/>
+        <source>Enter the file content search expression</source>
+        <translation type="unfinished"></translation>
     </message>
     <message>
         <location line="+5"/>
@@ -1660,7 +1698,12 @@
         <translation>Procurando...</translation>
     </message>
     <message>
-        <location line="+32"/>
+        <location line="+23"/>
+        <source>%1 match(es)</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+9"/>
         <source>Set search directory</source>
         <translation>Definir directório de procura</translation>
     </message>
@@ -1750,13 +1793,13 @@
 <context>
     <name>main_window</name>
     <message>
-        <location filename="../src/main-window.cc" line="-1696"/>
+        <location filename="../src/main-window.cc" line="-1758"/>
         <source>Load Workspace</source>
         <translation>Carregar ambiente de trabalho</translation>
     </message>
     <message>
-        <location line="+645"/>
-        <location line="+876"/>
+        <location line="+678"/>
+        <location line="+905"/>
         <source>About Octave</source>
         <translation>Sobre o Octave</translation>
     </message>
@@ -1771,12 +1814,7 @@
         <translation>Novo</translation>
     </message>
     <message>
-        <location line="+4"/>
-        <source>Script</source>
-        <translation>Script</translation>
-    </message>
-    <message>
-        <location line="+7"/>
+        <location line="+11"/>
         <source>Figure</source>
         <translation>Figura</translation>
     </message>
@@ -1816,12 +1854,23 @@
         <translation>Colar</translation>
     </message>
     <message>
-        <location line="-1265"/>
+        <location line="-1327"/>
         <source>Save Workspace As</source>
         <translation>Guardar Ambiente de Trabalho como</translation>
     </message>
     <message>
-        <location line="+124"/>
+        <location line="+84"/>
+        <source>The file %1
+can not be executed because its name
+is not a valid identifier.
+
+Do you want to execute
+%2
+instead?</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+73"/>
         <source>The release notes file &apos;%1&apos; is empty.</source>
         <translation>O ficheiro de notas da versão &apos;%1&apos; está vazio.</translation>
     </message>
@@ -1841,7 +1890,7 @@
         <translation>Notícias da comunidade Octave</translation>
     </message>
     <message>
-        <location line="+939"/>
+        <location line="+968"/>
         <source>Clear Clipboard</source>
         <translation>Limpar Área de Transferência</translation>
     </message>
@@ -1906,7 +1955,12 @@
         <translation></translation>
     </message>
     <message>
-        <location line="-151"/>
+        <location line="-1311"/>
+        <source>Octave</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+1160"/>
         <source>Load Workspace...</source>
         <translation>Carregar ambiente de trabalho...</translation>
     </message>
@@ -1916,7 +1970,12 @@
         <translation>Guardar Ambiente de Trabalho como...</translation>
     </message>
     <message>
-        <location line="+41"/>
+        <location line="+38"/>
+        <source>New Script</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+3"/>
         <source>Function...</source>
         <translation>Função...</translation>
     </message>
@@ -2007,8 +2066,8 @@
         <translation>Um nível de directório acima</translation>
     </message>
     <message>
-        <location line="-1283"/>
-        <location line="+1286"/>
+        <location line="-1312"/>
+        <location line="+1315"/>
         <source>Browse directories</source>
         <translation>Navegar directórios</translation>
     </message>
@@ -2082,7 +2141,7 @@
 <context>
     <name>news_reader</name>
     <message>
-        <location line="-1282"/>
+        <location line="-1311"/>
         <source>&lt;html&gt;
 &lt;body&gt;
 &lt;p&gt;
@@ -2141,18 +2200,18 @@
 <context>
     <name>octave_dock_widget</name>
     <message>
-        <location filename="../src/octave-dock-widget.cc" line="+61"/>
-        <location line="+163"/>
+        <location filename="../src/octave-dock-widget.cc" line="+60"/>
+        <location line="+170"/>
         <source>Undock widget</source>
         <translation>Desacoplar painel</translation>
     </message>
     <message>
-        <location line="-153"/>
+        <location line="-160"/>
         <source>Hide widget</source>
         <translation>Esconder painel</translation>
     </message>
     <message>
-        <location line="+104"/>
+        <location line="+107"/>
         <source>Dock widget</source>
         <translation>Acoplar painel</translation>
     </message>
@@ -2183,7 +2242,7 @@
 <context>
     <name>octave_qt_link</name>
     <message>
-        <location filename="../src/octave-qt-link.cc" line="+94"/>
+        <location filename="../src/octave-qt-link.cc" line="+97"/>
         <location line="+6"/>
         <location line="+7"/>
         <source>Yes</source>
@@ -2210,13 +2269,13 @@
     </message>
     <message>
         <location line="+211"/>
-        <source>The file %1 does not exist in the load path.  To debug the function you are editing, you must either change to the directory %2 or add that directory to the load path.</source>
-        <translation>O ficheiro %1 não existe no caminho de pesquisa. Para depurar a função que está a ser editada, é preciso mudar para o directório %2 ou adicionar esse directório ao caminho de pesquisa.</translation>
+        <source>The file %1 does not exist in the load path.  To run or debug the function you are editing, you must either change to the directory %2 or add that directory to the load path.</source>
+        <translation type="unfinished"></translation>
     </message>
     <message>
         <location line="+1"/>
-        <source>The file %1 is shadowed by a file with the same name in the load path.  To debug the function you are editing, change to the directory %2.</source>
-        <translation>O ficheiro %1 é ignorado a favor de outro ficheiro no caminho de pesquisa com o mesmo nome. Para depurar a função, é preciso mudar para o directório %2.</translation>
+        <source>The file %1 is shadowed by a file with the same name in the load path. To run or debug the function you are editing, change to the directory %2.</source>
+        <translation type="unfinished"></translation>
     </message>
     <message>
         <location line="+2"/>
@@ -2267,17 +2326,17 @@
 <context>
     <name>settings_dialog</name>
     <message>
-        <location filename="../src/settings-dialog.ui" line="+29"/>
+        <location filename="../src/settings-dialog.ui" line="+23"/>
         <source>Settings</source>
         <translation>Configurações</translation>
     </message>
     <message>
-        <location line="+13"/>
+        <location line="+19"/>
         <source>General</source>
         <translation>Geral</translation>
     </message>
     <message>
-        <location line="+97"/>
+        <location line="+191"/>
         <source>Octave logo only</source>
         <translation>Apenas logotipo do Octave</translation>
     </message>
@@ -2292,17 +2351,37 @@
         <translation>Ícones gráficos</translation>
     </message>
     <message>
-        <location line="+39"/>
+        <location line="-179"/>
+        <source>Dock widget title bar</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+40"/>
+        <source>Custom style</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+26"/>
+        <source>Background color</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+29"/>
+        <source>Text color</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+212"/>
         <source>Editor</source>
         <translation>Editor</translation>
     </message>
     <message>
-        <location line="+71"/>
+        <location line="+102"/>
         <source>Color</source>
         <translation>Cor</translation>
     </message>
     <message>
-        <location line="+120"/>
+        <location line="+170"/>
         <source>Indent width</source>
         <translation>Largura da identação</translation>
     </message>
@@ -2312,7 +2391,7 @@
         <translation>Tabulador identa linha</translation>
     </message>
     <message>
-        <location line="+7"/>
+        <location line="+23"/>
         <source>Auto indentation</source>
         <translation>Auto-identação</translation>
     </message>
@@ -2357,62 +2436,67 @@
         <translation>Restaurar abas de edição da sessão anterior durante inicialização</translation>
     </message>
     <message>
-        <location line="+60"/>
+        <location line="+34"/>
         <source>Use custom file editor</source>
         <translation>Usar editor de texto externo</translation>
     </message>
     <message>
-        <location line="+32"/>
+        <location line="+20"/>
+        <source>emacs +%l %f </source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+35"/>
         <source>Editor Styles</source>
         <translation>Estilos do Editor</translation>
     </message>
     <message>
-        <location line="+24"/>
+        <location line="+17"/>
         <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Select font, font size (as a difference from the default size), font style (&lt;b&gt;b&lt;/b&gt;old, &lt;b&gt;i&lt;/b&gt;talic, &lt;b&gt;u&lt;/b&gt;nderline), text color and background color (for the latter, the color pink (255,0,255) is a placeholder for the default background color).&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
         <translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Seleccionar tipo de letra, tamanho (como diferença para o tamanho padrão), decoração (&lt;b&gt;n&lt;/b&gt;egrito, &lt;b&gt;i&lt;/b&gt;tálico, &lt;b&gt;s&lt;/b&gt;ublinhado), cor do texto e cor do fundo de tela (para o último, a cor rosa (255,0,255) é sinônimo da cor de fundo padrão).&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
     </message>
     <message>
-        <location line="+108"/>
+        <location line="+191"/>
         <source>Terminal Colors</source>
         <translation>Cores do Terminal</translation>
     </message>
     <message>
-        <location line="+45"/>
+        <location line="-100"/>
         <source>Font</source>
         <translation>Tipo de Letra</translation>
     </message>
     <message>
-        <location line="-757"/>
+        <location line="-770"/>
         <source>Show line numbers</source>
         <translation>Exibir número de linha</translation>
     </message>
     <message>
-        <location line="+27"/>
+        <location line="+46"/>
         <source>Highlight current line</source>
         <translation>Enfatizar linha actual</translation>
     </message>
     <message>
-        <location line="+262"/>
+        <location line="+328"/>
         <source>Code completion</source>
         <translation>Sguestões para copletar código</translation>
     </message>
     <message>
-        <location line="-282"/>
+        <location line="-361"/>
         <source>Show complete path in window title</source>
         <translation>Exibir caminho completo no título da janela</translation>
     </message>
     <message>
-        <location line="-17"/>
+        <location line="-23"/>
         <source>Show whitespace</source>
         <translation>Mostrar whitespace</translation>
     </message>
     <message>
-        <location line="+27"/>
+        <location line="+33"/>
         <source>Do not show whitespace used for indentation</source>
         <translation>Não mostrar whitespace usado para indentação</translation>
     </message>
     <message>
-        <location line="+290"/>
+        <location line="+369"/>
         <source># of characters typed before completion list displayed</source>
         <translation>Número de carácteres antes de mostrar lista de preenchimento automático</translation>
     </message>
@@ -2422,87 +2506,144 @@
         <translation>Criar ficheiros não existentes automaticamente</translation>
     </message>
     <message>
-        <location line="+57"/>
+        <location line="+31"/>
         <source>command line (%f=file, %l=line):</source>
         <translation>linha do comando (%f=ficheiro, %l=linha):</translation>
     </message>
     <message>
-        <location line="+10"/>
-        <source>emacs</source>
-        <translation>emacs</translation>
-    </message>
-    <message>
-        <location line="+67"/>
-        <source>Terminal</source>
-        <translation>Terminal</translation>
-    </message>
-    <message>
-        <location line="+15"/>
-        <source>Cursor type:</source>
-        <translation>Tipo de Cursor:</translation>
-    </message>
-    <message>
-        <location line="+23"/>
-        <source>Cursor blinking</source>
-        <translation>Indicador piscante</translation>
-    </message>
-    <message>
-        <location line="+7"/>
-        <source>Use foreground color</source>
-        <translation>Usar cor do fundo</translation>
-    </message>
-    <message>
         <location line="+94"/>
+        <source>Terminal</source>
+        <translation>Terminal</translation>
+    </message>
+    <message>
+        <location line="+45"/>
+        <source>Cursor type:</source>
+        <translation>Tipo de Cursor:</translation>
+    </message>
+    <message>
+        <location line="-11"/>
+        <source>Cursor blinking</source>
+        <translation>Indicador piscante</translation>
+    </message>
+    <message>
+        <location line="-7"/>
+        <source>Use foreground color</source>
+        <translation>Usar cor do fundo</translation>
+    </message>
+    <message>
+        <location line="+53"/>
         <source>Font size</source>
         <translation>Tamanho da letra</translation>
     </message>
     <message>
-        <location line="+35"/>
+        <location line="+99"/>
+        <source>Set focus to terminal when running a command from within another widget</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+34"/>
         <source>File Browser</source>
         <translation>Navegador de Ficheiros</translation>
     </message>
     <message>
+        <location line="+46"/>
+        <source>Show file size</source>
+        <translation>Mostrar tamanho do ficheiro</translation>
+    </message>
+    <message>
+        <location line="-14"/>
+        <source>Show file type</source>
+        <translation>Mostrar tipo de ficheiro</translation>
+    </message>
+    <message>
+        <location line="+21"/>
+        <source>Show date of last modification</source>
+        <translation>Mostrar data da última modificação</translation>
+    </message>
+    <message>
+        <location line="-14"/>
+        <source>Show hidden files</source>
+        <translation>Mostrar ficheiros escondidos</translation>
+    </message>
+    <message>
+        <location line="-1316"/>
+        <source>Interface</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+221"/>
+        <source>Octave Startup</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
         <location line="+6"/>
-        <source>Show file size</source>
-        <translation>Mostrar tamanho do ficheiro</translation>
-    </message>
-    <message>
-        <location line="+7"/>
-        <source>Show file type</source>
-        <translation>Mostrar tipo de ficheiro</translation>
-    </message>
-    <message>
-        <location line="+7"/>
-        <source>Show date of last modification</source>
-        <translation>Mostrar data da última modificação</translation>
-    </message>
-    <message>
-        <location line="+7"/>
-        <source>Show hidden files</source>
-        <translation>Mostrar ficheiros escondidos</translation>
-    </message>
-    <message>
-        <location line="+14"/>
-        <source>Alternating row colors</source>
-        <translation>Cores de linhas alternantes</translation>
-    </message>
-    <message>
-        <location line="+21"/>
-        <source>Workspace</source>
-        <translation>Ambiente de trabalho</translation>
-    </message>
-    <message>
-        <location line="+30"/>
-        <source>Storage Class Colors</source>
-        <translation>Cores das Classes de Armazenamento</translation>
+        <source>These preferences are applied after the startup files like .octaverc.</source>
+        <translation type="unfinished"></translation>
     </message>
     <message>
         <location line="+35"/>
+        <location line="+1104"/>
+        <source>Startup path</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="-1091"/>
+        <location line="+1108"/>
+        <source>Browse</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="-1101"/>
+        <source>Restore last Octave directory of previous session</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+214"/>
+        <source>Tab width min.</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+52"/>
+        <source>max.</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+750"/>
+        <source>Display</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+39"/>
+        <source>Alternating row colors</source>
+        <translation>Cores de linhas alternantes</translation>
+    </message>
+    <message>
+        <location line="+12"/>
+        <source>Behavior</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+27"/>
+        <source>Restore last directory of previous session</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+65"/>
+        <source>Workspace</source>
+        <translation>Ambiente de trabalho</translation>
+    </message>
+    <message>
+        <location line="+38"/>
+        <source>Storage Class Colors</source>
+        <translation>Cores das Classes de Armazenamento</translation>
+    </message>
+    <message>
+        <location line="+40"/>
         <source>Network</source>
         <translation>Rede</translation>
     </message>
     <message>
-        <location line="+8"/>
+        <location line="+23"/>
         <source>Allow Octave to connect to the Octave web site to display current news and information</source>
         <translation>Permitir ao Octave ligar-se ao site do Octave para mostrar notícias e informações</translation>
     </message>
@@ -2517,27 +2658,27 @@
         <translation>Proxy HTTP</translation>
     </message>
     <message>
-        <location line="-1129"/>
+        <location line="-1356"/>
         <source>Icon set for dock widgets</source>
         <translation>Conjunto de ícones para paineis</translation>
     </message>
     <message>
-        <location line="+7"/>
+        <location line="-48"/>
         <source>Language (requires restart)</source>
         <translation>Idioma (reinicialização do Octave necessária)</translation>
     </message>
     <message>
-        <location line="+7"/>
+        <location line="-122"/>
         <source>Icon size</source>
         <translation>Tamanho do Ícone</translation>
     </message>
     <message>
-        <location line="+991"/>
+        <location line="+1318"/>
         <source>Synchronize Octave working directory with file browser</source>
         <translation>Sincronizar o directório de trabalho do Octave com o navegador de ficheiros</translation>
     </message>
     <message>
-        <location line="+129"/>
+        <location line="+213"/>
         <source>Socks5Proxy</source>
         <translation>Proxy Socks 5</translation>
     </message>
@@ -2567,9 +2708,9 @@
         <translation>Senha:</translation>
     </message>
     <message>
-        <location filename="../src/settings-dialog.cc" line="+71"/>
+        <location filename="../src/settings-dialog.cc" line="+74"/>
         <location line="+4"/>
-        <location line="+389"/>
+        <location line="+437"/>
         <source>System setting</source>
         <translation>Configuração do sistema</translation>
     </message>
@@ -2616,6 +2757,16 @@
         <comment>short form for underlined</comment>
         <translation>s</translation>
     </message>
+    <message>
+        <location line="+419"/>
+        <source>Set Octave Startup Directory</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+6"/>
+        <source>Set File Browser Startup Directory</source>
+        <translation type="unfinished"></translation>
+    </message>
 </context>
 <context>
     <name>setup_community_news</name>
@@ -2683,7 +2834,7 @@
 <context>
     <name>webinfo</name>
     <message>
-        <location filename="../src/qtinfo/webinfo.cc" line="+80"/>
+        <location filename="../src/qtinfo/webinfo.cc" line="+83"/>
         <source>Type here and press &apos;Return&apos; to search</source>
         <translation>Digite aqui e pressione &apos;Enter&apos; para buscar</translation>
     </message>
@@ -2692,6 +2843,16 @@
         <source>Global search</source>
         <translation>Procura global</translation>
     </message>
+    <message>
+        <location line="+22"/>
+        <source>Error</source>
+        <translation type="unfinished">Erro</translation>
+    </message>
+    <message>
+        <location line="+3"/>
+        <source>The info file %1 does not exist</source>
+        <translation type="unfinished"></translation>
+    </message>
 </context>
 <context>
     <name>welcome_wizard</name>
@@ -2725,8 +2886,8 @@
     </message>
     <message>
         <location line="+1"/>
-        <source>Storage Class</source>
-        <translation>Classe de Armazenamento</translation>
+        <source>Attribute</source>
+        <translation type="unfinished"></translation>
     </message>
     <message>
         <location line="+109"/>
@@ -2774,8 +2935,8 @@
     </message>
     <message>
         <location line="+1"/>
-        <source>Colors for the storage class:</source>
-        <translation>Cores para classe de armazenamento:</translation>
+        <source>Colors for variable attributes:</source>
+        <translation type="unfinished"></translation>
     </message>
 </context>
 </TS>
--- a/libgui/languages/ru_RU.ts	Fri Feb 06 08:31:09 2015 -0800
+++ b/libgui/languages/ru_RU.ts	Fri Feb 06 08:31:49 2015 -0800
@@ -62,7 +62,7 @@
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="../src/main-window.cc" line="+1900"/>
+        <location filename="../src/main-window.cc" line="+1963"/>
         <source>&lt;p&gt;&lt;strong&gt;A Note about Octave&apos;s New GUI&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;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.  But because it is not quite as polished as we would like, we have decided to wait until the 4.0.x release series before making the GUI the default interface.&lt;/p&gt;&lt;p&gt;Given the length of time and the number of bug fixes and improvements since the last major release, we also decided against delaying the release of all these new improvements any longer just to perfect the GUI.  So please enjoy the 3.8 release of Octave and the preview of the new GUI.  We believe it is working reasonably well, but we also know that there are some obvious rough spots and many things that could be improved.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;We Need Your Help&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;There are many ways that you can help us fix the remaining problems, complete the GUI, and improve the overall user experience for both novices and experts alike (links will open an external browser):&lt;/p&gt;&lt;p&gt;&lt;ul&gt;&lt;li&gt;If you are a skilled software developer, you can help by contributing your time to help &lt;a href=&quot;http://octave.org/get-involved.html&quot;&gt;develop Octave&lt;/a&gt;.&lt;/li&gt;&lt;li&gt;If Octave does not work properly, you are encouraged to &lt;a href=&quot;http://octave.org/bugs.html&quot;&gt;report problems &lt;/a&gt; that you find.&lt;/li&gt;&lt;li&gt;Whether you are a user or developer, you can &lt;a href=&quot;http://octave.org/donate.html&quot;&gt;help to fund the project&lt;/a&gt;.  Octave development takes a lot of time and expertise.  Your contributions help to ensure that Octave will continue to improve.&lt;/li&gt;&lt;/ul&gt;&lt;/p&gt;&lt;p&gt;We hope you find Octave to be useful.  Please help us make it even better for the future!&lt;/p&gt;</source>
         <translation type="unfinished"></translation>
     </message>
@@ -88,7 +88,7 @@
 <context>
     <name>QWinTerminalImpl</name>
     <message>
-        <location filename="../qterminal/libqterminal/win32/QWinTerminalImpl.cpp" line="+1536"/>
+        <location filename="../qterminal/libqterminal/win32/QWinTerminalImpl.cpp" line="+1539"/>
         <source>copied selection to clipboard</source>
         <translation>выделенное скопировано в буфер обмена</translation>
     </message>
@@ -143,17 +143,12 @@
 уже открыт в редакторе</translation>
     </message>
     <message>
-        <location line="+255"/>
+        <location line="+268"/>
         <source>&amp;%1 %2</source>
         <translation>&amp;%1 %2</translation>
     </message>
     <message>
-        <location line="+175"/>
-        <source>&amp;New File</source>
-        <translation>Созд&amp;ать</translation>
-    </message>
-    <message>
-        <location line="+6"/>
+        <location line="+207"/>
         <source>&amp;Save File</source>
         <translation>&amp;Сохранить</translation>
     </message>
@@ -163,7 +158,12 @@
         <translation>&amp;Открыть...</translation>
     </message>
     <message>
-        <location line="+6"/>
+        <location line="-3"/>
+        <source>&amp;New Script</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+9"/>
         <source>Save File &amp;As...</source>
         <translation>Сохранить &amp;как...</translation>
     </message>
@@ -249,6 +249,16 @@
     </message>
     <message>
         <location line="+3"/>
+        <source>&amp;Indent</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+2"/>
+        <source>&amp;Unindent</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+3"/>
         <source>&amp;Find and Replace...</source>
         <translation>&amp;Найти и заменить...</translation>
     </message>
@@ -263,7 +273,7 @@
         <translation>&amp;Перейти к строчке...</translation>
     </message>
     <message>
-        <location line="+55"/>
+        <location line="+57"/>
         <source>&amp;Recent Editor Files</source>
         <translation>&amp;Недавние файлы редактора</translation>
     </message>
@@ -288,7 +298,7 @@
         <translation>Закрыть другие файлы</translation>
     </message>
     <message>
-        <location line="+31"/>
+        <location line="+34"/>
         <source>&amp;Preferences...</source>
         <translation>&amp;Настройки...</translation>
     </message>
@@ -318,7 +328,7 @@
         <translation>&amp;Документация по зарезервированному слову</translation>
     </message>
     <message>
-        <location line="-741"/>
+        <location line="-790"/>
         <source>Could not open file
 %1
 for read: %2.</source>
@@ -350,7 +360,7 @@
         <translation></translation>
     </message>
     <message>
-        <location line="+521"/>
+        <location line="+567"/>
         <source>&amp;File</source>
         <translation>&amp;Файл</translation>
     </message>
@@ -365,7 +375,7 @@
         <translation>&amp;Правка</translation>
     </message>
     <message>
-        <location line="+30"/>
+        <location line="+33"/>
         <source>&amp;Debug</source>
         <translation>&amp;Отладка</translation>
     </message>
@@ -378,7 +388,7 @@
 <context>
     <name>file_editor_tab</name>
     <message>
-        <location filename="../src/m-editor/file-editor-tab.cc" line="+803"/>
+        <location filename="../src/m-editor/file-editor-tab.cc" line="+824"/>
         <source>Goto line</source>
         <translation>Перейти к строчке</translation>
     </message>
@@ -388,7 +398,7 @@
         <translation></translation>
     </message>
     <message>
-        <location line="+71"/>
+        <location line="+108"/>
         <location line="+69"/>
         <source>&lt;unnamed&gt;</source>
         <translation>&lt;без названия&gt;</translation>
@@ -405,14 +415,15 @@
     </message>
     <message>
         <location line="+10"/>
-        <location line="+122"/>
-        <location line="+150"/>
+        <location line="+123"/>
+        <location line="+112"/>
+        <location line="+69"/>
         <location line="+22"/>
         <source>Octave Editor</source>
         <translation>Редактор Octave</translation>
     </message>
     <message>
-        <location line="-293"/>
+        <location line="-325"/>
         <source>The file
 %1
 is about to be closed but has been modified.
@@ -423,12 +434,12 @@
 %2</translation>
     </message>
     <message>
-        <location line="+201"/>
+        <location line="+203"/>
         <source>Octave Files (*.m);;All Files (*)</source>
         <translation>Файлы Octave (*.m);;Все файлы (*)</translation>
     </message>
     <message>
-        <location line="+86"/>
+        <location line="+116"/>
         <source>
 
 Warning: The contents in the editor is modified!</source>
@@ -446,14 +457,14 @@
 был удален или переименован. Вы хотите сохранить его?%2</translation>
     </message>
     <message>
-        <location line="-172"/>
+        <location line="-203"/>
         <source>Could not open file %1 for write:
 %2.</source>
         <translation>Не удалось открыть файл %1 для записи:
 %2.</translation>
     </message>
     <message>
-        <location line="-975"/>
+        <location line="-1032"/>
         <source>Line:</source>
         <translation></translation>
     </message>
@@ -463,7 +474,18 @@
         <translation></translation>
     </message>
     <message>
-        <location line="+1122"/>
+        <location line="+1141"/>
+        <source>&quot;%1&quot;
+is not a valid identifier.
+
+If you keep this file name, you will not be able to
+call your script using its name as an Octave command.
+
+Do you want to choose another name?</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+69"/>
         <source>It seems that &apos;%1&apos; has been modified by another application. Do you want to reload it?</source>
         <translation>Кажется, файл &apos;%1&apos; был изменен другим приложением. Вы хотите обновить его содержимое?</translation>
     </message>
@@ -496,7 +518,12 @@
         <translation></translation>
     </message>
     <message>
-        <location line="+373"/>
+        <location line="+15"/>
+        <source>Set Browser Directory...</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+379"/>
         <source>Find Files...</source>
         <translation>Найти файлы...</translation>
     </message>
@@ -507,16 +534,17 @@
     </message>
     <message>
         <location line="+3"/>
+        <location line="+333"/>
         <source>New Directory</source>
         <translation>Новая директория</translation>
     </message>
     <message>
-        <location line="-323"/>
+        <location line="-656"/>
         <source>Double-click a file to open it</source>
         <translation></translation>
     </message>
     <message>
-        <location line="-79"/>
+        <location line="-100"/>
         <source>Show Octave directory</source>
         <translation>Перейти к текущей директории Octave</translation>
     </message>
@@ -541,7 +569,7 @@
         <translation>Показывать домашнюю директорию</translation>
     </message>
     <message>
-        <location line="+12"/>
+        <location line="+16"/>
         <source>Search Directory...</source>
         <translation></translation>
     </message>
@@ -561,7 +589,7 @@
         <translation>Новая директория...</translation>
     </message>
     <message>
-        <location line="+276"/>
+        <location line="+297"/>
         <source>File size</source>
         <translation></translation>
     </message>
@@ -673,7 +701,12 @@
 </translation>
     </message>
     <message>
-        <location line="+17"/>
+        <location line="+1"/>
+        <source>New File.txt</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+16"/>
         <source>Create Directory</source>
         <translation>Создать директорию</translation>
     </message>
@@ -737,7 +770,12 @@
 <context>
     <name>find_dialog</name>
     <message>
-        <location filename="../src/m-editor/find-dialog.cc" line="+77"/>
+        <location filename="../src/m-editor/find-dialog.cc" line="+74"/>
+        <source>Find and Replace</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+3"/>
         <source>Find &amp;what:</source>
         <translation>&amp;Найти:</translation>
     </message>
@@ -807,7 +845,7 @@
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location line="+71"/>
+        <location line="+72"/>
         <source>Search from end</source>
         <translation>Искать с конца</translation>
     </message>
@@ -817,7 +855,7 @@
         <translation>Искать с начала</translation>
     </message>
     <message>
-        <location line="+121"/>
+        <location line="+119"/>
         <source>Replace Result</source>
         <translation type="unfinished"></translation>
     </message>
@@ -827,7 +865,7 @@
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location line="+10"/>
+        <location line="+12"/>
         <source>Find Result</source>
         <translation type="unfinished"></translation>
     </message>
@@ -850,12 +888,7 @@
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location line="+2"/>
-        <source>Enter the filename expression</source>
-        <translation type="unfinished"></translation>
-    </message>
-    <message>
-        <location line="+6"/>
+        <location line="+8"/>
         <source>Start in:</source>
         <translation type="unfinished"></translation>
     </message>
@@ -875,22 +908,12 @@
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location line="+3"/>
-        <source>Recurse directories</source>
-        <translation type="unfinished"></translation>
-    </message>
-    <message>
-        <location line="+4"/>
+        <location line="+7"/>
         <source>Search recursively through directories for matching files</source>
         <translation>Искать рекурсивно в директориях подходящие файлы</translation>
     </message>
     <message>
-        <location line="+2"/>
-        <source>Include directories</source>
-        <translation type="unfinished"></translation>
-    </message>
-    <message>
-        <location line="+4"/>
+        <location line="+6"/>
         <source>Include matching directories in search results</source>
         <translation type="unfinished"></translation>
     </message>
@@ -910,8 +933,23 @@
         <translation>Содержит текст:</translation>
     </message>
     <message>
-        <location line="+1"/>
-        <source>Search must match text</source>
+        <location line="-35"/>
+        <source>Enter the filename search expression</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+18"/>
+        <source>Search subdirectories</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+6"/>
+        <source>Include directory names</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+12"/>
+        <source>Enter the file content search expression</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
@@ -975,7 +1013,12 @@
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location line="+32"/>
+        <location line="+23"/>
+        <source>%1 match(es)</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+9"/>
         <source>Set search directory</source>
         <translation>Установить директорию для поиска</translation>
     </message>
@@ -1061,13 +1104,13 @@
 <context>
     <name>main_window</name>
     <message>
-        <location filename="../src/main-window.cc" line="-1696"/>
+        <location filename="../src/main-window.cc" line="-1758"/>
         <source>Load Workspace</source>
         <translation>Загрузить область переменных</translation>
     </message>
     <message>
-        <location line="+645"/>
-        <location line="+876"/>
+        <location line="+678"/>
+        <location line="+905"/>
         <source>About Octave</source>
         <translation>Об Octave</translation>
     </message>
@@ -1082,12 +1125,7 @@
         <translation>Новый</translation>
     </message>
     <message>
-        <location line="+4"/>
-        <source>Script</source>
-        <translation>Скрипт</translation>
-    </message>
-    <message>
-        <location line="+7"/>
+        <location line="+11"/>
         <source>Figure</source>
         <translation></translation>
     </message>
@@ -1127,12 +1165,23 @@
         <translation>Вставить</translation>
     </message>
     <message>
-        <location line="-1265"/>
+        <location line="-1327"/>
         <source>Save Workspace As</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location line="+124"/>
+        <location line="+84"/>
+        <source>The file %1
+can not be executed because its name
+is not a valid identifier.
+
+Do you want to execute
+%2
+instead?</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+73"/>
         <source>The release notes file &apos;%1&apos; is empty.</source>
         <translation type="unfinished"></translation>
     </message>
@@ -1152,7 +1201,7 @@
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location line="+939"/>
+        <location line="+968"/>
         <source>Clear Clipboard</source>
         <translation type="unfinished"></translation>
     </message>
@@ -1217,7 +1266,12 @@
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location line="-151"/>
+        <location line="-1311"/>
+        <source>Octave</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+1160"/>
         <source>Load Workspace...</source>
         <translation>Загрузить область переменных...</translation>
     </message>
@@ -1227,7 +1281,12 @@
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location line="+41"/>
+        <location line="+38"/>
+        <source>New Script</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+3"/>
         <source>Function...</source>
         <translation>Функция...</translation>
     </message>
@@ -1318,8 +1377,8 @@
         <translation>Одной директорией вверх</translation>
     </message>
     <message>
-        <location line="-1283"/>
-        <location line="+1286"/>
+        <location line="-1312"/>
+        <location line="+1315"/>
         <source>Browse directories</source>
         <translation>Просмотр директорий</translation>
     </message>
@@ -1393,7 +1452,7 @@
 <context>
     <name>news_reader</name>
     <message>
-        <location line="-1282"/>
+        <location line="-1311"/>
         <source>&lt;html&gt;
 &lt;body&gt;
 &lt;p&gt;
@@ -1429,18 +1488,18 @@
 <context>
     <name>octave_dock_widget</name>
     <message>
-        <location filename="../src/octave-dock-widget.cc" line="+61"/>
-        <location line="+163"/>
+        <location filename="../src/octave-dock-widget.cc" line="+60"/>
+        <location line="+170"/>
         <source>Undock widget</source>
         <translation>Открепить виджет</translation>
     </message>
     <message>
-        <location line="-153"/>
+        <location line="-160"/>
         <source>Hide widget</source>
         <translation>Спрятать виджет</translation>
     </message>
     <message>
-        <location line="+104"/>
+        <location line="+107"/>
         <source>Dock widget</source>
         <translation>Закрепить виджет</translation>
     </message>
@@ -1471,7 +1530,7 @@
 <context>
     <name>octave_qt_link</name>
     <message>
-        <location filename="../src/octave-qt-link.cc" line="+94"/>
+        <location filename="../src/octave-qt-link.cc" line="+97"/>
         <location line="+6"/>
         <location line="+7"/>
         <source>Yes</source>
@@ -1498,12 +1557,12 @@
     </message>
     <message>
         <location line="+211"/>
-        <source>The file %1 does not exist in the load path.  To debug the function you are editing, you must either change to the directory %2 or add that directory to the load path.</source>
-        <translation>Файл %1 не существует в пути загрузки.  Чтобы отладить редактируемую вами функцию, вы должны либо изменить директорию на %2, или добавить эту директорию в путь загрузки.</translation>
+        <source>The file %1 does not exist in the load path.  To run or debug the function you are editing, you must either change to the directory %2 or add that directory to the load path.</source>
+        <translation type="unfinished"></translation>
     </message>
     <message>
         <location line="+1"/>
-        <source>The file %1 is shadowed by a file with the same name in the load path.  To debug the function you are editing, change to the directory %2.</source>
+        <source>The file %1 is shadowed by a file with the same name in the load path. To run or debug the function you are editing, change to the directory %2.</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
@@ -1549,17 +1608,17 @@
 <context>
     <name>settings_dialog</name>
     <message>
-        <location filename="../src/settings-dialog.ui" line="+29"/>
+        <location filename="../src/settings-dialog.ui" line="+23"/>
         <source>Settings</source>
         <translation>Параметры</translation>
     </message>
     <message>
-        <location line="+13"/>
+        <location line="+19"/>
         <source>General</source>
         <translation>Основное</translation>
     </message>
     <message>
-        <location line="+97"/>
+        <location line="+191"/>
         <source>Octave logo only</source>
         <translation type="unfinished">Только логотип Octave</translation>
     </message>
@@ -1569,17 +1628,37 @@
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location line="+46"/>
+        <location line="-172"/>
+        <source>Dock widget title bar</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+40"/>
+        <source>Custom style</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+26"/>
+        <source>Background color</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+29"/>
+        <source>Text color</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+212"/>
         <source>Editor</source>
         <translation>Редактор</translation>
     </message>
     <message>
-        <location line="+71"/>
+        <location line="+102"/>
         <source>Color</source>
         <translation>Цвет</translation>
     </message>
     <message>
-        <location line="+120"/>
+        <location line="+170"/>
         <source>Indent width</source>
         <translation>Ширина отступа</translation>
     </message>
@@ -1589,7 +1668,7 @@
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location line="+7"/>
+        <location line="+23"/>
         <source>Auto indentation</source>
         <translation>Авто-отступы</translation>
     </message>
@@ -1634,67 +1713,114 @@
         <translation>Восстанавливать вкладки редактора с предыдущей сессии во время запуска</translation>
     </message>
     <message>
-        <location line="+60"/>
+        <location line="+34"/>
         <source>Use custom file editor</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location line="+32"/>
+        <location line="+20"/>
+        <source>emacs +%l %f </source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+35"/>
         <source>Editor Styles</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location line="+24"/>
+        <location line="+17"/>
         <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Select font, font size (as a difference from the default size), font style (&lt;b&gt;b&lt;/b&gt;old, &lt;b&gt;i&lt;/b&gt;talic, &lt;b&gt;u&lt;/b&gt;nderline), text color and background color (for the latter, the color pink (255,0,255) is a placeholder for the default background color).&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location line="+108"/>
+        <location line="+191"/>
         <source>Terminal Colors</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location line="+45"/>
+        <location line="-100"/>
         <source>Font</source>
         <translation>Шрифт</translation>
     </message>
     <message>
-        <location line="-757"/>
+        <location line="-770"/>
         <source>Show line numbers</source>
         <translation>Показывать количество строк</translation>
     </message>
     <message>
-        <location line="+27"/>
+        <location line="+46"/>
         <source>Highlight current line</source>
         <translation>Подсвечивать текущую строку</translation>
     </message>
     <message>
-        <location line="+262"/>
+        <location line="+328"/>
         <source>Code completion</source>
         <translation>Дополнение кода</translation>
     </message>
     <message>
-        <location line="-282"/>
+        <location line="-361"/>
         <source>Show complete path in window title</source>
         <translation>Показывать полный путь в заголовке окна</translation>
     </message>
     <message>
-        <location line="-72"/>
+        <location line="-366"/>
+        <source>Interface</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+187"/>
         <source>Graphic icons</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location line="+55"/>
+        <location line="+34"/>
+        <source>Octave Startup</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+6"/>
+        <source>These preferences are applied after the startup files like .octaverc.</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+35"/>
+        <location line="+1104"/>
+        <source>Startup path</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="-1091"/>
+        <location line="+1108"/>
+        <source>Browse</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="-1101"/>
+        <source>Restore last Octave directory of previous session</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+61"/>
         <source>Show whitespace</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location line="+27"/>
+        <location line="+33"/>
         <source>Do not show whitespace used for indentation</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location line="+290"/>
+        <location line="+120"/>
+        <source>Tab width min.</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+52"/>
+        <source>max.</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+197"/>
         <source># of characters typed before completion list displayed</source>
         <translation type="unfinished"></translation>
     </message>
@@ -1704,87 +1830,102 @@
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location line="+57"/>
+        <location line="+31"/>
         <source>command line (%f=file, %l=line):</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location line="+10"/>
-        <source>emacs</source>
-        <translation>emacs</translation>
-    </message>
-    <message>
-        <location line="+67"/>
+        <location line="+94"/>
         <source>Terminal</source>
         <translation>Командная строка</translation>
     </message>
     <message>
-        <location line="+15"/>
+        <location line="+45"/>
         <source>Cursor type:</source>
         <translation>Тип курсора:</translation>
     </message>
     <message>
-        <location line="+23"/>
+        <location line="-11"/>
         <source>Cursor blinking</source>
         <translation>Мигающий курсор</translation>
     </message>
     <message>
-        <location line="+7"/>
+        <location line="-7"/>
         <source>Use foreground color</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location line="+94"/>
+        <location line="+53"/>
         <source>Font size</source>
         <translation>Размер шрифта</translation>
     </message>
     <message>
-        <location line="+35"/>
+        <location line="+99"/>
+        <source>Set focus to terminal when running a command from within another widget</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+34"/>
         <source>File Browser</source>
         <translation>Файловый менеджер</translation>
     </message>
     <message>
-        <location line="+6"/>
+        <location line="+46"/>
         <source>Show file size</source>
         <translation>Показывать размер файлов</translation>
     </message>
     <message>
-        <location line="+7"/>
+        <location line="-14"/>
         <source>Show file type</source>
         <translation>Показывать типы файлов</translation>
     </message>
     <message>
-        <location line="+7"/>
+        <location line="+21"/>
         <source>Show date of last modification</source>
         <translation>Показывать дату последнего изменения</translation>
     </message>
     <message>
-        <location line="+7"/>
+        <location line="-14"/>
         <source>Show hidden files</source>
         <translation>Показывать скрытые файлы</translation>
     </message>
     <message>
-        <location line="+14"/>
+        <location line="-18"/>
+        <source>Display</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+39"/>
         <source>Alternating row colors</source>
         <translation>Чередующиеся цвета строк</translation>
     </message>
     <message>
-        <location line="+21"/>
+        <location line="+12"/>
+        <source>Behavior</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+27"/>
+        <source>Restore last directory of previous session</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+65"/>
         <source>Workspace</source>
         <translation>Область переменных</translation>
     </message>
     <message>
-        <location line="+30"/>
+        <location line="+38"/>
         <source>Storage Class Colors</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location line="+35"/>
+        <location line="+40"/>
         <source>Network</source>
         <translation>Сеть</translation>
     </message>
     <message>
-        <location line="+8"/>
+        <location line="+23"/>
         <source>Allow Octave to connect to the Octave web site to display current news and information</source>
         <translation type="unfinished"></translation>
     </message>
@@ -1799,27 +1940,27 @@
         <translation>HttpProxy</translation>
     </message>
     <message>
-        <location line="-1129"/>
+        <location line="-1356"/>
         <source>Icon set for dock widgets</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location line="+7"/>
+        <location line="-48"/>
         <source>Language (requires restart)</source>
         <translation>Язык (требуется перезапуск)</translation>
     </message>
     <message>
-        <location line="+7"/>
+        <location line="-122"/>
         <source>Icon size</source>
         <translation>Размер иконок</translation>
     </message>
     <message>
-        <location line="+991"/>
+        <location line="+1318"/>
         <source>Synchronize Octave working directory with file browser</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location line="+129"/>
+        <location line="+213"/>
         <source>Socks5Proxy</source>
         <translation>Socks5Proxy</translation>
     </message>
@@ -1849,9 +1990,9 @@
         <translation>Пароль:</translation>
     </message>
     <message>
-        <location filename="../src/settings-dialog.cc" line="+71"/>
+        <location filename="../src/settings-dialog.cc" line="+74"/>
         <location line="+4"/>
-        <location line="+389"/>
+        <location line="+437"/>
         <source>System setting</source>
         <translation type="unfinished"></translation>
     </message>
@@ -1898,6 +2039,16 @@
         <comment>short form for underlined</comment>
         <translation type="unfinished"></translation>
     </message>
+    <message>
+        <location line="+419"/>
+        <source>Set Octave Startup Directory</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+6"/>
+        <source>Set File Browser Startup Directory</source>
+        <translation type="unfinished"></translation>
+    </message>
 </context>
 <context>
     <name>setup_community_news</name>
@@ -1954,7 +2105,7 @@
 <context>
     <name>webinfo</name>
     <message>
-        <location filename="../src/qtinfo/webinfo.cc" line="+80"/>
+        <location filename="../src/qtinfo/webinfo.cc" line="+83"/>
         <source>Type here and press &apos;Return&apos; to search</source>
         <translation>Вводите сюда и нажмите &apos;Enter&apos;, чтобы начать поиск</translation>
     </message>
@@ -1963,6 +2114,16 @@
         <source>Global search</source>
         <translation>Глобальный поиск</translation>
     </message>
+    <message>
+        <location line="+22"/>
+        <source>Error</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+3"/>
+        <source>The info file %1 does not exist</source>
+        <translation type="unfinished"></translation>
+    </message>
 </context>
 <context>
     <name>welcome_wizard</name>
@@ -1996,7 +2157,7 @@
     </message>
     <message>
         <location line="+1"/>
-        <source>Storage Class</source>
+        <source>Attribute</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
@@ -2045,7 +2206,7 @@
     </message>
     <message>
         <location line="+1"/>
-        <source>Colors for the storage class:</source>
+        <source>Colors for variable attributes:</source>
         <translation type="unfinished"></translation>
     </message>
 </context>
--- a/libgui/languages/translators	Fri Feb 06 08:31:09 2015 -0800
+++ b/libgui/languages/translators	Fri Feb 06 08:31:49 2015 -0800
@@ -6,6 +6,7 @@
 de_DE Andreas Weber <andy.weber.aw@googlemail.com>
 es_ES Valentin Ortega-Clavero <arcanos3030@gmail.com>
 fr_FR David Bateman <dbateman@free.fr>, Catalin Codreanu <codreanu.catalin@gmail.com>
+it_IT Massimiliano Fasi <massimiliano.fasi@gmail.com>
 pt_BR Júlio Hoffimann Mendes <julio.hoffimann@gmail.com>
 pt_PT Carnë Draug <carandraug@octave.org>
 ru_RU Andriy Shinkarchuck <adriano32.gnu@gmail.com>
--- a/libgui/languages/uk_UA.ts	Fri Feb 06 08:31:09 2015 -0800
+++ b/libgui/languages/uk_UA.ts	Fri Feb 06 08:31:49 2015 -0800
@@ -62,7 +62,7 @@
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="../src/main-window.cc" line="+1900"/>
+        <location filename="../src/main-window.cc" line="+1963"/>
         <source>&lt;p&gt;&lt;strong&gt;A Note about Octave&apos;s New GUI&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;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.  But because it is not quite as polished as we would like, we have decided to wait until the 4.0.x release series before making the GUI the default interface.&lt;/p&gt;&lt;p&gt;Given the length of time and the number of bug fixes and improvements since the last major release, we also decided against delaying the release of all these new improvements any longer just to perfect the GUI.  So please enjoy the 3.8 release of Octave and the preview of the new GUI.  We believe it is working reasonably well, but we also know that there are some obvious rough spots and many things that could be improved.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;We Need Your Help&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;There are many ways that you can help us fix the remaining problems, complete the GUI, and improve the overall user experience for both novices and experts alike (links will open an external browser):&lt;/p&gt;&lt;p&gt;&lt;ul&gt;&lt;li&gt;If you are a skilled software developer, you can help by contributing your time to help &lt;a href=&quot;http://octave.org/get-involved.html&quot;&gt;develop Octave&lt;/a&gt;.&lt;/li&gt;&lt;li&gt;If Octave does not work properly, you are encouraged to &lt;a href=&quot;http://octave.org/bugs.html&quot;&gt;report problems &lt;/a&gt; that you find.&lt;/li&gt;&lt;li&gt;Whether you are a user or developer, you can &lt;a href=&quot;http://octave.org/donate.html&quot;&gt;help to fund the project&lt;/a&gt;.  Octave development takes a lot of time and expertise.  Your contributions help to ensure that Octave will continue to improve.&lt;/li&gt;&lt;/ul&gt;&lt;/p&gt;&lt;p&gt;We hope you find Octave to be useful.  Please help us make it even better for the future!&lt;/p&gt;</source>
         <translation type="unfinished"></translation>
     </message>
@@ -88,7 +88,7 @@
 <context>
     <name>QWinTerminalImpl</name>
     <message>
-        <location filename="../qterminal/libqterminal/win32/QWinTerminalImpl.cpp" line="+1536"/>
+        <location filename="../qterminal/libqterminal/win32/QWinTerminalImpl.cpp" line="+1539"/>
         <source>copied selection to clipboard</source>
         <translation type="unfinished"></translation>
     </message>
@@ -807,17 +807,12 @@
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location line="+255"/>
+        <location line="+268"/>
         <source>&amp;%1 %2</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location line="+175"/>
-        <source>&amp;New File</source>
-        <translation type="unfinished">&amp;Створити</translation>
-    </message>
-    <message>
-        <location line="+6"/>
+        <location line="+207"/>
         <source>&amp;Save File</source>
         <translation type="unfinished">&amp;Зберегти</translation>
     </message>
@@ -827,7 +822,12 @@
         <translation>&amp;Відкрити...</translation>
     </message>
     <message>
-        <location line="+6"/>
+        <location line="-3"/>
+        <source>&amp;New Script</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+9"/>
         <source>Save File &amp;As...</source>
         <translation>Зберегти &amp;як...</translation>
     </message>
@@ -913,6 +913,16 @@
     </message>
     <message>
         <location line="+3"/>
+        <source>&amp;Indent</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+2"/>
+        <source>&amp;Unindent</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+3"/>
         <source>&amp;Find and Replace...</source>
         <translation type="unfinished"></translation>
     </message>
@@ -927,7 +937,7 @@
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location line="+55"/>
+        <location line="+57"/>
         <source>&amp;Recent Editor Files</source>
         <translation type="unfinished"></translation>
     </message>
@@ -952,7 +962,7 @@
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location line="+31"/>
+        <location line="+34"/>
         <source>&amp;Preferences...</source>
         <translation type="unfinished"></translation>
     </message>
@@ -982,7 +992,7 @@
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location line="-741"/>
+        <location line="-790"/>
         <source>Could not open file
 %1
 for read: %2.</source>
@@ -1008,7 +1018,7 @@
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location line="+521"/>
+        <location line="+567"/>
         <source>&amp;File</source>
         <translation type="unfinished">&amp;Файл</translation>
     </message>
@@ -1023,7 +1033,7 @@
         <translation type="unfinished">&amp;Правка</translation>
     </message>
     <message>
-        <location line="+30"/>
+        <location line="+33"/>
         <source>&amp;Debug</source>
         <translation type="unfinished"></translation>
     </message>
@@ -1036,7 +1046,7 @@
 <context>
     <name>file_editor_tab</name>
     <message>
-        <location filename="../src/m-editor/file-editor-tab.cc" line="+803"/>
+        <location filename="../src/m-editor/file-editor-tab.cc" line="+824"/>
         <source>Goto line</source>
         <translation type="unfinished"></translation>
     </message>
@@ -1046,7 +1056,7 @@
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location line="+71"/>
+        <location line="+108"/>
         <location line="+69"/>
         <source>&lt;unnamed&gt;</source>
         <translation type="unfinished"></translation>
@@ -1063,14 +1073,15 @@
     </message>
     <message>
         <location line="+10"/>
-        <location line="+122"/>
-        <location line="+150"/>
+        <location line="+123"/>
+        <location line="+112"/>
+        <location line="+69"/>
         <location line="+22"/>
         <source>Octave Editor</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location line="-293"/>
+        <location line="-325"/>
         <source>The file
 %1
 is about to be closed but has been modified.
@@ -1078,12 +1089,12 @@
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location line="+201"/>
+        <location line="+203"/>
         <source>Octave Files (*.m);;All Files (*)</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location line="+86"/>
+        <location line="+116"/>
         <source>
 
 Warning: The contents in the editor is modified!</source>
@@ -1097,13 +1108,13 @@
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location line="-172"/>
+        <location line="-203"/>
         <source>Could not open file %1 for write:
 %2.</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location line="-975"/>
+        <location line="-1032"/>
         <source>Line:</source>
         <translation type="unfinished"></translation>
     </message>
@@ -1113,7 +1124,18 @@
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location line="+1122"/>
+        <location line="+1141"/>
+        <source>&quot;%1&quot;
+is not a valid identifier.
+
+If you keep this file name, you will not be able to
+call your script using its name as an Octave command.
+
+Do you want to choose another name?</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+69"/>
         <source>It seems that &apos;%1&apos; has been modified by another application. Do you want to reload it?</source>
         <translation type="unfinished"></translation>
     </message>
@@ -1146,7 +1168,12 @@
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location line="+373"/>
+        <location line="+15"/>
+        <source>Set Browser Directory...</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+379"/>
         <source>Find Files...</source>
         <translation type="unfinished"></translation>
     </message>
@@ -1157,16 +1184,17 @@
     </message>
     <message>
         <location line="+3"/>
+        <location line="+333"/>
         <source>New Directory</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location line="-323"/>
+        <location line="-656"/>
         <source>Double-click a file to open it</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location line="-79"/>
+        <location line="-100"/>
         <source>Show Octave directory</source>
         <translation type="unfinished"></translation>
     </message>
@@ -1191,7 +1219,7 @@
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location line="+12"/>
+        <location line="+16"/>
         <source>Search Directory...</source>
         <translation type="unfinished"></translation>
     </message>
@@ -1211,7 +1239,7 @@
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location line="+276"/>
+        <location line="+297"/>
         <source>File size</source>
         <translation type="unfinished"></translation>
     </message>
@@ -1322,7 +1350,12 @@
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location line="+17"/>
+        <location line="+1"/>
+        <source>New File.txt</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+16"/>
         <source>Create Directory</source>
         <translation type="unfinished"></translation>
     </message>
@@ -1385,7 +1418,12 @@
 <context>
     <name>find_dialog</name>
     <message>
-        <location filename="../src/m-editor/find-dialog.cc" line="+77"/>
+        <location filename="../src/m-editor/find-dialog.cc" line="+74"/>
+        <source>Find and Replace</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+3"/>
         <source>Find &amp;what:</source>
         <translation type="unfinished"></translation>
     </message>
@@ -1455,7 +1493,7 @@
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location line="+71"/>
+        <location line="+72"/>
         <source>Search from end</source>
         <translation type="unfinished"></translation>
     </message>
@@ -1465,7 +1503,7 @@
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location line="+121"/>
+        <location line="+119"/>
         <source>Replace Result</source>
         <translation type="unfinished"></translation>
     </message>
@@ -1475,7 +1513,7 @@
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location line="+10"/>
+        <location line="+12"/>
         <source>Find Result</source>
         <translation type="unfinished"></translation>
     </message>
@@ -1498,12 +1536,7 @@
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location line="+2"/>
-        <source>Enter the filename expression</source>
-        <translation type="unfinished"></translation>
-    </message>
-    <message>
-        <location line="+6"/>
+        <location line="+8"/>
         <source>Start in:</source>
         <translation type="unfinished"></translation>
     </message>
@@ -1523,22 +1556,12 @@
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location line="+3"/>
-        <source>Recurse directories</source>
-        <translation type="unfinished"></translation>
-    </message>
-    <message>
-        <location line="+4"/>
+        <location line="+7"/>
         <source>Search recursively through directories for matching files</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location line="+2"/>
-        <source>Include directories</source>
-        <translation type="unfinished"></translation>
-    </message>
-    <message>
-        <location line="+4"/>
+        <location line="+6"/>
         <source>Include matching directories in search results</source>
         <translation type="unfinished"></translation>
     </message>
@@ -1558,8 +1581,23 @@
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location line="+1"/>
-        <source>Search must match text</source>
+        <location line="-35"/>
+        <source>Enter the filename search expression</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+18"/>
+        <source>Search subdirectories</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+6"/>
+        <source>Include directory names</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+12"/>
+        <source>Enter the file content search expression</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
@@ -1623,7 +1661,12 @@
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location line="+32"/>
+        <location line="+23"/>
+        <source>%1 match(es)</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+9"/>
         <source>Set search directory</source>
         <translation type="unfinished"></translation>
     </message>
@@ -1709,13 +1752,13 @@
 <context>
     <name>main_window</name>
     <message>
-        <location filename="../src/main-window.cc" line="-1696"/>
+        <location filename="../src/main-window.cc" line="-1758"/>
         <source>Load Workspace</source>
         <translation type="unfinished">Завантажити область змінних</translation>
     </message>
     <message>
-        <location line="+645"/>
-        <location line="+876"/>
+        <location line="+678"/>
+        <location line="+905"/>
         <source>About Octave</source>
         <translation type="unfinished">Про Octave</translation>
     </message>
@@ -1730,12 +1773,7 @@
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location line="+4"/>
-        <source>Script</source>
-        <translation type="unfinished"></translation>
-    </message>
-    <message>
-        <location line="+7"/>
+        <location line="+11"/>
         <source>Figure</source>
         <translation type="unfinished"></translation>
     </message>
@@ -1775,12 +1813,23 @@
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location line="-1265"/>
+        <location line="-1327"/>
         <source>Save Workspace As</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location line="+124"/>
+        <location line="+84"/>
+        <source>The file %1
+can not be executed because its name
+is not a valid identifier.
+
+Do you want to execute
+%2
+instead?</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+73"/>
         <source>The release notes file &apos;%1&apos; is empty.</source>
         <translation type="unfinished"></translation>
     </message>
@@ -1800,7 +1849,7 @@
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location line="+939"/>
+        <location line="+968"/>
         <source>Clear Clipboard</source>
         <translation type="unfinished"></translation>
     </message>
@@ -1865,7 +1914,12 @@
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location line="-151"/>
+        <location line="-1311"/>
+        <source>Octave</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+1160"/>
         <source>Load Workspace...</source>
         <translation type="unfinished"></translation>
     </message>
@@ -1875,7 +1929,12 @@
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location line="+41"/>
+        <location line="+38"/>
+        <source>New Script</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+3"/>
         <source>Function...</source>
         <translation type="unfinished"></translation>
     </message>
@@ -1966,8 +2025,8 @@
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location line="-1283"/>
-        <location line="+1286"/>
+        <location line="-1312"/>
+        <location line="+1315"/>
         <source>Browse directories</source>
         <translation type="unfinished"></translation>
     </message>
@@ -2041,7 +2100,7 @@
 <context>
     <name>news_reader</name>
     <message>
-        <location line="-1282"/>
+        <location line="-1311"/>
         <source>&lt;html&gt;
 &lt;body&gt;
 &lt;p&gt;
@@ -2077,18 +2136,18 @@
 <context>
     <name>octave_dock_widget</name>
     <message>
-        <location filename="../src/octave-dock-widget.cc" line="+61"/>
-        <location line="+163"/>
+        <location filename="../src/octave-dock-widget.cc" line="+60"/>
+        <location line="+170"/>
         <source>Undock widget</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location line="-153"/>
+        <location line="-160"/>
         <source>Hide widget</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location line="+104"/>
+        <location line="+107"/>
         <source>Dock widget</source>
         <translation type="unfinished"></translation>
     </message>
@@ -2119,7 +2178,7 @@
 <context>
     <name>octave_qt_link</name>
     <message>
-        <location filename="../src/octave-qt-link.cc" line="+94"/>
+        <location filename="../src/octave-qt-link.cc" line="+97"/>
         <location line="+6"/>
         <location line="+7"/>
         <source>Yes</source>
@@ -2144,12 +2203,12 @@
     </message>
     <message>
         <location line="+211"/>
-        <source>The file %1 does not exist in the load path.  To debug the function you are editing, you must either change to the directory %2 or add that directory to the load path.</source>
+        <source>The file %1 does not exist in the load path.  To run or debug the function you are editing, you must either change to the directory %2 or add that directory to the load path.</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
         <location line="+1"/>
-        <source>The file %1 is shadowed by a file with the same name in the load path.  To debug the function you are editing, change to the directory %2.</source>
+        <source>The file %1 is shadowed by a file with the same name in the load path. To run or debug the function you are editing, change to the directory %2.</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
@@ -2195,17 +2254,17 @@
 <context>
     <name>settings_dialog</name>
     <message>
-        <location filename="../src/settings-dialog.ui" line="+29"/>
+        <location filename="../src/settings-dialog.ui" line="+23"/>
         <source>Settings</source>
         <translation type="unfinished">Налаштування</translation>
     </message>
     <message>
-        <location line="+13"/>
+        <location line="+19"/>
         <source>General</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location line="+97"/>
+        <location line="+191"/>
         <source>Octave logo only</source>
         <translation type="unfinished"></translation>
     </message>
@@ -2215,17 +2274,37 @@
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location line="+46"/>
+        <location line="-172"/>
+        <source>Dock widget title bar</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+40"/>
+        <source>Custom style</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+26"/>
+        <source>Background color</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+29"/>
+        <source>Text color</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+212"/>
         <source>Editor</source>
         <translation type="unfinished">Редактор</translation>
     </message>
     <message>
-        <location line="+71"/>
+        <location line="+102"/>
         <source>Color</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location line="+120"/>
+        <location line="+170"/>
         <source>Indent width</source>
         <translation type="unfinished"></translation>
     </message>
@@ -2235,7 +2314,7 @@
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location line="+7"/>
+        <location line="+23"/>
         <source>Auto indentation</source>
         <translation type="unfinished"></translation>
     </message>
@@ -2280,67 +2359,114 @@
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location line="+60"/>
+        <location line="+34"/>
         <source>Use custom file editor</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location line="+32"/>
+        <location line="+20"/>
+        <source>emacs +%l %f </source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+35"/>
         <source>Editor Styles</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location line="+24"/>
+        <location line="+17"/>
         <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Select font, font size (as a difference from the default size), font style (&lt;b&gt;b&lt;/b&gt;old, &lt;b&gt;i&lt;/b&gt;talic, &lt;b&gt;u&lt;/b&gt;nderline), text color and background color (for the latter, the color pink (255,0,255) is a placeholder for the default background color).&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location line="+108"/>
+        <location line="+191"/>
         <source>Terminal Colors</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location line="+45"/>
+        <location line="-100"/>
         <source>Font</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location line="-757"/>
+        <location line="-770"/>
         <source>Show line numbers</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location line="+27"/>
+        <location line="+46"/>
         <source>Highlight current line</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location line="+262"/>
+        <location line="+328"/>
         <source>Code completion</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location line="-282"/>
+        <location line="-361"/>
         <source>Show complete path in window title</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location line="-72"/>
+        <location line="-366"/>
+        <source>Interface</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+187"/>
         <source>Graphic icons</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location line="+55"/>
+        <location line="+34"/>
+        <source>Octave Startup</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+6"/>
+        <source>These preferences are applied after the startup files like .octaverc.</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+35"/>
+        <location line="+1104"/>
+        <source>Startup path</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="-1091"/>
+        <location line="+1108"/>
+        <source>Browse</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="-1101"/>
+        <source>Restore last Octave directory of previous session</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+61"/>
         <source>Show whitespace</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location line="+27"/>
+        <location line="+33"/>
         <source>Do not show whitespace used for indentation</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location line="+290"/>
+        <location line="+120"/>
+        <source>Tab width min.</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+52"/>
+        <source>max.</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+197"/>
         <source># of characters typed before completion list displayed</source>
         <translation type="unfinished"></translation>
     </message>
@@ -2350,87 +2476,102 @@
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location line="+57"/>
+        <location line="+31"/>
         <source>command line (%f=file, %l=line):</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location line="+10"/>
-        <source>emacs</source>
-        <translation type="unfinished">emacs</translation>
-    </message>
-    <message>
-        <location line="+67"/>
-        <source>Terminal</source>
-        <translation type="unfinished">Командний рядок</translation>
-    </message>
-    <message>
-        <location line="+15"/>
-        <source>Cursor type:</source>
-        <translation type="unfinished"></translation>
-    </message>
-    <message>
-        <location line="+23"/>
-        <source>Cursor blinking</source>
-        <translation type="unfinished"></translation>
-    </message>
-    <message>
-        <location line="+7"/>
-        <source>Use foreground color</source>
-        <translation type="unfinished"></translation>
-    </message>
-    <message>
         <location line="+94"/>
+        <source>Terminal</source>
+        <translation type="unfinished">Командний рядок</translation>
+    </message>
+    <message>
+        <location line="+45"/>
+        <source>Cursor type:</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="-11"/>
+        <source>Cursor blinking</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="-7"/>
+        <source>Use foreground color</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+53"/>
         <source>Font size</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location line="+35"/>
+        <location line="+99"/>
+        <source>Set focus to terminal when running a command from within another widget</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+34"/>
         <source>File Browser</source>
         <translation type="unfinished">Файловий менеджер</translation>
     </message>
     <message>
-        <location line="+6"/>
+        <location line="+46"/>
         <source>Show file size</source>
         <translation type="unfinished">Показувати розмір файлів</translation>
     </message>
     <message>
-        <location line="+7"/>
+        <location line="-14"/>
         <source>Show file type</source>
         <translation type="unfinished">Показувати типи файлів</translation>
     </message>
     <message>
-        <location line="+7"/>
-        <source>Show date of last modification</source>
-        <translation type="unfinished">Показувати дату останньої зміни</translation>
-    </message>
-    <message>
-        <location line="+7"/>
-        <source>Show hidden files</source>
-        <translation type="unfinished">Показувати приховані файли</translation>
-    </message>
-    <message>
-        <location line="+14"/>
-        <source>Alternating row colors</source>
-        <translation type="unfinished">Чергувати колір рядків</translation>
-    </message>
-    <message>
         <location line="+21"/>
+        <source>Show date of last modification</source>
+        <translation type="unfinished">Показувати дату останньої зміни</translation>
+    </message>
+    <message>
+        <location line="-14"/>
+        <source>Show hidden files</source>
+        <translation type="unfinished">Показувати приховані файли</translation>
+    </message>
+    <message>
+        <location line="-18"/>
+        <source>Display</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+39"/>
+        <source>Alternating row colors</source>
+        <translation type="unfinished">Чергувати колір рядків</translation>
+    </message>
+    <message>
+        <location line="+12"/>
+        <source>Behavior</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+27"/>
+        <source>Restore last directory of previous session</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+65"/>
         <source>Workspace</source>
         <translation type="unfinished">Область змінних</translation>
     </message>
     <message>
-        <location line="+30"/>
+        <location line="+38"/>
         <source>Storage Class Colors</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location line="+35"/>
+        <location line="+40"/>
         <source>Network</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location line="+8"/>
+        <location line="+23"/>
         <source>Allow Octave to connect to the Octave web site to display current news and information</source>
         <translation type="unfinished"></translation>
     </message>
@@ -2445,27 +2586,27 @@
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location line="-1129"/>
+        <location line="-1356"/>
         <source>Icon set for dock widgets</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location line="+7"/>
+        <location line="-48"/>
         <source>Language (requires restart)</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location line="+7"/>
+        <location line="-122"/>
         <source>Icon size</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location line="+991"/>
+        <location line="+1318"/>
         <source>Synchronize Octave working directory with file browser</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location line="+129"/>
+        <location line="+213"/>
         <source>Socks5Proxy</source>
         <translation type="unfinished"></translation>
     </message>
@@ -2495,9 +2636,9 @@
         <translation type="unfinished">Пароль:</translation>
     </message>
     <message>
-        <location filename="../src/settings-dialog.cc" line="+71"/>
+        <location filename="../src/settings-dialog.cc" line="+74"/>
         <location line="+4"/>
-        <location line="+389"/>
+        <location line="+437"/>
         <source>System setting</source>
         <translation type="unfinished"></translation>
     </message>
@@ -2544,6 +2685,16 @@
         <comment>short form for underlined</comment>
         <translation type="unfinished"></translation>
     </message>
+    <message>
+        <location line="+419"/>
+        <source>Set Octave Startup Directory</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+6"/>
+        <source>Set File Browser Startup Directory</source>
+        <translation type="unfinished"></translation>
+    </message>
 </context>
 <context>
     <name>setup_community_news</name>
@@ -2600,7 +2751,7 @@
 <context>
     <name>webinfo</name>
     <message>
-        <location filename="../src/qtinfo/webinfo.cc" line="+80"/>
+        <location filename="../src/qtinfo/webinfo.cc" line="+83"/>
         <source>Type here and press &apos;Return&apos; to search</source>
         <translation type="unfinished"></translation>
     </message>
@@ -2609,6 +2760,16 @@
         <source>Global search</source>
         <translation type="unfinished"></translation>
     </message>
+    <message>
+        <location line="+22"/>
+        <source>Error</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+3"/>
+        <source>The info file %1 does not exist</source>
+        <translation type="unfinished"></translation>
+    </message>
 </context>
 <context>
     <name>welcome_wizard</name>
@@ -2642,7 +2803,7 @@
     </message>
     <message>
         <location line="+1"/>
-        <source>Storage Class</source>
+        <source>Attribute</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
@@ -2691,7 +2852,7 @@
     </message>
     <message>
         <location line="+1"/>
-        <source>Colors for the storage class:</source>
+        <source>Colors for variable attributes:</source>
         <translation type="unfinished"></translation>
     </message>
 </context>
--- a/libgui/link-deps.mk	Fri Feb 06 08:31:09 2015 -0800
+++ b/libgui/link-deps.mk	Fri Feb 06 08:31:49 2015 -0800
@@ -7,10 +7,11 @@
 endif
 
 LIBOCTGUI_LINK_DEPS += \
-  @QT_LIBS@
+  $(QT_LIBS) \
+  $(OPENGL_LIBS)
 
 LIBOCTGUI_LINK_OPTS = \
-  @QT_LDFLAGS@
+  $(QT_LDFLAGS)
 
 if AMCOND_LINK_ALL_DEPS
   LIBOCTGUI_LINK_DEPS += $(LIBOCTINTERP_LINK_DEPS)
--- a/libgui/qterminal/libqterminal/QTerminal.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/libgui/qterminal/libqterminal/QTerminal.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -118,4 +118,5 @@
     (cursorUseForegroundColor,
      settings->value ("terminal/color_c",
                       QVariant (colors.at (3))).value<QColor> ());
+  setScrollBufferSize (settings->value ("terminal/history_buffer",1000).toInt () );
 }
--- a/libgui/qterminal/libqterminal/QTerminal.h	Fri Feb 06 08:31:09 2015 -0800
+++ b/libgui/qterminal/libqterminal/QTerminal.h	Fri Feb 06 08:31:49 2015 -0800
@@ -81,6 +81,8 @@
   virtual void setCursorColor (bool useForegroundColor,
                                const QColor& color) = 0;
 
+  virtual void setScrollBufferSize(int value=1000) = 0;
+
 signals:
 
   void report_status_message (const QString&);
@@ -93,6 +95,8 @@
 
   virtual void pasteClipboard (void) = 0;
 
+  virtual void selectAll (void) = 0;
+
   virtual void handleCustomContextMenuRequested (const QPoint& at)
   {
     QClipboard * cb = QApplication::clipboard ();
@@ -106,6 +110,8 @@
 
   void notice_settings (const QSettings *settings);
 
+  virtual void init_terminal_size (void) { }
+
   void terminal_interrupt (void) { emit interrupt_signal (); }
 
 protected:
@@ -126,6 +132,12 @@
 
     _contextMenu->addSeparator ();
 
+    _selectall_action = _contextMenu->addAction (
+                      tr ("Select All"), this, SLOT (selectAll ()));
+
+
+    _contextMenu->addSeparator ();
+
     _contextMenu->addAction (tr ("Clear All"), parent (),
                              SLOT (handle_clear_command_window_request ()));
 
@@ -138,11 +150,17 @@
     connect (xparent, SIGNAL (settings_changed (const QSettings *)),
              this, SLOT (notice_settings (const QSettings *)));
 
+    connect (xparent, SIGNAL (init_terminal_size_signal ()),
+             this, SLOT (init_terminal_size ()));
+
     connect (xparent, SIGNAL (copyClipboard_signal ()),
              this, SLOT (copyClipboard ()));
 
     connect (xparent, SIGNAL (pasteClipboard_signal ()),
              this, SLOT (pasteClipboard ()));
+
+    connect (xparent, SIGNAL (selectAll_signal ()),
+             this, SLOT (selectAll ()));
   }
 
 private:
@@ -150,6 +168,7 @@
   QMenu *_contextMenu;
   QAction * _copy_action;
   QAction * _paste_action;
+  QAction * _selectall_action;
 };
 
 #endif // QTERMINAL_H
--- a/libgui/qterminal/libqterminal/unix/QUnixTerminalImpl.cpp	Fri Feb 06 08:31:09 2015 -0800
+++ b/libgui/qterminal/libqterminal/unix/QUnixTerminalImpl.cpp	Fri Feb 06 08:31:49 2015 -0800
@@ -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
@@ -69,13 +69,23 @@
     m_terminalModel = new TerminalModel(m_kpty);
     m_terminalModel->setAutoClose(true);
     m_terminalModel->setCodec(QTextCodec::codecForName("UTF-8"));
-    m_terminalModel->setHistoryType(HistoryTypeBuffer(1000));
+    m_terminalModel->setHistoryType(HistoryTypeBuffer (1000));
     m_terminalModel->setDarkBackground(true);
     m_terminalModel->setKeyBindings("");
     m_terminalModel->run();
     m_terminalModel->addView(m_terminalView);
     connectToPty();
 }
+void QUnixTerminalImpl::setScrollBufferSize(int value)
+{
+  if (value > 0)
+    {
+      m_terminalModel->clearHistory ();
+      m_terminalModel->setHistoryType (HistoryTypeBuffer ( value ));
+    }
+  else
+    m_terminalModel->setHistoryType (HistoryTypeNone ());
+}
 
 void QUnixTerminalImpl::connectToPty()
 {
@@ -205,6 +215,12 @@
     m_terminalView->pasteClipboard();
 }
 
+void QUnixTerminalImpl::selectAll()
+{
+    m_terminalView->selectAll();
+}
+
+
 QString QUnixTerminalImpl::selectedText ()
 {
   return m_terminalView->selectedText ();
--- a/libgui/qterminal/libqterminal/unix/QUnixTerminalImpl.h	Fri Feb 06 08:31:09 2015 -0800
+++ b/libgui/qterminal/libqterminal/unix/QUnixTerminalImpl.h	Fri Feb 06 08:31:49 2015 -0800
@@ -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
@@ -47,12 +47,13 @@
     void setForegroundColor (const QColor& color);
     void setSelectionColor (const QColor& color);
     void setCursorColor (bool useForegroundColor, const QColor& color);
-
+    void setScrollBufferSize(int value);
     QString selectedText();
 
 public slots:
     void copyClipboard();
     void pasteClipboard();
+    void selectAll();
 
 protected:
     void showEvent(QShowEvent *);
--- a/libgui/qterminal/libqterminal/unix/Screen.cpp	Fri Feb 06 08:31:09 2015 -0800
+++ b/libgui/qterminal/libqterminal/unix/Screen.cpp	Fri Feb 06 08:31:49 2015 -0800
@@ -110,7 +110,7 @@
 
 // Cursor Setting --------------------------------------------------------------
 
-/*! \section Cursor
+/*! @section Cursor
 
     The `cursor' is a location within the screen that is implicitely used in
     many operations. The operations within this section allow to manipulate
@@ -502,7 +502,7 @@
 /*!
     returns the image.
 
-    Get the size of the image by \sa getLines and \sa getColumns.
+    Get the size of the image by @sa getLines and @sa getColumns.
 
     NOTE that the image returned by this function must later be
     freed.
@@ -861,7 +861,7 @@
 
 /*! scroll up `n' lines within current region.
     The `n' new lines are cleared.
-    \sa setRegion \sa scrollDown
+    @sa setRegion @sa scrollDown
 */
 
 QRect Screen::lastScrolledRegion() const
@@ -889,7 +889,7 @@
 
 /*! scroll down `n' lines within current region.
     The `n' new lines are cleared.
-    \sa setRegion \sa scrollUp
+    @sa setRegion @sa scrollUp
 */
 
 void Screen::scrollDown(int from, int n)
@@ -949,7 +949,7 @@
 
 // Erasing ---------------------------------------------------------------------
 
-/*! \section Erasing
+/*! @section Erasing
 
     This group of operations erase parts of the screen contents by filling
     it with spaces colored due to the current rendition settings.
--- a/libgui/qterminal/libqterminal/unix/Screen.h	Fri Feb 06 08:31:09 2015 -0800
+++ b/libgui/qterminal/libqterminal/unix/Screen.h	Fri Feb 06 08:31:49 2015 -0800
@@ -50,7 +50,7 @@
 class TerminalCharacterDecoder;
 
 /**
-    \brief An image of characters with associated attributes.
+    @brief An image of characters with associated attributes.
 
     The terminal emulation ( Emulation ) receives a serial stream of
     characters from the program currently running in the terminal.
--- a/libgui/qterminal/libqterminal/unix/SelfListener.cpp	Fri Feb 06 08:31:09 2015 -0800
+++ b/libgui/qterminal/libqterminal/unix/SelfListener.cpp	Fri Feb 06 08:31:49 2015 -0800
@@ -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 Feb 06 08:31:09 2015 -0800
+++ b/libgui/qterminal/libqterminal/unix/SelfListener.h	Fri Feb 06 08:31:49 2015 -0800
@@ -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 Feb 06 08:31:09 2015 -0800
+++ b/libgui/qterminal/libqterminal/unix/TerminalModel.cpp	Fri Feb 06 08:31:49 2015 -0800
@@ -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 Feb 06 08:31:09 2015 -0800
+++ b/libgui/qterminal/libqterminal/unix/TerminalModel.h	Fri Feb 06 08:31:49 2015 -0800
@@ -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 Feb 06 08:31:09 2015 -0800
+++ b/libgui/qterminal/libqterminal/unix/TerminalView.cpp	Fri Feb 06 08:31:49 2015 -0800
@@ -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
@@ -2293,6 +2293,20 @@
     }
 }
 
+void TerminalView::selectAll()
+{
+  if ( !_screenWindow || !hasFocus())
+    return;
+
+  _screenWindow->setSelectionStart(0,-_screenWindow->currentLine(), false);
+  //_screenWindow->setSelectionEnd(_screenWindow->windowColumns(),
+  //                               _screenWindow->windowLines());
+
+  _screenWindow->setSelectionEnd(_screenWindow->columnCount(),
+                                 _screenWindow->windowLines());
+}
+
+
 void TerminalView::pasteSelection()
 {
   emitSelection(true,false);
@@ -2612,6 +2626,17 @@
   //  KUrl::List urls = KUrl::List::fromMimeData(event->mimeData());
 
   QString dropText;
+
+  if (event->mimeData ()->hasUrls ())
+  {
+    foreach (QUrl url, event->mimeData ()->urls ())
+    {
+      if(dropText.length () > 0)
+        dropText += "\n";
+      dropText  += url.toLocalFile ();
+    }
+  }
+
   /*  if (!urls.isEmpty())
   {
     for ( int i = 0 ; i < urls.count() ; i++ )
--- a/libgui/qterminal/libqterminal/unix/TerminalView.h	Fri Feb 06 08:31:09 2015 -0800
+++ b/libgui/qterminal/libqterminal/unix/TerminalView.h	Fri Feb 06 08:31:49 2015 -0800
@@ -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
@@ -416,6 +416,11 @@
      */
     void pasteSelection();
 
+    /**
+     * selects all content
+     */
+    void selectAll();
+
 	 /**
 	 * Causes the widget to display or hide a message informing the user that terminal
 	 * output has been suspended (by using the flow control key combination Ctrl+S)
--- a/libgui/qterminal/libqterminal/unix/Vt102Emulation.cpp	Fri Feb 06 08:31:09 2015 -0800
+++ b/libgui/qterminal/libqterminal/unix/Vt102Emulation.cpp	Fri Feb 06 08:31:49 2015 -0800
@@ -1221,10 +1221,10 @@
 
 /*! shows the contents of the scan buffer.
 
-    This functions is used for diagnostics. It is called by \e ReportErrorToken
+    This functions is used for diagnostics. It is called by @e ReportErrorToken
     to inform about strings that cannot be decoded or handled by the emulation.
 
-    \sa ReportErrorToken
+    @sa ReportErrorToken
 */
 
 static void hexdump(int* s, int len)
--- a/libgui/qterminal/libqterminal/win32/QWinTerminalImpl.cpp	Fri Feb 06 08:31:09 2015 -0800
+++ b/libgui/qterminal/libqterminal/win32/QWinTerminalImpl.cpp	Fri Feb 06 08:31:49 2015 -0800
@@ -1,3 +1,4 @@
+
 /*
 
 Copyright (C) 2011, 2013 Michael Goffioul.
@@ -24,7 +25,7 @@
 #include <QClipboard>
 #include <QColor>
 #include <QFont>
-#include <QHBoxLayout>
+#include <QGridLayout>
 #include <QPaintEvent>
 #include <QPainter>
 #include <QResizeEvent>
@@ -35,6 +36,9 @@
 #include <QToolTip>
 #include <QCursor>
 #include <QMessageBox>
+#include <QDragEnterEvent>
+#include <QDropEvent>
+#include <QUrl>
 
 #include <fcntl.h>
 #include <io.h>
@@ -173,16 +177,21 @@
   QConsolePrivate (QWinTerminalImpl* parent, const QString& cmd = QString ());
   ~QConsolePrivate (void);
 
-  void updateConsoleSize (bool sync = false);
+  void updateConsoleSize (bool sync = false, bool allow_smaller_width = false);
   void syncConsoleParameters (void);
   void grabConsoleBuffer (CHAR_INFO* buf = 0);
-  void updateScrollBar (void);
-  void setScrollValue (int value);
+  void updateHorizontalScrollBar (void);
+  void updateVerticalScrollBar (void);
+  void setHorizontalScrollValue (int value);
+  void setVerticalScrollValue (int value);
   void updateConsoleView (bool grab = true);
   void monitorConsole (void);
   void startCommand (void);
   void sendConsoleText (const QString& s);
   QRect cursorRect (void);
+  void selectAll();
+  void selectWord(const QPoint& cellPos);
+  void selectLine(const QPoint& cellPos);
 
   void log (const char* fmt, ...);
 
@@ -204,6 +213,7 @@
   void setForegroundColor (const QColor& color);
   void setSelectionColor (const QColor& color);
   void setCursorColor (bool useForegroundColor, const QColor& color);
+  void setScrollBufferSize (int value);
 
   void drawTextBackground (QPainter& p, int cx1, int cy1, int cx2, int cy2,
                            int cw, int ch);
@@ -249,7 +259,8 @@
   HANDLE m_process;
 
   QConsoleView* m_consoleView;
-  QScrollBar* m_scrollBar;
+  QScrollBar* m_horizontalScrollBar;
+  QScrollBar* m_verticalScrollBar;
   QTimer* m_consoleWatcher;
   QConsoleThread *m_consoleThread;
 
@@ -362,13 +373,15 @@
   m_buffer = m_tmpBuffer = 0;
 
   m_consoleView = new QConsoleView (parent);
-  m_scrollBar = new QScrollBar (Qt::Vertical, parent);
+  m_horizontalScrollBar = new QScrollBar (Qt::Horizontal, parent);
+  m_verticalScrollBar = new QScrollBar (Qt::Vertical, parent);
 
-  QHBoxLayout* l = new QHBoxLayout (parent);
+  QGridLayout* l = new QGridLayout (parent);
   l->setContentsMargins (0, 0, 0, 0);
   l->setSpacing (0);
-  l->addWidget (m_consoleView, 1);
-  l->addWidget (m_scrollBar, 0);
+  l->addWidget (m_consoleView, 0, 0);
+  l->addWidget (m_horizontalScrollBar, 1, 0);
+  l->addWidget (m_verticalScrollBar, 0, 1);
 
   // Choose 15 (0xF) as index into the Windows console color map for the
   // background and 0 (0x0) as the index for the foreground.  This
@@ -394,7 +407,8 @@
   parent->setFocusPolicy (Qt::StrongFocus);
   parent->winId ();
 
-  updateScrollBar ();
+  updateHorizontalScrollBar ();
+  updateVerticalScrollBar ();
 
   m_consoleWatcher = new QTimer (parent);
   m_consoleWatcher->setInterval (10);
@@ -404,8 +418,12 @@
   QObject::connect (m_blinkCursorTimer, SIGNAL (timeout()),
                     q, SLOT (blinkCursorEvent ()));
 
-  QObject::connect (m_scrollBar, SIGNAL (valueChanged (int)),
-                    q, SLOT (scrollValueChanged (int)));
+  QObject::connect (m_horizontalScrollBar, SIGNAL (valueChanged (int)),
+                    q, SLOT (horizontalScrollValueChanged (int)));
+
+  QObject::connect (m_verticalScrollBar, SIGNAL (valueChanged (int)),
+                    q, SLOT (verticalScrollValueChanged (int)));
+
   QObject::connect (m_consoleWatcher, SIGNAL (timeout (void)),
                     q, SLOT (monitorConsole (void)));
 
@@ -575,6 +593,9 @@
 void QConsolePrivate::setBackgroundColor (const QColor& color)
 {
   m_colors[15] = color;
+
+  QPalette palette (color);
+  m_consoleView->setPalette (palette);
 }
 
 void QConsolePrivate::setForegroundColor (const QColor& color)
@@ -593,6 +614,16 @@
   m_cursorColor = useForegroundColor ? QColor () : color;
 }
 
+void QConsolePrivate::setScrollBufferSize (int value)
+{
+  CONSOLE_SCREEN_BUFFER_INFO sbi;
+  GetConsoleScreenBufferInfo (m_stdOut, &sbi);
+
+  m_bufferSize = QSize (sbi.dwSize.X, (SHORT)value);
+
+  updateConsoleSize (true);
+}
+
 void QConsolePrivate::drawTextBackground (QPainter& p, int cx1, int cy1,
                                           int cx2, int cy2, int cw, int ch)
 {
@@ -654,6 +685,83 @@
   p.restore ();
 }
 
+void QConsolePrivate::selectAll()
+{
+  m_beginSelection = QPoint (0,0);
+  m_endSelection = QPoint(m_bufferSize.width (),
+                          m_cursorPos.y());
+  updateSelection();
+}
+
+void QConsolePrivate::selectWord (const QPoint & cellpos)
+{
+  QPoint begin = cellpos;
+  QPoint end = cellpos;
+
+  int stride = m_consoleRect.width ();
+
+  int verticalScrollOffset = m_consoleRect.top ();
+  int horizontalScrollOffset = m_consoleRect.left ();
+
+  // get begin, end in buffer offsets
+  begin.ry () -= verticalScrollOffset;
+  end.ry () -= verticalScrollOffset;
+
+  begin.rx () -= horizontalScrollOffset;
+  end.rx () -= horizontalScrollOffset;
+
+  // loog at current clicked on char to determinate ig getting space chunk or nonspace chunk
+  if (QChar(m_buffer[begin.y ()*stride + begin.x ()].Char.UnicodeChar).isSpace () == false)
+  {
+    // from current char, go back and fwd to find start and end of block
+    while(begin.x () > 0 &&
+          QChar(m_buffer[begin.y ()*stride + begin.x () -1].Char.UnicodeChar).isSpace() == false)
+    {
+        begin.rx () --;
+    }
+
+    while(end.x () < m_consoleRect.width () &&
+          QChar(m_buffer[end.y ()*stride + end.x () +1].Char.UnicodeChar).isSpace() == false)
+    {
+      end.rx () ++;
+    }
+  }
+  else
+  {
+    while(begin.x () > 0 &&
+          QChar(m_buffer[begin.y ()*stride + begin.x () -1].Char.UnicodeChar).isSpace())
+    {
+      begin.rx () --;
+    }
+
+    while(end.x () < m_consoleRect.width () &&
+          QChar(m_buffer[end.y ()*stride + end.x () +1].Char.UnicodeChar).isSpace ())
+    {
+      end.rx () ++;
+    }
+  }
+
+  // convert console  offsets to absolute cell positions
+  begin.ry () += verticalScrollOffset;
+  end.ry () += verticalScrollOffset;
+
+  begin.rx () += horizontalScrollOffset;
+  end.rx () += horizontalScrollOffset;
+
+  m_beginSelection = begin;
+  m_endSelection = end;
+
+  updateSelection ();
+}
+
+void QConsolePrivate::selectLine (const QPoint & cellpos)
+{
+  m_beginSelection = QPoint (0, cellpos.y ());
+  m_endSelection = QPoint (m_bufferSize.width ()-1, cellpos.y ());
+  updateSelection ();
+}
+
+
 void QConsolePrivate::drawSelection (QPainter& p, int cx1, int cy1,
                                      int cx2, int cy2, int cw, int ch)
 {
@@ -667,10 +775,14 @@
   if (haveSelection)
     maybeSwapPoints (begin, end);
 
-  int scrollOffset = m_consoleRect.top ();
+  int verticalScrollOffset = m_consoleRect.top ();
+  int horizontalScrollOffset = m_consoleRect.left ();
 
-  begin.ry () -= scrollOffset;
-  end.ry () -= scrollOffset;
+  begin.ry () -= verticalScrollOffset;
+  end.ry () -= verticalScrollOffset;
+
+  begin.rx () -= horizontalScrollOffset;
+  end.rx () -= horizontalScrollOffset;
 
   int ascent = p.fontMetrics ().ascent ();
   int stride = m_consoleRect.width ();
@@ -871,7 +983,7 @@
 
 //////////////////////////////////////////////////////////////////////////////
 
-void QConsolePrivate::updateConsoleSize (bool sync)
+void QConsolePrivate::updateConsoleSize (bool sync, bool allow_smaller_width)
 {
   QFontMetrics fm (m_font);
   QSize winSize = m_consoleView->size ();
@@ -882,9 +994,30 @@
   m_consoleRect.setWidth (winSize.width () / fm.averageCharWidth ());
   m_consoleRect.setHeight (winSize.height () / fm.lineSpacing ());
 
-  m_bufferSize.rwidth () = m_consoleRect.width ();
-  m_bufferSize.rheight () = qMax (m_bufferSize.height (),
-                                  m_consoleRect.height ());
+  // Don't shrink the size of the buffer.  That way wide lines won't be
+  // truncated and will reappear if the window is enlarged again later.
+
+  if (allow_smaller_width || m_consoleRect.width () > m_bufferSize.width ())
+    m_bufferSize.rwidth () = m_consoleRect.width ();
+
+  if (qMax (m_bufferSize.height (), m_consoleRect.height ())
+      > m_bufferSize.height ())
+    m_bufferSize.rheight () = qMax (m_bufferSize.height (),
+                                    m_consoleRect.height ());
+
+  // Store the terminal size in the environment.  When Octave is
+  // initialized, we ask the command editor (usually readline) to prefer
+  // using these values rather than querying the terminal so that the
+  // buffer size can be larger than the size of the window that the
+  // command editor will actually use.
+
+  qputenv ("LINES", QByteArray::number (m_consoleRect.height ()));
+  qputenv ("COLUMNS", QByteArray::number (m_consoleRect.width ()));
+
+  // Force the command line editor (usually readline) to notice the
+  // change in screen size as soon as possible.
+
+  q->setSize (m_consoleRect.height (), m_consoleRect.width ());
 
   m_consoleRect.moveLeft (0);
   if (m_consoleRect.bottom () >= m_bufferSize.height ())
@@ -902,7 +1035,8 @@
   if (sync)
     syncConsoleParameters ();
 
-  updateScrollBar ();
+  updateHorizontalScrollBar ();
+  updateVerticalScrollBar ();
 }
 
 //////////////////////////////////////////////////////////////////////////////
@@ -989,25 +1123,70 @@
 
 //////////////////////////////////////////////////////////////////////////////
 
-void QConsolePrivate::updateScrollBar (void)
+void QConsolePrivate::updateHorizontalScrollBar (void)
 {
-  m_scrollBar->setMinimum (0);
-  if (m_bufferSize.height () > m_consoleRect.height ())
-    m_scrollBar->setMaximum (m_bufferSize.height () - m_consoleRect.height ());
+  m_horizontalScrollBar->setMinimum (0);
+  if (m_bufferSize.width () > m_consoleRect.width ())
+    m_horizontalScrollBar->setMaximum (m_bufferSize.width () - m_consoleRect.width ());
   else
-    m_scrollBar->setMaximum (0);
-  m_scrollBar->setSingleStep (1);
-  m_scrollBar->setPageStep (m_consoleRect.height ());
-  m_scrollBar->setValue (m_consoleRect.top ());
+    m_horizontalScrollBar->setMaximum (0);
+  m_horizontalScrollBar->setSingleStep (1);
+  m_horizontalScrollBar->setPageStep (m_consoleRect.width ());
+  m_horizontalScrollBar->setValue (m_consoleRect.left ());
+
+  log ("Horizontal scrollbar parameters updated: %d/%d/%d/%d\n",
+       m_horizontalScrollBar->minimum (),
+       m_horizontalScrollBar->maximum (),
+       m_horizontalScrollBar->singleStep (),
+       m_horizontalScrollBar->pageStep ());
+}
 
-  log ("Scrollbar parameters updated: %d/%d/%d/%d\n",
-       m_scrollBar->minimum (), m_scrollBar->maximum (),
-       m_scrollBar->singleStep (), m_scrollBar->pageStep ());
+void QConsolePrivate::updateVerticalScrollBar (void)
+{
+  m_verticalScrollBar->setMinimum (0);
+  if (m_bufferSize.height () > m_consoleRect.height ())
+    m_verticalScrollBar->setMaximum (m_bufferSize.height () - m_consoleRect.height ());
+  else
+    m_verticalScrollBar->setMaximum (0);
+  m_verticalScrollBar->setSingleStep (1);
+  m_verticalScrollBar->setPageStep (m_consoleRect.height ());
+  m_verticalScrollBar->setValue (m_consoleRect.top ());
+
+  log ("Vertical scrollbar parameters updated: %d/%d/%d/%d\n",
+       m_verticalScrollBar->minimum (), m_verticalScrollBar->maximum (),
+       m_verticalScrollBar->singleStep (), m_verticalScrollBar->pageStep ());
 }
 
 //////////////////////////////////////////////////////////////////////////////
 
-void QConsolePrivate::setScrollValue (int value)
+void QConsolePrivate::setHorizontalScrollValue (int value)
+{
+  if (value == m_consoleRect.left ())
+    return;
+
+  SMALL_RECT r;
+  HANDLE hStdOut = m_stdOut;
+
+  if (value + m_consoleRect.width () > m_bufferSize.width ())
+    value = m_bufferSize.width () - m_consoleRect.width ();
+
+  r.Left = value;
+  r.Top = m_consoleRect.top ();
+  r.Right = value + m_consoleRect.width () - 1;
+  r.Bottom = m_consoleRect.bottom ();
+
+  log ("Scrolling window horizontally: (%d, %d) -> (%d, %d) [%d x %d]\n",
+       r.Left, r.Top, r.Right, r.Bottom,
+       r.Right - r.Left + 1, r.Bottom - r.Top + 1);
+
+  if (SetConsoleWindowInfo (hStdOut, TRUE, &r))
+    {
+      m_consoleRect.moveLeft (value);
+      updateConsoleView ();
+    }
+}
+
+void QConsolePrivate::setVerticalScrollValue (int value)
 {
   if (value == m_consoleRect.top ())
     return;
@@ -1023,7 +1202,7 @@
   r.Right = m_consoleRect.right ();
   r.Bottom = value + m_consoleRect.height () - 1;
 
-  log ("Scrolling window: (%d, %d) -> (%d, %d) [%d x %d]\n",
+  log ("Scrolling window vertically: (%d, %d) -> (%d, %d) [%d x %d]\n",
        r.Left, r.Top, r.Right, r.Bottom,
        r.Right - r.Left + 1, r.Bottom - r.Top + 1);
 
@@ -1070,7 +1249,8 @@
           // Buffer size changed
           m_bufferSize.rwidth () = sbi.dwSize.X;
           m_bufferSize.rheight () = sbi.dwSize.Y;
-          updateScrollBar ();
+          updateHorizontalScrollBar ();
+          updateVerticalScrollBar ();
         }
 
       if (m_cursorPos.x () != sbi.dwCursorPosition.X
@@ -1098,7 +1278,8 @@
           m_consoleRect = QRect (sbi.srWindow.Left, sbi.srWindow.Top,
                                  sbi.srWindow.Right - sbi.srWindow.Left + 1,
                                  sbi.srWindow.Bottom - sbi.srWindow.Top + 1);
-          updateScrollBar ();
+          updateHorizontalScrollBar ();
+          updateVerticalScrollBar ();
           updateConsoleView ();
           return;
         }
@@ -1238,12 +1419,18 @@
 //////////////////////////////////////////////////////////////////////////////
 
 QWinTerminalImpl::QWinTerminalImpl (QWidget* parent)
-    : QTerminal (parent), d (new QConsolePrivate (this))
+    : QTerminal (parent), d (new QConsolePrivate (this)),
+      allowTripleClick (false)
 {
     installEventFilter (this);
 
     connect (this, SIGNAL (set_global_shortcuts_signal (bool)),
            parent, SLOT (set_global_shortcuts (bool)));
+
+    connect (this, SIGNAL (set_screen_size_signal (int, int)),
+             parent, SLOT (set_screen_size (int, int)));
+
+    setAcceptDrops (true);
 }
 
 //////////////////////////////////////////////////////////////////////////////
@@ -1272,7 +1459,11 @@
 
 void QWinTerminalImpl::mousePressEvent (QMouseEvent *event)
 {
-  if (event->button () == Qt::LeftButton)
+  if (allowTripleClick)
+    {
+      mouseTripleClickEvent (event);
+    }
+  else if (event->button () == Qt::LeftButton)
     {
       d->m_settingSelection = true;
 
@@ -1282,7 +1473,7 @@
 
 void QWinTerminalImpl::mouseReleaseEvent (QMouseEvent *event)
 {
-  if (event->button () == Qt::LeftButton)
+  if (event->button () == Qt::LeftButton && d->m_settingSelection)
     {
       d->m_endSelection = d->posToCell (event->pos ());
 
@@ -1292,6 +1483,36 @@
     }
 }
 
+void QWinTerminalImpl::mouseDoubleClickEvent (QMouseEvent *event)
+{
+  if (event->button () == Qt::LeftButton)
+    {
+      // doubleclick - select word
+      d->m_settingSelection = false;
+
+      d->selectWord (d->posToCell (event->pos ()));
+
+      allowTripleClick = true;
+
+      QTimer::singleShot (QApplication::doubleClickInterval (),this,
+                     SLOT (tripleClickTimeout ()));
+
+    }
+}
+
+void QWinTerminalImpl::mouseTripleClickEvent (QMouseEvent *event)
+{
+  if (event->button () == Qt::LeftButton)
+    {
+      d->selectLine (d->posToCell (event->pos ()));
+    }
+}
+
+void QWinTerminalImpl::tripleClickTimeout ()
+{
+  allowTripleClick = false;
+}
+
 //////////////////////////////////////////////////////////////////////////////
 
 void QWinTerminalImpl::viewResizeEvent (QConsoleView*, QResizeEvent*)
@@ -1357,6 +1578,13 @@
     }
 }
 
+// Reset width of console buffer and terminal window to be the same.
+
+void QWinTerminalImpl::init_terminal_size (void)
+{
+  d->updateConsoleSize (true, true);
+}
+
 //////////////////////////////////////////////////////////////////////////////
 
 void QWinTerminalImpl::wheelEvent (QWheelEvent* event)
@@ -1365,16 +1593,21 @@
     {
       // Forward to the scrollbar (avoid recursion)
       d->m_inWheelEvent = true;
-      QApplication::sendEvent (d->m_scrollBar, event);
+      QApplication::sendEvent (d->m_verticalScrollBar, event);
       d->m_inWheelEvent = false;
     }
 }
 
 //////////////////////////////////////////////////////////////////////////////
 
-void QWinTerminalImpl::scrollValueChanged (int value)
+void QWinTerminalImpl::horizontalScrollValueChanged (int value)
 {
-  d->setScrollValue (value);
+  d->setHorizontalScrollValue (value);
+}
+
+void QWinTerminalImpl::verticalScrollValueChanged (int value)
+{
+  d->setVerticalScrollValue (value);
 }
 
 //////////////////////////////////////////////////////////////////////////////
@@ -1500,6 +1733,12 @@
   d->setCursorColor (useForegroundColor, color);
 }
 
+void QWinTerminalImpl::setScrollBufferSize(int value)
+{
+  d->setScrollBufferSize (value);
+}
+
+
 //////////////////////////////////////////////////////////////////////////////
 
 void QWinTerminalImpl::setTerminalFont (const QFont& f)
@@ -1513,8 +1752,9 @@
 
 void QWinTerminalImpl::setSize (int columns, int lines)
 {
-  Q_UNUSED (columns);
-  Q_UNUSED (lines);
+  d->log ("emit set_screen_size_signal (%d, %d)\n", columns, lines);
+
+  emit set_screen_size_signal (columns, lines);
 }
 
 //////////////////////////////////////////////////////////////////////////////
@@ -1549,6 +1789,16 @@
     sendText (text);
 }
 
+//////////////////////////////////////////////////////////////////////////////
+
+void QWinTerminalImpl::selectAll (void)
+{
+  if(!hasFocus()) return;
+
+  d->selectAll();
+}
+
+
 
 //////////////////////////////////////////////////////////////////////////////
 
@@ -1557,3 +1807,31 @@
   QString selection = d->getSelection ();
   return selection;
 }
+
+//////////////////////////////////////////////////////////////////////////////
+
+void QWinTerminalImpl::dragEnterEvent (QDragEnterEvent *event)
+{
+   if (event->mimeData ()->hasUrls ())
+     {
+       event->acceptProposedAction();
+     }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+void QWinTerminalImpl::dropEvent (QDropEvent *event)
+{
+  QString dropText;
+
+  if (event->mimeData ()->hasUrls ())
+    {
+      foreach (QUrl url, event->mimeData ()->urls ())
+        {
+          if(dropText.length () > 0)
+            dropText += "\n";
+          dropText  += url.toLocalFile ();
+        }
+      sendText (dropText);
+    }
+}
--- a/libgui/qterminal/libqterminal/win32/QWinTerminalImpl.h	Fri Feb 06 08:31:09 2015 -0800
+++ b/libgui/qterminal/libqterminal/win32/QWinTerminalImpl.h	Fri Feb 06 08:31:49 2015 -0800
@@ -32,6 +32,8 @@
 class QResizeEvent;
 class QWheelEvent;
 class QPoint;
+class QDragEnterEvent;
+class QDropEvent;
 
 class QConsolePrivate;
 class QConsoleThread;
@@ -60,18 +62,22 @@
   void setForegroundColor (const QColor& color);
   void setSelectionColor (const QColor& color);
   void setCursorColor (bool useForegoundColor, const QColor& color);
+  void setScrollBufferSize(int value);
 
   QString selectedText ();
 
 public slots:
   void copyClipboard (void);
   void pasteClipboard (void);
+  void selectAll (void);
   void blinkCursorEvent (void);
+  void init_terminal_size (void);
 
 signals:
   void terminated (void);
   void titleChanged (const QString&);
   void set_global_shortcuts_signal (bool);
+  void set_screen_size_signal (int, int);
 
 protected:
   void viewPaintEvent (QConsoleView*, QPaintEvent*);
@@ -86,16 +92,24 @@
   void mouseMoveEvent (QMouseEvent *event);
   void mousePressEvent (QMouseEvent *event);
   void mouseReleaseEvent (QMouseEvent *event);
+  void mouseDoubleClickEvent (QMouseEvent* event);
+  void mouseTripleClickEvent (QMouseEvent* event);
 
   bool eventFilter(QObject *obj, QEvent *ev);
 
+  void dragEnterEvent(QDragEnterEvent *event);
+  void dropEvent(QDropEvent *event);
+
 private slots:
-  void scrollValueChanged (int value);
+  void horizontalScrollValueChanged (int value);
+  void verticalScrollValueChanged (int value);
   void monitorConsole (void);
   void updateSelection (void);
+  void tripleClickTimeout (void);
 
 private:
   QConsolePrivate* d;
+  bool allowTripleClick;
 };
 
 //////////////////////////////////////////////////////////////////////////////
--- a/libgui/src/dialog.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/libgui/src/dialog.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -466,18 +466,18 @@
            &uiwidget_creator,
            SLOT (filedialog_finished (const QStringList&, const QString&,
                                       int)));
+  connect (this, SIGNAL (accepted ()), this, SLOT (acceptSelection ()));
+  connect (this, SIGNAL (rejected ()), this, SLOT (rejectSelection ()));
 }
 
 void
-FileDialog::reject (void)
+FileDialog::rejectSelection(void)
 {
   QStringList empty;
   emit finish_input (empty, "", 0);
-  done (QDialog::Rejected);
-
 }
 
-void FileDialog::accept (void)
+void FileDialog::acceptSelection (void)
 {
   QStringList string_result;
   QString path;
@@ -485,20 +485,33 @@
 
   string_result = selectedFiles ();
 
+  if (testOption (QFileDialog::ShowDirsOnly)  == true &&
+      string_result.size () > 0)
+    {
+      path = string_result[0];
+    }
+  else
+    {
+      path = directory ().absolutePath ();
+    }
+
   // Matlab expects just the file name, whereas the file dialog gave us
-  // pull path names, so fix it.
+  // full path names, so fix it.
 
   for (int i = 0; i < string_result.size (); i++)
     string_result[i] = QFileInfo (string_result[i]).fileName ();
 
+  // if not showing only dirs, add end slash for the path component
+  if (testOption (QFileDialog::ShowDirsOnly)  == false)
+    path = path + "/";
 
-  path = directory ().absolutePath ();
+  // convert to native slashes
+  path = QDir::toNativeSeparators (path);
 
   QStringList name_filters = nameFilters ();
   idx = name_filters.indexOf (selectedNameFilter ()) + 1;
 
   // send the selected info
   emit finish_input (string_result, path, idx);
-  done (QDialog::Accepted);
 }
 
--- a/libgui/src/dialog.h	Fri Feb 06 08:31:09 2015 -0800
+++ b/libgui/src/dialog.h	Fri Feb 06 08:31:49 2015 -0800
@@ -261,9 +261,9 @@
 
 private slots:
 
-  void reject (void);
+  void rejectSelection (void);
 
-  void accept (void);
+  void acceptSelection (void);
 };
 
 #endif
--- a/libgui/src/documentation-dock-widget.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/libgui/src/documentation-dock-widget.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -52,12 +52,17 @@
   _webinfo->pasteClipboard ();
 }
 void
+documentation_dock_widget::selectAll ()
+{
+  _webinfo->selectAll ();
+}
+
+void
 documentation_dock_widget::showDoc (const QString &name)
 {
-  // show the doc pane
+  // show the doc pane without focus for carrying on typing in the console
   if (!isVisible ())
     setVisible (true);
-  setFocus ();
   raise ();
 
   _webinfo->load_ref (name);
--- a/libgui/src/documentation-dock-widget.h	Fri Feb 06 08:31:09 2015 -0800
+++ b/libgui/src/documentation-dock-widget.h	Fri Feb 06 08:31:49 2015 -0800
@@ -38,6 +38,7 @@
 protected slots:
   void copyClipboard ();
   void pasteClipboard ();
+  void selectAll ();
 
   void showDoc (const QString & name);
 private:
--- a/libgui/src/files-dock-widget.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/libgui/src/files-dock-widget.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -127,7 +127,7 @@
 
   popdown_menu->addSeparator ();
   popdown_menu->addAction (QIcon (":/actions/icons/folder.png"),
-                           tr ("Search Directory..."),
+                           tr ("Set Browser Directory..."),
                            this, SLOT (popdownmenu_search_dir (bool)));
   popdown_menu->addSeparator ();
   popdown_menu->addAction (QIcon (":/actions/icons/findf.png"),
@@ -155,8 +155,29 @@
   QSettings *settings = resource_manager::get_settings ();
   // FIXME: what should happen if settings is 0?
 
-  // Create the QFileSystemModel starting in the actual directory
-  QDir curr_dir;
+  // Create the QFileSystemModel starting in the desired directory
+  QDir startup_dir;  // take current dir
+
+  if (settings->value ("filesdockwidget/restore_last_dir",false).toBool ())
+    {
+      // restore last dir from previous session
+      QStringList last_dirs
+        = settings->value ("filesdockwidget/mru_dir_list").toStringList ();
+      if (last_dirs.length () > 0)
+        startup_dir = QDir (last_dirs.at (0));  // last dir in previous session
+    }
+  else if (! settings->value ("filesdockwidget/startup_dir").toString ().isEmpty ())
+    {
+      // do not restore but there is a startup dir configured
+      startup_dir = QDir (settings->value ("filesdockwidget/startup_dir").toString ());
+    }
+
+  if (! startup_dir.exists ())
+    {
+      // the configured startup dir does not exist, take actual one
+      startup_dir = QDir ();
+    }
+
   _file_system_model = new QFileSystemModel (this);
   if (settings->value ("filesdockwidget/showHiddenFiles",false).toBool ())
     {
@@ -168,7 +189,7 @@
       _file_system_model->setFilter (QDir::NoDotAndDotDot | QDir::AllEntries);
     }
   QModelIndex rootPathIndex = _file_system_model->setRootPath (
-                                curr_dir.absolutePath ());
+                                startup_dir.absolutePath ());
 
   // Attach the model to the QTreeView and set the root index
   _file_tree_view = new FileTreeViewer (container);
@@ -502,18 +523,18 @@
         }
 
       menu.addSeparator ();
-      menu.addAction (tr ("Rename"), this, SLOT (contextmenu_rename (bool)));
-      menu.addAction (QIcon (":/actions/icons/editdelete.png"), tr ("Delete"),
-                      this, SLOT (contextmenu_delete (bool)));
+      menu.addAction (tr ("Rename..."), this, SLOT (contextmenu_rename (bool)));
+      menu.addAction (QIcon (":/actions/icons/editdelete.png"),
+                      tr ("Delete..."), this, SLOT (contextmenu_delete (bool)));
 
       if (info.isDir ())
         {
           menu.addSeparator ();
           menu.addAction (QIcon (":/actions/icons/filenew.png"),
-                          tr ("New File"),
+                          tr ("New File..."),
                           this, SLOT (contextmenu_newfile (bool)));
           menu.addAction (QIcon (":/actions/icons/folder_new.png"),
-                          tr ("New Directory"),
+                          tr ("New Directory..."),
                           this, SLOT (contextmenu_newdir (bool)));
         }
 
@@ -530,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 ())
@@ -640,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;
 
@@ -836,7 +857,7 @@
 
   QString name = QInputDialog::getText (this, tr ("Create File"),
        tr ("Create file in\n","String ends with \\n!") + parent_dir,
-       QLineEdit::Normal, "New File.txt", &ok);
+       QLineEdit::Normal, tr ("New File.txt"), &ok);
   if (ok && name.length () > 0)
     {
       name = parent_dir + "/" + name;
@@ -854,7 +875,7 @@
 
   QString name = QInputDialog::getText (this, tr ("Create Directory"),
                 tr ("Create folder in\n","String ends with \\n!") + parent_dir,
-                QLineEdit::Normal, "New Directory", &ok);
+                QLineEdit::Normal, tr ("New Directory"), &ok);
   if (ok && name.length () > 0)
     {
       QDir dir (parent_dir);
@@ -903,5 +924,20 @@
     }
 }
 
+void
+files_dock_widget::selectAll ()
+{
+  if (_file_tree_view->hasFocus ())
+    _file_tree_view->selectAll ();
+  if (_current_directory->hasFocus ())
+    {
+      QLineEdit * edit = _current_directory->lineEdit ();
+      if (edit)
+        {
+          edit->selectAll ();
+        }
+    }
+}
 
 
+
--- a/libgui/src/files-dock-widget.h	Fri Feb 06 08:31:09 2015 -0800
+++ b/libgui/src/files-dock-widget.h	Fri Feb 06 08:31:49 2015 -0800
@@ -40,8 +40,8 @@
 #include "octave-dock-widget.h"
 
 /**
-   \class files_dock_widget
-   \brief Dock widget to display files in the current directory.
+   @class files_dock_widget
+   @brief Dock widget to display files in the current directory.
 */
 class files_dock_widget : public octave_dock_widget
 {
@@ -113,6 +113,7 @@
   /* from octave_doc_widget */
   void copyClipboard ();
   void pasteClipboard ();
+  void selectAll ();
 
 signals:
 
--- a/libgui/src/find-files-dialog.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/libgui/src/find-files-dialog.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -61,7 +61,7 @@
 
   QLabel * file_name_label = new QLabel (tr ("Named:"));
   _file_name_edit = new QLineEdit;
-  _file_name_edit->setToolTip (tr ("Enter the filename expression"));
+  _file_name_edit->setToolTip (tr ("Enter the filename search expression"));
 
   _file_name_edit->setText (settings->value ("findfiles/file_name",
                                              "*").toString ());
@@ -79,13 +79,13 @@
   _browse_button->setToolTip (tr ("Browse for start directory"));
   connect (_browse_button, SIGNAL (clicked ()), this, SLOT (browse_folders ()));
 
-  _recurse_dirs_check = new QCheckBox (tr ("Recurse directories"));
+  _recurse_dirs_check = new QCheckBox (tr ("Search subdirectories"));
   _recurse_dirs_check->setChecked (settings->value ("findfiles/recurse_dirs",
                                                     false).toBool ());
   _recurse_dirs_check->setToolTip (
     tr ("Search recursively through directories for matching files"));
 
-  _include_dirs_check = new QCheckBox (tr ("Include directories"));
+  _include_dirs_check = new QCheckBox (tr ("Include directory names"));
   _include_dirs_check->setChecked (settings->value ("findfiles/include_dirs",
                                                     false).toBool ());
   _include_dirs_check->setToolTip (
@@ -97,7 +97,7 @@
   _name_case_check->setToolTip (tr ("Set matching name is case insensitive"));
 
   _contains_text_check = new QCheckBox (tr ("Contains text:"));
-  _contains_text_check->setToolTip (tr ("Search must match text"));
+  _contains_text_check->setToolTip (tr ("Enter the file content search expression"));
   _contains_text_check->setChecked (settings->value ("findfiles/check_text",
                                                       false).toBool ());
 
@@ -304,7 +304,7 @@
   _contains_text_edit->setEnabled (true);
 
   find_files_model *m = static_cast<find_files_model *> (_file_list->model ());
-  QString res_str = QString ("%1 matches").arg (m->rowCount ());
+  QString res_str = QString (tr("%1 match(es)")).arg (m->rowCount ());
 
   _status_bar->showMessage (res_str);
 }
--- a/libgui/src/find-files-model.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/libgui/src/find-files-model.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -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 Feb 06 08:31:09 2015 -0800
+++ b/libgui/src/history-dock-widget.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -29,8 +29,12 @@
 #include <QVBoxLayout>
 #include <QMenu>
 #include <QScrollBar>
+#include <QDesktopWidget>
+#include <QCompleter>
+#include <QLabel>
 
 #include "error.h"
+#include "resource-manager.h"
 
 #include "cmd-hist.h"
 
@@ -71,28 +75,105 @@
            SIGNAL (customContextMenuRequested (const QPoint &)), this,
            SLOT (ctxMenu (const QPoint &)));
 
-  _filter_line_edit = new QLineEdit (this);
-  _filter_line_edit->setStatusTip (
-    tr ("Enter text to filter the command history."));
-  QVBoxLayout *vbox_layout = new QVBoxLayout ();
+  _filter = new QComboBox (this);
+  _filter->setToolTip (tr ("Enter text to filter the command history"));
+  _filter->setEditable (true);
+  _filter->setMaxCount (MaxFilterHistory);
+  _filter->setInsertPolicy (QComboBox::NoInsert);
+  _filter->setSizeAdjustPolicy (
+            QComboBox::AdjustToMinimumContentsLengthWithIcon);
+  QSizePolicy sizePol (QSizePolicy::Expanding, QSizePolicy::Maximum);
+  _filter->setSizePolicy (sizePol);
+  _filter->completer ()->setCaseSensitivity (Qt::CaseSensitive);
+
+  QLabel *filter_label = new QLabel (tr ("Filter"));
+
+  _filter_checkbox = new QCheckBox ();
 
   setWindowIcon (QIcon (":/actions/icons/logo.png"));
   set_title (tr ("Command History"));
   setWidget (new QWidget ());
 
+  QVBoxLayout *vbox_layout = new QVBoxLayout ();
+  QHBoxLayout *hbox_layout = new QHBoxLayout ();
+  hbox_layout->addWidget (filter_label);
+  hbox_layout->addWidget (_filter_checkbox);
+  hbox_layout->addWidget (_filter);
+  vbox_layout->addLayout (hbox_layout);
   vbox_layout->addWidget (_history_list_view);
-  vbox_layout->addWidget (_filter_line_edit);
   vbox_layout->setMargin (2);
 
   widget ()->setLayout (vbox_layout);
 
-  connect (_filter_line_edit, SIGNAL (textEdited (QString)),
-           &_sort_filter_proxy_model, SLOT (setFilterWildcard (QString)));
+  setFocusProxy (_filter->lineEdit ());
+
+  // Init state of the filter
+  QSettings *settings = resource_manager::get_settings ();
+  _filter->addItems (settings->value ("history_dock_widget/mru_list").toStringList ());
+
+  bool filter_state =
+            settings->value ("history_dock_widget/filter_active", false).toBool ();
+  _filter_checkbox->setChecked (filter_state);
+  filter_activate (filter_state);
+
+  // Connect signals and slots
+  connect (_filter, SIGNAL (editTextChanged (const QString&)),
+           &_sort_filter_proxy_model, SLOT (setFilterWildcard (const QString&)));
+  connect (_filter_checkbox, SIGNAL (toggled (bool)),
+           this, SLOT (filter_activate (bool)));
+  connect (_filter->lineEdit (), SIGNAL (editingFinished ()),
+           this, SLOT (update_filter_history ()));
 
   connect (_history_list_view, SIGNAL (doubleClicked (QModelIndex)),
            this, SLOT (handle_double_click (QModelIndex)));
 
-  setFocusProxy (_filter_line_edit);
+  // shrink max. displayed entry size to desktop width
+  QSize screen = QDesktopWidget ().screenGeometry ().size ();
+  int w = screen.width ();
+  QFontMetrics fm = _history_list_view->fontMetrics ();
+  int h = fm.height ();
+  _history_list_view->setGridSize (QSize (w,h));
+  _history_list_view->setTextElideMode (Qt::ElideRight);
+}
+
+history_dock_widget::~history_dock_widget ()
+{
+  QSettings *settings = resource_manager::get_settings ();
+
+  settings->setValue ("history_dock_widget/filter_active",
+                      _filter_checkbox->isChecked ());
+
+  QStringList mru;
+  for (int i = 0; i < _filter->count (); i++)
+    mru.append (_filter->itemText (i));
+  settings->setValue ("history_dock_widget/mru_list", mru);
+
+  settings->sync ();
+}
+
+void
+history_dock_widget::filter_activate (bool state)
+{
+  _filter->setEnabled (state);
+  _sort_filter_proxy_model.setDynamicSortFilter (state);
+
+  if (state)
+    _sort_filter_proxy_model.setFilterWildcard (_filter->currentText ());
+  else
+    _sort_filter_proxy_model.setFilterWildcard (QString ());
+}
+
+void
+history_dock_widget::update_filter_history ()
+{
+  QString text = _filter->currentText ();   // get current text
+  int index = _filter->findText (text);     // and its actual index
+
+  if (index > -1)
+    _filter->removeItem (index);    // remove if already existing
+
+  _filter->insertItem (0, text);    // (re)insert at beginning
+  _filter->setCurrentIndex (0);
 }
 
 void history_dock_widget::ctxMenu (const QPoint &xpos)
@@ -203,22 +284,34 @@
 {
   if (_history_list_view->hasFocus ())
     handle_contextmenu_copy (true);
-  if (_filter_line_edit->hasFocus () && _filter_line_edit->hasSelectedText ())
+  if (_filter->lineEdit ()->hasFocus () && _filter->lineEdit ()->hasSelectedText ())
     {
       QClipboard *clipboard = QApplication::clipboard ();
-      clipboard->setText ( _filter_line_edit->selectedText ());
+      clipboard->setText ( _filter->lineEdit ()->selectedText ());
     }
 }
 
 void
 history_dock_widget::pasteClipboard ()
 {
-  if (_filter_line_edit->hasFocus ())
+  if (_filter->lineEdit ()->hasFocus ())
     {
       QClipboard *clipboard = QApplication::clipboard ();
       QString str =  clipboard->text ();
       if (str.length () > 0)
-        _filter_line_edit->insert (str);
+        _filter->lineEdit ()->insert (str);
     }
 }
 
+void
+history_dock_widget::selectAll ()
+{
+  if (_filter->lineEdit ()->hasFocus ())
+    {
+        _filter->lineEdit ()->selectAll ();
+    }
+  if (_history_list_view->hasFocus ())
+    {
+        _history_list_view->selectAll ();
+    }
+}
--- a/libgui/src/history-dock-widget.h	Fri Feb 06 08:31:09 2015 -0800
+++ b/libgui/src/history-dock-widget.h	Fri Feb 06 08:31:49 2015 -0800
@@ -27,6 +27,9 @@
 #include <QListView>
 #include <QSortFilterProxyModel>
 #include <QStringListModel>
+#include <QComboBox>
+#include <QCheckBox>
+
 #include "octave-dock-widget.h"
 
 class history_dock_widget : public octave_dock_widget
@@ -36,6 +39,7 @@
 public:
 
   history_dock_widget (QWidget *parent = 0);
+  ~history_dock_widget ();
 
 public slots:
 
@@ -56,6 +60,9 @@
 
 private slots:
 
+  void update_filter_history ();
+  void filter_activate (bool enable);
+
   void handle_double_click (QModelIndex modelIndex);
   void handle_contextmenu_copy (bool flag);
   void handle_contextmenu_evaluate (bool flag);
@@ -64,16 +71,20 @@
 
   void copyClipboard ();
   void pasteClipboard ();
+  void selectAll ();
 
 private:
 
   void construct ();
   QListView *_history_list_view;
-  QLineEdit *_filter_line_edit;
   QSortFilterProxyModel _sort_filter_proxy_model;
 
   /** Stores the current history_model. */
   QStringListModel *_history_model;
+
+  QCheckBox *_filter_checkbox;
+  QComboBox *_filter;
+  enum { MaxFilterHistory = 10 };
 };
 
 #endif // HISTORYDOCKWIDGET_H
Binary file libgui/src/icons/widget-close-light.png has changed
Binary file libgui/src/icons/widget-dock-light.png has changed
Binary file libgui/src/icons/widget-undock-light.png has changed
--- a/libgui/src/m-editor/file-editor-interface.h	Fri Feb 06 08:31:09 2015 -0800
+++ b/libgui/src/m-editor/file-editor-interface.h	Fri Feb 06 08:31:49 2015 -0800
@@ -40,10 +40,11 @@
 
   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;
 
+  virtual void insert_new_open_actions (QAction*,QAction*,QAction*) = 0;
   virtual void handle_enter_debug_mode (void) = 0;
   virtual void handle_exit_debug_mode (void) = 0;
 
@@ -59,7 +60,11 @@
 
   virtual void handle_edit_file_request (const QString& file) = 0;
 
-  virtual void set_focus () = 0;
+  virtual bool check_closing (int closing_state) = 0;
+
+  virtual void empty_script (bool, bool) = 0;
+
+  virtual void enable_menu_shortcuts (bool enable) = 0;
 
 public slots:
   virtual void request_new_file (const QString& command = QString ()) = 0;
--- a/libgui/src/m-editor/file-editor-tab.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/libgui/src/m-editor/file-editor-tab.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -1,3 +1,4 @@
+
 /*
 
 Copyright (C) 2011-2013 Jacob Dawid
@@ -47,15 +48,20 @@
 #include <QVBoxLayout>
 #include <QInputDialog>
 #include <QPrintDialog>
+#include <QDateTime>
 
 #include "file-editor-tab.h"
 #include "file-editor.h"
+#include "octave-txt-lexer.h"
 
 #include "file-ops.h"
 
 #include "debug.h"
 #include "octave-qt-link.h"
 #include "version.h"
+#include "utils.h"
+#include "defaults.h"
+#include <oct-map.h>
 
 // Make parent null for the file editor tab so that warning
 // WindowModal messages don't affect grandparents.
@@ -63,7 +69,9 @@
 {
   QString directory = directory_arg;
   _lexer_apis = 0;
-  _app_closing = false;
+  _app_closing = 0;   // app is not closing
+  _is_octave_file = true;
+  _modal_dialog = false;
 
   // Make sure there is a slash at the end of the directory name
   // for identification when saved later.
@@ -74,34 +82,30 @@
   _file_system_watcher.setObjectName ("_qt_autotest_force_engine_poller");
 
   _edit_area = new octave_qscintilla (this);
-  // Connect signal for command execution to a slot of this tab which in turn
-  // emits a signal connected to the main window.
-  // Direct connection is not possible because tab's parent is null.
-  connect (_edit_area,
-           SIGNAL (execute_command_in_terminal_signal (const QString&)),
-           this,
-           SLOT (execute_command_in_terminal (const QString&)));
 
-  connect (_edit_area,
-           SIGNAL (cursorPositionChanged (int, int)),
-           this,
-           SLOT (handle_cursor_moved (int,int)));
+  connect (_edit_area, SIGNAL (cursorPositionChanged (int, int)),
+           this, SLOT (handle_cursor_moved (int,int)));
+
+  connect (_edit_area, SIGNAL (context_menu_edit_signal (const QString&)),
+           this, SLOT (handle_context_menu_edit (const QString&)));
 
   // create statusbar for row/col indicator and eol mode
   _status_bar = new QStatusBar (this);
 
   // eol mode
+  QLabel *eol_label = new QLabel (tr ("eol:"), this);
   _eol_indicator = new QLabel ("",this);
   _eol_indicator->setMinimumSize (35,0);
+  _status_bar->addPermanentWidget (eol_label, 0);
   _status_bar->addPermanentWidget (_eol_indicator, 0);
 
   // row- and col-indicator
   _row_indicator = new QLabel ("", this);
   _row_indicator->setMinimumSize (30,0);
-  QLabel *row_label = new QLabel (tr ("Line:"), this);
+  QLabel *row_label = new QLabel (tr ("line:"), this);
   _col_indicator = new QLabel ("", this);
   _col_indicator->setMinimumSize (25,0);
-  QLabel *col_label = new QLabel (tr ("Col:"), this);
+  QLabel *col_label = new QLabel (tr ("col:"), this);
   _status_bar->addPermanentWidget (row_label, 0);
   _status_bar->addPermanentWidget (_row_indicator, 0);
   _status_bar->addPermanentWidget (col_label, 0);
@@ -130,10 +134,6 @@
   _edit_area->setMarginsBackgroundColor (QColor (232, 232, 220));
   _edit_area->setMarginType (2, QsciScintilla::TextMargin);
 
-  // code folding
-  _edit_area->setMarginType (3, QsciScintilla::SymbolMargin);
-  _edit_area->setFolding (QsciScintilla::BoxedTreeFoldStyle , 3);
-
   // other features
   _edit_area->setBraceMatching (QsciScintilla::StrictBraceMatch);
   _edit_area->setAutoIndent (true);
@@ -143,8 +143,7 @@
   _edit_area->setUtf8 (true);
 
   // auto completion
-  _edit_area->autoCompleteFromAll ();
-  _edit_area->setAutoCompletionSource (QsciScintilla::AcsAll);
+  _edit_area->SendScintilla (QsciScintillaBase::SCI_AUTOCSETCANCELATSTART, false);
 
   QVBoxLayout *edit_area_layout = new QVBoxLayout ();
   edit_area_layout->addWidget (_edit_area);
@@ -198,9 +197,107 @@
 }
 
 void
-file_editor_tab::execute_command_in_terminal (const QString& command)
+file_editor_tab::handle_context_menu_edit (const QString& word_at_cursor)
 {
-  emit execute_command_in_terminal_signal (command); // connected to main window
+  // search for a subfunction in actual file (this is done at first because
+  // octave finds this function before other with same name in the search path
+  QRegExp rxfun1 ("^[\t ]*function[^=]+=[\t ]*"
+      + word_at_cursor + "[\t ]*\\([^\\)]*\\)[\t ]*$");
+  QRegExp rxfun2 ("^[\t ]*function[\t ]+"
+      + word_at_cursor + "[\t ]*\\([^\\)]*\\)[\t ]*$");
+  QRegExp rxfun3 ("^[\t ]*function[\t ]+"
+      + word_at_cursor + "[\t ]*$");
+  QRegExp rxfun4 ("^[\t ]*function[^=]+=[\t ]*"
+      + word_at_cursor + "[\t ]*$");
+
+  int pos_fct = -1;
+  QStringList lines = _edit_area->text ().split ("\n");
+
+  int line;
+  for (line = 0; line < lines.count (); line++)
+    {
+      if ((pos_fct = rxfun1.indexIn (lines.at (line))) != -1)
+        break;
+      if ((pos_fct = rxfun2.indexIn (lines.at (line))) != -1)
+        break;
+      if ((pos_fct = rxfun3.indexIn (lines.at (line))) != -1)
+        break;
+      if ((pos_fct = rxfun4.indexIn (lines.at (line))) != -1)
+        break;
+    }
+
+  if (pos_fct > -1)
+    { // reg expr. found: it is an internal function
+      _edit_area->setCursorPosition (line, pos_fct);
+      _edit_area->SendScintilla (2613, line); // SCI_SETFIRSTVISIBLELINE
+      return;
+    }
+
+  // Is it a regular function within the search path? (Call __which__)
+  octave_value_list fct = F__which__ (ovl (word_at_cursor.toStdString ()),0);
+  octave_map map = fct(0).map_value ();
+
+  QString type = QString::fromStdString (
+                         map.contents ("type").data ()[0].string_value ());
+  QString name = QString::fromStdString (
+                         map.contents ("name").data ()[0].string_value ());
+
+  QString message = QString ();
+  QString filename = QString ();
+
+  if (type == QString("built-in function"))
+    { // built in function: can't edit
+      message = tr ("%1 is a built-in function");
+    }
+  else if (type.isEmpty ())
+    {
+      // function not known to octave -> try directory of edited file
+      QFileInfo file = QFileInfo (_file_name);
+      file = QFileInfo (QDir (file.canonicalPath ()), word_at_cursor + ".m");
+
+      if (file.exists ())
+        {
+          filename = file.canonicalFilePath (); // local file exists
+        }
+      else
+        { // local file does not exist -> try private directory
+          file = QFileInfo (_file_name);
+          file = QFileInfo (QDir (file.canonicalPath () + "/private"),
+                            word_at_cursor + ".m");
+
+          if (file.exists ())
+            {
+              filename = file.canonicalFilePath ();  // private function exists
+            }
+          else
+            {
+              message = tr ("Can not find function %1");  // no file found
+            }
+        }
+    }
+
+  if (! message.isEmpty ())
+    {
+      QMessageBox *msgBox
+          = new QMessageBox (QMessageBox::Critical,
+                             tr ("Octave Editor"),
+                             message.arg (name),
+                             QMessageBox::Ok, this);
+
+      msgBox->setWindowModality (Qt::NonModal);
+      msgBox->setAttribute (Qt::WA_DeleteOnClose);
+      msgBox->show ();
+      return;
+    }
+
+  if ( filename.isEmpty ())
+    filename = QString::fromStdString (
+                           map.contents ("file").data ()[0].string_value ());
+
+  if (! filename.endsWith (".m"))
+    filename.append (".m");
+
+  emit request_open_file (filename);
 }
 
 void
@@ -218,9 +315,9 @@
   update_lexer ();
 
   // update the file editor with current editing directory
-  emit editor_state_changed (_copy_available, _file_name);
+  emit editor_state_changed (_copy_available, _file_name, _is_octave_file);
+
   // add the new file to the mru list
-
   emit mru_add_file (_file_name);
 }
 
@@ -273,6 +370,8 @@
   delete lexer;
   lexer = 0;
 
+  _is_octave_file = false;
+
   if (_file_name.endsWith (".m")
       || _file_name.endsWith ("octaverc"))
     {
@@ -280,7 +379,10 @@
       lexer = new QsciLexerOctave ();
 #elif defined (HAVE_LEXER_MATLAB)
       lexer = new QsciLexerMatlab ();
+#else
+      lexer = new octave_txt_lexer ();
 #endif
+      _is_octave_file = true;
     }
 
   if (! lexer)
@@ -309,35 +411,99 @@
         {
           lexer = new QsciLexerDiff ();
         }
+      else if (_file_name.endsWith (".sh"))
+        {
+          lexer = new QsciLexerBash ();
+        }
       else if (! valid_file_name ())
         {
           // new, no yet named file: let us assume it is octave
 #if defined (HAVE_LEXER_OCTAVE)
           lexer = new QsciLexerOctave ();
+          _is_octave_file = true;
 #elif defined (HAVE_LEXER_MATLAB)
           lexer = new QsciLexerMatlab ();
+          _is_octave_file = true;
 #else
-          lexer = new QsciLexerBash ();
+          lexer = new octave_txt_lexer ();
 #endif
         }
       else
         {
           // other or no extension
-          lexer = new QsciLexerBash ();
+          lexer = new octave_txt_lexer ();
         }
     }
 
+  QSettings *settings = resource_manager::get_settings ();
+
+  // build information for auto completion (APIs)
   _lexer_apis = new QsciAPIs(lexer);
+
   if (_lexer_apis)
     {
+      bool update_apis_file = false;  // flag, whether update of apis files
+
       // get path to prepared api info
       QDesktopServices desktopServices;
       QString prep_apis_path
         = desktopServices.storageLocation (QDesktopServices::HomeLocation)
           + "/.config/octave/"  + QString(OCTAVE_VERSION) + "/qsci/";
-      _prep_apis_file = prep_apis_path + lexer->lexer () + ".pap";
+
+      // get settings which infos are used for octave
+      bool octave_builtins = settings->value (
+                  "editor/codeCompletion_octave_builtins", true).toBool ();
+      bool octave_functions = settings->value (
+                  "editor/codeCompletion_octave_functions", true).toBool ();
+
+      if (_is_octave_file)
+        {
+          // octave file: keywords are always used
+          _prep_apis_file = prep_apis_path + lexer->lexer () + "_k";
+
+          if (octave_builtins)
+            _prep_apis_file = _prep_apis_file + "b";  // use builtins, too
+
+          if (octave_functions)
+            _prep_apis_file = _prep_apis_file + "f";  // use keywords, too
+
+          _prep_apis_file = _prep_apis_file + ".pap"; // final name of apis file
+
+          // check whether the APIs info needs to be prepared and saved
+          QFileInfo apis_file = QFileInfo (_prep_apis_file);
+          update_apis_file = ! apis_file.exists ();  // flag whether apis file needs update
 
-      if (!_lexer_apis->loadPrepared (_prep_apis_file))
+          // function list depends on installed packages: check mod. date
+          if (! update_apis_file & octave_functions)
+            {
+              // check whether package file is newer than apis_file
+              QDateTime apis_date = apis_file.lastModified ();
+
+              // compare to local package list
+              // FIXME: How to get user chosen location?
+              QFileInfo local_pkg_list = QFileInfo (
+                desktopServices.storageLocation (QDesktopServices::HomeLocation)
+                + "/.octave_packages");
+              if (local_pkg_list.exists ()
+                  & (apis_date < local_pkg_list.lastModified ()) )
+                update_apis_file = true;
+
+              // compare to global package list
+              // FIXME: How to get user chosen location?
+              QFileInfo global_pkg_list = QFileInfo (
+                                        QString::fromStdString (Voctave_home)
+                                        + "/share/octave/octave_packages");
+               if (global_pkg_list.exists ()
+                   & (apis_date < global_pkg_list.lastModified ()) )
+                update_apis_file = true;
+            }
+          }
+        else  // no octave file, just add extension
+          {
+            _prep_apis_file = prep_apis_path + lexer->lexer () + ".pap";
+          }
+
+      if (update_apis_file | !_lexer_apis->loadPrepared (_prep_apis_file))
         {
           // no prepared info loaded, prepare and save if possible
 
@@ -345,12 +511,34 @@
           QString keyword;
           QStringList keyword_list;
           int i,j;
-          for (i=1; i<=3; i++) // test the first 5 keyword sets
+
+          if (_is_octave_file)
             {
-              keyword = QString(lexer->keywords (i));           // get list
-              keyword_list = keyword.split (QRegExp ("\\s+"));  // split
-              for (j = 0; j < keyword_list.size (); j++)        // add to API
-                _lexer_apis->add (keyword_list.at (j));
+              // octave: get keywords from internal informations depending on
+              //         user preferences
+
+              // keywords are always used
+              add_octave_apis (F__keywords__ ());       // add new entries
+
+              if (octave_builtins)
+                add_octave_apis (F__builtins__ ());       // add new entries
+
+              if (octave_functions)
+                add_octave_apis (F__list_functions__ ()); // add new entries
+
+            }
+          else
+            {
+
+              _prep_apis_file = prep_apis_path + lexer->lexer () + ".pap";
+
+              for (i=1; i<=3; i++) // test the first 5 keyword sets
+                {
+                  keyword = QString(lexer->keywords (i));           // get list
+                  keyword_list = keyword.split (QRegExp ("\\s+"));  // split
+                  for (j = 0; j < keyword_list.size (); j++)        // add to API
+                    _lexer_apis->add (keyword_list.at (j));
+                }
             }
 
           // dsiconnect slot for saving prepared info if already connected
@@ -366,11 +554,11 @@
         }
     }
 
-  QSettings *settings = resource_manager::get_settings ();
-  if (settings)
-    lexer->readSettings (*settings);
+  lexer->readSettings (*settings);
 
   _edit_area->setLexer (lexer);
+  _edit_area->setCaretForegroundColor (lexer->color (0));
+  _edit_area->setIndentationGuidesForegroundColor (lexer->color (0));
 
   // fix line number width with respect to the font size of the lexer
   if (settings->value ("editor/showLineNumbers", true).toBool ())
@@ -380,6 +568,17 @@
 
 }
 
+// function for adding entries to the octave lexer's APIs
+void
+file_editor_tab::add_octave_apis (octave_value_list key_ovl)
+{
+  octave_value keys = key_ovl(0);
+  Cell key_list = keys.cell_value ();
+
+  for (int idx = 0; idx < key_list.numel (); idx++)
+    _lexer_apis->add (QString (key_list.elem (idx).string_value ().data ()));
+}
+
 void
 file_editor_tab::save_apis_info ()
 {
@@ -411,51 +610,6 @@
 }
 
 void
-file_editor_tab::undo (const QWidget *ID)
-{
-  if (ID != this)
-    return;
-
-  _edit_area->undo ();
-}
-
-void
-file_editor_tab::redo (const QWidget *ID)
-{
-  if (ID != this)
-    return;
-
-  _edit_area->redo ();
-}
-
-void
-file_editor_tab::copy (const QWidget *ID)
-{
-  if (ID != this)
-    return;
-
-  _edit_area->copy ();
-}
-
-void
-file_editor_tab::cut (const QWidget *ID)
-{
-  if (ID != this)
-    return;
-
-  _edit_area->cut ();
-}
-
-void
-file_editor_tab::paste (const QWidget *ID)
-{
-  if (ID != this)
-    return;
-
-  _edit_area->paste ();
-}
-
-void
 file_editor_tab::context_help (const QWidget *ID, bool doc)
 {
   if (ID != this)
@@ -523,8 +677,12 @@
   if (ID != this)
     return;
 
-  if (_edit_area->isModified ())
-    save_file (_file_name);
+  if (_edit_area->isModified () | ! valid_file_name ())
+    {
+      _modal_dialog = true;    // force modal dialog if the file is a new one
+      save_file (_file_name);  // save file dialog
+      _modal_dialog = false;   // back to non-modal dialogs
+    }
 
   QFileInfo info (_file_name);
   emit run_file_signal (info);
@@ -734,6 +892,15 @@
 }
 
 void
+file_editor_tab::scintilla_command (const QWidget *ID, unsigned int sci_msg)
+{
+  if (ID != this)
+    return;
+
+  _edit_area->SendScintilla (sci_msg);
+}
+
+void
 file_editor_tab::comment_selected_text (const QWidget *ID)
 {
   if (ID != this)
@@ -752,6 +919,66 @@
 }
 
 void
+file_editor_tab::indent_selected_text (const QWidget *ID)
+{
+  if (ID != this)
+    return;
+
+  do_indent_selected_text (true);
+}
+
+void
+file_editor_tab::unindent_selected_text (const QWidget *ID)
+{
+  if (ID != this)
+    return;
+
+  do_indent_selected_text (false);
+}
+
+void
+file_editor_tab::convert_eol (const QWidget *ID, QsciScintilla::EolMode eol_mode)
+{
+  if (ID != this)
+    return;
+
+  _edit_area->convertEols (eol_mode);
+  _edit_area->setEolMode (eol_mode);
+  update_eol_indicator ();
+}
+
+void
+file_editor_tab::zoom_in (const QWidget *ID)
+{
+  if (ID != this)
+    return;
+
+  _edit_area->zoomIn (1);
+  auto_margin_width ();
+}
+
+void
+file_editor_tab::zoom_out (const QWidget *ID)
+{
+  if (ID != this)
+    return;
+
+  _edit_area->zoomOut (1);
+  auto_margin_width ();
+}
+
+void
+file_editor_tab::zoom_normal (const QWidget *ID)
+{
+  if (ID != this)
+    return;
+
+  _edit_area->zoomTo (0);
+  auto_margin_width ();
+}
+
+
+void
 file_editor_tab::handle_find_dialog_finished (int)
 {
   // Find dialog is going to hide.  Save location of window for
@@ -782,14 +1009,15 @@
       _find_dialog->setWindowModality (Qt::NonModal);
       _find_dialog_geometry = _find_dialog->geometry ();
     }
-
-  if (!_find_dialog->isVisible ())
+  else if (!_find_dialog->isVisible ())
     {
       _find_dialog->setGeometry (_find_dialog_geometry);
-      _find_dialog->show ();
-      _find_dialog_is_visible = true;
+      QPoint p = _find_dialog->pos ();
+      _find_dialog->move(p.x ()+10, p.y ()+10);
     }
 
+  _find_dialog->show ();
+  _find_dialog_is_visible = true;
   _find_dialog->activateWindow ();
   _find_dialog->init_search_text ();
 
@@ -819,6 +1047,81 @@
     _edit_area->setCursorPosition (line-1, 0);
 }
 
+void
+file_editor_tab::move_match_brace (const QWidget *ID, bool select)
+{
+  if (ID != this)
+    return;
+
+  if (select)
+    _edit_area->selectToMatchingBrace ();
+  else
+    _edit_area->moveToMatchingBrace ();
+}
+
+void
+file_editor_tab::show_auto_completion (const QWidget *ID)
+{
+  if (ID != this)
+    return;
+
+  QsciScintilla::AutoCompletionSource s = _edit_area->autoCompletionSource ();
+  switch (s)
+    {
+      case QsciScintilla::AcsAll:
+        _edit_area->autoCompleteFromAll ();
+        break;
+
+      case QsciScintilla::AcsAPIs:
+        _edit_area->autoCompleteFromAPIs ();
+        break;
+
+      case QsciScintilla::AcsDocument:
+        _edit_area->autoCompleteFromDocument ();
+        break;
+
+      case QsciScintilla::AcsNone:
+        break;
+    }
+}
+
+void
+file_editor_tab::do_indent_selected_text (bool indent)
+{
+  // TODO
+  _edit_area->beginUndoAction ();
+
+  if (_edit_area->hasSelectedText ())
+    {
+      int lineFrom, lineTo, colFrom, colTo;
+      _edit_area->getSelection (&lineFrom, &colFrom, &lineTo, &colTo);
+
+      if (colTo == 0)  // the beginning of last line is not selected
+        lineTo--;        // stop at line above
+
+      for (int i = lineFrom; i <= lineTo; i++)
+        {
+          if (indent)
+            _edit_area->indent (i);
+          else
+            _edit_area->unindent (i);
+        }
+      //set selection on (un)indented section
+      _edit_area->setSelection (lineFrom, 0, lineTo,
+                                _edit_area->text (lineTo).length ());
+    }
+  else
+    {
+      int cpline, col;
+      _edit_area->getCursorPosition (&cpline, &col);
+      if (indent)
+        _edit_area->indent (cpline);
+      else
+        _edit_area->unindent (cpline);
+    }
+
+  _edit_area->endUndoAction ();
+}
 
 void
 file_editor_tab::do_comment_selected_text (bool comment)
@@ -901,16 +1204,17 @@
 file_editor_tab::handle_copy_available (bool enableCopy)
 {
   _copy_available = enableCopy;
-  emit editor_state_changed (_copy_available, QDir::cleanPath (_file_name));
+  emit editor_state_changed (_copy_available, QDir::cleanPath (_file_name),
+                             _is_octave_file);
 }
 
 // show_dialog: shows a modal or non modal dialog depeding on the closing
-//              of the app
+//              of the app and the flag _modal_dialog
 void
 file_editor_tab::show_dialog (QDialog *dlg)
 {
   dlg->setAttribute (Qt::WA_DeleteOnClose);
-  if (_app_closing)
+  if (_app_closing | _modal_dialog)
     dlg->exec ();
   else
     {
@@ -934,13 +1238,24 @@
                                              QMessageBox::Discard;
       QString available_actions;
 
-      if (_app_closing)
-        available_actions = tr ("Do you want to save or discard the changes?");
-      else
+      switch (_app_closing)
         {
-          buttons = buttons | QMessageBox::Cancel;  // cancel is allowed
-          available_actions
-            = tr ("Do you want to cancel closing, save or discard the changes?");
+          case -1:  // octave is exiting and so does the gui
+            available_actions =
+              tr ("Do you want to save or discard the changes?");
+            break;
+
+          case 1:   // gui is exiting
+            available_actions =
+              tr ("Do you want to cancel exiting octave, save or discard the changes?");
+            buttons = buttons | QMessageBox::Cancel;
+            break;
+
+          case 0:   // tab is closing
+            available_actions =
+              tr ("Do you want to cancel closing, save or discard the changes?");
+            buttons = buttons | QMessageBox::Cancel;
+            break;
         }
 
       QString file;
@@ -1017,6 +1332,7 @@
     return file.errorString ();
 
   QTextStream in (&file);
+  in.setCodec("UTF-8");
   QApplication::setOverrideCursor (Qt::WaitCursor);
   _edit_area->setText (in.readAll ());
   _edit_area->setEolMode (detect_eol_mode ());
@@ -1066,17 +1382,34 @@
         }
     }
 
-  QsciScintilla::EolMode eol_mode = QsciScintilla::EolUnix;
-  int count_max = count_lf;
+  // get default from OS or from settings
+#if defined (Q_OS_WIN32)
+  int os_eol_mode = QsciScintilla::EolWindows;
+#elif defined (Q_OS_MAC)
+  int os_eol_mode = QsciScintilla::EolMac;
+#else
+  int os_eol_mode = QsciScintilla::EolUnix;
+#endif
+QSettings *settings = resource_manager::get_settings ();
+QsciScintilla::EolMode eol_mode = static_cast<QsciScintilla::EolMode> (
+      settings->value("editor/default_eol_mode",os_eol_mode).toInt ());
 
+  int count_max = 0;
+
+  if (count_crlf > count_max)
+    {
+      eol_mode = QsciScintilla::EolWindows;
+      count_max = count_crlf;
+    }
   if (count_cr > count_max)
     {
       eol_mode = QsciScintilla::EolMac;
       count_max = count_cr;
     }
-  if (count_crlf > count_max)
+  if (count_lf > count_max)
     {
-      eol_mode = QsciScintilla::EolWindows;
+      eol_mode = QsciScintilla::EolUnix;
+      count_max = count_lf;
     }
 
   return eol_mode;
@@ -1103,9 +1436,26 @@
 file_editor_tab::new_file (const QString &commands)
 {
   update_window_title (false); // window title (no modification)
+
+  QSettings *settings = resource_manager::get_settings ();
+
+  // set the eol mode from the settings or depending on the OS if the entry is
+  // missing in the settings
+#if defined (Q_OS_WIN32)
+  int eol_mode = QsciScintilla::EolWindows;
+#elif defined (Q_OS_MAC)
+  int eol_mode = QsciScintilla::EolMac;
+#else
+  int eol_mode = QsciScintilla::EolUnix;
+#endif
+  _edit_area->setEolMode (
+    static_cast<QsciScintilla::EolMode> (
+      settings->value("editor/default_eol_mode",eol_mode).toInt ()));
+
+  update_eol_indicator ();
+
   _edit_area->setText (commands);
   _edit_area->setModified (false); // new file is not modified yet
-  update_eol_indicator ();
 }
 
 void
@@ -1154,6 +1504,7 @@
 
   // save the contents into the file
   QTextStream out (&file);
+  out.setCodec("UTF-8");
   QApplication::setOverrideCursor (Qt::WaitCursor);
   out << _edit_area->text ();
   out.flush ();
@@ -1205,9 +1556,56 @@
   // it had/has no effect on Windows, though)
   fileDialog->setOption(QFileDialog::DontUseNativeDialog, true);
 
+  // get the dialog's layout for adding extra elements
+  QGridLayout *dialog_layout = dynamic_cast<QGridLayout*> (fileDialog->layout ());
+  int rows = dialog_layout->rowCount ();
+
+  // define a new grid layout with the extra elements
+  QGridLayout *extra = new QGridLayout (fileDialog);
+  QSpacerItem *spacer = new QSpacerItem (1,1,QSizePolicy::Expanding,
+                                             QSizePolicy::Fixed);
+  QFrame *separator = new QFrame (fileDialog);
+  separator->setFrameShape (QFrame::HLine);   // horizontal line as separator
+  separator->setFrameStyle (QFrame::Sunken);
+
+  // combo box for choosing new line ending chars
+  QLabel *label_eol = new QLabel (tr ("Line Endings:"));
+  QComboBox *combo_eol = new QComboBox ();
+  combo_eol->addItem ("Windows (CRLF)");  // ensure the same order as in
+  combo_eol->addItem ("Mac (CR)");        // the settings dialog
+  combo_eol->addItem ("Unix (LF)");
+  _save_as_desired_eol = _edit_area->eolMode ();      // init with current eol
+  combo_eol->setCurrentIndex (_save_as_desired_eol);
+
+  // track changes in the combo box
+  connect (combo_eol, SIGNAL (currentIndexChanged (int)),
+           this, SLOT (handle_combo_eol_current_index (int)));
+
+  // build the extra grid layout
+  extra->addWidget (separator,0,0,1,3);
+  extra->addWidget (label_eol,1,0);
+  extra->addWidget (combo_eol,1,1);
+  extra->addItem   (spacer,   1,2);
+
+  // and add the extra grid layout to the dialog's layout
+  dialog_layout->addLayout (extra,rows,0,1,dialog_layout->columnCount ());
+
+  // add the possible filters and the default suffix
+  QStringList filters;
+  filters << tr ("Octave Files (*.m)")
+          << tr ("All Files (*)");
+  fileDialog->setNameFilters (filters);
+  fileDialog->setDefaultSuffix ("m");
+
   if (valid_file_name ())
     {
       fileDialog->selectFile (_file_name);
+      QFileInfo file_info (_file_name);
+      if (file_info.suffix () != "m")
+        { // it is not an octave file
+          fileDialog->selectNameFilter (filters.at (1));  // "All Files"
+          fileDialog->setDefaultSuffix ("");              // no default suffix
+        }
     }
   else
     {
@@ -1221,13 +1619,19 @@
           // constructor argument.
           fileDialog->setDirectory (_file_name);
         }
+
+      // propose a name corresponding to the function name
+      QString fname = get_function_name ();
+      if (! fname.isEmpty ())
+        fileDialog->selectFile (fname + ".m");
     }
 
-  fileDialog->setNameFilter (tr ("Octave Files (*.m);;All Files (*)"));
-  fileDialog->setDefaultSuffix ("m");
   fileDialog->setAcceptMode (QFileDialog::AcceptSave);
   fileDialog->setViewMode (QFileDialog::Detail);
 
+  connect (fileDialog, SIGNAL (filterSelected (const QString&)),
+           this, SLOT (handle_save_as_filter_selected (const QString&)));
+
   if (remove_on_success)
     {
       connect (fileDialog, SIGNAL (fileSelected (const QString&)),
@@ -1246,8 +1650,55 @@
 }
 
 void
+file_editor_tab::handle_combo_eol_current_index (int index)
+{
+  _save_as_desired_eol = static_cast<QsciScintilla::EolMode> (index);
+}
+
+void
+file_editor_tab::handle_save_as_filter_selected (const QString& filter)
+{
+  QFileDialog *file_dialog = qobject_cast<QFileDialog *> (sender ());
+
+  QRegExp rx ("\\*\\.([^ ^\\)]*)[ \\)]");   // regexp for suffix in filter
+  int index = rx.indexIn (filter,0);        // get first suffix in filter
+
+  if (index > -1)
+    file_dialog->setDefaultSuffix (rx.cap (1)); // found a suffix, set default
+  else
+    file_dialog->setDefaultSuffix ("");         // not found, clear default
+}
+
+bool
+file_editor_tab::check_valid_identifier (QString file_name)
+{
+  QFileInfo file = QFileInfo (file_name);
+  QString base_name = file.baseName ();
+
+  if ((file.suffix () == "m")
+      && (! valid_identifier (base_name.toStdString ())))
+    {
+      int ans = QMessageBox::question (0, tr ("Octave Editor"),
+         tr ("\"%1\"\n"
+             "is not a valid identifier.\n\n"
+             "If you keep this file name, you will not be able to\n"
+             "call your script using its name as an Octave command.\n\n"
+             "Do you want to choose another name?").arg (base_name),
+          QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes);
+
+      if (ans == QMessageBox::Yes)
+        return true;
+    }
+
+  return false;
+}
+
+void
 file_editor_tab::handle_save_file_as_answer (const QString& saveFileName)
 {
+  if (_save_as_desired_eol != _edit_area->eolMode ())
+    convert_eol (this,_save_as_desired_eol);
+
   if (saveFileName == _file_name)
     {
       // same name as actual file, save it as "save" would do
@@ -1256,18 +1707,31 @@
   else
     {
       // Have editor check for conflict, do not delete tab after save.
-      emit editor_check_conflict_save (saveFileName, false);
+      if (check_valid_identifier (saveFileName))
+        save_file_as (false);
+      else
+        emit editor_check_conflict_save (saveFileName, false);
     }
 }
 
 void
 file_editor_tab::handle_save_file_as_answer_close (const QString& saveFileName)
 {
+  if (_save_as_desired_eol != _edit_area->eolMode ())
+    {
+      _edit_area->setReadOnly (false);  // was set to read-only in save_file_as
+      convert_eol (this,_save_as_desired_eol);
+      _edit_area->setReadOnly (true);   // restore read-only mode
+    }
+
   // saveFileName == _file_name can not happen, because we only can get here
   // when we close a tab and _file_name is not a valid file name yet
 
   // Have editor check for conflict, delete tab after save.
-  emit editor_check_conflict_save (saveFileName, true);
+  if (check_valid_identifier (saveFileName))
+    save_file_as (true);
+  else
+    emit editor_check_conflict_save (saveFileName, true);
 }
 
 void
@@ -1289,21 +1753,28 @@
 
   if (QFile::exists (_file_name))
     {
-      // Create a WindowModal message that blocks the edit area
-      // by making _edit_area parent.
-      QMessageBox* msgBox
-        = new QMessageBox (QMessageBox::Warning,
-                           tr ("Octave Editor"),
-                           tr ("It seems that \'%1\' has been modified by another application. Do you want to reload it?").
-                           arg (_file_name),
-                           QMessageBox::Yes | QMessageBox::No, this);
+      if (_always_reload_changed_files)
+
+              load_file (_file_name);
 
-      connect (msgBox, SIGNAL (finished (int)),
-               this, SLOT (handle_file_reload_answer (int)));
+      else
+        {
+          // Create a WindowModal message that blocks the edit area
+          // by making _edit_area parent.
+          QMessageBox* msgBox
+            = new QMessageBox (QMessageBox::Warning,
+                               tr ("Octave Editor"),
+                               tr ("It seems that \'%1\' has been modified by another application. Do you want to reload it?").
+                               arg (_file_name),
+                               QMessageBox::Yes | QMessageBox::No, this);
 
-      msgBox->setWindowModality (Qt::WindowModal);
-      msgBox->setAttribute (Qt::WA_DeleteOnClose);
-      msgBox->show ();
+          connect (msgBox, SIGNAL (finished (int)),
+                   this, SLOT (handle_file_reload_answer (int)));
+
+          msgBox->setWindowModality (Qt::WindowModal);
+          msgBox->setAttribute (Qt::WA_DeleteOnClose);
+          msgBox->show ();
+        }
     }
   else
     {
@@ -1340,6 +1811,23 @@
 
   update_lexer ();
 
+  // code folding
+  if (settings->value ("editor/code_folding",true).toBool ())
+    {
+      _edit_area->setMarginType (3, QsciScintilla::SymbolMargin);
+      _edit_area->setFolding (QsciScintilla::BoxedTreeFoldStyle , 3);
+    }
+  else
+    {
+      _edit_area->setFolding (QsciScintilla::NoFoldStyle, 3);
+    }
+
+  // status bar
+  if (settings->value ("editor/show_edit_status_bar",true).toBool ())
+    _status_bar->show ();
+  else
+    _status_bar->hide ();
+
   //highlight current line color
   QVariant default_var = QColor (240, 240, 240);
   QColor setting_color = settings->value ("editor/highlight_current_line_color",
@@ -1348,30 +1836,29 @@
   _edit_area->setCaretLineVisible
     (settings->value ("editor/highlightCurrentLine", true).toBool ());
 
-  if (settings->value ("editor/codeCompletion", true).toBool ())  // auto compl.
-    {
-      bool match_keywords = settings->value
+  bool match_keywords = settings->value
                             ("editor/codeCompletion_keywords",true).toBool ();
-      bool match_document = settings->value
+  bool match_document = settings->value
                             ("editor/codeCompletion_document",true).toBool ();
 
-      QsciScintilla::AutoCompletionSource source = QsciScintilla::AcsNone;
-      if (match_keywords)
-        if (match_document)
-          source = QsciScintilla::AcsAll;
-        else
-          source = QsciScintilla::AcsAPIs;
-      else if (match_document)
-        source = QsciScintilla::AcsDocument;
-      _edit_area->setAutoCompletionSource (source);
+  QsciScintilla::AutoCompletionSource source = QsciScintilla::AcsNone;
+  if (match_keywords)
+    if (match_document)
+      source = QsciScintilla::AcsAll;
+    else
+      source = QsciScintilla::AcsAPIs;
+  else if (match_document)
+    source = QsciScintilla::AcsDocument;
+  _edit_area->setAutoCompletionSource (source);
 
-      _edit_area->setAutoCompletionReplaceWord
-        (settings->value ("editor/codeCompletion_replace",false).toBool ());
-      _edit_area->setAutoCompletionCaseSensitivity
-        (settings->value ("editor/codeCompletion_case",true).toBool ());
-      _edit_area->setAutoCompletionThreshold
-        (settings->value ("editor/codeCompletion_threshold",2).toInt ());
-    }
+  _edit_area->setAutoCompletionReplaceWord
+      (settings->value ("editor/codeCompletion_replace",false).toBool ());
+  _edit_area->setAutoCompletionCaseSensitivity
+      (settings->value ("editor/codeCompletion_case",true).toBool ());
+
+  if (settings->value ("editor/codeCompletion", true).toBool ())
+    _edit_area->setAutoCompletionThreshold
+      (settings->value ("editor/codeCompletion_threshold",2).toInt ());
   else
     _edit_area->setAutoCompletionThreshold (-1);
 
@@ -1383,6 +1870,9 @@
   else
     _edit_area->setWhitespaceVisibility (QsciScintilla::WsInvisible);
 
+  _edit_area->setEolVisibility (
+              settings->value("editor/show_eol_chars",false).toBool ());
+
   if (settings->value ("editor/showLineNumbers", true).toBool ())
     {
       _edit_area->setMarginLineNumbers (2, true);
@@ -1404,13 +1894,32 @@
         (settings->value ("editor/backspace_unindents_line",false).toBool ());
   _edit_area->setIndentationGuides
         (settings->value ("editor/show_indent_guides",false).toBool ());
+  _edit_area->setIndentationsUseTabs
+        (settings->value ("editor/indent_uses_tabs",false).toBool ());
+  _edit_area->setIndentationWidth
+        (settings->value ("editor/indent_width",2).toInt ());
 
   _edit_area->setTabWidth
         (settings->value ("editor/tab_width",2).toInt ());
 
+  _edit_area->SendScintilla (QsciScintillaBase::SCI_SETHSCROLLBAR,
+        settings->value ("editor/show_hscroll_bar",true).toBool ());
+  _edit_area->SendScintilla (QsciScintillaBase::SCI_SETSCROLLWIDTH,-1);
+  _edit_area->SendScintilla (QsciScintillaBase::SCI_SETSCROLLWIDTHTRACKING,true);
+
   _long_title = settings->value ("editor/longWindowTitle", false).toBool ();
   update_window_title (_edit_area->isModified ());
 
+  _edit_area->setEdgeColumn (
+              settings->value ("editor/long_line_column",80).toInt ());
+  if (settings->value ("editor/long_line_marker",true).toBool ())
+    _edit_area->setEdgeMode (QsciScintilla::EdgeLine);
+  else
+    _edit_area->setEdgeMode (QsciScintilla::EdgeNone);
+
+  // reload changed files
+  _always_reload_changed_files =
+        settings->value ("editor/always_reload_changed_files",false).toBool ();
 }
 
 void
@@ -1419,14 +1928,16 @@
   _edit_area->setMarginWidth (2, "1"+QString::number (_edit_area->lines ()));
 }
 
-void
-file_editor_tab::conditional_close (const QWidget *ID, bool app_closing)
+// the following close request was changed from a signal slot into a
+// normal function because we need the return value from close whether
+// the tab really was closed (for canceling exiting octave).
+// When emitting a signal, only the return value from the last slot
+// goes back to the sender
+bool
+file_editor_tab::conditional_close (int app_closing)
 {
-  if (ID != this)
-    return;
-
   _app_closing = app_closing;
-  close ();
+  return close ();
 }
 
 void
@@ -1449,10 +1960,13 @@
   if (_find_dialog && _find_dialog_is_visible)
     {
       _find_dialog->setGeometry (_find_dialog_geometry);
+      QPoint p = _find_dialog->pos ();
+      _find_dialog->move(p.x ()+10, p.y ()+10);
       _find_dialog->show ();
     }
 
-  emit editor_state_changed (_copy_available, QDir::cleanPath (_file_name));
+  emit editor_state_changed (_copy_available, QDir::cleanPath (_file_name),
+                             _is_octave_file);
 }
 
 void
@@ -1563,8 +2077,36 @@
 void
 file_editor_tab::handle_cursor_moved (int line, int col)
 {
+  if (_edit_area->SendScintilla (QsciScintillaBase::SCI_AUTOCACTIVE))
+    show_auto_completion (this);
+
   _row_indicator->setNum (line+1);
   _col_indicator->setNum (col+1);
 }
 
+QString
+file_editor_tab::get_function_name ()
+{
+  QRegExp rxfun1 ("^[\t ]*function[^=]+=([^\\(]+)\\([^\\)]*\\)[\t ]*$");
+  QRegExp rxfun2 ("^[\t ]*function[\t ]+([^\\(]+)\\([^\\)]*\\)[\t ]*$");
+  QRegExp rxfun3 ("^[\t ]*function[^=]+=[\t ]*([^\\s]+)[\t ]*$");
+  QRegExp rxfun4 ("^[\t ]*function[\t ]+([^\\s]+)[\t ]*$");
+
+  QStringList lines = _edit_area->text ().split ("\n");
+
+  for (int i = 0; i < lines.count (); i++)
+    {
+      if (rxfun1.indexIn (lines.at (i)) != -1)
+        return rxfun1.cap (1).remove (QRegExp("[ \t]*"));
+      else if (rxfun2.indexIn (lines.at (i)) != -1)
+        return rxfun2.cap (1).remove (QRegExp("[ \t]*"));
+      else if (rxfun3.indexIn (lines.at (i)) != -1)
+        return rxfun3.cap (1).remove (QRegExp("[ \t]*"));
+      else if (rxfun4.indexIn (lines.at (i)) != -1)
+        return rxfun4.cap (1).remove (QRegExp("[ \t]*"));
+    }
+
+  return QString ();
+}
+
 #endif
--- a/libgui/src/m-editor/file-editor-tab.h	Fri Feb 06 08:31:09 2015 -0800
+++ b/libgui/src/m-editor/file-editor-tab.h	Fri Feb 06 08:31:49 2015 -0800
@@ -31,9 +31,11 @@
 #include <Qsci/qsciapis.h>
 #include <QStatusBar>
 #include <QLabel>
+#include <QComboBox>
 
 #include "find-dialog.h"
 #include "octave-qscintilla.h"
+#include "builtin-defun-decls.h"
 
 class file_editor;
 
@@ -47,6 +49,12 @@
 
   ~file_editor_tab (void);
 
+  octave_qscintilla *qsci_edit_area () { return _edit_area; }
+
+  // Will initiate close if associated with the identifier tag.
+  bool conditional_close (int app_closing = 0);  // default 0: close tab only
+
+
 public slots:
 
   void update_window_title (bool modified);
@@ -57,9 +65,6 @@
   // Tells the editor tab to react on changed settings.
   void notice_settings (const QSettings *settings);
 
-  // Will initiate close if associated with the identifier tag.
-  void conditional_close (const QWidget *ID, bool app_closing = false);
-
   // Change to a different editor tab by identifier tag.
   void change_editor_state (const QWidget *ID);
 
@@ -67,11 +72,6 @@
   void file_name_query (const QWidget *ID);
 
   void set_focus (const QWidget *ID);
-  void undo (const QWidget *ID);
-  void redo (const QWidget *ID);
-  void copy (const QWidget *ID);
-  void cut (const QWidget *ID);
-  void paste (const QWidget *ID);
   void context_help (const QWidget *ID, bool);
   void context_edit (const QWidget *ID);
   void save_file (const QWidget *ID);
@@ -91,10 +91,23 @@
   void previous_breakpoint (const QWidget *ID);
   void remove_all_breakpoints (const QWidget *ID);
 
+  void scintilla_command (const QWidget *, unsigned int);
+
   void comment_selected_text (const QWidget *ID);
   void uncomment_selected_text (const QWidget *ID);
+
+  void indent_selected_text (const QWidget *ID);
+  void unindent_selected_text (const QWidget *ID);
+  void convert_eol (const QWidget *ID, QsciScintilla::EolMode);
+
+  void zoom_in (const QWidget *ID);
+  void zoom_out (const QWidget *ID);
+  void zoom_normal (const QWidget *ID);
+
   void find (const QWidget *ID);
   void goto_line (const QWidget *ID, int line = -1);
+  void move_match_brace (const QWidget *ID, bool select);
+  void show_auto_completion (const QWidget *ID);
 
   void insert_debugger_pointer (const QWidget *ID, int line = -1);
   void delete_debugger_pointer (const QWidget *ID, int line = -1);
@@ -108,19 +121,21 @@
 
   void file_has_changed (const QString& fileName);
 
-  void execute_command_in_terminal (const QString& command);
+  void handle_context_menu_edit (const QString&);
 
 signals:
 
   void file_name_changed (const QString& fileName, const QString& toolTip);
-  void editor_state_changed (bool copy_available, const QString& fileName);
+  void editor_state_changed (bool copy_available, const QString& fileName,
+                             bool is_octave_file);
   void tab_remove_request ();
   void add_filename_to_list (const QString&, QWidget *);
   void mru_add_file (const QString& file_name);
   void editor_check_conflict_save (const QString& saveFileName,
                                    bool remove_on_success);
   void run_file_signal (const QFileInfo& info);
-  void execute_command_in_terminal_signal (const QString&);
+  void set_global_edit_shortcuts_signal (bool);
+  void request_open_file (const QString&);
 
 protected:
 
@@ -145,6 +160,8 @@
   void handle_save_file_as_answer (const QString& fileName);
   void handle_save_file_as_answer_close (const QString& fileName);
   void handle_save_file_as_answer_cancel ();
+  void handle_save_as_filter_selected (const QString& filter);
+  void handle_combo_eol_current_index (int index);
 
   // When apis preparation has finished and is ready to save
   void save_apis_info ();
@@ -176,6 +193,7 @@
   bool valid_file_name (const QString& file=QString ());
   void save_file (const QString& saveFileName, bool remove_on_success = false);
   void save_file_as (bool remove_on_success = false);
+  bool check_valid_identifier (QString file_name);
 
   void update_lexer ();
   void request_add_breakpoint (int line);
@@ -185,12 +203,16 @@
   int check_file_modified ();
   void do_comment_selected_text (bool comment);
   QString comment_string (const QString&);
+  void do_indent_selected_text (bool indent);
 
   void add_breakpoint_callback (const bp_info& info);
   void remove_breakpoint_callback (const bp_info& info);
   void remove_all_breakpoints_callback (const bp_info& info);
   void center_current_line ();
 
+  void add_octave_apis (octave_value_list key_ovl);
+  QString get_function_name ();
+
   QsciScintilla::EolMode detect_eol_mode ();
   void update_eol_indicator ();
 
@@ -201,12 +223,17 @@
   QLabel *_col_indicator;
   QLabel *_eol_indicator;
 
+  QsciScintilla::EolMode _save_as_desired_eol;
+
   QString _file_name;
   QString _file_name_short;
 
   bool _long_title;
   bool _copy_available;
-  bool _app_closing;
+  int _app_closing;     // -1: octave exits, 1: exit request in gui, 0: no exit
+  bool _is_octave_file;
+  bool _modal_dialog;
+  bool _always_reload_changed_files;
 
   QFileSystemWatcher _file_system_watcher;
 
--- a/libgui/src/m-editor/file-editor.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/libgui/src/m-editor/file-editor.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -28,6 +28,8 @@
 
 #include "file-editor.h"
 #include "resource-manager.h"
+#include "shortcut-manager.h"
+
 #include <QVBoxLayout>
 #include <QApplication>
 #include <QFile>
@@ -36,8 +38,10 @@
 #include <QMessageBox>
 #include <QStyle>
 #include <QTextStream>
+#include <QTabBar>
 #include <QProcess>
 #include <QInputDialog>
+#include <Qsci/qscicommandset.h>
 
 #include "octave-link.h"
 #include "utils.h"
@@ -53,10 +57,26 @@
   construct ();
 
   setVisible (false);
+
+  setAcceptDrops(true);
 }
 
 file_editor::~file_editor (void)
 {
+  // Close open tabs, if existing. In this case app closing must be
+  // initiated by octave. All tabs will be definetly closed and the
+  // user can not cancel exiting (close state -1)
+  if (_tab_widget->count ())
+    check_closing (-1);
+
+  if (_mru_file_menu)
+    delete _mru_file_menu;
+}
+
+bool
+file_editor::check_closing (int closing_state)
+{
+  // Save open files for restoring in next session; this only is possible
   QSettings *settings = resource_manager::get_settings ();
 
   // Have all file editor tabs signal what their file names are.
@@ -76,31 +96,29 @@
   settings->setValue ("editor/savedSessionTabs", fetFileNames);
   settings->sync ();
 
+  // Close all tabs. If exit is requested by the gui (octave still running)
+  // check whether closing a tab is successful or whether user wnats to cancel
+  // exiting the program. Return false in the latter case.
+  file_editor_tab *editor_tab;
+
   for (int index = _tab_widget->count ()-1; index >= 0; index--)
     {
-      // true: app closing
-      emit fetab_close_request (_tab_widget->widget (index), true);
+      editor_tab = static_cast <file_editor_tab *> (_tab_widget->widget (index));
+      if ((! editor_tab->conditional_close (closing_state)) && closing_state == 1)
+        return false;
     }
 
-  if (_mru_file_menu)
-    delete _mru_file_menu;
+  // Here, we really want to exit and all tabs are closed
+  return true;
 }
 
+
 void
 file_editor::focus (void)
 {
-  set_focus ();
-}
+  octave_dock_widget::focus ();
 
-// set focus to editor and its current tab
-void
-file_editor::set_focus (void)
-{
-  if (!isVisible ())
-    setVisible (true);
-  setFocus ();
-  activateWindow ();
-  raise ();
+// set focus to current tab
   QWidget *fileEditorTab = _tab_widget->currentWidget ();
   if (fileEditorTab)
     emit fetab_set_focus (fileEditorTab);
@@ -147,7 +165,7 @@
     {
       add_file_editor_tab (fileEditorTab, "");  // new tab with empty title
       fileEditorTab->new_file (commands);       // title is updated here
-      set_focus ();                             // focus editor and new tab
+      focus ();                                 // focus editor and new tab
     }
 }
 
@@ -211,10 +229,11 @@
 
   fileDialog->setAcceptMode (QFileDialog::AcceptOpen);
   fileDialog->setViewMode (QFileDialog::Detail);
+  fileDialog->setFileMode (QFileDialog::ExistingFiles);
   fileDialog->setDirectory (ced);
 
-  connect (fileDialog, SIGNAL (fileSelected (const QString&)),
-           this, SLOT (request_open_file (const QString&)));
+  connect (fileDialog, SIGNAL (filesSelected (const QStringList&)),
+           this, SLOT (request_open_files (const QStringList&)));
 
   fileDialog->setWindowModality (Qt::NonModal);
   fileDialog->setAttribute (Qt::WA_DeleteOnClose);
@@ -254,7 +273,21 @@
       editor.replace ("%f", file_name);
       editor.replace ("%l", QString::number (line));
 
-      QProcess::startDetached (editor);
+      bool started_ok = QProcess::startDetached (editor);
+
+      if (started_ok != true)
+        {
+          QMessageBox *msgBox
+            = new QMessageBox (QMessageBox::Critical,
+                               tr ("Octave Editor"),
+                               tr ("Could not start custom file editor\n%1").
+                               arg (editor),
+                               QMessageBox::Ok, this);
+
+           msgBox->setWindowModality (Qt::NonModal);
+           msgBox->setAttribute (Qt::WA_DeleteOnClose);
+           msgBox->show ();
+        }
 
       if (line < 0 && ! file_name.isEmpty ())
         handle_mru_add_file (QFileInfo (file_name).canonicalFilePath ());
@@ -283,6 +316,13 @@
 }
 
 void
+file_editor::request_open_files (const QStringList& open_file_names)
+{
+  for (int i = 0; i < open_file_names.count (); i++)
+    request_open_file (open_file_names.at (i));
+}
+
+void
 file_editor::request_open_file (const QString& openFileName, int line,
                                 bool debug_pointer,
                                 bool breakpoint_marker, bool insert)
@@ -323,7 +363,7 @@
           if (! ((breakpoint_marker || debug_pointer) && is_editor_console_tabbed ()))
             {
               emit fetab_set_focus (tab);
-              set_focus ();
+              focus ();
             }
         }
       else
@@ -376,27 +416,31 @@
                   else
                     {
                       // File does not exist, should it be crated?
+                      bool create_file = true;
                       QMessageBox *msgBox;
-                      int answer;
                       QSettings *settings = resource_manager::get_settings ();
-                      if (settings->value ("editor/create_new_file", false).toBool ())
-                        {
-                          answer = QMessageBox::Yes;
-                        }
-                      else
+
+                      if (!settings->value ("editor/create_new_file", false).toBool ())
                         {
                           msgBox = new QMessageBox (QMessageBox::Question,
                                                     tr ("Octave Editor"),
                                                     tr ("File\n%1\ndoes not exist. "
                                                         "Do you want to create it?").arg (openFileName),
-                                                    QMessageBox::Yes
-                                                    | QMessageBox::No, 0);
+                                                    QMessageBox::NoButton,0);
+                          QPushButton *create_button =
+                            msgBox->addButton (tr ("Create"), QMessageBox::YesRole);
+                          msgBox->addButton (tr ("Cancel"), QMessageBox::RejectRole);
+                          msgBox->setDefaultButton (create_button);
+                          msgBox->exec ();
 
-                          msgBox->setAttribute (Qt::WA_DeleteOnClose);
-                          answer = msgBox->exec ();
+                          QAbstractButton *clicked_button = msgBox->clickedButton ();
+                          if (clicked_button != create_button)
+                            create_file = false;
+
+                          delete msgBox;
                         }
 
-                      if (answer == QMessageBox::Yes)
+                      if (create_file)
                         {
                           // create the file and call the editor again
                           QFile file (openFileName);
@@ -426,7 +470,7 @@
           if (! ((breakpoint_marker || debug_pointer) && is_editor_console_tabbed ()))
             {
               // really show editor and the current editor tab
-              set_focus ();
+              focus ();
               emit file_loaded_signal ();
             }
         }
@@ -556,33 +600,45 @@
 }
 
 void
-file_editor::request_undo (void)
+file_editor::request_undo (bool)
 {
-  emit fetab_undo (_tab_widget->currentWidget ());
+  emit fetab_scintilla_command (_tab_widget->currentWidget (),
+                                QsciScintillaBase::SCI_UNDO);
 }
 
 void
-file_editor::request_redo (void)
+file_editor::request_redo (bool)
 {
-  emit fetab_redo (_tab_widget->currentWidget ());
+  emit fetab_scintilla_command (_tab_widget->currentWidget (),
+                                QsciScintillaBase::SCI_REDO);
 }
 
 void
-file_editor::request_copy (void)
+file_editor::request_copy (bool)
 {
-  emit fetab_copy (_tab_widget->currentWidget ());
+  emit fetab_scintilla_command (_tab_widget->currentWidget (),
+                                QsciScintillaBase::SCI_COPY);
 }
 
 void
-file_editor::request_cut (void)
+file_editor::request_cut (bool)
 {
-  emit fetab_cut (_tab_widget->currentWidget ());
+  emit fetab_scintilla_command (_tab_widget->currentWidget (),
+                                QsciScintillaBase::SCI_CUT);
 }
 
 void
-file_editor::request_paste (void)
+file_editor::request_paste (bool)
 {
-  emit fetab_paste (_tab_widget->currentWidget ());
+  emit fetab_scintilla_command (_tab_widget->currentWidget (),
+                                QsciScintillaBase::SCI_PASTE);
+}
+
+void
+file_editor::request_selectall (bool)
+{
+  emit fetab_scintilla_command (_tab_widget->currentWidget (),
+                                QsciScintillaBase::SCI_SELECTALL);
 }
 
 void
@@ -603,26 +659,26 @@
 }
 
 void
-file_editor::request_save_file (void)
+file_editor::request_save_file (bool)
 {
   emit fetab_save_file (_tab_widget->currentWidget ());
 }
 
 void
-file_editor::request_save_file_as (void)
+file_editor::request_save_file_as (bool)
 {
   emit fetab_save_file_as (_tab_widget->currentWidget ());
 }
 
 void
-file_editor::request_print_file (void)
+file_editor::request_print_file (bool)
 {
   emit fetab_print_file (_tab_widget->currentWidget ());
 }
 
 
 void
-file_editor::request_run_file (void)
+file_editor::request_run_file (bool)
 {
   emit fetab_run_file (_tab_widget->currentWidget ());
 }
@@ -634,83 +690,203 @@
 }
 
 void
-file_editor::request_toggle_bookmark (void)
+file_editor::request_toggle_bookmark (bool)
 {
   emit fetab_toggle_bookmark (_tab_widget->currentWidget ());
 }
 
 void
-file_editor::request_next_bookmark (void)
+file_editor::request_next_bookmark (bool)
 {
   emit fetab_next_bookmark (_tab_widget->currentWidget ());
 }
 
 void
-file_editor::request_previous_bookmark (void)
+file_editor::request_previous_bookmark (bool)
 {
   emit fetab_previous_bookmark (_tab_widget->currentWidget ());
 }
 
 void
-file_editor::request_remove_bookmark (void)
+file_editor::request_remove_bookmark (bool)
 {
   emit fetab_remove_bookmark (_tab_widget->currentWidget ());
 }
 
 void
-file_editor::request_toggle_breakpoint (void)
+file_editor::request_toggle_breakpoint (bool)
 {
   emit fetab_toggle_breakpoint (_tab_widget->currentWidget ());
 }
 
 void
-file_editor::request_next_breakpoint (void)
+file_editor::request_next_breakpoint (bool)
 {
   emit fetab_next_breakpoint (_tab_widget->currentWidget ());
 }
 
 void
-file_editor::request_previous_breakpoint (void)
+file_editor::request_previous_breakpoint (bool)
 {
   emit fetab_previous_breakpoint (_tab_widget->currentWidget ());
 }
 
 void
-file_editor::request_remove_breakpoint (void)
+file_editor::request_remove_breakpoint (bool)
 {
   emit fetab_remove_all_breakpoints (_tab_widget->currentWidget ());
 }
 
+// slots for Edit->Commands actions
 void
-file_editor::request_comment_selected_text (void)
+file_editor::request_delete_start_word (bool)
+{
+  emit fetab_scintilla_command (_tab_widget->currentWidget (),
+                                QsciScintillaBase::SCI_DELWORDLEFT);
+}
+void
+file_editor::request_delete_end_word (bool)
+{
+  emit fetab_scintilla_command (_tab_widget->currentWidget (),
+                                QsciScintillaBase::SCI_DELWORDRIGHT);
+}
+void
+file_editor::request_delete_start_line (bool)
+{
+  emit fetab_scintilla_command (_tab_widget->currentWidget (),
+                                QsciScintillaBase::SCI_DELLINELEFT);
+}
+void
+file_editor::request_delete_end_line (bool)
+{
+  emit fetab_scintilla_command (_tab_widget->currentWidget (),
+                                QsciScintillaBase::SCI_DELLINERIGHT);
+}
+void
+file_editor::request_delete_line (bool)
+{
+  emit fetab_scintilla_command (_tab_widget->currentWidget (),
+                                QsciScintillaBase::SCI_LINEDELETE);
+}
+void
+file_editor::request_copy_line (bool)
+{
+  emit fetab_scintilla_command (_tab_widget->currentWidget (),
+                                QsciScintillaBase::SCI_LINECOPY);
+}
+void
+file_editor::request_cut_line (bool)
+{
+  emit fetab_scintilla_command (_tab_widget->currentWidget (),
+                                QsciScintillaBase::SCI_LINECUT);
+}
+void
+file_editor::request_duplicate_selection (bool)
+{
+  emit fetab_scintilla_command (_tab_widget->currentWidget (),
+                                QsciScintillaBase::SCI_SELECTIONDUPLICATE);
+}
+void
+file_editor::request_transpose_line (bool)
+{
+  emit fetab_scintilla_command (_tab_widget->currentWidget (),
+                                QsciScintillaBase::SCI_LINETRANSPOSE);
+}
+void
+file_editor::request_comment_selected_text (bool)
 {
   emit fetab_comment_selected_text (_tab_widget->currentWidget ());
 }
-
 void
-file_editor::request_uncomment_selected_text (void)
+file_editor::request_uncomment_selected_text (bool)
 {
   emit fetab_uncomment_selected_text (_tab_widget->currentWidget ());
 }
 
+// slots for Edit->Format actions
 void
-file_editor::request_find (void)
+file_editor::request_upper_case (bool)
+{
+  emit fetab_scintilla_command (_tab_widget->currentWidget (),
+                                QsciScintillaBase::SCI_UPPERCASE);
+}
+void
+file_editor::request_lower_case (bool)
+{
+  emit fetab_scintilla_command (_tab_widget->currentWidget (),
+                                QsciScintillaBase::SCI_LOWERCASE);
+}
+void
+file_editor::request_indent_selected_text (bool)
+{
+  emit fetab_indent_selected_text (_tab_widget->currentWidget ());
+}
+
+void
+file_editor::request_unindent_selected_text (bool)
+{
+  emit fetab_unindent_selected_text (_tab_widget->currentWidget ());
+}
+
+void
+file_editor::request_conv_eol_windows (bool)
+{
+  emit fetab_convert_eol (_tab_widget->currentWidget (),
+                          QsciScintilla::EolWindows);
+}
+void
+file_editor::request_conv_eol_unix (bool)
+{
+  emit fetab_convert_eol (_tab_widget->currentWidget (),
+                          QsciScintilla::EolUnix);
+}
+void
+file_editor::request_conv_eol_mac (bool)
+{
+  emit fetab_convert_eol (_tab_widget->currentWidget (),
+                          QsciScintilla::EolMac);
+}
+
+
+void
+file_editor::request_find (bool)
 {
   emit fetab_find (_tab_widget->currentWidget ());
 }
 
 void
-file_editor::request_goto_line (void)
+file_editor::request_goto_line (bool)
 {
   emit fetab_goto_line (_tab_widget->currentWidget ());
 }
 
+void
+file_editor::request_move_match_brace (bool)
+{
+  emit fetab_move_match_brace (_tab_widget->currentWidget (), false);
+}
+
+void
+file_editor::request_sel_match_brace (bool)
+{
+  emit fetab_move_match_brace (_tab_widget->currentWidget (), true);
+}
+
+void
+file_editor::request_completion (bool)
+{
+  emit fetab_completion (_tab_widget->currentWidget ());
+}
 
 void
 file_editor::handle_mru_add_file (const QString& file_name)
 {
+  if (_mru_files.count () && _mru_files.at (0) == file_name)
+    return;  // the first entry is already the actual file name
+
   _mru_files.removeAll (file_name);
   _mru_files.prepend (file_name);
+
   mru_menu_update ();
 }
 
@@ -766,26 +942,39 @@
 void
 file_editor::request_close_file (bool)
 {
-  emit fetab_close_request (_tab_widget->currentWidget ());
+  file_editor_tab *editor_tab =
+      static_cast <file_editor_tab *> (_tab_widget->currentWidget ());
+  editor_tab->conditional_close (0);  // 0: app is not closing, only tab
 }
 
 void
 file_editor::request_close_all_files (bool)
 {
+  file_editor_tab *editor_tab;
+
   // loop over all tabs starting from last one otherwise deletion changes index
   for (int index = _tab_widget->count ()-1; index >= 0; index--)
-    emit fetab_close_request (_tab_widget->widget (index));
+    {
+      editor_tab = static_cast <file_editor_tab *> (_tab_widget->widget (index));
+      editor_tab->conditional_close (0);  // 0: app is not closing, only tab
+    }
 }
 
 void
 file_editor::request_close_other_files (bool)
 {
+  file_editor_tab *editor_tab;
   QWidget *tabID = _tab_widget->currentWidget ();
+
   // loop over all tabs starting from last one otherwise deletion changes index
   for (int index = _tab_widget->count ()-1; index >= 0; index--)
     {
       if (tabID != _tab_widget->widget (index))
-        emit fetab_close_request (_tab_widget->widget (index));
+        {
+          editor_tab =
+              static_cast <file_editor_tab *> (_tab_widget->widget (index));
+          editor_tab->conditional_close (0);  // 0: app is not closing, only tab
+        }
     }
 }
 
@@ -793,12 +982,9 @@
 void
 file_editor::handle_tab_close_request (int index)
 {
-  // Signal to the tabs a request to close whomever matches the identifying
-  // tag (i.e., unique widget pointer).  The reason for this indirection is
-  // that it will enable a file editor widget to toss up a non-static
-  // dialog box and later signal that it wants to be removed.
-  QWidget *tabID = _tab_widget->widget (index);
-  emit fetab_close_request (tabID);
+  file_editor_tab *editor_tab =
+       static_cast <file_editor_tab *> (_tab_widget->widget (index));
+  editor_tab->conditional_close (0);  // 0: app is not closing, only tab
 }
 
 void
@@ -828,15 +1014,99 @@
   editor_tab_map[fileName] = ID;
 }
 
+// context menu of edit area
 void
 file_editor::active_tab_changed (int index)
 {
   emit fetab_change_request (_tab_widget->widget (index));
 }
 
+void file_editor::create_context_menu (QMenu *menu)
+{
+  // remove all standard actions from scintilla
+  QList<QAction *> all_actions = menu->actions ();
+  QAction* a;
+
+  foreach (a, all_actions)
+    menu->removeAction (a);
+
+  // add editor's actions with icons and customized shortcuts
+  menu->addAction (_undo_action);
+  menu->addAction (_redo_action);
+  menu->addSeparator ();
+  menu->addAction (_cut_action);
+  menu->addAction (_copy_action);
+  menu->addAction (_paste_action);
+  menu->addSeparator ();
+  menu->addAction (_selectall_action);
+  menu->addSeparator ();
+  menu->addAction (_run_selection_action);
+}
+
+void
+file_editor::toggle_preference (const QString& preference, bool def)
+{
+  QSettings *settings = resource_manager::get_settings ();
+  bool old = settings->value (preference,def).toBool ();
+  settings->setValue (preference,!old);
+  notice_settings (settings);
+}
+
+void
+file_editor::show_line_numbers (bool)
+{
+  toggle_preference ("editor/showLineNumbers",true);
+}
+void
+file_editor::show_white_space (bool)
+{
+  toggle_preference ("editor/show_white_space",false);
+}
+void
+file_editor::show_eol_chars (bool)
+{
+  toggle_preference ("editor/show_eol_chars",false);
+}
+void
+file_editor::show_indent_guides (bool)
+{
+  toggle_preference ("editor/show_indent_guides",false);
+}
+void
+file_editor::show_long_line (bool)
+{
+  toggle_preference ("editor/long_line_marker",true);
+}
+
+void
+file_editor::zoom_in (bool)
+{
+  emit fetab_zoom_in (_tab_widget->currentWidget ());
+}
+
+void
+file_editor::zoom_out (bool)
+{
+  emit fetab_zoom_out (_tab_widget->currentWidget ());
+}
+
+void
+file_editor::zoom_normal (bool)
+{
+  emit fetab_zoom_normal (_tab_widget->currentWidget ());
+}
+
+void
+file_editor::edit_status_update (bool undo, bool redo)
+{
+  _undo_action->setEnabled (undo);
+  _redo_action->setEnabled (redo);
+}
+
 void
 file_editor::handle_editor_state_changed (bool copy_available,
-                                          const QString& file_name)
+                                          const QString& file_name,
+                                          bool is_octave_file)
 {
   // In case there is some scenario where traffic could be coming from
   // all the file editor tabs, just process info from the current active tab.
@@ -844,7 +1114,8 @@
     {
       _copy_action->setEnabled (copy_available);
       _cut_action->setEnabled (copy_available);
-      _context_run_action->setEnabled (copy_available);
+      _run_selection_action->setEnabled (copy_available);
+      _run_action->setEnabled (is_octave_file);
 
       if (!file_name.isEmpty ())
         {
@@ -866,6 +1137,39 @@
 {
   int icon_size = settings->value ("toolbar_icon_size", 16).toInt ();
   _tool_bar->setIconSize (QSize (icon_size, icon_size));
+
+  int tab_width_min = settings->value ("editor/notebook_tab_width_min", 160)
+                                      .toInt ();
+  int tab_width_max = settings->value ("editor/notebook_tab_width_max", 300)
+                                      .toInt ();
+
+  if (settings->value ("editor/longWindowTitle", false).toBool ())
+    {
+      QString style_sheet = QString ("QTabBar::tab "
+                                     "{min-width: %1px; max-width: %2px;}")
+                             .arg (tab_width_min).arg (tab_width_max);
+      _tab_widget->setElideMode (Qt::ElideLeft);
+      _tab_widget->setStyleSheet (style_sheet);
+    }
+  else
+    _tab_widget->setElideMode (Qt::ElideNone);
+
+  _tab_widget->setUsesScrollButtons (true);
+
+  bool show_it;
+  show_it = settings->value ("editor/showLineNumbers",true).toBool ();
+  _show_linenum_action->setChecked (show_it);
+  show_it = settings->value ("editor/show_white_space",false).toBool ();
+  _show_whitespace_action->setChecked (show_it);
+  show_it = settings->value ("editor/show_eol_chars",false).toBool ();
+  _show_eol_action->setChecked (show_it);
+  show_it = settings->value ("editor/show_indent_guides",false).toBool ();
+  _show_indguide_action->setChecked (show_it);
+  show_it = settings->value ("editor/long_line_marker",true).toBool ();
+  _show_longline_action->setChecked (show_it);
+
+  set_shortcuts ();
+
   // Relay signal to file editor tabs.
   emit fetab_settings_changed (settings);
 }
@@ -883,6 +1187,59 @@
 }
 
 void
+file_editor::insert_new_open_actions (QAction *new_action,
+                                      QAction *new_fcn_action,
+                                      QAction *open_action)
+{
+  _fileMenu->insertAction (_mru_file_menu->menuAction (), open_action);
+  _fileMenu->insertAction (open_action, new_fcn_action);
+  _fileMenu->insertAction (new_fcn_action, new_action);
+  _tool_bar->insertAction (_save_action, open_action);
+  _tool_bar->insertAction (open_action, new_action);
+}
+
+QAction*
+file_editor::add_action (QMenu *menu, const QIcon &icon, const QString &text,
+                         const char *member)
+{
+  QAction *a = menu->addAction (icon, text, this, member);
+  addAction (a);  // important for shortcut context
+  a->setShortcutContext (Qt::WidgetWithChildrenShortcut);
+  return a;
+}
+
+void
+file_editor::enable_menu_shortcuts (bool enable)
+{
+  QHash<QMenu*, QStringList>::const_iterator i = _hash_menu_text.constBegin();
+
+ while (i != _hash_menu_text.constEnd())
+   {
+     i.key ()->setTitle (i.value ().at (! enable));
+     ++i;
+   }
+}
+
+QMenu*
+file_editor::m_add_menu (QMenuBar *p, QString name)
+{
+  QMenu *menu = p->addMenu (name);
+
+  QString base_name = name;  // get a copy
+  // replace intended '&' ("&&") by a temp. string
+  base_name.replace ("&&","___octave_amp_replacement___");
+  // remove single '&' (shortcut)
+  base_name.remove ("&");
+  // restore intended '&'
+  base_name.replace ("___octave_amp_replacement___","&&");
+
+  // remember names with and without shortcut
+  _hash_menu_text[menu] = QStringList () << name << base_name;
+
+  return menu;
+}
+
+void
 file_editor::construct (void)
 {
   QWidget *editor_widget = new QWidget (this);
@@ -897,79 +1254,13 @@
   _tool_bar->setMovable (true);
   _tab_widget = new QTabWidget (editor_widget);
   _tab_widget->setTabsClosable (true);
-
-  QAction *new_action = new QAction (QIcon (":/actions/icons/filenew.png"),
-                                     tr ("&New File"), _tool_bar);
-
-  QAction *open_action = new QAction (QIcon (":/actions/icons/folder_documents.png"),
-                                      tr ("&Open File..."), _tool_bar);
-
-  _save_action = new QAction (QIcon (":/actions/icons/filesave.png"),
-                              tr ("&Save File"), _tool_bar);
-
-  _save_as_action = new QAction (QIcon (":/actions/icons/filesaveas.png"),
-                                 tr ("Save File &As..."), _tool_bar);
-
-  _print_action = new QAction ( QIcon (":/actions/icons/fileprint.png"),
-                                tr ("Print..."), _tool_bar);
-
-  _undo_action = new QAction (QIcon (":/actions/icons/undo.png"),
-                              tr ("&Undo"), _tool_bar);
-
-  _redo_action = new QAction (QIcon (":/actions/icons/redo.png"),
-                              tr ("&Redo"), _tool_bar);
-
-  _copy_action = new QAction (QIcon (":/actions/icons/editcopy.png"),
-                              tr ("&Copy"), _tool_bar);
-  _copy_action->setEnabled (false);
-
-  _cut_action = new QAction (QIcon (":/actions/icons/editcut.png"),
-                             tr ("Cu&t"), _tool_bar);
-  _cut_action->setEnabled (false);
-
-  _paste_action
-    = new QAction (QIcon (":/actions/icons/editpaste.png"),
-                   tr ("Paste"), _tool_bar);
+#ifdef HAVE_QTABWIDGET_SETMOVABLE
+  _tab_widget->setMovable (true);
+#endif
 
-  _next_bookmark_action = new QAction (tr ("&Next Bookmark"), _tool_bar);
-
-  _previous_bookmark_action = new QAction (tr ("Pre&vious Bookmark"),
-                                           _tool_bar);
-
-  _toggle_bookmark_action = new QAction (tr ("Toggle &Bookmark"), _tool_bar);
-
-  _remove_bookmark_action
-    = new QAction (tr ("&Remove All Bookmarks"), _tool_bar);
-
-  QAction *next_breakpoint_action
-    = new QAction (QIcon (":/actions/icons/bp_next.png"),
-                   tr ("&Next Breakpoint"), _tool_bar);
-  QAction *previous_breakpoint_action
-    = new QAction (QIcon (":/actions/icons/bp_prev.png"),
-                   tr ("Pre&vious Breakpoint"), _tool_bar);
-  QAction *toggle_breakpoint_action
-    = new QAction (QIcon (":/actions/icons/bp_toggle.png"),
-                   tr ("Toggle &Breakpoint"), _tool_bar);
-  QAction *remove_all_breakpoints_action
-    = new QAction (QIcon (":/actions/icons/bp_rm_all.png"),
-                   tr ("&Remove All Breakpoints"), _tool_bar);
-
-  _comment_selection_action
-    = new QAction (tr ("&Comment"), _tool_bar);
-  _uncomment_selection_action
-    = new QAction (tr ("&Uncomment"), _tool_bar);
-
-  _find_action = new QAction (QIcon (":/actions/icons/find.png"),
-                              tr ("&Find and Replace..."), _tool_bar);
-
-  _run_action = new QAction (QIcon (":/actions/icons/artsbuilderexecute.png"),
-                             tr ("Save File and Run"), _tool_bar);
-
-  _goto_line_action = new QAction (tr ("Go &to Line..."), _tool_bar);
 
   // the mru-list and an empty array of actions
   QSettings *settings = resource_manager::get_settings ();
-  // FIXME: what should happen if settings is 0?
   _mru_files = settings->value ("editor/mru_file_list").toStringList ();
   for (int i = 0; i < MaxMRUFiles; ++i)
     {
@@ -977,27 +1268,258 @@
       _mru_file_actions[i]->setVisible (false);
     }
 
-  // some actions are disabled from the beginning
-  _copy_action->setEnabled (false);
-  _cut_action->setEnabled (false);
+  // menu bar
+
+  // file menu
+
+  _fileMenu = m_add_menu (_menu_bar, tr ("&File"));
+
+  // new and open menus are inserted later by the main window
+  _mru_file_menu = new QMenu (tr ("&Recent Editor Files"), _fileMenu);
+  for (int i = 0; i < MaxMRUFiles; ++i)
+    _mru_file_menu->addAction (_mru_file_actions[i]);
+  _fileMenu->addMenu (_mru_file_menu);
+
+  _fileMenu->addSeparator ();
+
+  _edit_function_action = add_action (_fileMenu, QIcon (),
+          tr ("&Edit Function"), SLOT (request_context_edit (bool)));
+
+  _fileMenu->addSeparator ();
+
+  _save_action = add_action (_fileMenu, QIcon (":/actions/icons/filesave.png"),
+          tr ("&Save File"), SLOT (request_save_file (bool)));
+  _save_as_action = add_action (_fileMenu, QIcon (":/actions/icons/filesaveas.png"),
+          tr ("Save File &As..."), SLOT (request_save_file_as (bool)));
+
+  _fileMenu->addSeparator ();
+
+  _close_action = add_action (_fileMenu,
+          QIcon::fromTheme("window-close",QIcon (":/actions/icons/fileclose.png")),
+          tr ("&Close"), SLOT (request_close_file (bool)));
+  _close_all_action = add_action (_fileMenu,
+          QIcon::fromTheme("window-close", QIcon (":/actions/icons/fileclose.png")),
+          tr ("Close All"), SLOT (request_close_all_files (bool)));
+  _close_others_action = add_action (_fileMenu,
+          QIcon::fromTheme("window-close", QIcon (":/actions/icons/fileclose.png")),
+          tr ("Close Other Files"), SLOT (request_close_other_files (bool)));
+
+  _fileMenu->addSeparator ();
+
+  _print_action = add_action (_fileMenu, QIcon (":/actions/icons/fileprint.png"),
+          tr ("Print..."), SLOT (request_print_file (bool)));
+
+  // edit menu
+
+  QMenu *editMenu = m_add_menu (_menu_bar, tr ("&Edit"));
+
+  _undo_action = add_action (editMenu, QIcon (":/actions/icons/undo.png"),
+          tr ("&Undo"), SLOT (request_undo (bool)));
+  _undo_action->setEnabled (false);
+  _redo_action = add_action (editMenu, QIcon (":/actions/icons/redo.png"),
+          tr ("&Redo"), SLOT (request_redo (bool)));
+  _redo_action->setEnabled (false);
+
+  editMenu->addSeparator ();
 
-  _run_action->setShortcutContext (Qt::WindowShortcut);
-  _save_action->setShortcutContext (Qt::WindowShortcut);
-  _save_as_action->setShortcutContext (Qt::WindowShortcut);
+  _copy_action = add_action (editMenu, QIcon (":/actions/icons/editcopy.png"),
+          tr ("&Copy"), SLOT (request_copy (bool)));
+  _copy_action->setEnabled (false);
+  _cut_action = add_action (editMenu, QIcon (":/actions/icons/editcut.png"),
+          tr ("Cu&t"), SLOT (request_cut (bool)));
+  _cut_action->setEnabled (false);
+  _paste_action = add_action (editMenu, QIcon (":/actions/icons/editpaste.png"),
+          tr ("Paste"), SLOT (request_paste (bool)));
+
+  editMenu->addSeparator ();
+
+  _selectall_action = add_action (editMenu, QIcon (), tr ("Select All"),
+          SLOT (request_selectall (bool)));
+
+  editMenu->addSeparator ();
+
+  _find_action = add_action (editMenu, QIcon (":/actions/icons/find.png"),
+          tr ("&Find and Replace..."), SLOT (request_find (bool)));
+
+  editMenu->addSeparator ();
+
+  _edit_cmd_menu = editMenu->addMenu (tr ("&Commands"));
+
+  _delete_line_action = add_action (_edit_cmd_menu, QIcon (),
+          tr ("Delete Line"), SLOT (request_delete_line (bool)));
+  _copy_line_action = add_action (_edit_cmd_menu, QIcon (),
+          tr ("Copy Line"), SLOT (request_copy_line (bool)));
+  _cut_line_action = add_action (_edit_cmd_menu, QIcon (),
+          tr ("Cut Line"), SLOT (request_cut_line (bool)));
+
+  _edit_cmd_menu->addSeparator ();
+
+  _delete_start_word_action = add_action (_edit_cmd_menu, QIcon (),
+          tr ("Delete to Start of Word"), SLOT (request_delete_start_word (bool)));
+  _delete_end_word_action = add_action (_edit_cmd_menu, QIcon (),
+          tr ("Delete to End of Word"), SLOT (request_delete_end_word (bool)));
+  _delete_start_line_action = add_action (_edit_cmd_menu, QIcon (),
+          tr ("Delete to Start of Line"), SLOT (request_delete_start_line (bool)));
+  _delete_end_line_action = add_action (_edit_cmd_menu, QIcon (),
+          tr ("Delete to End of Line"), SLOT (request_delete_end_line (bool)));
+
+  _edit_cmd_menu->addSeparator ();
+
+  _duplicate_selection_action = add_action (_edit_cmd_menu, QIcon (),
+          tr ("Duplicate Selection/Line"), SLOT (request_duplicate_selection (bool)));
+  _transpose_line_action = add_action (_edit_cmd_menu, QIcon (),
+          tr ("Transpose Line"), SLOT (request_transpose_line (bool)));
+
+  _edit_cmd_menu->addSeparator ();
+
+  _completion_action = add_action (_edit_cmd_menu, QIcon (),
+          tr ("&Show Completion List"), SLOT (request_completion (bool)));
+
+  _edit_fmt_menu = editMenu->addMenu (tr ("&Format"));
+
+  _upper_case_action = add_action (_edit_fmt_menu, QIcon (),
+          tr ("&Uppercase Selection"), SLOT (request_upper_case (bool)));
+  _lower_case_action = add_action (_edit_fmt_menu, QIcon (),
+          tr ("&Lowercase Selection"), SLOT (request_lower_case (bool)));
+
+  _edit_fmt_menu->addSeparator ();
+
+  _comment_selection_action = add_action (_edit_fmt_menu, QIcon (),
+          tr ("&Comment"), SLOT (request_comment_selected_text (bool)));
+  _uncomment_selection_action = add_action (_edit_fmt_menu, QIcon (),
+          tr ("&Uncomment"), SLOT (request_uncomment_selected_text (bool)));
+
+  _edit_fmt_menu->addSeparator ();
 
-  _print_action->setShortcutContext (Qt::WindowShortcut);
+  _indent_selection_action = add_action (_edit_fmt_menu, QIcon (),
+          tr ("&Indent"), SLOT (request_indent_selected_text (bool)));
+  _unindent_selection_action = add_action (_edit_fmt_menu, QIcon (),
+          tr ("&Unindent"), SLOT (request_unindent_selected_text (bool)));
+
+  _edit_fmt_menu->addSeparator ();
+
+  _conv_eol_windows_action = add_action (_edit_fmt_menu, QIcon (),
+          tr ("Convert Line Endings to &Windows (CRLF)"),
+          SLOT (request_conv_eol_windows (bool)));
+  _conv_eol_unix_action = add_action (_edit_fmt_menu, QIcon (),
+          tr ("Convert Line Endings to &Unix (LF)"),
+          SLOT (request_conv_eol_unix (bool)));
+  _conv_eol_mac_action = add_action (_edit_fmt_menu, QIcon (),
+          tr ("Convert Line Endings to &Mac (CR)"),
+          SLOT (request_conv_eol_mac (bool)));
+
+  _edit_nav_menu = editMenu->addMenu (tr ("Navi&gation"));
+
+  _goto_line_action = add_action (_edit_nav_menu, QIcon (),
+          tr ("Go &to Line..."), SLOT (request_goto_line (bool)));
+
+  _edit_cmd_menu->addSeparator ();
+
+  _move_to_matching_brace  = add_action (_edit_nav_menu, QIcon (),
+          tr ("Move to Matching Brace"), SLOT (request_move_match_brace (bool)));
+  _sel_to_matching_brace  = add_action (_edit_nav_menu, QIcon (),
+          tr ("Select to Matching Brace"), SLOT (request_sel_match_brace (bool)));
+
+  _edit_nav_menu->addSeparator ();
+
+  _next_bookmark_action =  add_action (_edit_nav_menu, QIcon (),
+          tr ("&Next Bookmark"), SLOT (request_next_bookmark (bool)));
+  _previous_bookmark_action =  add_action (_edit_nav_menu, QIcon (),
+          tr ("Pre&vious Bookmark"), SLOT (request_previous_bookmark (bool)));
+  _toggle_bookmark_action =  add_action (_edit_nav_menu, QIcon (),
+          tr ("Toggle &Bookmark"), SLOT (request_toggle_bookmark (bool)));
+  _remove_bookmark_action = add_action (_edit_nav_menu, QIcon (),
+          tr ("&Remove All Bookmarks"), SLOT (request_remove_bookmark (bool)));
+
+  editMenu->addSeparator ();
+
+  _preferences_action = add_action (editMenu,
+          QIcon (":/actions/icons/configure.png"),
+          tr ("&Preferences..."), SLOT (request_preferences (bool)));
+  _styles_preferences_action = add_action (editMenu,
+          QIcon (":/actions/icons/configure.png"),
+          tr ("&Styles Preferences..."), SLOT (request_styles_preferences (bool)));
+
+  // view menu
+
+  QMenu *view_menu = m_add_menu (_menu_bar, tr ("&View"));
+
+  _view_editor_menu = view_menu->addMenu (tr ("&Editor"));
+
+  _show_linenum_action = add_action (_view_editor_menu, QIcon (),
+          tr ("Show &Line Numbers"), SLOT (show_line_numbers (bool)));
+  _show_linenum_action->setCheckable (true);
+
+  _show_whitespace_action = add_action (_view_editor_menu, QIcon (),
+          tr ("Show &White Spaces"), SLOT (show_white_space (bool)));
+  _show_whitespace_action->setCheckable (true);
 
-  _next_bookmark_action->setShortcutContext (Qt::WindowShortcut);
-  _previous_bookmark_action->setShortcutContext (Qt::WindowShortcut);
-  _toggle_bookmark_action->setShortcutContext (Qt::WindowShortcut);
-  _comment_selection_action->setShortcutContext (Qt::WindowShortcut);
-  _uncomment_selection_action->setShortcutContext (Qt::WindowShortcut);
-  _find_action->setShortcutContext (Qt::WindowShortcut);
-  _goto_line_action->setShortcutContext (Qt::WindowShortcut);
+  _show_eol_action = add_action (_view_editor_menu, QIcon (),
+          tr ("Show Line &Endings"), SLOT (show_eol_chars (bool)));
+  _show_eol_action->setCheckable (true);
+
+  _show_indguide_action = add_action (_view_editor_menu, QIcon (),
+          tr ("Show &Indentation Guides"), SLOT (show_indent_guides (bool)));
+  _show_indguide_action->setCheckable (true);
+
+  _show_longline_action = add_action (_view_editor_menu, QIcon (),
+          tr ("Show Long Line &Marker"), SLOT (show_long_line (bool)));
+  _show_longline_action->setCheckable (true);
+
+  view_menu->addSeparator ();
+
+  _zoom_in_action = add_action (view_menu, QIcon (),
+          tr ("Zoom &In"), SLOT (zoom_in (bool)));
+  _zoom_out_action = add_action (view_menu, QIcon (),
+          tr ("Zoom &Out"), SLOT (zoom_out (bool)));
+  _zoom_normal_action = add_action (view_menu, QIcon (),
+          tr ("&Normal Size"), SLOT (zoom_normal (bool)));
+
+  _menu_bar->addMenu (view_menu);
+
+  // debug menu
+
+  _debug_menu = m_add_menu (_menu_bar, tr ("&Debug"));
+
+  _toggle_breakpoint_action = add_action (_debug_menu,
+          QIcon (":/actions/icons/bp_toggle.png"), tr ("Toggle &Breakpoint"),
+          SLOT (request_toggle_breakpoint (bool)));
+  _next_breakpoint_action = add_action (_debug_menu,
+          QIcon (":/actions/icons/bp_next.png"), tr ("&Next Breakpoint"),
+          SLOT (request_next_breakpoint (bool)));
+  _previous_breakpoint_action = add_action (_debug_menu,
+          QIcon (":/actions/icons/bp_prev.png"), tr ("Pre&vious Breakpoint"),
+          SLOT (request_previous_breakpoint (bool)));
+  _remove_all_breakpoints_action = add_action (_debug_menu,
+          QIcon (":/actions/icons/bp_rm_all.png"), tr ("&Remove All Breakpoints"),
+          SLOT (request_remove_breakpoint (bool)));
+
+  _debug_menu->addSeparator ();
+
+  // The other debug actions will be added by the main window.
+
+  // run menu
+
+  QMenu *_run_menu = m_add_menu (_menu_bar, tr ("&Run"));
+
+  _run_action = add_action (_run_menu, QIcon (":/actions/icons/artsbuilderexecute.png"),
+          tr ("Save File and Run"), SLOT (request_run_file (bool)));
+  _run_selection_action = add_action (_run_menu, QIcon (),
+          tr ("Run &Selection"), SLOT (request_context_run (bool)));
+  _run_selection_action->setEnabled (false);
+
+  // help menu
+
+  QMenu *_help_menu = m_add_menu (_menu_bar, tr ("&Help"));
+
+  _context_help_action = add_action (_help_menu, QIcon (),
+          tr ("&Help on Keyword"), SLOT (request_context_help (bool)));
+  _context_doc_action = add_action (_help_menu, QIcon (),
+          tr ("&Documentation on Keyword"), SLOT (request_context_doc (bool)));
 
   // toolbar
-  _tool_bar->addAction (new_action);
-  _tool_bar->addAction (open_action);
+
+  // new and open actions are inserted later from main window
   _tool_bar->addAction (_save_action);
   _tool_bar->addAction (_save_as_action);
   _tool_bar->addSeparator ();
@@ -1012,111 +1534,10 @@
   _tool_bar->addAction (_find_action);
   _tool_bar->addAction (_run_action);
   _tool_bar->addSeparator ();
-  _tool_bar->addAction (toggle_breakpoint_action);
-  _tool_bar->addAction (next_breakpoint_action);
-  _tool_bar->addAction (previous_breakpoint_action);
-  _tool_bar->addAction (remove_all_breakpoints_action);
-
-  // menu bar
-  QMenu *fileMenu = new QMenu (tr ("&File"), _menu_bar);
-
-  _mru_file_menu = new QMenu (tr ("&Recent Editor Files"), fileMenu);
-  for (int i = 0; i < MaxMRUFiles; ++i)
-    _mru_file_menu->addAction (_mru_file_actions[i]);
-
-  fileMenu->addAction (new_action);
-  fileMenu->addAction (QIcon (), tr ("New &Function..."),
-                      this, SLOT (request_new_function (bool)));
-  fileMenu->addAction (open_action);
-  fileMenu->addMenu (_mru_file_menu);
-  fileMenu->addSeparator ();
-  _context_edit_action =
-    fileMenu->addAction (QIcon (), tr ("&Edit Function"),
-                         this, SLOT (request_context_edit (bool)));
-  fileMenu->addSeparator ();
-  fileMenu->addAction (_save_action);
-  fileMenu->addAction (_save_as_action);
-
-  fileMenu->addSeparator ();
-  _close_action =
-    fileMenu->addAction (QIcon::fromTheme("window-close",
-                                          QIcon (":/actions/icons/fileclose.png")),
-                         tr ("&Close"), this, SLOT (request_close_file (bool)));
-  _close_all_action =
-    fileMenu->addAction (QIcon::fromTheme("window-close",
-                                          QIcon (":/actions/icons/fileclose.png")),
-                         tr ("Close All"),
-                         this, SLOT (request_close_all_files (bool)));
-  _close_others_action =
-    fileMenu->addAction (QIcon::fromTheme("window-close",
-                                          QIcon (":/actions/icons/fileclose.png")),
-                         tr ("Close Other Files"),
-                         this, SLOT (request_close_other_files (bool)));
-
-  fileMenu->addSeparator ();
-  fileMenu->addAction (_print_action);
-
-  _menu_bar->addMenu (fileMenu);
-
-
-  QMenu *editMenu = new QMenu (tr ("&Edit"), _menu_bar);
-  editMenu->addAction (_undo_action);
-  editMenu->addAction (_redo_action);
-  editMenu->addSeparator ();
-  editMenu->addAction (_copy_action);
-  editMenu->addAction (_cut_action);
-  editMenu->addAction (_paste_action);
-  editMenu->addSeparator ();
-  editMenu->addAction (_find_action);
-  editMenu->addSeparator ();
-  editMenu->addAction (_comment_selection_action);
-  editMenu->addAction (_uncomment_selection_action);
-  editMenu->addSeparator ();
-  editMenu->addAction (_toggle_bookmark_action);
-  editMenu->addAction (_next_bookmark_action);
-  editMenu->addAction (_previous_bookmark_action);
-  editMenu->addAction (_remove_bookmark_action);
-  editMenu->addSeparator ();
-  editMenu->addAction (_goto_line_action);
-  editMenu->addSeparator ();
-  _preferences_action =
-    editMenu->addAction (QIcon (":/actions/icons/configure.png"),
-                         tr ("&Preferences..."),
-                         this, SLOT (request_preferences (bool)));
-  _styles_preferences_action =
-    editMenu->addAction (QIcon (":/actions/icons/configure.png"),
-                         tr ("&Styles Preferences..."),
-                         this, SLOT (request_styles_preferences (bool)));
-  _menu_bar->addMenu (editMenu);
-
-  _debug_menu = new QMenu (tr ("&Debug"), _menu_bar);
-  _debug_menu->addAction (toggle_breakpoint_action);
-  _debug_menu->addAction (next_breakpoint_action);
-  _debug_menu->addAction (previous_breakpoint_action);
-  _debug_menu->addAction (remove_all_breakpoints_action);
-  _debug_menu->addSeparator ();
-  // The other debug actions will be added by the main window.
-  _menu_bar->addMenu (_debug_menu);
-
-  QMenu *_run_menu = new QMenu (tr ("&Run"), _menu_bar);
-  _run_menu->addAction (_run_action);
-  _context_run_action =
-    _run_menu->addAction (QIcon (), tr ("Run &Selection"),
-                          this, SLOT (request_context_run (bool)));
-  _context_run_action->setEnabled (false);
-  _menu_bar->addMenu (_run_menu);
-
-  QMenu *_help_menu = new QMenu (tr ("&Help"), _menu_bar);
-  _context_help_action =
-    _help_menu->addAction (QIcon (), tr ("&Help on Keyword"),
-                           this, SLOT (request_context_help (bool)));
-  _context_doc_action =
-    _help_menu->addAction (QIcon (), tr ("&Documentation on Keyword"),
-                           this, SLOT (request_context_doc (bool)));
-  _menu_bar->addMenu (_help_menu);
-
-  // shortcuts
-  set_shortcuts (true);
+  _tool_bar->addAction (_toggle_breakpoint_action);
+  _tool_bar->addAction (_next_breakpoint_action);
+  _tool_bar->addAction (_previous_breakpoint_action);
+  _tool_bar->addAction (_remove_all_breakpoints_action);
 
   // layout
   QVBoxLayout *vbox_layout = new QVBoxLayout ();
@@ -1138,75 +1559,6 @@
   connect (main_win (), SIGNAL (open_file_signal (const QString&)),
            this, SLOT (request_open_file (const QString&)));
 
-  connect (new_action, SIGNAL (triggered ()),
-           this, SLOT (request_new_file ()));
-
-  connect (open_action, SIGNAL (triggered ()),
-           this, SLOT (request_open_file ()));
-
-  connect (_undo_action, SIGNAL (triggered ()),
-           this, SLOT (request_undo ()));
-
-  connect (_redo_action, SIGNAL (triggered ()),
-           this, SLOT (request_redo ()));
-
-  connect (_copy_action, SIGNAL (triggered ()),
-           this, SLOT (request_copy ()));
-
-  connect (_cut_action, SIGNAL (triggered ()),
-           this, SLOT (request_cut ()));
-
-  connect (_paste_action, SIGNAL (triggered ()),
-           this, SLOT (request_paste ()));
-
-  connect (_save_action, SIGNAL (triggered ()),
-           this, SLOT (request_save_file ()));
-
-  connect (_save_as_action, SIGNAL (triggered ()),
-           this, SLOT (request_save_file_as ()));
-
-  connect (_print_action, SIGNAL (triggered ()),
-           this, SLOT (request_print_file ()));
-
-  connect (_run_action, SIGNAL (triggered ()),
-           this, SLOT (request_run_file ()));
-
-  connect (_toggle_bookmark_action, SIGNAL (triggered ()),
-           this, SLOT (request_toggle_bookmark ()));
-
-  connect (_next_bookmark_action, SIGNAL (triggered ()),
-           this, SLOT (request_next_bookmark ()));
-
-  connect (_previous_bookmark_action, SIGNAL (triggered ()),
-           this, SLOT (request_previous_bookmark ()));
-
-  connect (_remove_bookmark_action, SIGNAL (triggered ()),
-           this, SLOT (request_remove_bookmark ()));
-
-  connect (toggle_breakpoint_action, SIGNAL (triggered ()),
-           this, SLOT (request_toggle_breakpoint ()));
-
-  connect (next_breakpoint_action, SIGNAL (triggered ()),
-           this, SLOT (request_next_breakpoint ()));
-
-  connect (previous_breakpoint_action, SIGNAL (triggered ()),
-           this, SLOT (request_previous_breakpoint ()));
-
-  connect (remove_all_breakpoints_action, SIGNAL (triggered ()),
-           this, SLOT (request_remove_breakpoint ()));
-
-  connect (_comment_selection_action, SIGNAL (triggered ()),
-           this, SLOT (request_comment_selected_text ()));
-
-  connect (_uncomment_selection_action, SIGNAL (triggered ()),
-           this, SLOT (request_uncomment_selected_text ()));
-
-  connect (_find_action, SIGNAL (triggered ()),
-           this, SLOT (request_find ()));
-
-  connect (_goto_line_action, SIGNAL (triggered ()),
-           this, SLOT (request_goto_line ()));
-
   connect (_mru_file_menu, SIGNAL (triggered (QAction *)),
            this, SLOT (request_mru_open_file (QAction *)));
 
@@ -1233,7 +1585,11 @@
                            QStringList ()).toStringList ();
 
       for (int n = 0; n < sessionFileNames.count (); ++n)
-        request_open_file (sessionFileNames.at (n));
+        {
+          QFileInfo file = QFileInfo (sessionFileNames.at (n));
+          if (file.exists ())
+            request_open_file (sessionFileNames.at (n));
+        }
     }
 
   check_actions ();
@@ -1244,13 +1600,26 @@
 {
   _tab_widget->addTab (f, fn);
 
+  // signals from the qscintilla edit area
+  connect (f->qsci_edit_area (), SIGNAL (status_update (bool, bool)),
+           this, SLOT (edit_status_update (bool, bool)));
+
+  connect (f->qsci_edit_area (), SIGNAL (show_doc_signal (const QString&)),
+           main_win (), SLOT (handle_show_doc (const QString&)));
+
+  connect (f->qsci_edit_area (), SIGNAL (create_context_menu_signal (QMenu *)),
+           this, SLOT (create_context_menu (QMenu *)));
+
+  connect (f->qsci_edit_area (), SIGNAL (execute_command_in_terminal_signal (const QString&)),
+           main_win (), SLOT (execute_command_in_terminal (const QString&)));
+
   // Signals from the file editor_tab
   connect (f, SIGNAL (file_name_changed (const QString&, const QString&)),
            this, SLOT (handle_file_name_changed (const QString&,
                                                  const QString&)));
 
-  connect (f, SIGNAL (editor_state_changed (bool, const QString&)),
-           this, SLOT (handle_editor_state_changed (bool, const QString&)));
+  connect (f, SIGNAL (editor_state_changed (bool, const QString&, bool)),
+           this, SLOT (handle_editor_state_changed (bool, const QString&, bool)));
 
   connect (f, SIGNAL (tab_remove_request ()),
            this, SLOT (handle_tab_remove_request ()));
@@ -1267,16 +1636,16 @@
   connect (f, SIGNAL (run_file_signal (const QFileInfo&)),
            main_win (), SLOT (run_file_in_terminal (const QFileInfo&)));
 
-  connect (f, SIGNAL (execute_command_in_terminal_signal (const QString&)),
-           main_win (), SLOT (execute_command_in_terminal (const QString&)));
+  connect (f, SIGNAL (request_open_file (const QString&)),
+           this, SLOT (request_open_file (const QString&)));
+
+  connect (f, SIGNAL (set_global_edit_shortcuts_signal (bool)),
+           main_win (), SLOT (set_global_edit_shortcuts (bool)));
 
   // Signals from the file_editor non-trivial operations
   connect (this, SIGNAL (fetab_settings_changed (const QSettings *)),
            f, SLOT (notice_settings (const QSettings *)));
 
-  connect (this, SIGNAL (fetab_close_request (const QWidget*,bool)),
-           f, SLOT (conditional_close (const QWidget*,bool)));
-
   connect (this, SIGNAL (fetab_change_request (const QWidget*)),
            f, SLOT (change_editor_state (const QWidget*)));
 
@@ -1288,20 +1657,12 @@
            f, SLOT (save_file (const QWidget*, const QString&, bool)));
 
   // Signals from the file_editor trivial operations
-  connect (this, SIGNAL (fetab_undo (const QWidget*)),
-           f, SLOT (undo (const QWidget*)));
-
-  connect (this, SIGNAL (fetab_redo (const QWidget*)),
-           f, SLOT (redo (const QWidget*)));
-
-  connect (this, SIGNAL (fetab_copy (const QWidget*)),
-           f, SLOT (copy (const QWidget*)));
-
-  connect (this, SIGNAL (fetab_cut (const QWidget*)),
-           f, SLOT (cut (const QWidget*)));
-
-  connect (this, SIGNAL (fetab_paste (const QWidget*)),
-           f, SLOT (paste (const QWidget*)));
+  connect (this, SIGNAL (fetab_zoom_in (const QWidget*)),
+           f, SLOT (zoom_in (const QWidget*)));
+  connect (this, SIGNAL (fetab_zoom_out (const QWidget*)),
+           f, SLOT (zoom_out (const QWidget*)));
+  connect (this, SIGNAL (fetab_zoom_normal (const QWidget*)),
+           f, SLOT (zoom_normal (const QWidget*)));
 
   connect (this, SIGNAL (fetab_context_help (const QWidget*, bool)),
            f, SLOT (context_help (const QWidget*, bool)));
@@ -1348,18 +1709,36 @@
   connect (this, SIGNAL (fetab_remove_all_breakpoints (const QWidget*)),
            f, SLOT (remove_all_breakpoints (const QWidget*)));
 
+  connect (this, SIGNAL (fetab_scintilla_command (const QWidget *, unsigned int)),
+           f, SLOT (scintilla_command (const QWidget *, unsigned int)));
+
   connect (this, SIGNAL (fetab_comment_selected_text (const QWidget*)),
            f, SLOT (comment_selected_text (const QWidget*)));
 
   connect (this, SIGNAL (fetab_uncomment_selected_text (const QWidget*)),
            f, SLOT (uncomment_selected_text (const QWidget*)));
 
+  connect (this, SIGNAL (fetab_indent_selected_text (const QWidget*)),
+           f, SLOT (indent_selected_text (const QWidget*)));
+
+  connect (this, SIGNAL (fetab_unindent_selected_text (const QWidget*)),
+           f, SLOT (unindent_selected_text (const QWidget*)));
+
+  connect (this, SIGNAL (fetab_convert_eol (const QWidget*, QsciScintilla::EolMode)),
+           f, SLOT (convert_eol (const QWidget*, QsciScintilla::EolMode)));
+
   connect (this, SIGNAL (fetab_find (const QWidget*)),
            f, SLOT (find (const QWidget*)));
 
   connect (this, SIGNAL (fetab_goto_line (const QWidget*, int)),
            f, SLOT (goto_line (const QWidget*, int)));
 
+  connect (this, SIGNAL (fetab_move_match_brace (const QWidget*, bool)),
+           f, SLOT (move_match_brace (const QWidget*, bool)));
+
+  connect (this, SIGNAL (fetab_completion (const QWidget*)),
+           f, SLOT (show_auto_completion (const QWidget*)));
+
   connect (this, SIGNAL (fetab_set_focus (const QWidget*)),
            f, SLOT (set_focus (const QWidget*)));
 
@@ -1385,7 +1764,7 @@
 
   if (foc_w && foc_w->inherits ("octave_qscintilla"))
     {
-      request_copy ();
+      request_copy (true);
     }
 }
 void
@@ -1395,76 +1774,96 @@
 
   if (foc_w && foc_w->inherits ("octave_qscintilla"))
     {
-      request_paste ();
+      request_paste (true);
+    }
+}
+void
+file_editor::selectAll ()
+{
+  QWidget * foc_w = focusWidget ();
+
+  if (foc_w && foc_w->inherits ("octave_qscintilla"))
+    {
+      request_selectall (true);
     }
 }
 
 void
-file_editor::set_shortcuts (bool set)
+file_editor::set_shortcuts ()
 {
-  if (set)
-    {
-      _comment_selection_action->setShortcut (Qt::ControlModifier + Qt::Key_R);
-      _uncomment_selection_action->setShortcut (Qt::SHIFT
-                                                + Qt::ControlModifier
-                                                + Qt::Key_R);
-
-      _copy_action->setShortcut (QKeySequence::Copy);
-      _cut_action->setShortcut (QKeySequence::Cut);
-      _paste_action->setShortcut (QKeySequence::Paste);
-      _context_help_action->setShortcut (QKeySequence::HelpContents);
-      _context_doc_action->setShortcut (Qt::SHIFT + Qt::Key_F1);
+  // File menu
+  shortcut_manager::set_shortcut (_edit_function_action, "editor_file:edit_function");
+  shortcut_manager::set_shortcut (_save_action, "editor_file:save");
+  shortcut_manager::set_shortcut (_save_as_action, "editor_file:save_as");
+  shortcut_manager::set_shortcut (_close_action, "editor_file:close");
+  shortcut_manager::set_shortcut (_close_all_action, "editor_file:close_all");
+  shortcut_manager::set_shortcut (_close_others_action, "editor_file:close_other");
+  shortcut_manager::set_shortcut (_print_action, "editor_file:print");
 
-      _find_action->setShortcut (QKeySequence::Find);
-      _goto_line_action->setShortcut (Qt::ControlModifier+ Qt::Key_G);
-
-      _next_bookmark_action->setShortcut (Qt::Key_F2);
-      _previous_bookmark_action->setShortcut (Qt::SHIFT + Qt::Key_F2);
-      _toggle_bookmark_action->setShortcut (Qt::Key_F7);
+  // Edit menu
+  shortcut_manager::set_shortcut (_undo_action, "editor_edit:undo");
+  shortcut_manager::set_shortcut (_redo_action, "editor_edit:redo");
+  shortcut_manager::set_shortcut (_copy_action, "editor_edit:copy");
+  shortcut_manager::set_shortcut (_cut_action, "editor_edit:cut");
+  shortcut_manager::set_shortcut (_paste_action, "editor_edit:paste");
+  shortcut_manager::set_shortcut (_selectall_action, "editor_edit:select_all");
+  shortcut_manager::set_shortcut (_find_action, "editor_edit:find_replace");
 
-      _print_action->setShortcut (QKeySequence::Print);
-      _run_action->setShortcut (Qt::Key_F5);
-      _context_run_action->setShortcut (Qt::Key_F9);
-
-      _context_edit_action->setShortcut (Qt::ControlModifier + Qt::Key_E);
-      _save_action->setShortcut (QKeySequence::Save);
-      _save_as_action->setShortcut (QKeySequence::SaveAs);
-      _close_action->setShortcut (QKeySequence::Close);
+  shortcut_manager::set_shortcut (_delete_start_word_action, "editor_edit:delete_start_word");
+  shortcut_manager::set_shortcut (_delete_end_word_action, "editor_edit:delete_end_word");
+  shortcut_manager::set_shortcut (_delete_start_line_action, "editor_edit:delete_start_line");
+  shortcut_manager::set_shortcut (_delete_end_line_action, "editor_edit:delete_end_line");
+  shortcut_manager::set_shortcut (_delete_line_action, "editor_edit:delete_line");
+  shortcut_manager::set_shortcut (_copy_line_action, "editor_edit:copy_line");
+  shortcut_manager::set_shortcut (_cut_line_action, "editor_edit:cut_line");
+  shortcut_manager::set_shortcut (_duplicate_selection_action, "editor_edit:duplicate_selection");
+  shortcut_manager::set_shortcut (_transpose_line_action, "editor_edit:transpose_line");
+  shortcut_manager::set_shortcut (_comment_selection_action, "editor_edit:comment_selection");
+  shortcut_manager::set_shortcut (_uncomment_selection_action, "editor_edit:uncomment_selection");
 
-      _redo_action->setShortcut (QKeySequence::Redo);
-      _undo_action->setShortcut (QKeySequence::Undo);
-    }
-  else
-    {
-      QKeySequence no_key = QKeySequence ();
+  shortcut_manager::set_shortcut (_upper_case_action, "editor_edit:upper_case");
+  shortcut_manager::set_shortcut (_lower_case_action, "editor_edit:lower_case");
+  shortcut_manager::set_shortcut (_indent_selection_action, "editor_edit:indent_selection");
+  shortcut_manager::set_shortcut (_unindent_selection_action, "editor_edit:unindent_selection");
+  shortcut_manager::set_shortcut (_completion_action, "editor_edit:completion_list");
+  shortcut_manager::set_shortcut (_goto_line_action, "editor_edit:goto_line");
+  shortcut_manager::set_shortcut (_move_to_matching_brace, "editor_edit:move_to_brace");
+  shortcut_manager::set_shortcut (_sel_to_matching_brace, "editor_edit:select_to_brace");
+  shortcut_manager::set_shortcut (_toggle_bookmark_action, "editor_edit:toggle_bookmark");
+  shortcut_manager::set_shortcut (_next_bookmark_action, "editor_edit:next_bookmark");
+  shortcut_manager::set_shortcut (_previous_bookmark_action, "editor_edit:previous_bookmark");
+  shortcut_manager::set_shortcut (_remove_bookmark_action, "editor_edit:remove_bookmark");
+  shortcut_manager::set_shortcut (_preferences_action, "editor_edit:preferences");
+  shortcut_manager::set_shortcut (_styles_preferences_action, "editor_edit:styles_preferences");
 
-      _comment_selection_action->setShortcut (no_key);
-      _uncomment_selection_action->setShortcut (no_key);
-
-      _copy_action->setShortcut (no_key);
-      _cut_action->setShortcut (no_key);
-      _paste_action->setShortcut (no_key);
-      _context_help_action->setShortcut (no_key);
+  shortcut_manager::set_shortcut (_conv_eol_windows_action, "editor_edit:conv_eol_winows");
+  shortcut_manager::set_shortcut (_conv_eol_unix_action,    "editor_edit:conv_eol_unix");
+  shortcut_manager::set_shortcut (_conv_eol_mac_action,     "editor_edit:conv_eol_mac");
 
-      _find_action->setShortcut (no_key);
-      _goto_line_action->setShortcut (no_key);
-
-      _next_bookmark_action->setShortcut (no_key);
-      _previous_bookmark_action->setShortcut (no_key);
-      _toggle_bookmark_action->setShortcut (no_key);
+  // View menu
+  shortcut_manager::set_shortcut (_show_linenum_action, "editor_view:show_line_numbers");
+  shortcut_manager::set_shortcut (_show_whitespace_action, "editor_view:show_white_spaces");
+  shortcut_manager::set_shortcut (_show_eol_action, "editor_view:show_eol_chars");
+  shortcut_manager::set_shortcut (_show_indguide_action, "editor_view:show_ind_guides");
+  shortcut_manager::set_shortcut (_show_longline_action, "editor_view:show_long_line");
+  shortcut_manager::set_shortcut (_zoom_in_action, "editor_view:zoom_in");
+  shortcut_manager::set_shortcut (_zoom_out_action, "editor_view:zoom_out");
+  shortcut_manager::set_shortcut (_zoom_normal_action, "editor_view:zoom_normal");
 
-      _print_action->setShortcut (no_key);
-      _run_action->setShortcut (no_key);
-      _context_run_action->setShortcut (no_key);
+  // Debug menu
+  shortcut_manager::set_shortcut (_toggle_breakpoint_action, "editor_debug:toggle_breakpoint");
+  shortcut_manager::set_shortcut (_next_breakpoint_action, "editor_debug:next_breakpoint");
+  shortcut_manager::set_shortcut (_previous_bookmark_action, "editor_debug:previous_breakpoint");
+  shortcut_manager::set_shortcut (_remove_all_breakpoints_action, "editor_debug:remove_breakpoints");
 
-      _context_edit_action->setShortcut (no_key);
-      _save_action->setShortcut (no_key);
-      _save_as_action->setShortcut (no_key);
-      _close_action->setShortcut (no_key);
+  // Run menu
+  shortcut_manager::set_shortcut (_run_action, "editor_run:run_file");
+  shortcut_manager::set_shortcut (_run_selection_action, "editor_run:run_selection");
 
-      _redo_action->setShortcut (no_key);
-      _undo_action->setShortcut (no_key);
-    }
+  // Help menu
+  shortcut_manager::set_shortcut (_context_help_action, "editor_help:help_keyword");
+  shortcut_manager::set_shortcut (_context_doc_action,  "editor_help:doc_keyword");
+
 }
 
 void
@@ -1472,34 +1871,120 @@
 {
   bool  have_tabs = _tab_widget->count () > 0;
 
+  _edit_cmd_menu->setEnabled (have_tabs);
+  _edit_fmt_menu->setEnabled (have_tabs);
+  _edit_nav_menu->setEnabled (have_tabs);
+
   _comment_selection_action->setEnabled (have_tabs);
   _uncomment_selection_action->setEnabled (have_tabs);
+  _indent_selection_action->setEnabled (have_tabs);
+  _unindent_selection_action->setEnabled (have_tabs);
 
   _paste_action->setEnabled (have_tabs);
   _context_help_action->setEnabled (have_tabs);
   _context_doc_action->setEnabled (have_tabs);
 
-  _find_action->setEnabled (have_tabs);
-  _goto_line_action->setEnabled (have_tabs);
+  _view_editor_menu->setEnabled (have_tabs);
+  _zoom_in_action->setEnabled (have_tabs);
+  _zoom_out_action->setEnabled (have_tabs);
+  _zoom_normal_action->setEnabled (have_tabs);
 
-  _next_bookmark_action->setEnabled (have_tabs);
-  _previous_bookmark_action->setEnabled (have_tabs);
-  _toggle_bookmark_action->setEnabled (have_tabs);
-  _remove_bookmark_action->setEnabled (have_tabs);
-
+  _find_action->setEnabled (have_tabs);
   _print_action->setEnabled (have_tabs);
   _run_action->setEnabled (have_tabs);
 
-  _context_edit_action->setEnabled (have_tabs);
+  _edit_function_action->setEnabled (have_tabs);
   _save_action->setEnabled (have_tabs);
   _save_as_action->setEnabled (have_tabs);
   _close_action->setEnabled (have_tabs);
   _close_all_action->setEnabled (have_tabs);
   _close_others_action->setEnabled (have_tabs && _tab_widget->count () > 1);
 
-  _undo_action->setEnabled (have_tabs);
-  _redo_action->setEnabled (have_tabs);
+  _selectall_action->setEnabled (have_tabs);
 }
 
+// empty_script determines whether we have to create an empty script
+// 1. At startup, when the editor has to be (really) visible
+//    (Here we can not use the visibility changed signal)
+// 2. When the editor becomes visible when octave is running
+void
+file_editor::empty_script (bool startup, bool visible)
+{
+  bool real_visible;
+
+  if (startup)
+    real_visible = isVisible ();
+  else
+    real_visible = visible;
+
+  if (! real_visible || _tab_widget->count () > 0)
+    return;
+
+  if (startup && ! isFloating ())
+    {
+      // check is editor is really visible or hidden between tabbed widgets
+      QList<QTabBar *> tab_list = main_win ()->findChildren<QTabBar *>();
+
+      bool in_tab = false;
+      int i = 0;
+      while ((i < tab_list.count ()) && (! in_tab))
+        {
+          QTabBar *tab = tab_list.at (i);
+          i++;
+
+          int j = 0;
+          while ((j < tab->count ()) && (! in_tab))
+            {
+              // check all tabs for the editor
+              if (tab->tabText (j) == windowTitle ())
+                {
+                  // editor is in this tab widget
+                  in_tab = true;
+                  int top = tab->currentIndex ();
+                  if (top > -1 && tab->tabText (top) == windowTitle ())
+                    real_visible = true;  // and is the current tab
+                  else
+                    return; // not current tab -> not visible
+                }
+              j++;
+            }
+        }
+    }
+
+  request_new_file ("");
+}
+
+// This slot is a reimplementation of the virtual slot in octave_dock_widget.
+// We need this for creating an empty script when the editor has no open files
+// and is made visible
+void
+file_editor::handle_visibility (bool visible)
+  {
+    empty_script (false, visible);
+
+    if (visible && ! isFloating ())
+      focus ();
+  }
+
+void
+file_editor::dragEnterEvent (QDragEnterEvent *e)
+  {
+    if (e->mimeData ()->hasUrls ())
+      {
+        e->acceptProposedAction();
+      }
+  }
+
+void
+file_editor::dropEvent (QDropEvent *e)
+  {
+    if (e->mimeData ()->hasUrls ())
+      {
+        foreach (QUrl url, e->mimeData ()->urls ())
+        {
+          request_open_file (url.toLocalFile ());
+        }
+      }
+  }
 
 #endif
--- a/libgui/src/m-editor/file-editor.h	Fri Feb 06 08:31:09 2015 -0800
+++ b/libgui/src/m-editor/file-editor.h	Fri Feb 06 08:31:49 2015 -0800
@@ -29,6 +29,10 @@
 #include <QStatusBar>
 #include <QCloseEvent>
 #include <QTabWidget>
+#include <QStackedWidget>
+
+#include <QDragEnterEvent>
+#include <QDropEvent>
 
 #include <map>
 
@@ -52,16 +56,17 @@
   QMenu *get_mru_menu (void) { return _mru_file_menu; }
   QMenu *debug_menu (void);
   QToolBar *toolbar (void);
+  void insert_new_open_actions (QAction*,QAction*,QAction*);
 
-  void set_focus (void);
   void handle_enter_debug_mode (void);
   void handle_exit_debug_mode (void);
 
   void check_actions (void);
+  void empty_script (bool startup, bool visible);
+
 signals:
 
   void fetab_settings_changed (const QSettings *settings);
-  void fetab_close_request (const QWidget* ID, bool app_closing = false);
   void fetab_change_request (const QWidget* ID);
   void fetab_file_name_query (const QWidget* ID);
   // Save is a ping-pong type of communication
@@ -69,11 +74,6 @@
                         bool remove_on_success);
   // No fetab_open, functionality in editor
   // No fetab_new, functionality in editor
-  void fetab_undo (const QWidget* ID);
-  void fetab_redo (const QWidget* ID);
-  void fetab_copy (const QWidget* ID);
-  void fetab_cut (const QWidget* ID);
-  void fetab_paste (const QWidget* ID);
   void fetab_context_help (const QWidget* ID, bool);
   void fetab_context_edit (const QWidget* ID);
   void fetab_save_file (const QWidget* ID);
@@ -91,19 +91,33 @@
   void fetab_remove_all_breakpoints (const QWidget* ID);
   void fetab_comment_selected_text (const QWidget* ID);
   void fetab_uncomment_selected_text (const QWidget* ID);
+  void fetab_indent_selected_text (const QWidget* ID);
+  void fetab_unindent_selected_text (const QWidget* ID);
+  void fetab_convert_eol (const QWidget* ID, QsciScintilla::EolMode eol_mode);
   void fetab_find (const QWidget* ID);
   void fetab_goto_line (const QWidget* ID, int line = -1);
+  void fetab_move_match_brace (const QWidget* ID, bool select);
+  void fetab_completion (const QWidget*);
   void fetab_insert_debugger_pointer (const QWidget* ID, int line = -1);
   void fetab_delete_debugger_pointer (const QWidget* ID, int line = -1);
   void fetab_do_breakpoint_marker (bool insert, const QWidget* ID,
                                    int line = -1);
   void fetab_set_focus (const QWidget* ID);
+  void fetab_scintilla_command (const QWidget* ID, unsigned int sci_msg);
+
+  void fetab_zoom_in (const QWidget* ID);
+  void fetab_zoom_out (const QWidget* ID);
+  void fetab_zoom_normal (const QWidget* ID);
+
   void request_settings_dialog (const QString&);
   void execute_command_in_terminal_signal (const QString&);
   void file_loaded_signal ();
 
 public slots:
+
   void focus (void);
+  void enable_menu_shortcuts (bool);
+  bool check_closing (int closing_state);
 
   void request_new_file (const QString& commands);
   void request_new_script (const QString& commands);
@@ -113,35 +127,58 @@
   void request_close_all_files (bool);
   void request_close_other_files (bool);
   void request_mru_open_file (QAction *action);
-  void request_print_file (void);
+  void request_print_file (bool);
 
-  void request_undo (void);
-  void request_redo (void);
-  void request_copy (void);
-  void request_cut (void);
-  void request_paste (void);
+  void request_undo (bool);
+  void request_redo (bool);
+  void request_copy (bool);
+  void request_cut (bool);
+  void request_paste (bool);
+  void request_selectall (bool);
   void request_context_help (bool);
   void request_context_doc (bool);
   void request_context_edit (bool);
-  void request_save_file (void);
-  void request_save_file_as (void);
-  void request_run_file (void);
+  void request_save_file (bool);
+  void request_save_file_as (bool);
+  void request_run_file (bool);
   void request_context_run (bool);
-  void request_toggle_bookmark (void);
-  void request_next_bookmark (void);
-  void request_previous_bookmark (void);
-  void request_remove_bookmark (void);
+  void request_toggle_bookmark (bool);
+  void request_next_bookmark (bool);
+  void request_previous_bookmark (bool);
+  void request_remove_bookmark (bool);
+
+  void request_move_match_brace (bool);
+  void request_sel_match_brace (bool);
+  void request_toggle_breakpoint (bool);
+  void request_next_breakpoint (bool);
+  void request_previous_breakpoint (bool);
+  void request_remove_breakpoint (bool);
 
-  void request_toggle_breakpoint (void);
-  void request_next_breakpoint (void);
-  void request_previous_breakpoint (void);
-  void request_remove_breakpoint (void);
+  void request_delete_start_word (bool);
+  void request_delete_end_word (bool);
+  void request_delete_start_line (bool);
+  void request_delete_end_line (bool);
+  void request_delete_line (bool);
+  void request_copy_line (bool);
+  void request_cut_line (bool);
+  void request_duplicate_selection (bool);
+  void request_transpose_line (bool);
+
+  void request_comment_selected_text (bool);
+  void request_uncomment_selected_text (bool);
 
-  void request_comment_selected_text (void);
-  void request_uncomment_selected_text (void);
-  void request_find (void);
+  void request_upper_case (bool);
+  void request_lower_case (bool);
+  void request_indent_selected_text (bool);
+  void request_unindent_selected_text (bool);
+  void request_conv_eol_windows (bool);
+  void request_conv_eol_unix (bool);
+  void request_conv_eol_mac (bool);
 
-  void request_goto_line (void);
+  void request_find (bool);
+
+  void request_goto_line (bool);
+  void request_completion (bool);
 
   void handle_file_name_changed (const QString& fileName,
                                  const QString& toolTip);
@@ -149,7 +186,8 @@
   void handle_tab_remove_request (void);
   void handle_add_filename_to_list (const QString& fileName, QWidget *ID);
   void active_tab_changed (int index);
-  void handle_editor_state_changed (bool enableCopy, const QString& fileName);
+  void handle_editor_state_changed (bool enableCopy, const QString& fileName,
+                                    bool is_octave_file);
   void handle_mru_add_file (const QString& file_name);
   void check_conflict_save (const QString& fileName, bool remove_on_success);
 
@@ -163,16 +201,19 @@
   // Tells the editor to react on changed settings.
   void notice_settings (const QSettings *settings);
 
-  // Tells the ditor to dis- or enable some shortcuts
-  void set_shortcuts (bool set_shortcuts);
+  void set_shortcuts ();
+
+  void handle_visibility (bool visible);
 
 
 protected slots:
   void copyClipboard ();
   void pasteClipboard ();
+  void selectAll ();
 
 private slots:
 
+  void request_open_files (const QStringList&);
   void request_open_file (const QString& fileName, int line = -1,
                           bool debug_pointer = false,
                           bool breakpoint_marker = false, bool insert = true);
@@ -180,6 +221,23 @@
   void request_styles_preferences (bool);
   void restore_create_file_setting ();
 
+  void show_line_numbers (bool);
+  void show_white_space (bool);
+  void show_eol_chars (bool);
+  void show_indent_guides (bool);
+  void show_long_line (bool);
+  void zoom_in (bool);
+  void zoom_out (bool);
+  void zoom_normal (bool);
+
+  void create_context_menu (QMenu *);
+  void edit_status_update (bool, bool);
+
+protected:
+
+  void dragEnterEvent(QDragEnterEvent *event);
+  void dropEvent(QDropEvent *event);
+
 private:
 
   bool is_editor_console_tabbed ();
@@ -189,9 +247,16 @@
   void mru_menu_update (void);
   bool call_custom_editor (const QString& file_name = QString (), int line = -1);
 
+  void toggle_preference (const QString& preference, bool def);
+
   QWidget *find_tab_widget (const QString& openFileName) const;
+  QAction *add_action (QMenu *menu, const QIcon &icon, const QString &text,
+                       const char *member);
+
+  QMenu* m_add_menu (QMenuBar *p, QString text);
 
   std::map<QString, QWidget *> editor_tab_map;
+  QHash<QMenu*, QStringList> _hash_menu_text;
 
   QString ced;
 
@@ -199,18 +264,52 @@
   QToolBar *_tool_bar;
   QMenu *_debug_menu;
 
+  QAction *_new_action;
+  QAction *_new_function_action;
+  QAction *_open_action;
+
+  QAction *_upper_case_action;
+  QAction *_lower_case_action;
   QAction *_comment_selection_action;
   QAction *_uncomment_selection_action;
+  QAction *_indent_selection_action;
+  QAction *_unindent_selection_action;
+  QAction *_conv_eol_windows_action;
+  QAction *_conv_eol_unix_action;
+  QAction *_conv_eol_mac_action;
 
   QAction *_copy_action;
   QAction *_cut_action;
   QAction *_paste_action;
+  QAction *_selectall_action;
   QAction *_context_help_action;
   QAction *_context_doc_action;
 
+  QAction *_show_linenum_action;
+  QAction *_show_whitespace_action;
+  QAction *_show_eol_action;
+  QAction *_show_indguide_action;
+  QAction *_show_longline_action;
+  QAction *_zoom_in_action;
+  QAction *_zoom_out_action;
+  QAction *_zoom_normal_action;
+
+  QAction *_delete_start_word_action;
+  QAction *_delete_end_word_action;
+  QAction *_delete_start_line_action;
+  QAction *_delete_end_line_action;
+  QAction *_delete_line_action;
+  QAction *_copy_line_action;
+  QAction *_cut_line_action;
+  QAction *_duplicate_selection_action;
+  QAction *_transpose_line_action;
+
   QAction *_find_action;
   QAction *_goto_line_action;
+  QAction *_completion_action;
 
+  QAction *_move_to_matching_brace;
+  QAction *_sel_to_matching_brace;
   QAction *_next_bookmark_action;
   QAction *_previous_bookmark_action;
   QAction *_toggle_bookmark_action;
@@ -218,9 +317,9 @@
 
   QAction *_print_action;
   QAction *_run_action;
-  QAction *_context_run_action;
+  QAction *_run_selection_action;
 
-  QAction *_context_edit_action;
+  QAction *_edit_function_action;
   QAction *_save_action;
   QAction *_save_as_action;
   QAction *_close_action;
@@ -233,6 +332,17 @@
   QAction *_preferences_action;
   QAction *_styles_preferences_action;
 
+  QAction *_toggle_breakpoint_action;
+  QAction *_next_breakpoint_action;
+  QAction *_previous_breakpoint_action;
+  QAction *_remove_all_breakpoints_action;
+
+  QMenu *_edit_cmd_menu;
+  QMenu *_edit_fmt_menu;
+  QMenu *_edit_nav_menu;
+  QMenu *_fileMenu;
+  QMenu *_view_editor_menu;
+
   QTabWidget *_tab_widget;
 
   int _marker_breakpoint;
@@ -241,7 +351,6 @@
   QMenu *_mru_file_menu;
   QAction *_mru_file_actions[MaxMRUFiles];
   QStringList _mru_files;
-
 };
 
 #endif // FILEEDITORMDISUBWINDOW_H
--- a/libgui/src/m-editor/find-dialog.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/libgui/src/m-editor/find-dialog.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -71,7 +71,7 @@
 find_dialog::find_dialog (QsciScintilla* edit_area, QWidget *p)
   : QDialog (p)
 {
-  setWindowTitle ("Find and Replace");
+  setWindowTitle (tr ("Find and Replace"));
   setWindowIcon (QIcon(":/actions/icons/find.png"));
 
   _search_label = new QLabel (tr ("Find &what:"));
@@ -107,8 +107,13 @@
   _regex_check_box = new QCheckBox (tr ("Regular E&xpressions"));
   _backward_check_box = new QCheckBox (tr ("Search &backward"));
   _search_selection_check_box = new QCheckBox (tr ("Search se&lection"));
-  _search_selection_check_box->setCheckable (false); // TODO: Not implemented.
+#ifdef HAVE_QSCI_FINDSELECTION
+  _search_selection_check_box->setCheckable (true);
+  _search_selection_check_box->setEnabled (edit_area->hasSelectedText ());
+#else
+  _search_selection_check_box->setCheckable (false);
   _search_selection_check_box->setEnabled (false);
+#endif
 
   _edit_area = edit_area;
   connect (_find_next_button,   SIGNAL (clicked ()),
@@ -125,6 +130,15 @@
            this,                SLOT (handle_backward_search_changed (int)));
   connect (_button_box,         SIGNAL (rejected ()),
            this,                SLOT (close ()));
+  connect (_search_line_edit,   SIGNAL (textChanged (QString)),
+           this,                SLOT (handle_search_text_changed (QString)));
+
+#ifdef HAVE_QSCI_FINDSELECTION
+  connect (_edit_area, SIGNAL (copyAvailable (bool)),
+           this,       SLOT (handle_selection_changed (bool)));
+  connect (_search_selection_check_box, SIGNAL (stateChanged (int)),
+           this,                        SLOT (handle_sel_search_changed (int)));
+#endif
 
   QVBoxLayout *extension_layout = new QVBoxLayout ();
   extension_layout->setMargin (0);
@@ -157,16 +171,15 @@
   _extension->hide ();
   _find_next_button->setDefault (true);
   _find_result_available = false;
+  _rep_all = 0;
+  _rep_active = false;
 
   // move dialog to side of the parent if there is room on the desktop to do so.
-  QWidget * desktop = QApplication::desktop ();
-  int xp = p->x () + p->frameGeometry ().width ();
-  int yp=  p->y ();
-  if (desktop != 0 && sizeHint ().isValid ())
-    {
-      if (xp + sizeHint ().width () > desktop->width ())
-        xp = desktop->width () - sizeHint ().width ();
-    }
+  int xp = p->x () +20;
+  int yp = p->y () + p->frameGeometry ().height () - sizeHint ().height () -20;
+
+  if (yp < 0)
+    yp = 0;
 
   move (xp, yp);
 
@@ -182,6 +195,35 @@
     _from_start_check_box->setText (tr ("Search from start"));
 }
 
+// search text has changed: reset the search
+void
+find_dialog::handle_search_text_changed (QString)
+{
+  if (_search_selection_check_box->isChecked ())
+    _find_result_available = false;
+}
+
+#ifdef HAVE_QSCI_FINDSELECTION
+void
+find_dialog::handle_sel_search_changed (int selected)
+{
+  _from_start_check_box->setEnabled (! selected);
+  _find_result_available = false;
+}
+
+void
+find_dialog::handle_selection_changed (bool has_selected)
+{
+  if (_rep_active)
+    return;
+
+  _search_selection_check_box->setEnabled (has_selected);
+  _find_result_available = false;
+  if (! has_selected)
+    _search_selection_check_box->setChecked (false);
+}
+#endif
+
 // initialize search text with selected text if this is in one single line
 void
 find_dialog::init_search_text ()
@@ -210,102 +252,156 @@
 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 = true;
+  bool do_forward = forward;
 
-  if (_find_result_available)
+  if (_rep_all)
     {
-      // we found a match last time, cursor is at the end of the match
-      if (!forward)
+      if (_rep_all == 1)
         {
-          // backward: go back one position or we will find the same again
-          do_forward = false;
-          _edit_area->getCursorPosition (&line,&col);
-          if (col > 0)
-            _edit_area->setCursorPosition (line,--col);
+          line = 0;
+          col = 0;
         }
+      do_wrap = false;
+      // The following line is a workaround for the issue that when replacing
+      // a text with a new one with different size within the selection,
+      // the selection is not updated leading to missing or extra replacements.
+      // This does not happen, when the selection is search backwards
+      do_forward = ! _search_selection_check_box->isChecked ();
     }
-
-  _find_result_available = false;
-
-  if (_from_start_check_box->isChecked ())
+  else
     {
-      line = 0;
-      col  = 0;
-      if (_backward_check_box->isChecked ())
-        do_wrap = true;
+      if (_from_start_check_box->isChecked ())
+        {
+          if (do_forward)
+            {
+              line = 0;
+              col = 0;
+            }
+          else
+            {
+              line = _edit_area->lines () - 1;
+              col  = _edit_area->text (line).length () - 1;
+              if (col == -1)
+                col = 0;
+            }
+        }
+      else if (! do_forward)
+        {
+           // search from previous character if search backward
+           _edit_area->getCursorPosition (&line,&col);
+           int currpos = _edit_area->positionFromLineIndex(line,col);
+           if (currpos > 0) currpos --;
+           _edit_area->lineIndexFromPosition(currpos, &line,&col);
+        }
     }
 
   if (_edit_area)
     {
-      _find_result_available
-        = _edit_area->findFirst (_search_line_edit->text (),
-                                _regex_check_box->isChecked (),
-                                _case_check_box->isChecked (),
-                                _whole_words_check_box->isChecked (),
-                                do_wrap,
-                                do_forward,
-                                line,col,
-                                true
+      if (_edit_area->hasSelectedText ()
+          && _search_selection_check_box->isChecked ())
+        {
+#ifdef HAVE_QSCI_FINDSELECTION
+           if (_find_result_available)
+             _find_result_available = _edit_area->findNext ();
+           else
+            _find_result_available
+              = _edit_area->findFirstInSelection (
+                                      _search_line_edit->text (),
+                                      _regex_check_box->isChecked (),
+                                      _case_check_box->isChecked (),
+                                      _whole_words_check_box->isChecked (),
+                                      do_forward,
+                                      true
 #ifdef HAVE_QSCI_VERSION_2_6_0
-                                , true
+                                      , true
+#endif
+                                      );
 #endif
-                                );
+        }
+      else
+        {
+          _find_result_available
+            = _edit_area->findFirst (_search_line_edit->text (),
+                                    _regex_check_box->isChecked (),
+                                    _case_check_box->isChecked (),
+                                    _whole_words_check_box->isChecked (),
+                                    do_wrap,
+                                    do_forward,
+                                    line,col,
+                                    true
+#ifdef HAVE_QSCI_VERSION_2_6_0
+                                    , true
+#endif
+                                    );
+        }
     }
+
   if (_find_result_available)
     _from_start_check_box->setChecked (0);
-  else
+  else if (! _rep_all)
     no_matches_message ();
 }
 
+void
+find_dialog::do_replace ()
+{
+  _rep_active = true;  // changes in selection not made by the user
+  _edit_area->replace (_replace_line_edit->text ());
+  _rep_active = false;
+}
 
 void
 find_dialog::replace ()
 {
   if (_edit_area)
     {
-      _edit_area->replace (_replace_line_edit->text ());
-      if (!_edit_area->findNext())
-        no_matches_message ();
+      // The following line is a workaround for the issue that when replacing
+      // a text with a new one with different size within the selection,
+      // the selection is not updated leading to missing or extra replacements.
+      // This does not happen, when the selection is search backwards
+      if (_search_selection_check_box->isChecked ())
+        _backward_check_box->setChecked (true);
+
+      // do the replace if we have selected text
+      if (_find_result_available && _edit_area->hasSelectedText ())
+        do_replace ();
+
+      find_next ();
     }
 }
 
 void
 find_dialog::replace_all ()
 {
-  int count = 0;
+  int line, col;
 
-  // check whether find & replace srings are different (avoid endless loop!)
-  int strDiff;
-  Qt::CaseSensitivity cs;
-  if (_case_check_box->isChecked())
+  if (_edit_area)
     {
-      cs = Qt::CaseSensitive;
-    }
-  else
-    {
-      cs = Qt::CaseInsensitive;
-    }
-  strDiff = QString::compare (_search_line_edit->text(),
-                              _replace_line_edit->text(), cs);
+      _edit_area->getCursorPosition (&line,&col);
 
-  // replace all if strings are different
-  if (_edit_area && strDiff )
-    {
-      find (!_backward_check_box->isChecked ());  // find first occurence
+      _rep_all = 1;
+      find_next ();  // find first occurence (forward)
       while (_find_result_available)   // while search string is found
         {
-          _edit_area->replace (_replace_line_edit->text ());   // replace
-          count++;                                             // inc counter
-          _find_result_available = _edit_area->findNext();     // and find next
+          do_replace ();
+          _rep_all++;                                          // inc counter
+          find_next ();                                        // find next
         }
+
       QMessageBox msg_box (QMessageBox::Information, tr ("Replace Result"),
-                           tr ("%1 items replaced").arg(count),
+                           tr ("%1 items replaced").arg(_rep_all-1),
                            QMessageBox::Ok, this);
       msg_box.exec ();
+
+      _rep_all = 0;
+      _find_result_available = false;
+
+      if (! _search_selection_check_box->isChecked ())
+        _edit_area->setCursorPosition (line,col);
     }
-  // TODO: Show number of replaced strings
 }
 
 void
--- a/libgui/src/m-editor/find-dialog.h	Fri Feb 06 08:31:09 2015 -0800
+++ b/libgui/src/m-editor/find-dialog.h	Fri Feb 06 08:31:49 2015 -0800
@@ -79,7 +79,13 @@
   void init_search_text ();
 
 private slots:
+#ifdef HAVE_QSCI_FINDSELECTION
+  void handle_sel_search_changed (int);
+  void handle_selection_changed (bool has_selected);
+#endif
   void handle_backward_search_changed (int);
+  void handle_search_text_changed (QString new_search_text);
+
   void find (bool forward = true);
   void find_next ();
   void find_prev ();
@@ -87,7 +93,10 @@
   void replace_all ();
 
 private:
+
   void no_matches_message ();
+  void do_replace ();
+
   QLabel            *_search_label;
   QLineEdit         *_search_line_edit;
   QLabel            *_replace_label;
@@ -108,6 +117,8 @@
   QWidget           *_extension;
   QsciScintilla     *_edit_area;
   bool               _find_result_available;
+  int                _rep_all;
+  bool               _rep_active;
 };
 
 #endif // FIND_DIALOG_H
--- a/libgui/src/m-editor/octave-qscintilla.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/libgui/src/m-editor/octave-qscintilla.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -29,13 +29,107 @@
 #ifdef HAVE_QSCINTILLA
 
 #include <Qsci/qscilexer.h>
+#include <Qsci/qscicommandset.h>
+#include <QShortcut>
+#include <QMessageBox>
 
 #include "octave-qscintilla.h"
 #include "file-editor-tab.h"
+#include "shortcut-manager.h"
 
 octave_qscintilla::octave_qscintilla (QWidget *p)
   : QsciScintilla (p)
-{ }
+{
+  connect (this, SIGNAL (textChanged ()), this, SLOT (text_changed ()));
+
+  // clear scintilla edit shortcuts that are handled by the editor
+  QsciCommandSet *cmd_set = standardCommands ();
+
+#ifdef HAVE_QSCI_VERSION_2_6_0
+  // find () was added in QScintilla 2.6
+  cmd_set->find (QsciCommand::SelectionCopy)->setKey (0);
+  cmd_set->find (QsciCommand::SelectionCut)->setKey (0);
+  cmd_set->find (QsciCommand::Paste)->setKey (0);
+  cmd_set->find (QsciCommand::SelectAll)->setKey (0);
+  cmd_set->find (QsciCommand::SelectionDuplicate)->setKey (0);
+  cmd_set->find (QsciCommand::LineTranspose)->setKey (0);
+  cmd_set->find (QsciCommand::Undo)->setKey (0);
+  cmd_set->find (QsciCommand::Redo)->setKey (0);
+  cmd_set->find (QsciCommand::SelectionUpperCase)->setKey (0);
+  cmd_set->find (QsciCommand::SelectionLowerCase)->setKey (0);
+  cmd_set->find (QsciCommand::ZoomIn)->setKey (0);
+  cmd_set->find (QsciCommand::ZoomOut)->setKey (0);
+  cmd_set->find (QsciCommand::DeleteWordLeft)->setKey (0);
+  cmd_set->find (QsciCommand::DeleteWordRight)->setKey (0);
+  cmd_set->find (QsciCommand::DeleteLineLeft)->setKey (0);
+  cmd_set->find (QsciCommand::DeleteLineRight)->setKey (0);
+  cmd_set->find (QsciCommand::LineDelete)->setKey (0);
+  cmd_set->find (QsciCommand::LineCut)->setKey (0);
+  cmd_set->find (QsciCommand::LineCopy)->setKey (0);
+#else
+  // find commands via its default key (tricky way without find ())
+  QList< QsciCommand * > cmd_list = cmd_set->commands ();
+  for (int i = 0; i < cmd_list.length (); i++)
+    {
+      int cmd_key = cmd_list.at (i)->key ();
+      switch (cmd_key)
+        {
+          case Qt::Key_C | Qt::CTRL :               // SelectionCopy
+          case Qt::Key_X | Qt::CTRL :               // SelectionCut
+          case Qt::Key_V | Qt::CTRL :               // Paste
+          case Qt::Key_A | Qt::CTRL :               // SelectAll
+          case Qt::Key_D | Qt::CTRL :               // SelectionDuplicate
+          case Qt::Key_T | Qt::CTRL :               // LineTranspose
+          case Qt::Key_Z | Qt::CTRL :               // Undo
+          case Qt::Key_Y | Qt::CTRL :               // Redo
+          case Qt::Key_Z | Qt::CTRL | Qt::SHIFT :   // Redo
+          case Qt::Key_U | Qt::CTRL :               // SelectionLowerCase
+          case Qt::Key_U | Qt::CTRL | Qt::SHIFT :   // SelectionUpperCase
+          case Qt::Key_Plus | Qt::CTRL :            // ZoomIn
+          case Qt::Key_Minus | Qt::CTRL :           // ZoomOut
+          case Qt::Key_Backspace | Qt::CTRL | Qt::SHIFT :   // DeleteLineLeft
+          case Qt::Key_Delete | Qt::CTRL | Qt::SHIFT :      // DeleteLineRight
+          case Qt::Key_K | Qt::META :                       // DeleteLineRight
+          case Qt::Key_Backspace | Qt::CTRL :       // DeleteWordLeft
+          case Qt::Key_Delete | Qt::CTRL :          // DeleteWordRight
+          case Qt::Key_L | Qt::CTRL | Qt::SHIFT :   // LineDelete
+          case Qt::Key_L | Qt::CTRL :               // LineCut
+          case Qt::Key_T | Qt::CTRL | Qt::SHIFT :   // LineCopy
+            cmd_list.at (i)->setKey (0);
+        }
+    }
+#endif
+
+#if defined (Q_OS_MAC)
+  // Octave interprets Cmd key as Meta whereas Qscintilla interprets it
+  // as Ctrl. We thus invert Meta/Ctrl in Qscintilla's shortcuts list.
+  QList< QsciCommand * > cmd_list_mac = cmd_set->commands ();
+  for (int i = 0; i < cmd_list_mac.length (); i++)
+    {
+      // Primary key
+      int key = cmd_list_mac.at (i)->key ();
+
+      if (static_cast<int> (key | Qt::META) == key &&
+          static_cast<int> (key | Qt::CTRL) != key)
+        key = (key ^ Qt::META) | Qt::CTRL;
+      else if (static_cast<int> (key | Qt::CTRL) == key)
+        key = (key ^ Qt::CTRL) | Qt::META;
+
+      cmd_list_mac.at (i)->setKey (key);
+
+      // Alternate key
+      key = cmd_list_mac.at (i)->alternateKey ();
+
+      if (static_cast<int> (key | Qt::META) == key &&
+          static_cast<int> (key | Qt::CTRL) != key)
+        key = (key ^ Qt::META) | Qt::CTRL;
+      else if (static_cast<int> (key | Qt::CTRL) == key)
+        key = (key ^ Qt::CTRL) | Qt::META;
+
+      cmd_list_mac.at (i)->setAlternateKey (key);
+    }
+#endif
+}
 
 octave_qscintilla::~octave_qscintilla ()
 { }
@@ -44,11 +138,11 @@
 octave_qscintilla::get_global_textcursor_pos (QPoint *global_pos,
                                               QPoint *local_pos)
 {
-  long position = SendScintilla (QsciScintillaBase::SCI_GETCURRENTPOS);
+  long position = SendScintilla (SCI_GETCURRENTPOS);
   long point_x  = SendScintilla
-                    (QsciScintillaBase::SCI_POINTXFROMPOSITION,0,position);
+                    (SCI_POINTXFROMPOSITION,0,position);
   long point_y  = SendScintilla
-                    (QsciScintillaBase::SCI_POINTYFROMPOSITION,0,position);
+                    (SCI_POINTYFROMPOSITION,0,position);
   *local_pos = QPoint (point_x,point_y);  // local cursor position
   *global_pos = mapToGlobal (*local_pos); // global position of cursor
 }
@@ -94,11 +188,13 @@
 void
 octave_qscintilla::contextMenuEvent (QContextMenuEvent *e)
 {
-  QMenu *context_menu = createStandardContextMenu ( );  // standard menu
+  QPoint global_pos, local_pos;                         // the menu's position
+  QMenu *context_menu = createStandardContextMenu ();  // standard menu
 
-  // the menu's position
-  QPoint global_pos, local_pos;
+  // fill context menu with editor's standard actions
+  emit create_context_menu_signal (context_menu);
 
+  // determine position depending on mouse or keyboard event
   if (e->reason () == QContextMenuEvent::Mouse)
     {
       // context menu by mouse
@@ -135,10 +231,6 @@
           context_menu->addAction (tr ("Edit") + " " + _word_at_cursor,
                                    this, SLOT (contextmenu_edit (bool)));
         }
-      context_menu->addSeparator ();   // separator before custom entries
-      if (hasSelectedText ())
-        context_menu->addAction (tr ("&Run Selection"),
-                                 this, SLOT (contextmenu_run (bool)));
     }
 
   // finaly show the menu
@@ -163,18 +255,16 @@
 void
 octave_qscintilla::contextmenu_help_doc (bool documentation)
 {
-  QString command;
   if (documentation)
-    command = "doc ";
+    emit show_doc_signal (_word_at_cursor);
   else
-    command = "help ";
-  emit execute_command_in_terminal_signal (command + _word_at_cursor);
+    emit execute_command_in_terminal_signal ("help " + _word_at_cursor);
 }
 
 void
 octave_qscintilla::contextmenu_edit (bool)
 {
-  emit execute_command_in_terminal_signal (QString("edit ") + _word_at_cursor);
+  emit context_menu_edit_signal (_word_at_cursor);
 }
 
 void
@@ -182,8 +272,14 @@
 {
   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));
 }
 
+void
+octave_qscintilla::text_changed ()
+{
+  emit status_update (isUndoAvailable (), isRedoAvailable ());
+}
+
 #endif
--- a/libgui/src/m-editor/octave-qscintilla.h	Fri Feb 06 08:31:09 2015 -0800
+++ b/libgui/src/m-editor/octave-qscintilla.h	Fri Feb 06 08:31:49 2015 -0800
@@ -50,6 +50,11 @@
 signals:
 
   void execute_command_in_terminal_signal (const QString&);
+  void create_context_menu_signal (QMenu*);
+  void context_menu_edit_signal (const QString&);
+  void qsci_has_focus_signal (bool);
+  void status_update (bool,bool);
+  void show_doc_signal (const QString&);
 
 private slots:
 
@@ -59,6 +64,10 @@
   void contextmenu_edit (bool);
   void contextmenu_run (bool);
 
+  void text_changed (void);
+
+protected:
+
 private:
 
   QString _word_at_cursor;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libgui/src/m-editor/octave-txt-lexer.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,52 @@
+/*
+
+Copyright (C) 2014 Torsten
+
+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/>.
+
+*/
+
+// Author: Torsten <ttl@justmail.de>
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#ifdef HAVE_QSCINTILLA
+
+#include <Qsci/qscilexer.h>
+
+#include "octave-txt-lexer.h"
+
+QString
+octave_txt_lexer::description (int style) const
+{
+  if (style == 0)
+    return tr ("Default");
+  else
+    return QString ();
+};
+
+
+const char*
+octave_txt_lexer::language () const
+{
+  return "Text";
+}
+
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libgui/src/m-editor/octave-txt-lexer.h	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,43 @@
+/*
+
+Copyright (C) 2013 Torsten
+
+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/>.
+
+*/
+
+// Author: Torsten <ttl@justmail.de>
+
+#if !defined (octave_txt_lexer_h)
+#define octave_txt_lexer_h 1
+
+#include <Qsci/qsciscintilla.h>
+#include <Qsci/qscilexer.h>
+
+
+class octave_txt_lexer : public QsciLexer
+{
+  Q_OBJECT
+
+public:
+
+  virtual const char *language () const;
+  virtual QString description (int style) const;
+
+};
+
+#endif
\ No newline at end of file
--- a/libgui/src/main-window.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/libgui/src/main-window.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -51,6 +51,9 @@
 #endif
 #include "main-window.h"
 #include "settings-dialog.h"
+#include "shortcut-manager.h"
+
+#include "__init_qt__.h"
 
 #include "Array.h"
 #include "cmd-edit.h"
@@ -60,6 +63,7 @@
 #include "defaults.h"
 #include "symtab.h"
 #include "version.h"
+#include "utils.h"
 
 static file_editor_interface *
 create_default_editor (QWidget *p)
@@ -81,6 +85,7 @@
     doc_browser_window (new documentation_dock_widget (this)),
     editor_window (create_default_editor (this)),
     workspace_window (new workspace_view (this)),
+    _settings_dlg (0),
     find_files_dlg (0),
     release_notes_window (0),
     community_news_window (0),
@@ -91,13 +96,15 @@
     _cmd_queue_mutex (),
     _dbg_queue (new QStringList ()),  // no debug pending
     _dbg_processing (1),
-    _dbg_queue_mutex ()
+    _dbg_queue_mutex (),
+    _prevent_readline_conflicts (true)
 {
   QSettings *settings = resource_manager::get_settings ();
 
   bool connect_to_web = true;
   QDateTime last_checked;
   int serial = 0;
+  _active_dock = 0;
 
   if (settings)
     {
@@ -144,6 +151,11 @@
       delete release_notes_window;
       release_notes_window = 0;
     }
+  if (_settings_dlg)
+    {
+      delete _settings_dlg;
+      _settings_dlg = 0;
+    }
   if (community_news_window)
     {
       delete community_news_window;
@@ -153,6 +165,55 @@
   delete _cmd_queue;
 }
 
+// catch focus changes and determine the active dock widget
+void
+main_window::focus_changed (QWidget *, QWidget *new_widget)
+{
+  octave_dock_widget* dock = 0;
+  QWidget *w_new = new_widget;  // get a copy of new focus widget
+  QWidget *start = w_new;       // Save it as start of our search
+  int count = 0;                // fallback to prevent endless loop
+
+  while (w_new && w_new != _main_tool_bar && count < 100)
+    {
+      dock = qobject_cast <octave_dock_widget *> (w_new);
+      if (dock)
+        break; // it is a QDockWidget ==> exit loop
+
+#ifdef HAVE_QSCINTILLA
+      if (qobject_cast <octave_qscintilla *> (w_new))
+        {
+          dock = static_cast <octave_dock_widget *> (editor_window);
+          break; // it is the editor window ==> exit loop
+        }
+#endif
+
+      w_new = qobject_cast <QWidget *> (w_new->previousInFocusChain ());
+      if (w_new == start)
+        break; // we have arrived where we began ==> exit loop
+
+      count++;
+    }
+
+  // editor needs extra handling
+  octave_dock_widget *edit_dock_widget =
+                        static_cast <octave_dock_widget *> (editor_window);
+  // if new dock has focus, emit signal and store active focus
+  // except editor changes to a dialog (dock=0)
+  if ((dock || _active_dock != edit_dock_widget) && (dock != _active_dock))
+    {
+      // signal to all dock widgets for updating the style
+      emit active_dock_changed (_active_dock, dock);
+
+      if (edit_dock_widget == dock)
+        emit editor_focus_changed (true);
+      else if (edit_dock_widget == _active_dock)
+        emit editor_focus_changed (false);
+
+      _active_dock = dock;
+    }
+}
+
 bool
 main_window::command_window_has_focus (void) const
 {
@@ -244,17 +305,50 @@
   octave_link::post_event (this, &main_window::clear_history_callback);
 }
 
+bool
+main_window::focus_console_after_command ()
+{
+  QSettings *settings = resource_manager::get_settings ();
+  return settings->value ("terminal/focus_after_command",false).toBool ();
+}
+
 void
 main_window::execute_command_in_terminal (const QString& command)
 {
   queue_command (command);
-  focus_command_window ();
+  if (focus_console_after_command ())
+    focus_command_window ();
 }
 
 void
 main_window::run_file_in_terminal (const QFileInfo& info)
 {
+  QString file_name = info.canonicalFilePath ();
+  QString command = "run \"" + file_name + "\"";
+
+  QString function_name = info.fileName ();
+  function_name.chop (info.suffix ().length () + 1);
+
+  if (! valid_identifier (function_name.toStdString ()))
+    {
+      int ans = QMessageBox::question (0, tr ("Octave"),
+         tr ("The file %1\n"
+             "can not be executed because its name\n"
+             "is not a valid identifier.\n\n"
+             "Do you want to execute\n%2\n"
+             "instead?").
+          arg (file_name).arg (command),
+          QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes);
+
+      if (ans == QMessageBox::Yes)
+        execute_command_in_terminal (command);
+
+      return;
+    }
+
   octave_link::post_event (this, &main_window::run_file_callback, info);
+  if (focus_console_after_command ())
+    focus_command_window ();
 }
 
 void
@@ -331,14 +425,17 @@
       release_notes_window->setWindowTitle (tr ("Octave Release Notes"));
 
       browser->document()->adjustSize ();
-      QSize doc_size = browser->document()->size().toSize ();
-      doc_size.rwidth () += 45;
-      int h = QApplication::desktop ()->height ();
-      if (h > 800)
-        h = 800;
-      doc_size.rheight () = h;
-
-      release_notes_window->resize (doc_size);
+
+      // center the window on the screen where octave is running
+      QDesktopWidget *m_desktop = QApplication::desktop ();
+      int screen = m_desktop->screenNumber (this);  // screen of the main window
+      QRect screen_geo = m_desktop->availableGeometry (screen);
+      int win_x = screen_geo.width ();        // width of the screen
+      int win_y = screen_geo.height ();       // height of the screen
+      int reln_x = std::min (480, win_x-80);  // desired width of release notes
+      int reln_y = std::min (640, win_y-80);  // desired height of release notes
+      release_notes_window->resize (reln_x, reln_y);  // set size
+      release_notes_window->move (20, 0);     // move to the top left corner
     }
 
   if (! release_notes_window->isVisible ())
@@ -518,9 +615,16 @@
 
       community_news_window->setLayout (vlayout);
       community_news_window->setWindowTitle (tr ("Octave Community News"));
-      community_news_window->resize (640, 480);
-      int win_x = QApplication::desktop ()->width ();
-      int win_y = QApplication::desktop ()->height ();
+
+      // center the window on the screen where octave is running
+      QDesktopWidget *m_desktop = QApplication::desktop ();
+      int screen = m_desktop->screenNumber (this);  // screen of the main window
+      QRect screen_geo = m_desktop->availableGeometry (screen);
+      int win_x = screen_geo.width ();        // width of the screen
+      int win_y = screen_geo.height ();       // height of the screen
+      int news_x = std::min (640, win_x-80);  // desired width of news window
+      int news_y = std::min (480, win_y-80);  // desired height of news window
+      community_news_window->resize (news_x, news_y);  // set size and center
       community_news_window->move ((win_x - community_news_window->width ())/2,
                                    (win_y - community_news_window->height ())/2);
     }
@@ -570,18 +674,31 @@
 void
 main_window::process_settings_dialog_request (const QString& desired_tab)
 {
-  settings_dialog *settingsDialog = new settings_dialog (this, desired_tab);
-  int change_settings = settingsDialog->exec ();
-  if (change_settings == QDialog::Accepted)
-    {
-      settingsDialog->write_changed_settings ();
-      QSettings *settings = resource_manager::get_settings ();
-      if (settings)
-        emit settings_changed (settings);
+  if (_settings_dlg)  // _settings_dlg is a guarded pointer!
+    {                 // here the dialog is still open and called once again
+      if (! desired_tab.isEmpty ())
+        _settings_dlg->show_tab (desired_tab);
+      return;
     }
-  delete settingsDialog;
+
+  _settings_dlg = new settings_dialog (this, desired_tab);
+
+  connect (_settings_dlg, SIGNAL (apply_new_settings ()),
+           this, SLOT (request_reload_settings ()));
+
+  _settings_dlg->setModal (false);
+  _settings_dlg->setAttribute (Qt::WA_DeleteOnClose);
+  _settings_dlg->show ();
 }
 
+void
+main_window::request_reload_settings ()
+{
+  QSettings *settings = resource_manager::get_settings ();
+
+  if (settings)
+    emit settings_changed (settings);
+}
 
 void
 main_window::notice_settings (const QSettings *settings)
@@ -644,6 +761,19 @@
   int icon_size = settings->value ("toolbar_icon_size",16).toInt ();
   _main_tool_bar->setIconSize (QSize (icon_size,icon_size));
 
+  if (settings->value ("show_status_bar",true).toBool ())
+    status_bar->show ();
+  else
+    status_bar->hide ();
+
+  _prevent_readline_conflicts =
+    settings->value ("shortcuts/prevent_readline_conflicts", true).toBool ();
+  configure_shortcuts ();
+  set_global_shortcuts (command_window_has_focus ());
+
+  _suppress_dbg_location =
+        ! settings->value ("terminal/print_debug_location", false).toBool ();
+
   resource_manager::update_network_settings ();
 }
 
@@ -855,7 +985,8 @@
 main_window::closeEvent (QCloseEvent *e)
 {
   e->ignore ();
-  octave_link::post_event (this, &main_window::exit_callback);
+  if (confirm_exit_octave())
+    octave_link::post_event (this, &main_window::exit_callback);
 }
 
 void
@@ -882,6 +1013,12 @@
 }
 
 void
+main_window::init_terminal_size (void)
+{
+  emit init_terminal_size_signal ();
+}
+
+void
 main_window::set_window_layout (QSettings *settings)
 {
 #if ! defined (Q_OS_WIN32)
@@ -965,6 +1102,10 @@
 {
   foreach (octave_dock_widget *widget, dock_widget_list ())
     widget->connect_visibility_changed ();
+
+#ifdef HAVE_QSCINTILLA
+  editor_window->enable_menu_shortcuts (false);
+#endif
 }
 
 void
@@ -1000,6 +1141,22 @@
     emit pasteClipboard_signal ();
 }
 
+void
+main_window::selectAll (void)
+{
+  if (_current_directory_combo_box->hasFocus ())
+    {
+      QLineEdit * edit = _current_directory_combo_box->lineEdit ();
+      if (edit)
+        {
+          edit->selectAll ();
+        }
+    }
+  else
+    emit selectAll_signal ();
+}
+
+
 // Connect the signals emitted when the Octave thread wants to create
 // a dialog box of some sort.  Perhaps a better place for this would be
 // as part of the QUIWidgetCreator class.  However, mainWindow currently
@@ -1146,23 +1303,27 @@
 
   construct_tool_bar ();
 
-  construct_warning_bar ();
-
   connect (qApp, SIGNAL (aboutToQuit ()),
            this, SLOT (prepare_to_exit ()));
 
+  connect (qApp, SIGNAL (focusChanged (QWidget*, QWidget*)),
+           this, SLOT(focus_changed (QWidget*, QWidget*)));
+
   connect (this, SIGNAL (settings_changed (const QSettings *)),
            this, SLOT (notice_settings (const QSettings *)));
 
+  connect (this, SIGNAL (editor_focus_changed (bool)),
+           this, SLOT (set_global_edit_shortcuts (bool)));
+
+  connect (this, SIGNAL (editor_focus_changed (bool)),
+           editor_window, SLOT (enable_menu_shortcuts (bool)));
+
   connect (file_browser_window, SIGNAL (load_file_signal (const QString&)),
            this, SLOT (handle_load_workspace_request (const QString&)));
 
   connect (file_browser_window, SIGNAL (find_files_signal (const QString&)),
            this, SLOT (find_files (const QString&)));
 
-  connect (this, SIGNAL (set_widget_shortcuts_signal (bool)),
-           editor_window, SLOT (set_shortcuts (bool)));
-
   connect_uiwidget_links ();
 
   setWindowTitle ("Octave");
@@ -1218,19 +1379,61 @@
                                                           int)));
 #endif
 
-  QDir curr_dir;
-  set_current_working_directory (curr_dir.absolutePath ());
-
   octave_link::post_event (this, &main_window::resize_command_window_callback);
 
-  set_global_shortcuts (true);
+  install___init_qt___functions ();
+
+  Fregister_graphics_toolkit (ovl ("qt"));
+
+  configure_shortcuts ();
+}
+
+
+void
+main_window::handle_octave_ready ()
+{
+  // actions after the startup files are executed
+  QSettings *settings = resource_manager::get_settings ();
+
+  QDir startup_dir = QDir ();    // current octave dir after startup
+
+  if (settings->value ("restore_octave_dir").toBool ())
+    {
+      // restore last dir from previous session
+      QStringList curr_dirs
+        = settings->value ("MainWindow/current_directory_list").toStringList ();
+      startup_dir = QDir (curr_dirs.at (0));  // last dir in previous session
+    }
+  else if (! settings->value ("octave_startup_dir").toString ().isEmpty ())
+    {
+      // do not restore but there is a startup dir configured
+      startup_dir = QDir (settings->value ("octave_startup_dir").toString ());
+    }
+
+  if (! startup_dir.exists ())
+    {
+      // the configured startup dir does not exist, take actual one
+      startup_dir = QDir ();
+    }
+
+  set_current_working_directory (startup_dir.absolutePath ());
+
+#ifdef HAVE_QSCINTILLA
+  // Octave ready, determine whether to create an empty script.
+  // This can not be done when the editor is created because all functions
+  // must be known for the lexer's auto completion informations
+  editor_window->empty_script (true, false);
+#endif
+
+  focus_command_window ();  // make sure that the command window has focus
 
 }
 
+
 void
 main_window::construct_octave_qt_link (void)
 {
-  _octave_qt_link = new octave_qt_link ();
+  _octave_qt_link = new octave_qt_link (this);
 
   connect (_octave_qt_link, SIGNAL (exit_signal (int)),
            this, SLOT (exit (int)));
@@ -1337,10 +1540,57 @@
   construct_news_menu (menu_bar);
 }
 
+QAction*
+main_window::add_action (QMenu *menu, const QIcon &icon, const QString &text,
+                         const char *member, const QWidget *receiver)
+{
+  QAction *a;
+
+  if (receiver)
+    a = menu->addAction (icon, text, receiver, member);
+  else
+    a = menu->addAction (icon, text, this, member);
+
+  addAction (a);  // important for shortcut context
+  a->setShortcutContext (Qt::ApplicationShortcut);
+  return a;
+}
+
+void
+main_window::enable_menu_shortcuts (bool enable)
+{
+  QHash<QMenu*, QStringList>::const_iterator i = _hash_menu_text.constBegin();
+
+ while (i != _hash_menu_text.constEnd())
+   {
+     i.key ()->setTitle (i.value ().at (! enable));
+     ++i;
+   }
+}
+
+QMenu*
+main_window::m_add_menu (QMenuBar *p, QString name)
+{
+  QMenu *menu = p->addMenu (name);
+
+  QString base_name = name;  // get a copy
+  // replace intended '&' ("&&") by a temp. string
+  base_name.replace ("&&","___octave_amp_replacement___");
+  // remove single '&' (shortcut)
+  base_name.remove ("&");
+  // restore intended '&'
+  base_name.replace ("___octave_amp_replacement___","&&");
+
+  // remember names with and without shortcut
+  _hash_menu_text[menu] = QStringList () << name << base_name;
+
+  return menu;
+}
+
 void
 main_window::construct_file_menu (QMenuBar *p)
 {
-  QMenu *file_menu = p->addMenu (tr ("&File"));
+  QMenu *file_menu = m_add_menu (p, tr ("&File"));
 
   construct_new_menu (file_menu);
 
@@ -1348,23 +1598,27 @@
     = file_menu->addAction (QIcon (":/actions/icons/folder_documents.png"),
                             tr ("Open..."));
   _open_action->setShortcutContext (Qt::ApplicationShortcut);
-
+  _open_action->setToolTip (tr ("Open an existing file in editor"));
 
 #ifdef HAVE_QSCINTILLA
+  editor_window->insert_new_open_actions (_new_script_action,
+                                          _new_function_action,
+                                          _open_action);
+
   file_menu->addMenu (editor_window->get_mru_menu ());
 #endif
 
   file_menu->addSeparator ();
 
-  QAction *load_workspace_action
+  _load_workspace_action
     = file_menu->addAction (tr ("Load Workspace..."));
 
-  QAction *save_workspace_action
+  _save_workspace_action
     = file_menu->addAction (tr ("Save Workspace As..."));
 
   file_menu->addSeparator ();
 
-  QAction *preferences_action
+  _preferences_action
     = file_menu->addAction (QIcon (":/actions/icons/configure.png"),
                             tr ("Preferences..."));
 
@@ -1373,7 +1627,7 @@
   _exit_action = file_menu->addAction (tr ("Exit"));
   _exit_action->setShortcutContext (Qt::ApplicationShortcut);
 
-  connect (preferences_action, SIGNAL (triggered ()),
+  connect (_preferences_action, SIGNAL (triggered ()),
            this, SLOT (process_settings_dialog_request ()));
 
 #ifdef HAVE_QSCINTILLA
@@ -1381,10 +1635,10 @@
            editor_window, SLOT (request_open_file ()));
 #endif
 
-  connect (load_workspace_action, SIGNAL (triggered ()),
+  connect (_load_workspace_action, SIGNAL (triggered ()),
            this, SLOT (handle_load_workspace_request ()));
 
-  connect (save_workspace_action, SIGNAL (triggered ()),
+  connect (_save_workspace_action, SIGNAL (triggered ()),
            this, SLOT (handle_save_workspace_request ()));
 
   connect (_exit_action, SIGNAL (triggered ()),
@@ -1398,15 +1652,15 @@
 
   _new_script_action
     = new_menu->addAction (QIcon (":/actions/icons/filenew.png"),
-                           tr ("Script"));
+                           tr ("New Script"));
   _new_script_action->setShortcutContext (Qt::ApplicationShortcut);
 
-  _new_function_action = new_menu->addAction (tr ("Function..."));
+  _new_function_action = new_menu->addAction (tr ("New Function..."));
   _new_function_action->setEnabled (true);
   _new_function_action->setShortcutContext (Qt::ApplicationShortcut);
 
-  QAction *new_figure_action = new_menu->addAction (tr ("Figure"));
-  new_figure_action->setEnabled (true);
+  _new_figure_action = new_menu->addAction (tr ("New Figure"));
+  _new_figure_action->setEnabled (true);
 
 #ifdef HAVE_QSCINTILLA
   connect (_new_script_action, SIGNAL (triggered ()),
@@ -1416,33 +1670,32 @@
            editor_window, SLOT (request_new_function ()));
 #endif
 
-  connect (new_figure_action, SIGNAL (triggered ()),
+  connect (_new_figure_action, SIGNAL (triggered ()),
            this, SLOT (handle_new_figure_request ()));
 }
 
 void
 main_window::construct_edit_menu (QMenuBar *p)
 {
-  QMenu *edit_menu = p->addMenu (tr ("&Edit"));
+  QMenu *edit_menu = m_add_menu (p, tr ("&Edit"));
 
   QKeySequence ctrl_shift = Qt::ControlModifier + Qt::ShiftModifier;
 
   _undo_action
     = edit_menu->addAction (QIcon (":/actions/icons/undo.png"), tr ("Undo"));
-  _undo_action->setShortcut (QKeySequence::Undo);
 
   edit_menu->addSeparator ();
 
   _copy_action
     = edit_menu->addAction (QIcon (":/actions/icons/editcopy.png"),
                             tr ("Copy"), this, SLOT (copyClipboard ()));
-  _copy_action->setShortcut (QKeySequence::Copy);
-
 
   _paste_action
     = edit_menu->addAction (QIcon (":/actions/icons/editpaste.png"),
                             tr ("Paste"), this, SLOT (pasteClipboard ()));
-  _paste_action->setShortcut (QKeySequence::Paste);
+
+  _select_all_action
+    = edit_menu->addAction (tr ("Select All"), this, SLOT (selectAll ()));
 
   _clear_clipboard_action
     = edit_menu->addAction (tr ("Clear Clipboard"), this,
@@ -1454,25 +1707,25 @@
 
   edit_menu->addSeparator ();
 
-  QAction *clear_command_window_action
+  _clear_command_window_action
     = edit_menu->addAction (tr ("Clear Command Window"));
 
-  QAction *clear_command_history
+  _clear_command_history_action
     = edit_menu->addAction (tr ("Clear Command History"));
 
-  QAction *clear_workspace_action
+  _clear_workspace_action
     = edit_menu->addAction (tr ("Clear Workspace"));
 
   connect (_find_files_action, SIGNAL (triggered ()),
            this, SLOT (find_files ()));
 
-  connect (clear_command_window_action, SIGNAL (triggered ()),
+  connect (_clear_command_window_action, SIGNAL (triggered ()),
            this, SLOT (handle_clear_command_window_request ()));
 
-  connect (clear_command_history, SIGNAL (triggered ()),
+  connect (_clear_command_history_action, SIGNAL (triggered ()),
            this, SLOT (handle_clear_history_request ()));
 
-  connect (clear_workspace_action, SIGNAL (triggered ()),
+  connect (_clear_workspace_action, SIGNAL (triggered ()),
            this, SLOT (handle_clear_workspace_request ()));
 
   connect (_clipboard, SIGNAL (changed (QClipboard::Mode)),
@@ -1481,14 +1734,12 @@
 }
 
 QAction *
-main_window::construct_debug_menu_item (const char *icon_file,
-                                        const QString& item,
-                                        const QKeySequence& key)
+main_window::construct_debug_menu_item (const char *icon, const QString& item,
+                                        const char *member)
 {
-  QAction *action = _debug_menu->addAction (QIcon (icon_file), item);
+  QAction *action = add_action (_debug_menu, QIcon (icon), item, member);
 
   action->setEnabled (false);
-  action->setShortcut (key);
 
 #ifdef HAVE_QSCINTILLA
   editor_window->debug_menu ()->addAction (action);
@@ -1501,23 +1752,23 @@
 void
 main_window::construct_debug_menu (QMenuBar *p)
 {
-  _debug_menu = p->addMenu (tr ("De&bug"));
+  _debug_menu = m_add_menu (p, tr ("De&bug"));
 
   _debug_step_over = construct_debug_menu_item
-                       (":/actions/icons/db_step.png", tr ("Step"),
-                        Qt::Key_F10);
+                      (":/actions/icons/db_step.png", tr ("Step"),
+                       SLOT (debug_step_over ()));
 
   _debug_step_into = construct_debug_menu_item
-                       (":/actions/icons/db_step_in.png", tr ("Step In"),
-                        Qt::Key_F11);
+                      (":/actions/icons/db_step_in.png", tr ("Step In"),
+                       SLOT (debug_step_into ()));
 
   _debug_step_out = construct_debug_menu_item
                       (":/actions/icons/db_step_out.png", tr ("Step Out"),
-                       Qt::ShiftModifier + Qt::Key_F11);
+                       SLOT (debug_step_out ()));
 
   _debug_continue = construct_debug_menu_item
                       (":/actions/icons/db_cont.png", tr ("Continue"),
-                       Qt::Key_F5);
+                       SLOT (debug_continue ()));
 
   _debug_menu->addSeparator ();
 #ifdef HAVE_QSCINTILLA
@@ -1525,415 +1776,142 @@
 #endif
 
   _debug_quit = construct_debug_menu_item
-                (":/actions/icons/db_stop.png", tr ("Exit Debug Mode"),
-                 Qt::ShiftModifier + Qt::Key_F5);
-
-  connect (_debug_step_over, SIGNAL (triggered ()),
-           this, SLOT (debug_step_over ()));
-
-  connect (_debug_step_into, SIGNAL (triggered ()),
-           this, SLOT (debug_step_into ()));
-
-  connect (_debug_step_out, SIGNAL (triggered ()),
-           this, SLOT (debug_step_out ()));
-
-  connect (_debug_continue, SIGNAL (triggered ()),
-           this, SLOT (debug_continue ()));
-
-  connect (_debug_quit, SIGNAL (triggered ()),
-           this, SLOT (debug_quit ()));
+                      (":/actions/icons/db_stop.png", tr ("Quit Debug Mode"),
+                       SLOT (debug_quit ()));
 }
 
 QAction *
 main_window::construct_window_menu_item (QMenu *p, const QString& item,
-                                         bool checkable,
-                                         const QKeySequence& key)
+                                         bool checkable, QWidget *widget)
 {
-  QAction *action = p->addAction (item);
-
+  QAction *action = p->addAction (QIcon (), item);
+
+  addAction (action);  // important for shortcut context
   action->setCheckable (checkable);
-  action->setShortcut (key);
   action->setShortcutContext (Qt::ApplicationShortcut);
 
+  if (widget)  // might be zero for editor_window
+    {
+      if (checkable)
+        {
+          // action for visibilty of dock widget
+          connect (action, SIGNAL (toggled (bool)),
+                   widget, SLOT (setVisible (bool)));
+
+          connect (widget, SIGNAL (active_changed (bool)),
+                  action, SLOT (setChecked (bool)));
+        }
+      else
+        {
+          // action for focus of dock widget
+          connect (action, SIGNAL (triggered ()), widget, SLOT (focus ()));
+        }
+    }
+
   return action;
 }
 
 void
 main_window::construct_window_menu (QMenuBar *p)
 {
-  QMenu *window_menu = p->addMenu (tr ("&Window"));
-
-  QKeySequence ctrl = Qt::ControlModifier;
-  QKeySequence ctrl_shift = Qt::ControlModifier + Qt::ShiftModifier;
-
-  QAction *show_command_window_action = construct_window_menu_item
-                                        (window_menu,
-                                         tr ("Show Command Window"), true,
-                                         ctrl_shift + Qt::Key_0);
-
-  QAction *show_history_action = construct_window_menu_item
-                                 (window_menu, tr ("Show Command History"),
-                                  true, ctrl_shift + Qt::Key_1);
-
-  QAction *show_file_browser_action =  construct_window_menu_item
-                                       (window_menu, tr ("Show File Browser"),
-                                        true, ctrl_shift + Qt::Key_2);
-
-  QAction *show_workspace_action = construct_window_menu_item
-                                   (window_menu, tr ("Show Workspace"), true,
-                                    ctrl_shift + Qt::Key_3);
-
-  QAction *show_editor_action = construct_window_menu_item
-                                (window_menu, tr ("Show Editor"), true,
-                                 ctrl_shift + Qt::Key_4);
-
-  QAction *show_documentation_action = construct_window_menu_item
-                                       (window_menu, tr ("Show Documentation"),
-                                        true, ctrl_shift + Qt::Key_5);
-
-  window_menu->addSeparator ();
-
-  QAction *command_window_action = construct_window_menu_item
-                                   (window_menu, tr ("Command Window"), false,
-                                    ctrl + Qt::Key_0);
-
-  QAction *history_action = construct_window_menu_item
-                            (window_menu, tr ("Command History"), false,
-                             ctrl + Qt::Key_1);
-
-  QAction *file_browser_action = construct_window_menu_item
-                                 (window_menu, tr ("File Browser"), false,
-                                  ctrl + Qt::Key_2);
-
-  QAction *workspace_action = construct_window_menu_item
-                              (window_menu, tr ("Workspace"), false,
-                               ctrl + Qt::Key_3);
-
-  QAction *editor_action = construct_window_menu_item
-                           (window_menu, tr ("Editor"), false,
-                            ctrl + Qt::Key_4);
-
-  QAction *documentation_action = construct_window_menu_item
-                                  (window_menu, tr ("Documentation"), false,
-                                   ctrl + Qt::Key_5);
+  QMenu *window_menu = m_add_menu (p, tr ("&Window"));
+
+  _show_command_window_action = construct_window_menu_item
+            (window_menu, tr ("Show Command Window"), true, command_window);
+
+  _show_history_action = construct_window_menu_item
+            (window_menu, tr ("Show Command History"), true, history_window);
+
+  _show_file_browser_action = construct_window_menu_item
+            (window_menu, tr ("Show File Browser"), true, file_browser_window);
+
+  _show_workspace_action = construct_window_menu_item
+            (window_menu, tr ("Show Workspace"), true, workspace_window);
+
+  _show_editor_action = construct_window_menu_item
+            (window_menu, tr ("Show Editor"), true, editor_window);
+
+  _show_documentation_action = construct_window_menu_item
+            (window_menu, tr ("Show Documentation"), true, doc_browser_window);
 
   window_menu->addSeparator ();
 
-  QAction *reset_windows_action
-    = window_menu->addAction (tr ("Reset Default Window Layout"));
-
-  connect (show_command_window_action, SIGNAL (toggled (bool)),
-           command_window, SLOT (setVisible (bool)));
-
-  connect (command_window, SIGNAL (active_changed (bool)),
-           show_command_window_action, SLOT (setChecked (bool)));
-
-  connect (show_workspace_action, SIGNAL (toggled (bool)),
-           workspace_window, SLOT (setVisible (bool)));
-
-  connect (workspace_window, SIGNAL (active_changed (bool)),
-           show_workspace_action, SLOT (setChecked (bool)));
-
-  connect (show_history_action, SIGNAL (toggled (bool)),
-           history_window, SLOT (setVisible (bool)));
-
-  connect (history_window, SIGNAL (active_changed (bool)),
-           show_history_action, SLOT (setChecked (bool)));
-
-  connect (show_file_browser_action, SIGNAL (toggled (bool)),
-           file_browser_window, SLOT (setVisible (bool)));
-
-  connect (file_browser_window, SIGNAL (active_changed (bool)),
-           show_file_browser_action, SLOT (setChecked (bool)));
-
-#ifdef HAVE_QSCINTILLA
-  connect (show_editor_action, SIGNAL (toggled (bool)),
-           editor_window, SLOT (setVisible (bool)));
-
-  connect (editor_window, SIGNAL (active_changed (bool)),
-           show_editor_action, SLOT (setChecked (bool)));
-#endif
-
-  connect (show_documentation_action, SIGNAL (toggled (bool)),
-           doc_browser_window, SLOT (setVisible (bool)));
-
-  connect (doc_browser_window, SIGNAL (active_changed (bool)),
-           show_documentation_action, SLOT (setChecked (bool)));
-
-  connect (command_window_action, SIGNAL (triggered ()),
-           command_window, SLOT (focus ()));
-
-  connect (workspace_action, SIGNAL (triggered ()),
-           workspace_window, SLOT (focus ()));
-
-  connect (history_action, SIGNAL (triggered ()),
-           history_window, SLOT (focus ()));
-
-  connect (file_browser_action, SIGNAL (triggered ()),
-           file_browser_window, SLOT (focus ()));
-
-#ifdef HAVE_QSCINTILLA
-  connect (editor_action, SIGNAL (triggered ()),
-           editor_window, SLOT (focus ()));
-#endif
-
-  connect (documentation_action, SIGNAL (triggered ()),
-           doc_browser_window, SLOT (focus ()));
-
-  connect (reset_windows_action, SIGNAL (triggered ()),
-           this, SLOT (reset_windows ()));
+  _command_window_action = construct_window_menu_item
+            (window_menu, tr ("Command Window"), false, command_window);
+
+  _history_action = construct_window_menu_item
+            (window_menu, tr ("Command History"), false, history_window);
+
+  _file_browser_action = construct_window_menu_item
+            (window_menu, tr ("File Browser"), false, file_browser_window);
+
+  _workspace_action = construct_window_menu_item
+            (window_menu, tr ("Workspace"), false, workspace_window);
+
+  _editor_action = construct_window_menu_item
+            (window_menu, tr ("Editor"), false, editor_window);
+
+  _documentation_action = construct_window_menu_item
+            (window_menu, tr ("Documentation"), false, doc_browser_window);
+
+  window_menu->addSeparator ();
+
+  _reset_windows_action = add_action (window_menu, QIcon (),
+              tr ("Reset Default Window Layout"), SLOT (reset_windows ()));
 }
 
 void
 main_window::construct_help_menu (QMenuBar *p)
 {
-  QMenu *help_menu = p->addMenu (tr ("&Help"));
+  QMenu *help_menu = m_add_menu (p, tr ("&Help"));
 
   construct_documentation_menu (help_menu);
 
   help_menu->addSeparator ();
 
-  QAction *report_bug_action
-    = help_menu->addAction (tr ("Report Bug"));
-
-  QAction *octave_packages_action
-    = help_menu->addAction (tr ("Octave Packages"));
-
-  QAction *agora_action
-    = help_menu->addAction (tr ("Share Code"));
-
-  QAction *contribute_action
-    = help_menu->addAction (tr ("Contribute to Octave"));
-
-  QAction *developer_action
-    = help_menu->addAction (tr ("Octave Developer Resources"));
+  _report_bug_action = add_action (help_menu, QIcon (),
+            tr ("Report Bug"), SLOT (open_bug_tracker_page ()));
+
+  _octave_packages_action =  add_action (help_menu, QIcon (),
+            tr ("Octave Packages"), SLOT (open_octave_packages_page ()));
+
+  _agora_action = add_action (help_menu, QIcon (),
+            tr ("Share Code"), SLOT (open_agora_page ()));
+
+  _contribute_action = add_action (help_menu, QIcon (),
+            tr ("Contribute to Octave"), SLOT (open_contribute_page ()));
+
+  _developer_action = add_action (help_menu, QIcon (),
+            tr ("Octave Developer Resources"), SLOT (open_developer_page ()));
 
   help_menu->addSeparator ();
 
-  QAction *about_octave_action
-    = help_menu->addAction (tr ("About Octave"));
-
-  connect (report_bug_action, SIGNAL (triggered ()),
-           this, SLOT (open_bug_tracker_page ()));
-
-  connect (octave_packages_action, SIGNAL (triggered ()),
-           this, SLOT (open_octave_packages_page ()));
-
-  connect (agora_action, SIGNAL (triggered ()),
-           this, SLOT (open_agora_page ()));
-
-  connect (contribute_action, SIGNAL (triggered ()),
-           this, SLOT (open_contribute_page ()));
-
-  connect (developer_action, SIGNAL (triggered ()),
-           this, SLOT (open_developer_page ()));
-
-  connect (about_octave_action, SIGNAL (triggered ()),
-           this, SLOT (show_about_octave ()));
+  _about_octave_action = add_action (help_menu, QIcon (),
+            tr ("About Octave"), SLOT (show_about_octave ()));
 }
 
 void
 main_window::construct_documentation_menu (QMenu *p)
 {
-  QMenu *documentation_menu = p->addMenu (tr ("Documentation"));
-
-  QAction *ondisk_documentation_action
-    = documentation_menu->addAction (tr ("On Disk"));
-
-  QAction *online_documentation_action
-    = documentation_menu->addAction (tr ("Online"));
-
-  connect (ondisk_documentation_action, SIGNAL (triggered ()),
-           doc_browser_window, SLOT (focus ()));
-
-  connect (online_documentation_action, SIGNAL (triggered ()),
-           this, SLOT (open_online_documentation_page ()));
+  QMenu *doc_menu = p->addMenu (tr ("Documentation"));
+
+  _ondisk_doc_action = add_action (doc_menu, QIcon (),
+                     tr ("On Disk"), SLOT (focus ()), doc_browser_window);
+
+  _online_doc_action = add_action (doc_menu, QIcon (),
+                     tr ("Online"), SLOT (open_online_documentation_page ()));
 }
 
 void
 main_window::construct_news_menu (QMenuBar *p)
 {
-  QMenu *news_menu = p->addMenu (tr ("&News"));
-
-  QAction *release_notes_action
-    = news_menu->addAction (tr ("Release Notes"));
-
-  QAction *current_news_action
-    = news_menu->addAction (tr ("Community News"));
-
-  connect (release_notes_action, SIGNAL (triggered ()),
-           this, SLOT (display_release_notes ()));
-
-  connect (current_news_action, SIGNAL (triggered ()),
-           this, SLOT (load_and_display_community_news ()));
-}
-
-void
-main_window::construct_warning_bar (void)
-{
-  QSettings *settings = resource_manager::get_settings ();
-
-  if (settings
-      && settings->value ("General/hide_new_gui_warning", false).toBool ())
-    {
-      construct_gui_info_button ();
-
-      return;
-    }
-
-  _warning_bar = new QDockWidget (this);
-  _warning_bar->setAttribute (Qt::WA_DeleteOnClose);
-
-  QFrame *box = new QFrame (_warning_bar);
-
-  QLabel *icon = new QLabel (box);
-  QIcon warning_icon
-    = QIcon::fromTheme ("dialog-warning",
-                        QIcon (":/actions/icons/warning.png"));
-  QPixmap icon_pixmap = warning_icon.pixmap (QSize (32, 32));
-  icon->setPixmap (icon_pixmap);
-
-  QTextBrowser *msg = new QTextBrowser (box);
-  msg->setOpenExternalLinks (true);
-  msg->setText
-    (tr ("<strong>You are using a release candidate of Octave's experimental GUI.</strong>  "
-         "Octave is under continuous improvement and the GUI will be the "
-         "default interface for the 4.0 release.  For more information, "
-         "select the \"Release Notes\" item in the \"News\" menu of the GUI, "
-         "or visit <a href=\"http://octave.org\">http://octave.org</a>."));
-
-  msg->setStyleSheet ("background-color: #ffd97f; color: black; margin 4px;");
-  msg->setMinimumWidth (100);
-  msg->setMinimumHeight (60);
-  msg->setMaximumHeight (80);
-  msg->setSizePolicy (QSizePolicy (QSizePolicy::Expanding,
-                                   QSizePolicy::Minimum));
-
-  QPushButton *info_button = new QPushButton (tr ("More Info"), box);
-  QPushButton *hide_button = new QPushButton (tr ("Hide"), box);
-
-  connect (info_button, SIGNAL (clicked ()),
-           this, SLOT (show_gui_info ()));
-
-  connect (hide_button, SIGNAL (clicked ()),
-           this, SLOT (hide_warning_bar ()));
-
-  QVBoxLayout *button_layout = new QVBoxLayout;
-
-  button_layout->addWidget (info_button);
-  button_layout->addWidget (hide_button);
-
-  QHBoxLayout *icon_and_message = new QHBoxLayout;
-
-  icon_and_message->addWidget (icon);
-  icon_and_message->addSpacing (10);
-  icon_and_message->addWidget (msg);
-  icon_and_message->addSpacing (10);
-  icon_and_message->addLayout (button_layout);
-
-  icon_and_message->setAlignment (hide_button, Qt::AlignTop);
-
-  box->setFrameStyle (QFrame::Box);
-  box->setLineWidth (2);
-  box->setMaximumWidth (1000);
-  box->adjustSize ();
-  box->setLayout (icon_and_message);
-
-  _warning_bar->setFeatures (QDockWidget::NoDockWidgetFeatures);
-  _warning_bar->setObjectName ("WarningToolBar");
-  _warning_bar->setWidget (box);
-
-  setCorner (Qt::TopLeftCorner, Qt::TopDockWidgetArea);
-  setCorner (Qt::TopRightCorner, Qt::TopDockWidgetArea);
-
-  addDockWidget (Qt::TopDockWidgetArea, _warning_bar);
-};
-
-void
-main_window::construct_gui_info_button (void)
-{
-  QIcon warning_icon
-    = QIcon::fromTheme ("dialog-warning",
-                        QIcon (":/actions/icons/warning.png"));
-
-  _gui_info_button
-    = new QPushButton (warning_icon, tr ("Experimental GUI Info"));
-
-  _main_tool_bar->addWidget (_gui_info_button);
-
-  connect (_gui_info_button, SIGNAL (clicked ()),
-           this, SLOT (show_gui_info ()));
-}
-
-void
-main_window::hide_warning_bar (void)
-{
-  QSettings *settings = resource_manager::get_settings ();
-
-  if (settings)
-    {
-      settings->setValue ("General/hide_new_gui_warning", true);
-
-      settings->sync ();
-    }
-
-  removeDockWidget (_warning_bar);
-
-  construct_gui_info_button ();
-}
-
-void
-main_window::show_gui_info (void)
-{
-  QString gui_info
-    ( 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.  "
-         "But because it is not quite as polished as we would like, we "
-         "have decided to wait until the 4.0.x release series before "
-         "making the GUI the default interface.</p>"
-         "<p>Given the length of time and the number of bug fixes and "
-         "improvements since the last major release, we also "
-         "decided against delaying the release of all these new "
-         "improvements any longer just to perfect the GUI.  So please "
-         "enjoy the 3.8 release of Octave and the preview of the new GUI.  "
-         "We believe it is working reasonably well, but we also know that "
-         "there are some obvious rough spots and many things that could be "
-         "improved.</p>"
-         "<p><strong>We Need Your Help</strong></p>"
-         "<p>There are many ways that you can help us fix the remaining "
-         "problems, complete the GUI, and improve the overall user "
-         "experience for both novices and experts alike (links will open "
-         "an external browser):</p>"
-         "<p><ul><li>If you are a skilled software developer, you can "
-         "help by contributing your time to help "
-         "<a href=\"http://octave.org/get-involved.html\">develop "
-         "Octave</a>.</li>"
-         "<li>If Octave does not work properly, you are encouraged to "
-         "<a href=\"http://octave.org/bugs.html\">report problems </a> "
-         "that you find.</li>"
-         "<li>Whether you are a user or developer, you can "
-         "<a href=\"http://octave.org/donate.html\">help to fund the "
-         "project</a>.  "
-         "Octave development takes a lot of time and expertise.  "
-         "Your contributions help to ensure that Octave will continue "
-         "to improve.</li></ul></p>"
-         "<p>We hope you find Octave to be useful.  Please help us make "
-         "it even better for the future!</p>"));
-
-  QMessageBox gui_info_dialog (QMessageBox::Warning,
-                               tr ("Experimental GUI Info"),
-                               QString (gui_info.length (),' '), QMessageBox::Close);
-  QGridLayout *box_layout
-      = qobject_cast<QGridLayout *>(gui_info_dialog.layout());
-  if (box_layout)
-    {
-      QTextEdit *text = new QTextEdit(gui_info);
-      text->setReadOnly(true);
-      box_layout->addWidget(text, 0, 1);
-    }
-  gui_info_dialog.exec ();
+  QMenu *news_menu = m_add_menu (p, tr ("&News"));
+
+  _release_notes_action = add_action (news_menu, QIcon (),
+            tr ("Release Notes"), SLOT (display_release_notes ()));
+
+  _current_news_action = add_action (news_menu, QIcon (),
+            tr ("Community News"), SLOT (load_and_display_community_news ()));
 }
 
 void
@@ -2044,6 +2022,12 @@
 }
 
 void
+main_window::set_screen_size_callback (const int_pair& sz)
+{
+  command_editor::set_screen_size (sz.first, sz.second);
+}
+
+void
 main_window::clear_history_callback (void)
 {
   Fhistory (ovl ("-c"));
@@ -2072,7 +2056,8 @@
       command_editor::redisplay ();
       // We are executing inside the command editor event loop.  Force
       // the current line to be returned for processing.
-      command_editor::interrupt ();
+      Fdb_next_breakpoint_quiet (ovl (_suppress_dbg_location));
+      command_editor::accept_line ();
     }
 
   if (repost)  // queue not empty, so repost event for further processing
@@ -2127,13 +2112,22 @@
       _dbg_queue_mutex.unlock ();
 
       if (debug == "step")
-        Fdbstep ();
+        {
+          Fdb_next_breakpoint_quiet (ovl (_suppress_dbg_location));
+          Fdbstep ();
+        }
       else if (debug == "cont")
-        Fdbcont ();
+        {
+          Fdb_next_breakpoint_quiet (ovl (_suppress_dbg_location));
+          Fdbcont ();
+        }
       else if (debug == "quit")
         Fdbquit ();
       else
-        Fdbstep (ovl (debug.toStdString ()));
+        {
+          Fdb_next_breakpoint_quiet (ovl (_suppress_dbg_location));
+          Fdbstep (ovl (debug.toStdString ()));
+        }
 
       command_editor::interrupt (true);
     }
@@ -2188,40 +2182,149 @@
 }
 
 void
+main_window::set_global_edit_shortcuts (bool editor_has_focus)
+{
+  // this slot is called when editor gets/loses focus
+  if (editor_has_focus)
+    { // disable shortcuts that are also provided by the editor itself
+      QKeySequence no_key = QKeySequence ();
+      _copy_action->setShortcut (no_key);
+      _paste_action->setShortcut (no_key);
+      _undo_action->setShortcut (no_key);
+      _select_all_action->setShortcut (no_key);
+    }
+  else
+    { // editor loses focus, set the global shortcuts
+      shortcut_manager::set_shortcut (_copy_action, "main_edit:copy");
+      shortcut_manager::set_shortcut (_paste_action, "main_edit:paste");
+      shortcut_manager::set_shortcut (_undo_action, "main_edit:undo");
+      shortcut_manager::set_shortcut (_select_all_action, "main_edit:select_all");
+    }
+
+  // dis-/enable global menu depending on editor's focus
+  enable_menu_shortcuts (! editor_has_focus);
+}
+
+void
+main_window::configure_shortcuts ()
+{
+  // file menu
+  shortcut_manager::set_shortcut (_open_action, "main_file:open_file");
+  shortcut_manager::set_shortcut (_new_script_action, "main_file:new_file");
+  shortcut_manager::set_shortcut (_new_function_action, "main_file:new_function");
+  shortcut_manager::set_shortcut (_new_function_action, "main_file:new_figure");
+  shortcut_manager::set_shortcut (_load_workspace_action, "main_file:load_workspace");
+  shortcut_manager::set_shortcut (_save_workspace_action, "main_file:save_workspace");
+  shortcut_manager::set_shortcut (_preferences_action, "main_file:preferences");
+  shortcut_manager::set_shortcut (_exit_action,"main_file:exit");
+
+  // edit menu
+  shortcut_manager::set_shortcut (_copy_action, "main_edit:copy");
+  shortcut_manager::set_shortcut (_paste_action, "main_edit:paste");
+  shortcut_manager::set_shortcut (_undo_action, "main_edit:undo");
+  shortcut_manager::set_shortcut (_select_all_action, "main_edit:select_all");
+  shortcut_manager::set_shortcut (_clear_clipboard_action, "main_edit:clear_clipboard");
+  shortcut_manager::set_shortcut (_find_files_action, "main_edit:find_in_files");
+  shortcut_manager::set_shortcut (_clear_command_history_action, "main_edit:clear_history");
+  shortcut_manager::set_shortcut (_clear_command_window_action, "main_edit:clear_command_window");
+  shortcut_manager::set_shortcut (_clear_workspace_action, "main_edit:clear_workspace");
+
+  // debug menu
+  shortcut_manager::set_shortcut (_debug_step_over, "main_debug:step_over");
+  shortcut_manager::set_shortcut (_debug_step_into, "main_debug:step_into");
+  shortcut_manager::set_shortcut (_debug_step_out,  "main_debug:step_out");
+  shortcut_manager::set_shortcut (_debug_continue,  "main_debug:continue");
+  shortcut_manager::set_shortcut (_debug_quit,  "main_debug:quit");
+
+  // window menu
+  shortcut_manager::set_shortcut (_show_command_window_action, "main_window:show_command");
+  shortcut_manager::set_shortcut (_show_history_action, "main_window:show_history");
+  shortcut_manager::set_shortcut (_show_workspace_action,  "main_window:show_workspace");
+  shortcut_manager::set_shortcut (_show_file_browser_action,  "main_window:show_file_browser");
+  shortcut_manager::set_shortcut (_show_editor_action, "main_window:show_editor");
+  shortcut_manager::set_shortcut (_show_documentation_action, "main_window:show_doc");
+  shortcut_manager::set_shortcut (_command_window_action, "main_window:command");
+  shortcut_manager::set_shortcut (_history_action, "main_window:history");
+  shortcut_manager::set_shortcut (_workspace_action,  "main_window:workspace");
+  shortcut_manager::set_shortcut (_file_browser_action,  "main_window:file_browser");
+  shortcut_manager::set_shortcut (_editor_action, "main_window:editor");
+  shortcut_manager::set_shortcut (_documentation_action, "main_window:doc");
+  shortcut_manager::set_shortcut (_reset_windows_action, "main_window:reset");
+
+  // help menu
+  shortcut_manager::set_shortcut (_ondisk_doc_action, "main_help:ondisk_doc");
+  shortcut_manager::set_shortcut (_online_doc_action, "main_help:online_doc");
+  shortcut_manager::set_shortcut (_report_bug_action, "main_help:report_bug");
+  shortcut_manager::set_shortcut (_octave_packages_action, "main_help:packages");
+  shortcut_manager::set_shortcut (_agora_action, "main_help:agora");
+  shortcut_manager::set_shortcut (_contribute_action, "main_help:contribute");
+  shortcut_manager::set_shortcut (_developer_action, "main_help:developer");
+  shortcut_manager::set_shortcut (_about_octave_action, "main_help:about");
+
+  // news menu
+  shortcut_manager::set_shortcut (_release_notes_action, "main_news:release_notes");
+  shortcut_manager::set_shortcut (_current_news_action, "main_news:community_news");
+}
+
+void
 main_window::set_global_shortcuts (bool set_shortcuts)
 {
+  // this slot is called when the terminal gets/loses focus
+
+  // return if the user don't want to use readline shortcuts
+  if (! _prevent_readline_conflicts)
+    return;
+
   if (set_shortcuts)
-    {
-
-      _open_action->setShortcut (QKeySequence::Open);
-      _new_script_action->setShortcut (QKeySequence::New);
-      _new_function_action->setShortcut (Qt::ControlModifier
-                                       + Qt::ShiftModifier
-                                       + Qt::Key_N);
-
-      _exit_action->setShortcut (QKeySequence::Quit);
-
-      _find_files_action->setShortcut (Qt::ControlModifier
-                                       + Qt::ShiftModifier
-                                       + Qt::Key_F);
-
+    { // terminal loses focus: set the global shortcuts
+      configure_shortcuts ();
     }
   else
-    {
-
+    { // terminal gets focus: disable some shortcuts
       QKeySequence no_key = QKeySequence ();
 
+      // file menu
       _open_action->setShortcut (no_key);
       _new_script_action->setShortcut (no_key);
       _new_function_action->setShortcut (no_key);
-
+      _new_function_action->setShortcut (no_key);
+      _load_workspace_action->setShortcut (no_key);
+      _save_workspace_action->setShortcut (no_key);
+      _preferences_action->setShortcut (no_key);
       _exit_action->setShortcut (no_key);
 
+      // edit menu
+      _select_all_action->setShortcut (no_key);
+      _clear_clipboard_action->setShortcut (no_key);
       _find_files_action->setShortcut (no_key);
-
+      _clear_command_history_action->setShortcut (no_key);
+      _clear_command_window_action->setShortcut (no_key);
+      _clear_workspace_action->setShortcut (no_key);
+
+      // window menu
+      _reset_windows_action->setShortcut (no_key);
+
+      // help menu
+      _ondisk_doc_action->setShortcut (no_key);
+      _online_doc_action->setShortcut (no_key);
+      _report_bug_action->setShortcut (no_key);
+      _octave_packages_action->setShortcut (no_key);
+      _agora_action->setShortcut (no_key);
+      _contribute_action->setShortcut (no_key);
+      _developer_action->setShortcut (no_key);
+      _about_octave_action->setShortcut (no_key);
+
+      // news menu
+      _release_notes_action->setShortcut (no_key);
+      _current_news_action->setShortcut (no_key);
     }
-
-  emit set_widget_shortcuts_signal (set_shortcuts);
+}
+
+void
+main_window::set_screen_size (int ht, int wd)
+{
+  octave_link::post_event (this, &main_window::set_screen_size_callback,
+                           int_pair (ht, wd));
 }
 
 void
@@ -2254,3 +2357,30 @@
 {
   _clipboard->clear (QClipboard::Clipboard);
 }
+
+bool
+main_window::confirm_exit_octave ()
+{
+  bool closenow = true;
+
+  QSettings *settings = resource_manager::get_settings ();
+
+  if (settings->value ("prompt_to_exit", false).toBool ())
+    {
+      int ans = QMessageBox::question (this, tr ("Octave"),
+         tr ("Are you sure you want to exit Octave?"),
+          QMessageBox::Ok | QMessageBox::Cancel, QMessageBox::Ok);
+
+      if (ans !=  QMessageBox::Ok)
+        return false;
+
+    }
+
+#ifdef HAVE_QSCINTILLA
+  closenow = editor_window->check_closing (1);  // 1: exit request from gui
+#endif
+
+  return closenow;
+}
+
+
--- a/libgui/src/main-window.h	Fri Feb 06 08:31:09 2015 -0800
+++ b/libgui/src/main-window.h	Fri Feb 06 08:31:49 2015 -0800
@@ -37,6 +37,7 @@
 #include <QToolButton>
 #include <QComboBox>
 #include <QSemaphore>
+#include <QPointer>
 
 // Editor includes
 #include "file-editor-interface.h"
@@ -57,8 +58,10 @@
 #include "octave-dock-widget.h"
 #include "find-files-dialog.h"
 
+class settings_dialog;
+
 /**
- * \class MainWindow
+ * @class MainWindow
  *
  * Represents the main window.
  */
@@ -69,6 +72,7 @@
 public:
 
   typedef std::pair <std::string, std::string> name_pair;
+  typedef std::pair <int, int> int_pair;
 
   main_window (QWidget *parent = 0);
 
@@ -79,7 +83,12 @@
   void focus_command_window (void);
 
 signals:
+
+  void active_dock_changed (octave_dock_widget *, octave_dock_widget *);
+  void editor_focus_changed (bool);
+
   void settings_changed (const QSettings *);
+  void init_terminal_size_signal (void);
   void new_file_signal (const QString&);
   void open_file_signal (const QString&);
 
@@ -92,10 +101,13 @@
 
   void copyClipboard_signal (void);
   void pasteClipboard_signal (void);
-
-  void set_widget_shortcuts_signal (bool);
+  void selectAll_signal (void);
 
 public slots:
+
+  void focus_changed (QWidget *w_old, QWidget *w_new);
+  void request_reload_settings ();
+
   void report_status_message (const QString& statusMessage);
   void handle_save_workspace_request (void);
   void handle_load_workspace_request (const QString& file = QString ());
@@ -124,9 +136,6 @@
   void exit (int status);
   void reset_windows (void);
 
-  void hide_warning_bar (void);
-  void show_gui_info (void);
-
   void change_directory (const QString& dir);
   void browse_for_directory (void);
   void set_current_working_directory (const QString& dir);
@@ -152,12 +161,14 @@
                                                 const QString& file, int line);
 
   void read_settings (void);
+  void init_terminal_size (void);
   void set_window_layout (QSettings *settings);
   void write_settings (void);
   void connect_visibility_changed (void);
 
   void copyClipboard (void);
   void pasteClipboard (void);
+  void selectAll (void);
 
   void connect_uiwidget_links ();
 
@@ -185,12 +196,17 @@
 
   void handle_show_doc (const QString &file);
 
+  void handle_octave_ready ();
+
   // find files dialog
   void find_files (const QString &startdir=QDir::currentPath ());
   void find_files_finished (int);
 
   // setting global shortcuts
   void set_global_shortcuts (bool enable);
+  void set_global_edit_shortcuts (bool enable);
+
+  void set_screen_size (int ht, int wd);
 
   // handling the clipboard
   void clipboard_has_changed (QClipboard::Mode);
@@ -209,28 +225,26 @@
 
   void construct_octave_qt_link (void);
 
+  QAction *add_action (QMenu *menu, const QIcon &icon, const QString &text,
+                       const char *member, const QWidget *receiver = 0);
+
+  void enable_menu_shortcuts (bool enable);
+  QMenu* m_add_menu (QMenuBar *p, QString text);
   void construct_menu_bar (void);
   void construct_file_menu (QMenuBar *p);
   void construct_new_menu (QMenu *p);
   void construct_edit_menu (QMenuBar *p);
-  void construct_debug_menu_item (QMenu *p, const QString& item,
-                                  const QKeySequence& key);
-  QAction *construct_debug_menu_item (const char *icon_file,
-                                      const QString& item,
-                                      const QKeySequence& key);
+  QAction *construct_debug_menu_item (const char *icon, const QString& item,
+                                      const char* member);
   void construct_debug_menu (QMenuBar *p);
   QAction *construct_window_menu_item (QMenu *p, const QString& item,
-                                       bool checkable,
-                                       const QKeySequence& key);
+                                       bool checkable, QWidget*);
   void construct_window_menu (QMenuBar *p);
   void construct_help_menu (QMenuBar *p);
   void construct_documentation_menu (QMenu *p);
 
   void construct_news_menu (QMenuBar *p);
 
-  void construct_warning_bar (void);
-  void construct_gui_info_button (void);
-
   void construct_tool_bar (void);
 
   void establish_octave_link (void);
@@ -247,12 +261,15 @@
 
   void resize_command_window_callback (void);
 
+  void set_screen_size_callback (const int_pair&);
+
   void clear_workspace_callback (void);
 
   void clear_history_callback (void);
 
   void execute_command_callback ();
   void run_file_callback (const QFileInfo& info);
+  bool focus_console_after_command ();
 
   void new_figure_callback (void);
 
@@ -266,8 +283,15 @@
 
   void execute_debug_callback ();
 
+  void configure_shortcuts ();
+
+  bool confirm_exit_octave ();
+
   workspace_model *_workspace_model;
 
+  QHash<QMenu*, QStringList> _hash_menu_text;
+
+
   // Toolbars.
   QStatusBar *status_bar;
 
@@ -291,14 +315,12 @@
     list.append (static_cast<octave_dock_widget *> (workspace_window));
     return list;
   }
+  octave_dock_widget *_active_dock;
 
   QString _release_notes_icon;
 
   QToolBar *_main_tool_bar;
 
-  QDockWidget *_warning_bar;
-  QPushButton *_gui_info_button;
-
   QMenu *_debug_menu;
 
   QAction *_debug_continue;
@@ -310,14 +332,47 @@
   QAction *_new_script_action;
   QAction *_new_function_action;
   QAction *_open_action;
+  QAction *_new_figure_action;
+  QAction *_load_workspace_action;
+  QAction *_save_workspace_action;
+  QAction *_preferences_action;
+  QAction *_exit_action;
 
   QAction *_copy_action;
   QAction *_paste_action;
   QAction *_clear_clipboard_action;
   QAction *_undo_action;
-
+  QAction *_clear_command_window_action;
+  QAction *_clear_command_history_action;
+  QAction *_clear_workspace_action;
   QAction *_find_files_action;
-  QAction *_exit_action;
+  QAction *_select_all_action;
+
+  QAction *_show_command_window_action;
+  QAction *_show_history_action;
+  QAction *_show_workspace_action;
+  QAction *_show_file_browser_action;
+  QAction *_show_editor_action;
+  QAction *_show_documentation_action;
+  QAction *_command_window_action;
+  QAction *_history_action;
+  QAction *_workspace_action;
+  QAction *_file_browser_action;
+  QAction *_editor_action;
+  QAction *_documentation_action;
+  QAction *_reset_windows_action;
+
+  QAction *_ondisk_doc_action;
+  QAction *_online_doc_action;
+  QAction *_report_bug_action;
+  QAction *_octave_packages_action;
+  QAction *_agora_action;
+  QAction *_contribute_action;
+  QAction *_developer_action;
+  QAction *_about_octave_action;
+
+  QAction *_release_notes_action;
+  QAction *_current_news_action;
 
   // Toolbars.
   QComboBox *_current_directory_combo_box;
@@ -326,6 +381,9 @@
   static const int current_directory_max_count = 16;
   QLineEdit *_current_directory_line_edit;
 
+  // settings dialog as guarded pointer (set to 0 when deleted)
+  QPointer<settings_dialog> _settings_dlg;
+
   // Find files dialog
   find_files_dialog * find_files_dlg;
 
@@ -350,6 +408,9 @@
   QStringList *_dbg_queue;
   QSemaphore   _dbg_processing;
   QMutex       _dbg_queue_mutex;
+
+  bool _prevent_readline_conflicts;
+  bool _suppress_dbg_location;
 };
 
 class news_reader : public QObject
--- a/libgui/src/module.mk	Fri Feb 06 08:31:09 2015 -0800
+++ b/libgui/src/module.mk	Fri Feb 06 08:31:49 2015 -0800
@@ -67,6 +67,9 @@
   src/icons/widget-close.png \
   src/icons/widget-dock.png \
   src/icons/widget-undock.png \
+  src/icons/widget-close-light.png \
+  src/icons/widget-dock-light.png \
+  src/icons/widget-undock-light.png \
   src/icons/zoom-in.png \
   src/icons/zoom-out.png
 
@@ -78,7 +81,8 @@
   src/m-editor/moc-file-editor-tab.cc \
   src/m-editor/moc-file-editor.cc \
   src/m-editor/moc-find-dialog.cc \
-  src/m-editor/moc-octave-qscintilla.cc
+  src/m-editor/moc-octave-qscintilla.cc \
+  src/m-editor/moc-octave-txt-lexer.cc
 endif
 
 octave_gui_MOC += \
@@ -93,6 +97,7 @@
   src/moc-terminal-dock-widget.cc \
   src/moc-color-picker.cc \
   src/moc-resource-manager.cc \
+  src/moc-shortcut-manager.cc \
   src/moc-welcome-wizard.cc \
   src/moc-workspace-model.cc \
   src/moc-workspace-view.cc \
@@ -122,6 +127,7 @@
   src/m-editor/file-editor.h \
   src/m-editor/find-dialog.h \
   src/m-editor/octave-qscintilla.h \
+  src/m-editor/octave-txt-lexer.h \
   src/main-window.h \
   src/octave-gui.h \
   src/octave-interpreter.h \
@@ -130,6 +136,7 @@
   src/qtinfo/webinfo.h \
   src/resource-manager.h \
   src/settings-dialog.h \
+  src/shortcut-manager.h \
   src/thread-manager.h \
   src/terminal-dock-widget.h \
   src/color-picker.h \
@@ -148,6 +155,7 @@
   src/m-editor/file-editor.cc \
   src/m-editor/find-dialog.cc \
   src/m-editor/octave-qscintilla.cc \
+  src/m-editor/octave-txt-lexer.cc \
   src/main-window.cc \
   src/octave-dock-widget.cc \
   src/octave-gui.cc \
@@ -157,6 +165,7 @@
   src/qtinfo/webinfo.cc \
   src/resource-manager.cc \
   src/settings-dialog.cc \
+  src/shortcut-manager.cc \
   src/thread-manager.cc \
   src/terminal-dock-widget.cc \
   src/color-picker.cc \
@@ -170,12 +179,16 @@
 
 src_libgui_src_la_CPPFLAGS = \
   $(AM_CPPFLAGS) \
+  $(FT2_CPPFLAGS) \
+  $(FONTCONFIG_CPPFLAGS) \
+  $(HDF5_CPPFLAGS) \
   @OCTGUI_DLL_DEFS@ \
   @QT_CPPFLAGS@ \
   -I$(srcdir)/qterminal/libqterminal \
   -Isrc -I$(srcdir)/src \
   -I$(srcdir)/src/m-editor \
   -I$(srcdir)/src/qtinfo \
+  -I$(srcdir)/graphics \
   -I$(top_srcdir)/liboctave/cruft/misc \
   -I$(top_srcdir)/liboctave/array \
   -I$(top_builddir)/liboctave/numeric -I$(top_srcdir)/liboctave/numeric \
--- a/libgui/src/octave-dock-widget.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/libgui/src/octave-dock-widget.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -27,7 +27,6 @@
 
 #include <QApplication>
 #include <QToolBar>
-#include <QToolButton>
 #include <QAction>
 #include <QHBoxLayout>
 #include <QLabel>
@@ -48,7 +47,10 @@
            this, SLOT (handle_visibility_changed (bool)));
 
   connect (p, SIGNAL (settings_changed (const QSettings*)),
-           this, SLOT (notice_settings (const QSettings*)));
+           this, SLOT (handle_settings (const QSettings*)));
+
+  connect (p, SIGNAL (active_dock_changed (octave_dock_widget*, octave_dock_widget*)),
+           this, SLOT (handle_active_dock_changed (octave_dock_widget*, octave_dock_widget*)));
 
 #if defined (Q_OS_WIN32)
   // windows: add an extra title bar that persists when floating
@@ -61,31 +63,33 @@
   _dock_action-> setToolTip (tr ("Undock widget"));
   connect (_dock_action, SIGNAL (triggered (bool)),
            this, SLOT (change_floating (bool)));
-  QToolButton *dock_button = new QToolButton (this);
-  dock_button->setDefaultAction (_dock_action);
-  dock_button->setFocusPolicy (Qt::NoFocus);
-  dock_button->setIconSize (QSize (12,12));
+  _dock_button = new QToolButton (this);
+  _dock_button->setDefaultAction (_dock_action);
+  _dock_button->setFocusPolicy (Qt::NoFocus);
+  _dock_button->setIconSize (QSize (12,12));
 
-  QAction *close_action = new QAction
-                   (QIcon (":/actions/icons/widget-close.png"), "", this );
-  close_action-> setToolTip (tr ("Hide widget"));
-  connect (close_action, SIGNAL (triggered (bool)),
+  _close_action = new QAction
+                   (QIcon (":/actions/icons/widget-close.png"), "", this);
+  _close_action-> setToolTip (tr ("Hide widget"));
+  connect (_close_action, SIGNAL (triggered (bool)),
            this, SLOT (change_visibility (bool)));
-  QToolButton *close_button = new QToolButton (this);
-  close_button->setDefaultAction (close_action);
-  close_button->setFocusPolicy (Qt::NoFocus);
-  close_button->setIconSize (QSize (12,12));
+  _close_button = new QToolButton (this);
+  _close_button->setDefaultAction (_close_action);
+  _close_button->setFocusPolicy (Qt::NoFocus);
+  _close_button->setIconSize (QSize (12,12));
+
+  _icon_color = "";
 
   QHBoxLayout *h_layout = new QHBoxLayout ();
   h_layout->addStretch (100);
-  h_layout->addWidget (dock_button);
-  h_layout->addWidget (close_button);
+  h_layout->addWidget (_dock_button);
+  h_layout->addWidget (_close_button);
   h_layout->setSpacing (0);
-  h_layout->setContentsMargins (6,0,0,0);
+  h_layout->setContentsMargins (5,2,2,2);
 
-  QWidget *title_widget = new QWidget ();
-  title_widget->setLayout (h_layout);
-  setTitleBarWidget (title_widget);
+  _title_widget = new QWidget ();
+  _title_widget->setLayout (h_layout);
+  setTitleBarWidget (_title_widget);
 
 #else
 
@@ -104,6 +108,11 @@
            this, SLOT (copyClipboard ()));
   connect (p, SIGNAL (pasteClipboard_signal ()),
            this, SLOT (pasteClipboard ()));
+  connect (p, SIGNAL (selectAll_signal ()),
+           this, SLOT (selectAll ()));
+
+  installEventFilter (this);
+
 }
 
 octave_dock_widget::~octave_dock_widget ()
@@ -147,6 +156,7 @@
   QHBoxLayout* h_layout =
     static_cast<QHBoxLayout *> (titleBarWidget ()->layout ());
   QLabel *label = new QLabel (title);
+  label->setStyleSheet ("background: transparent;");
   h_layout->insertWidget (0,label);
 #endif
   setWindowTitle (title);
@@ -171,10 +181,10 @@
 
   // remove parent and adjust the (un)dock icon
   setParent (0, Qt::Window);
-  _dock_action->setIcon (QIcon (":/actions/icons/widget-dock.png"));
+  _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 ());
 
@@ -183,6 +193,10 @@
   // non windows: Just set the appripriate window flag
   setWindowFlags (Qt::Window);
 
+  QString css = styleSheet ();
+  css.replace ("widget-undock","widget-dock");
+  setStyleSheet (css);
+
 #endif
 
   _floating = true;
@@ -194,7 +208,7 @@
 {
 #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 ();
 
@@ -220,14 +234,21 @@
     setParent (_parent);
 
   // adjust the (un)dock icon
-  _dock_action->setIcon (QIcon (":/actions/icons/widget-undock.png"));
+  _dock_action->setIcon (QIcon (":/actions/icons/widget-undock"+_icon_color+".png"));
   _dock_action->setToolTip (tr ("Undock widget"));
 
 #else
 
   // non windows: just say we are a docked widget again
+
+  Q_UNUSED (dock);
+
   setWindowFlags (Qt::Widget);
 
+  QString css = styleSheet ();
+  css.replace ("widget-dock","widget-undock");
+  setStyleSheet (css);
+
 #endif
 
   _floating = false;
@@ -262,3 +283,151 @@
   if (w && w->focusProxy ()) w = w->focusProxy ();
   return w;
 }
+
+void
+octave_dock_widget::set_style (bool active)
+{
+  QString css;
+  QString css_button;
+  QString dock_icon;
+
+  QString icon_col = _icon_color;
+
+  if (_floating)
+    dock_icon = "widget-dock";
+  else
+    dock_icon = "widget-undock";
+
+  if (_custom_style)
+    {
+
+      QColor bg_col, fg_col;
+
+      if (active)
+        {
+          bg_col = _bg_color_active;
+          fg_col = _fg_color_active;
+          icon_col = _icon_color_active;
+        }
+      else
+        {
+          bg_col = _bg_color;
+          fg_col = _fg_color;
+          icon_col = _icon_color;
+        }
+
+      QString background =
+          QString ("background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,"
+                   "            stop: 0 %1, stop: 0.75 %2, stop: 0.9 %2, stop: 1.0 %1);").
+                   arg (bg_col.lighter ().name ()).
+                   arg (bg_col.name ());
+
+#if defined (Q_OS_WIN32)
+      css = background + QString (" color: %1 ;").arg (fg_col.name ());
+#else
+      css = QString ("QDockWidget::title { " + background +
+                     "                     text-align: center left;"
+                     "                     padding: 0px 0px 0px 4px;}\n"
+                     "QDockWidget { color: %1 ; "
+                     "  titlebar-close-icon: url(:/actions/icons/widget-close%2.png);"
+                     "  titlebar-normal-icon: url(:/actions/icons/"+dock_icon+"%2); }"
+                     "QDockWidget::close-button,"
+                     "QDockWidget::float-button { border: 0px;}"
+                     ).
+                     arg (fg_col.name ()).
+                     arg (icon_col);
+#endif
+    }
+  else
+    {
+#if defined (Q_OS_WIN32)
+      css = QString ("");
+#else
+      css = QString ("QDockWidget::title { text-align: center left;"
+                     "                     padding: 0px 0px 0px 4px;}"
+                     "QDockWidget {"
+                     "  titlebar-close-icon: url(:/actions/icons/widget-close.png);"
+                     "  titlebar-normal-icon: url(:/actions/icons/"+dock_icon+"); }"
+                     "QDockWidget::close-button,"
+                     "QDockWidget::float-button { border: 0px; }"
+                    );
+#endif
+    }
+
+#if defined (Q_OS_WIN32)
+  _title_widget->setStyleSheet (css);
+  css_button = QString ("background: transparent; border: 0px;");
+  _dock_button->setStyleSheet (css_button);
+  _close_button->setStyleSheet (css_button);
+  _dock_action->setIcon (QIcon (":/actions/icons/" + dock_icon + icon_col + ".png"));
+  _close_action->setIcon (QIcon (":/actions/icons/widget-close" + dock_icon + icon_col + ".png"));
+#else
+  setStyleSheet (css);
+#endif
+}
+
+void
+octave_dock_widget::handle_settings (const QSettings *settings)
+{
+  _custom_style =
+    settings->value ("DockWidgets/widget_title_custom_style",false).toBool ();
+
+  QColor default_var = QColor (0,0,0);
+  _fg_color = settings->value ("Dockwidgets/title_fg_color",
+                                default_var).value<QColor> ();
+  default_var = QColor (0,0,0);
+  _fg_color_active = settings->value ("Dockwidgets/title_fg_color_active",
+                                default_var).value<QColor> ();
+
+  default_var = QColor (255,255,255);
+  _bg_color = settings->value ("Dockwidgets/title_bg_color",
+                                default_var).value<QColor> ();
+  default_var = QColor (192,192,192);
+  _bg_color_active = settings->value ("Dockwidgets/title_bg_color_active",
+                                       default_var).value<QColor> ();
+
+  int r, g, b;
+  _bg_color.getRgb (&r, &g, &b);
+  if (r+g+b < 400)
+      _icon_color = "-light";
+  else
+    _icon_color = "";
+
+  _bg_color_active.getRgb (&r, &g, &b);
+  if (r+g+b < 400)
+      _icon_color_active = "-light";
+  else
+    _icon_color_active = "";
+
+  notice_settings (settings);  // call individual handler
+
+  set_style (false);
+}
+
+bool octave_dock_widget::eventFilter(QObject *obj, QEvent *e)
+{
+  if (e->type () == QEvent::NonClientAreaMouseButtonDblClick)
+    {
+      e->ignore (); // ignore double clicks into window decoration elements
+      return true;
+    }
+
+  return QDockWidget::eventFilter (obj,e);
+}
+
+void
+octave_dock_widget::handle_active_dock_changed (octave_dock_widget *w_old,
+                                                octave_dock_widget *w_new)
+{
+  if (_custom_style && this == w_old)
+    {
+      set_style (false);
+      update ();
+    }
+
+  if (_custom_style && this == w_new)
+    {
+      set_style (true);
+      update ();
+    }
+}
--- a/libgui/src/octave-dock-widget.h	Fri Feb 06 08:31:09 2015 -0800
+++ b/libgui/src/octave-dock-widget.h	Fri Feb 06 08:31:49 2015 -0800
@@ -27,6 +27,7 @@
 #include <QSettings>
 #include <QIcon>
 #include <QMainWindow>
+#include <QToolButton>
 #include <QMouseEvent>
 
 class octave_dock_widget : public QDockWidget
@@ -81,6 +82,9 @@
   virtual void notice_settings (const QSettings*)
   {
   }
+  void handle_settings (const QSettings*);
+
+  void handle_active_dock_changed (octave_dock_widget*, octave_dock_widget*);
 
   QMainWindow *main_win () { return _parent; }
 
@@ -99,6 +103,12 @@
   virtual void pasteClipboard ()
   {
   }
+  virtual void selectAll ()
+  {
+  }
+
+  // event filter for double clicks into the window decoration elements
+  bool eventFilter(QObject *obj, QEvent *e);
 
 private slots:
 
@@ -107,9 +117,25 @@
 
 private:
 
+  void set_style (bool active);
+
   QMainWindow *_parent;  // store the parent since we are reparenting to 0
+  bool _floating;
+  bool _custom_style;
+  QColor _bg_color;
+  QColor _bg_color_active;
+  QColor _fg_color;
+  QColor _fg_color_active;
+  QString _icon_color;
+  QString _icon_color_active;
+
+#if defined (Q_OS_WIN32)
+  QWidget *_title_widget;
+  QToolButton *_dock_button;
+  QToolButton *_close_button;
   QAction *_dock_action;
-  bool _floating;
+  QAction *_close_action;
+#endif
 
 };
 
--- a/libgui/src/octave-gui.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/libgui/src/octave-gui.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -48,6 +48,7 @@
 
 #include "welcome-wizard.h"
 #include "resource-manager.h"
+#include "shortcut-manager.h"
 #include "main-window.h"
 #include "octave-gui.h"
 #include "thread-manager.h"
@@ -88,7 +89,7 @@
 // Disable all Qt messages by default.
 
 static void
-message_handler (QtMsgType type, const char *msg)
+message_handler (QtMsgType, const char *)
 {
 }
 
@@ -158,19 +159,24 @@
         octave_env::putenv ("TERM", "cygwin");
 #endif
 
+      // shortcut manager
+      shortcut_manager::init_data ();
+
       // Create and show main window.
 
       main_window w;
 
       w.read_settings ();
 
-      w.focus_command_window ();
+      w.init_terminal_size ();
 
       // Connect signals for changes in visibility not before w
       // is shown.
 
       w.connect_visibility_changed ();
 
+      w.focus_command_window ();
+
       return application.exec ();
     }
   else
--- a/libgui/src/octave-interpreter.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/libgui/src/octave-interpreter.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -43,6 +43,8 @@
   octave_initialize_interpreter (octave_cmdline_argc, octave_cmdline_argv,
                                  octave_embedded);
 
+  emit octave_ready_signal ();
+
   octave_execute_interpreter ();
 }
 
--- a/libgui/src/octave-interpreter.h	Fri Feb 06 08:31:09 2015 -0800
+++ b/libgui/src/octave-interpreter.h	Fri Feb 06 08:31:49 2015 -0800
@@ -38,6 +38,10 @@
 
   octave_interpreter (void) : QObject (), thread_manager () { }
 
+signals:
+
+  void octave_ready_signal ();
+
 public slots:
 
   // Initialize and execute the octave interpreter.
--- a/libgui/src/octave-qt-link.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/libgui/src/octave-qt-link.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -43,13 +43,16 @@
 
 #include "resource-manager.h"
 
-octave_qt_link::octave_qt_link (void)
+octave_qt_link::octave_qt_link (QWidget *p)
   : octave_link (), main_thread (new QThread ()),
     command_interpreter (new octave_interpreter ())
 {
   connect (this, SIGNAL (execute_interpreter_signal (void)),
            command_interpreter, SLOT (execute (void)));
 
+  connect (command_interpreter, SIGNAL (octave_ready_signal ()),
+           p, SLOT (handle_octave_ready ()));
+
   command_interpreter->moveToThread (main_thread);
 
   main_thread->start ();
@@ -90,21 +93,21 @@
   QFileInfo file_info (QString::fromStdString (file));
   QStringList btn;
   QStringList role;
-  role << "AcceptRole" << "AcceptRole";
-  btn << tr ("Yes") << tr ("No");
+  role << "YesRole" << "RejectRole";
+  btn << tr ("Create") << tr ("Cancel");
 
   uiwidget_creator.signal_dialog (
     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 ("Create"), role );
 
   // Wait while the user is responding to message box.
   uiwidget_creator.wait ();
   // The GUI has sent a signal and the process has been awakened.
   QString answer = uiwidget_creator.get_dialog_button ();
 
-  return (answer == tr ("Yes"));
+  return (answer == tr ("Create"));
 }
 
 int
@@ -308,8 +311,8 @@
 
   QString msg
     = (addpath_option
-       ? tr ("The file %1 does not exist in the load path.  To debug the function you are editing, you must either change to the directory %2 or add that directory to the load path.").arg (qfile).arg (qdir)
-       : tr ("The file %1 is shadowed by a file with the same name in the load path.  To debug the function you are editing, change to the directory %2.").arg (qfile).arg (qdir));
+       ? tr ("The file %1 does not exist in the load path.  To run or debug the function you are editing, you must either change to the directory %2 or add that directory to the load path.").arg (qfile).arg (qdir)
+       : tr ("The file %1 is shadowed by a file with the same name in the load path. To run or debug the function you are editing, change to the directory %2.").arg (qfile).arg (qdir));
 
   QString title = tr ("Change Directory or Add Directory to Load Path");
 
--- a/libgui/src/octave-qt-link.h	Fri Feb 06 08:31:09 2015 -0800
+++ b/libgui/src/octave-qt-link.h	Fri Feb 06 08:31:49 2015 -0800
@@ -39,9 +39,9 @@
 // Defined for purposes of sending QList<int> as part of signal.
 typedef QList<int> QIntList;
 
-// \class OctaveLink
-// \brief Provides threadsafe access to octave.
-// \author Jacob Dawid
+// @class OctaveLink
+// @brief Provides threadsafe access to octave.
+// @author Jacob Dawid
 //
 // This class is a wrapper around octave and provides thread safety by
 // buffering access operations to octave and executing them in the
@@ -53,7 +53,7 @@
 
 public:
 
-  octave_qt_link (void);
+  octave_qt_link (QWidget *p);
 
   ~octave_qt_link (void);
 
--- a/libgui/src/qtinfo/parser.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/libgui/src/qtinfo/parser.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -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>
@@ -47,7 +47,7 @@
   _compressors_map.insert ("Z",    "gunzip -c \"%1\"");
 }
 
-void
+bool
 parser::set_info_path (const QString& infoPath)
 {
   this->_info_path = infoPath;
@@ -56,15 +56,32 @@
 
   QFileInfo info (infoPath);
 
-  QString path = info.absolutePath ();
-  QString fileName = info.fileName ();
+  bool info_file_exists = info.exists ();
+  QHash<QString, QString>::iterator it;
+  for (it = _compressors_map.begin (); it != _compressors_map.end (); it++)
+    {
+      if (info_file_exists)
+        break;
+      info_file_exists = QFileInfo (info.absoluteFilePath () + "." + it.key ()).exists ();
+    }
 
-  QDir infoDir (path);
-  QStringList filter;
-  filter.append (fileName + "*");
+  if (info_file_exists)
+    {
+      QString path = info.absolutePath ();
+      QString fileName = info.fileName ();
+
+      QDir infoDir (path);
+      QStringList filter;
+      filter.append (fileName + "*");
 
-  _info_files = infoDir.entryInfoList (filter, QDir::Files);
-  parse_info_map ();
+      _info_files = infoDir.entryInfoList (filter, QDir::Files);
+
+      parse_info_map ();
+
+      return true;
+    }
+  else
+    return false;
 }
 
 QString
@@ -77,7 +94,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 ()));
@@ -115,6 +132,10 @@
 
       return ref.pos-_node_map [ref._node_name].pos;
     }
+  if (_node_map.contains (node))
+    {
+      return 0;  // node: show from the beginning
+    }
   return -1;
 }
 
@@ -277,7 +298,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 +351,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 +457,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 +492,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 +522,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 +560,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 +600,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);
@@ -653,8 +675,25 @@
         {
           // found ref, so return its name
           text = "XREF" + ref_name;
+          break;
         }
     }
+
+  if (text.isEmpty ())  // try the statement-nodes
+    {
+      QHash<QString, node_map_item>::iterator itn;
+      for (itn=_node_map.begin (); itn!=_node_map.end (); ++itn)
+        {
+          QString k = itn.key ();
+          if (k == "The " + ref_name + " Statement")
+            {
+              // found ref, so return its name
+              text = k;
+              break;
+            }
+        }
+    }
+
   return text;
 }
 
--- a/libgui/src/qtinfo/parser.h	Fri Feb 06 08:31:09 2015 -0800
+++ b/libgui/src/qtinfo/parser.h	Fri Feb 06 08:31:49 2015 -0800
@@ -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>
@@ -30,7 +30,7 @@
 #include <QHash>
 
 /**
- * \class parser
+ * @class parser
  * This class gets nodes and searchs inside of 'info files'.
  * <p>Each info file has nodes. Every node has the documentation.
  * Info files contains a map with position of each node.</p>
@@ -53,7 +53,7 @@
 
 public:
   parser (QObject *parent = 0);
-  void set_info_path (const QString& _info_path);
+  bool set_info_path (const QString& _info_path);
   QString get_info_path ();
   QString search_node (const QString& node);
   QString global_search (const QString& text, int maxFounds);
@@ -103,9 +103,9 @@
   QIODevice *open_file(QFileInfo & fileInfo);
 
   /** Calculates real position of nodes.
-    * \param pos position from info file.
-    * \param fileInfo returns file what contains that position.
-    * \param realPos returns real position inside of fileInfo.
+    * @param pos position from info file.
+    * @param fileInfo returns file what contains that position.
+    * @param realPos returns real position inside of fileInfo.
     */
   void real_position (int pos, QFileInfo & file_info, int & real_pos);
 
--- a/libgui/src/qtinfo/webinfo.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/libgui/src/qtinfo/webinfo.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -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>
@@ -57,7 +57,9 @@
   _tab_bar->setSizePolicy (QSizePolicy::Preferred,QSizePolicy::Preferred);
   _tab_bar->setExpanding (false);
   _tab_bar->setTabsClosable (true);
+#ifdef HAVE_QTABWIDGET_SETMOVABLE
   _tab_bar->setMovable (true);
+#endif
   hbox_layout->addWidget (_tab_bar);
 
   _zoom_in_button = new QToolButton (this);
@@ -94,15 +96,30 @@
 
   resize (500, 300);
 
-  set_info_path (QString::fromStdString (Vinfo_file));
+  if (! set_info_path (QString::fromStdString (Vinfo_file)))
+    { // Info file does not exist
+      _search_check_box->setEnabled (false);
+      _search_line_edit->setEnabled (false);
 
+      QTextBrowser *msg = addNewTab (tr ("Error"));
+      QString msg_text = QString (
+          "<html><body><br><br><center><b>%1</b></center></body></html>").
+          arg (tr ("The info file<p>%1<p>or compressed versions do not exist").
+          arg(QString::fromStdString (Vinfo_file)));
+      msg->setHtml (msg_text);
+    }
 }
 
-void
+bool
 webinfo::set_info_path (const QString& info_path)
 {
-  _parser.set_info_path (info_path);
-  load_node ("Top");
+  if (_parser.set_info_path (info_path))
+    {
+      load_node ("Top");
+      return true;
+    }
+  else
+    return false;
 }
 
 void
@@ -165,7 +182,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)));
 
@@ -267,6 +284,20 @@
 }
 
 void
+webinfo::selectAll ()
+{
+  if (_search_line_edit->hasFocus ())
+    {
+      _search_line_edit->selectAll ();
+    }
+  if (_text_browser->hasFocus ())
+    {
+      _text_browser->selectAll ();
+    }
+}
+
+
+void
 webinfo::pasteClipboard ()
 {
   if (_search_line_edit->hasFocus ())
--- a/libgui/src/qtinfo/webinfo.h	Fri Feb 06 08:31:09 2015 -0800
+++ b/libgui/src/qtinfo/webinfo.h	Fri Feb 06 08:31:49 2015 -0800
@@ -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"
@@ -38,7 +38,7 @@
   Q_OBJECT
 public:
   webinfo (QWidget *parent = 0);
-  void set_info_path (const QString& info_path);
+  bool set_info_path (const QString& info_path);
   void load_node (const QString& node_name);
 
   void load_ref (const QString &ref_name);
@@ -53,6 +53,7 @@
 
   void copyClipboard ();
   void pasteClipboard ();
+  void selectAll ();
 
 private:
   QTextBrowser        *_text_browser;
--- a/libgui/src/resource.qrc	Fri Feb 06 08:31:09 2015 -0800
+++ b/libgui/src/resource.qrc	Fri Feb 06 08:31:49 2015 -0800
@@ -63,5 +63,8 @@
         <file>icons/widget-close.png</file>
         <file>icons/widget-dock.png</file>
         <file>icons/widget-undock.png</file>
+        <file>icons/widget-close-light.png</file>
+        <file>icons/widget-dock-light.png</file>
+        <file>icons/widget-undock-light.png</file>
     </qresource>
 </RCC>
--- a/libgui/src/settings-dialog.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/libgui/src/settings-dialog.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -25,15 +25,19 @@
 #endif
 
 #include "resource-manager.h"
+#include "shortcut-manager.h"
 #include "workspace-model.h"
 #include "settings-dialog.h"
 #include "ui-settings-dialog.h"
 #include <QDir>
 #include <QFileInfo>
+#include <QFileDialog>
 #include <QVector>
 #include <QHash>
 
 #ifdef HAVE_QSCINTILLA
+#include "octave-qscintilla.h"
+#include "octave-txt-lexer.h"
 #include <QScrollArea>
 
 #if defined (HAVE_QSCI_QSCILEXEROCTAVE_H)
@@ -57,7 +61,9 @@
   ui->setupUi (this);
 
   QSettings *settings = resource_manager::get_settings ();
-  // FIXME: what should happen if settings is 0?
+
+  // restore last geometry
+  restoreGeometry (settings->value("settings/geometry").toByteArray ());
 
   // look for available language files and the actual settings
   QString qm_dir_name = resource_manager::get_gui_translation_dir ();
@@ -90,14 +96,71 @@
   ui->general_icon_graphic-> setChecked (widget_icon_set == "GRAPHIC");
   ui->general_icon_letter-> setChecked (widget_icon_set == "LETTER");
 
+  // custom title bar of dock widget
+  QVariant default_var = QColor (255,255,255);
+  QColor bg_color = settings->value ("Dockwidgets/title_bg_color",
+                                      default_var).value<QColor> ();
+  _widget_title_bg_color = new color_picker (bg_color);
+  _widget_title_bg_color->setEnabled (false);
+  ui->layout_widget_bgtitle->addWidget (_widget_title_bg_color,0);
+  connect (ui->cb_widget_custom_style, SIGNAL (toggled (bool)),
+           _widget_title_bg_color, SLOT (setEnabled (bool)));
+
+  default_var = QColor (192,192,192);
+  QColor bg_color_active = settings->value ("Dockwidgets/title_bg_color_active",
+                                      default_var).value<QColor> ();
+  _widget_title_bg_color_active = new color_picker (bg_color_active);
+  _widget_title_bg_color_active->setEnabled (false);
+  ui->layout_widget_bgtitle_active->addWidget (_widget_title_bg_color_active,0);
+  connect (ui->cb_widget_custom_style, SIGNAL (toggled (bool)),
+           _widget_title_bg_color_active, SLOT (setEnabled (bool)));
+
+  default_var = QColor (0,0,0);
+  QColor fg_color = settings->value ("Dockwidgets/title_fg_color",
+                                      default_var).value<QColor> ();
+  _widget_title_fg_color = new color_picker (fg_color);
+  _widget_title_fg_color->setEnabled (false);
+  ui->layout_widget_fgtitle->addWidget (_widget_title_fg_color,0);
+  connect (ui->cb_widget_custom_style, SIGNAL (toggled (bool)),
+           _widget_title_fg_color, SLOT (setEnabled (bool)));
+
+  default_var = QColor (0,0,0);
+  QColor fg_color_active = settings->value ("Dockwidgets/title_fg_color_active",
+                                      default_var).value<QColor> ();
+  _widget_title_fg_color_active = new color_picker (fg_color_active);
+  _widget_title_fg_color_active->setEnabled (false);
+  ui->layout_widget_fgtitle_active->addWidget (_widget_title_fg_color_active,0);
+  connect (ui->cb_widget_custom_style, SIGNAL (toggled (bool)),
+           _widget_title_fg_color_active, SLOT (setEnabled (bool)));
+
+  ui->cb_widget_custom_style->setChecked (
+    settings->value ("DockWidgets/widget_title_custom_style",false).toBool ());
+
+  // prompt on exit
+  ui->cb_prompt_to_exit->setChecked (
+    settings->value ("prompt_to_exit",false).toBool ());
+
+  // Main status bar
+  ui->cb_status_bar->setChecked (
+    settings->value ("show_status_bar",true).toBool ());
+
+  // Octave startup
+  ui->cb_restore_octave_dir->setChecked (
+                 settings->value ("restore_octave_dir",false).toBool ());
+  ui->le_octave_dir->setText (
+                 settings->value ("octave_startup_dir").toString ());
+  connect (ui->pb_octave_dir, SIGNAL (pressed ()),
+           this, SLOT (get_octave_dir ()));
+
+  // editor
   ui->useCustomFileEditor->setChecked (settings->value ("useCustomFileEditor",
                                                         false).toBool ());
   ui->customFileEditor->setText (
     settings->value ("customFileEditor").toString ());
   ui->editor_showLineNumbers->setChecked (
-    settings->value ("editor/showLineNumbers",true).toBool () );
+    settings->value ("editor/showLineNumbers",true).toBool ());
 
-  QVariant default_var = QColor (240, 240, 240);
+  default_var = QColor (240, 240, 240);
   QColor setting_color = settings->value ("editor/highlight_current_line_color",
                                           default_var).value<QColor> ();
   _editor_current_line_color = new color_picker (setting_color);
@@ -107,14 +170,30 @@
   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 (
+    settings->value ("editor/long_line_column",80).toInt ());
+  ui->cb_edit_status_bar->setChecked (
+    settings->value ("editor/show_edit_status_bar",true).toBool ());
+  ui->cb_code_folding->setChecked (
+    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 (
     settings->value ("editor/codeCompletion_keywords",true).toBool ());
+  ui->editor_checkbox_ac_builtins->setEnabled (
+    ui->editor_checkbox_ac_keywords->isChecked ());
+  ui->editor_checkbox_ac_functions->setEnabled (
+    ui->editor_checkbox_ac_keywords->isChecked ());
+  ui->editor_checkbox_ac_builtins->setChecked (
+    settings->value ("editor/codeCompletion_octave_builtins",true).toBool ());
+  ui->editor_checkbox_ac_functions->setChecked (
+    settings->value ("editor/codeCompletion_octave_functions",true).toBool ());
   ui->editor_checkbox_ac_document->setChecked (
     settings->value ("editor/codeCompletion_document",false).toBool ());
   ui->editor_checkbox_ac_case->setChecked (
@@ -125,6 +204,24 @@
     settings->value ("editor/show_white_space", false).toBool ());
   ui->editor_ws_indent_checkbox->setChecked (
     settings->value ("editor/show_white_space_indent",false).toBool ());
+  ui->cb_show_eol->setChecked (
+    settings->value ("editor/show_eol_chars",false).toBool () );
+  ui->cb_show_hscrollbar->setChecked (
+    settings->value ("editor/show_hscroll_bar",true).toBool ());
+
+#ifdef HAVE_QSCINTILLA
+#if defined (Q_OS_WIN32)
+  int eol_mode = QsciScintilla::EolWindows;
+#elif defined (Q_OS_MAC)
+  int eol_mode = QsciScintilla::EolMac;
+#else
+  int eol_mode = QsciScintilla::EolUnix;
+#endif
+#else
+  int eol_mode = 2;
+#endif
+  ui->combo_eol_mode->setCurrentIndex (
+    settings->value ("editor/default_eol_mode",eol_mode).toInt () );
   ui->editor_auto_ind_checkbox->setChecked (
     settings->value ("editor/auto_indent", true).toBool ());
   ui->editor_tab_ind_checkbox->setChecked (
@@ -135,39 +232,38 @@
     settings->value ("editor/show_indent_guides",false).toBool ());
   ui->editor_ind_width_spinbox->setValue (
     settings->value ("editor/indent_width", 2).toInt ());
+  ui->editor_ind_uses_tabs_checkbox->setChecked (
+    settings->value ("editor/indent_uses_tabs", false).toBool ());
   ui->editor_tab_width_spinbox->setValue (
     settings->value ("editor/tab_width", 2).toInt ());
   ui->editor_longWindowTitle->setChecked (
     settings->value ("editor/longWindowTitle",false).toBool ());
+  ui->editor_notebook_tab_width_min->setValue (
+    settings->value ("editor/notebook_tab_width_min", 160).toInt ());
+  ui->editor_notebook_tab_width_max->setValue (
+    settings->value ("editor/notebook_tab_width_max", 300).toInt ());
   ui->editor_restoreSession->setChecked (
     settings->value ("editor/restoreSession", true).toBool ());
   ui->editor_create_new_file->setChecked (
     settings->value ("editor/create_new_file",false).toBool ());
+  ui->editor_reload_changed_files->setChecked (
+    settings->value ("editor/always_reload_changed_files",false).toBool ());
+
+  // 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->showFileSize->setChecked (
-    settings->value ("filesdockwidget/showFileSize", false).toBool ());
-  ui->showFileType->setChecked (
-    settings->value ("filesdockwidget/showFileType", false).toBool ());
-  ui->showLastModified->setChecked (
-    settings->value ("filesdockwidget/showLastModified",false).toBool ());
-  ui->showHiddenFiles->setChecked (
-    settings->value ("filesdockwidget/showHiddenFiles",false).toBool ());
-  ui->useAlternatingRowColors->setChecked (
-    settings->value ("filesdockwidget/useAlternatingRowColors",true).toBool ());
-  ui->sync_octave_directory->setChecked (
-    settings->value ("filesdockwidget/sync_octave_directory",true).toBool ());
-  ui->checkbox_allow_web_connect->setChecked (
-    settings->value ("news/allow_web_connection",false).toBool ());
-  ui->useProxyServer->setChecked (
-    settings->value ("useProxyServer", false).toBool ());
-  ui->proxyHostName->setText (settings->value ("proxyHostName").toString ());
+  ui->terminal_history_buffer->setValue (
+     settings->value ("terminal/history_buffer",1000).toInt ());
   ui->terminal_cursorBlinking->setChecked (
     settings->value ("terminal/cursorBlinking",true).toBool ());
   ui->terminal_cursorUseForegroundColor->setChecked (
     settings->value ("terminal/cursorUseForegroundColor",true).toBool ());
+  ui->terminal_focus_command->setChecked (
+    settings->value ("terminal/focus_after_command",false).toBool ());
+  ui->terminal_print_dbg_location->setChecked (
+    settings->value ("terminal/print_debug_location",false).toBool ());
 
   QString cursorType
     = settings->value ("terminal/cursorType", "ibeam").toString ();
@@ -186,9 +282,37 @@
   else if (cursorType == "underline")
     ui->terminal_cursorType->setCurrentIndex (2);
 
+  // file browser
+  ui->showFileSize->setChecked (
+    settings->value ("filesdockwidget/showFileSize", false).toBool ());
+  ui->showFileType->setChecked (
+    settings->value ("filesdockwidget/showFileType", false).toBool ());
+  ui->showLastModified->setChecked (
+    settings->value ("filesdockwidget/showLastModified",false).toBool ());
+  ui->showHiddenFiles->setChecked (
+    settings->value ("filesdockwidget/showHiddenFiles",false).toBool ());
+  ui->useAlternatingRowColors->setChecked (
+    settings->value ("filesdockwidget/useAlternatingRowColors",true).toBool ());
+  connect (ui->sync_octave_directory, SIGNAL (toggled (bool)),
+           this, SLOT (set_disabled_pref_file_browser_dir (bool)));
+  ui->sync_octave_directory->setChecked (
+    settings->value ("filesdockwidget/sync_octave_directory",true).toBool ());
+  ui->cb_restore_file_browser_dir->setChecked (
+                 settings->value ("filesdockwidget/restore_last_dir",false).toBool ());
+  ui->le_file_browser_dir->setText (
+                 settings->value ("filesdockwidget/startup_dir").toString ());
+  connect (ui->pb_file_browser_dir, SIGNAL (pressed ()),
+           this, SLOT (get_file_browser_dir ()));
+
+  ui->checkbox_allow_web_connect->setChecked (
+    settings->value ("news/allow_web_connection",false).toBool ());
+  ui->useProxyServer->setChecked (
+    settings->value ("useProxyServer", false).toBool ());
+  ui->proxyHostName->setText (settings->value ("proxyHostName").toString ());
+
   int currentIndex = 0;
   QString proxyTypeString = settings->value ("proxyType").toString ();
-  while ( (currentIndex < ui->proxyType->count ())
+  while ((currentIndex < ui->proxyType->count ())
           && (ui->proxyType->currentText () != proxyTypeString))
     {
       currentIndex++;
@@ -199,12 +323,38 @@
   ui->proxyUserName->setText (settings->value ("proxyUserName").toString ());
   ui->proxyPassword->setText (settings->value ("proxyPassword").toString ());
 
-  // qorkspace colors
+  // Workspace
+  // colors
   read_workspace_colors (settings);
+  // hide tool tips
+  ui->cb_hide_tool_tips->setChecked (
+    settings->value ("workspaceview/hide_tool_tips",false).toBool ());
 
   // terminal colors
   read_terminal_colors (settings);
 
+  // shortcuts
+
+  ui->cb_prevent_readline_conflicts->setChecked (
+    settings->value ("shortcuts/prevent_readline_conflicts", true).toBool ());
+  int set = settings->value ("shortcuts/set",0).toInt ();
+  ui->rb_sc_set1->setChecked (set == 0);
+  ui->rb_sc_set2->setChecked (set == 1);
+
+  // initialize the tree view with all shortcut data
+  shortcut_manager::fill_treewidget (ui->shortcuts_treewidget);
+
+  // connect the buttons for import/export of the shortcut sets
+  connect (ui->btn_import_shortcut_set1, SIGNAL (clicked ()),
+           this, SLOT (import_shortcut_set1 ()));
+  connect (ui->btn_export_shortcut_set1, SIGNAL (clicked ()),
+           this, SLOT (export_shortcut_set1 ()));
+  connect (ui->btn_import_shortcut_set2, SIGNAL (clicked ()),
+           this, SLOT (import_shortcut_set2 ()));
+  connect (ui->btn_export_shortcut_set2, SIGNAL (clicked ()),
+           this, SLOT (export_shortcut_set2 ()));
+
+
 #ifdef HAVE_QSCINTILLA
   // editor styles: create lexer, read settings, and create dialog elements
   QsciLexer *lexer;
@@ -232,22 +382,17 @@
   lexer = new QsciLexerBash ();
   read_lexer_settings (lexer,settings);
   delete lexer;
+  lexer = new octave_txt_lexer ();
+  read_lexer_settings (lexer,settings);
+  delete lexer;
 #endif
 
   // which tab is the desired one?
-  if (desired_tab.isEmpty ())
-    ui->tabWidget->setCurrentIndex (settings->value ("settings/last_tab",
-                                    0).toInt ());
-  else
-    {
-      QHash <QString, QWidget*> tab_hash;
-      tab_hash["editor"] = ui->tab_editor;
-      tab_hash["editor_styles"] = ui->tab_editor_styles;
-      ui->tabWidget->setCurrentIndex (
-        ui->tabWidget->indexOf (tab_hash.value (desired_tab)));
-    }
+  show_tab (desired_tab);
 
-
+  // connect button box signal
+  connect (ui->button_box, SIGNAL (clicked (QAbstractButton *)),
+           this,           SLOT (button_clicked (QAbstractButton *)));
 }
 
 settings_dialog::~settings_dialog ()
@@ -255,6 +400,24 @@
   delete ui;
 }
 
+void
+settings_dialog::show_tab (const QString& tab)
+{
+  if (tab.isEmpty ())
+    {
+      QSettings *settings = resource_manager::get_settings ();
+      ui->tabWidget->setCurrentIndex (settings->value ("settings/last_tab",
+                                      0).toInt ());
+    }
+  else
+    {
+      QHash <QString, QWidget*> tab_hash;
+      tab_hash["editor"] = ui->tab_editor;
+      tab_hash["editor_styles"] = ui->tab_editor_styles;
+      ui->tabWidget->setCurrentIndex (
+        ui->tabWidget->indexOf (tab_hash.value (tab)));
+    }
+}
 
 #ifdef HAVE_QSCINTILLA
 int
@@ -465,8 +628,33 @@
     language = "SYSTEM";
   settings->setValue ("language", language);
 
-  // other settings
+  // dock widget title bar
+  settings->setValue ("DockWidgets/widget_title_custom_style",
+                      ui->cb_widget_custom_style->isChecked ());
+  settings->setValue ("Dockwidgets/title_bg_color",
+                      _widget_title_bg_color->color ());
+  settings->setValue ("Dockwidgets/title_bg_color_active",
+                      _widget_title_bg_color_active->color ());
+  settings->setValue ("Dockwidgets/title_fg_color",
+                      _widget_title_fg_color->color ());
+  settings->setValue ("Dockwidgets/title_fg_color_active",
+                      _widget_title_fg_color_active->color ());
+
+  // icon size
   settings->setValue ("toolbar_icon_size", ui->toolbar_icon_size->value ());
+
+  // promp to exit
+  settings->setValue ("prompt_to_exit", ui->cb_prompt_to_exit->isChecked ());
+
+  // status bar
+  settings->setValue ( "show_status_bar", ui->cb_status_bar->isChecked ());
+
+  // Octave startup
+  settings->setValue ("restore_octave_dir",
+                      ui->cb_restore_octave_dir->isChecked ());
+  settings->setValue ("octave_startup_dir", ui->le_octave_dir->text ());
+
+  //editor
   settings->setValue ("useCustomFileEditor",
                       ui->useCustomFileEditor->isChecked ());
   settings->setValue ("customFileEditor", ui->customFileEditor->text ());
@@ -476,12 +664,24 @@
                       ui->editor_highlightCurrentLine->isChecked ());
   settings->setValue ("editor/highlight_current_line_color",
                       _editor_current_line_color->color ());
+  settings->setValue ("editor/long_line_marker",
+                      ui->editor_long_line_marker->isChecked ());
+  settings->setValue ("editor/long_line_column",
+                      ui->editor_long_line_column->value ());
+  settings->setValue ("editor/code_folding",
+                      ui->cb_code_folding->isChecked ());
+  settings->setValue ("editor/show_edit_status_bar",
+                      ui->cb_edit_status_bar->isChecked ());
   settings->setValue ("editor/codeCompletion",
                       ui->editor_codeCompletion->isChecked ());
   settings->setValue ("editor/codeCompletion_threshold",
                       ui->editor_spinbox_ac_threshold->value ());
   settings->setValue ("editor/codeCompletion_keywords",
                       ui->editor_checkbox_ac_keywords->isChecked ());
+  settings->setValue ("editor/codeCompletion_octave_builtins",
+                      ui->editor_checkbox_ac_builtins->isChecked ());
+  settings->setValue ("editor/codeCompletion_octave_functions",
+                      ui->editor_checkbox_ac_functions->isChecked ());
   settings->setValue ("editor/codeCompletion_document",
                       ui->editor_checkbox_ac_document->isChecked ());
   settings->setValue ("editor/codeCompletion_case",
@@ -492,6 +692,12 @@
                       ui->editor_ws_checkbox->isChecked ());
   settings->setValue ("editor/show_white_space_indent",
                       ui->editor_ws_indent_checkbox->isChecked ());
+  settings->setValue ("editor/show_eol_chars",
+                      ui->cb_show_eol->isChecked ());
+  settings->setValue ("editor/show_hscroll_bar",
+                      ui->cb_show_hscrollbar->isChecked ());
+  settings->setValue ("editor/default_eol_mode",
+                      ui->combo_eol_mode->currentIndex ());
   settings->setValue ("editor/auto_indent",
                       ui->editor_auto_ind_checkbox->isChecked ());
   settings->setValue ("editor/tab_indents_line",
@@ -502,17 +708,26 @@
                       ui->editor_ind_guides_checkbox->isChecked ());
   settings->setValue ("editor/indent_width",
                       ui->editor_ind_width_spinbox->value ());
+  settings->setValue ("editor/indent_uses_tabs",
+                      ui->editor_ind_uses_tabs_checkbox->isChecked ());
   settings->setValue ("editor/tab_width",
                       ui->editor_tab_width_spinbox->value ());
   settings->setValue ("editor/longWindowTitle",
                       ui->editor_longWindowTitle->isChecked ());
+  settings->setValue ("editor/notebook_tab_width_min",
+                      ui->editor_notebook_tab_width_min->value ());
+  settings->setValue ("editor/notebook_tab_width_max",
+                      ui->editor_notebook_tab_width_max->value ());
   settings->setValue ("editor/restoreSession",
                       ui->editor_restoreSession->isChecked ());
   settings->setValue ("editor/create_new_file",
                       ui->editor_create_new_file->isChecked ());
+  settings->setValue ("editor/always_reload_changed_files",
+                      ui->editor_reload_changed_files->isChecked ());
   settings->setValue ("terminal/fontSize", ui->terminal_fontSize->value ());
   settings->setValue ("terminal/fontName",
                       ui->terminal_fontName->currentFont ().family ());
+
   settings->setValue ("filesdockwidget/showFileSize",
                       ui->showFileSize->isChecked ());
   settings->setValue ("filesdockwidget/showFileType",
@@ -525,6 +740,12 @@
                       ui->useAlternatingRowColors->isChecked ());
   settings->setValue ("filesdockwidget/sync_octave_directory",
                       ui->sync_octave_directory->isChecked ());
+  settings->setValue ("filesdockwidget/restore_last_dir",
+                      ui->cb_restore_file_browser_dir->isChecked ());
+  settings->setValue ("filesdockwidget/startup_dir",
+                      ui->le_file_browser_dir->text ());
+
+
   settings->setValue ("news/allow_web_connection",
                       ui->checkbox_allow_web_connect->isChecked ());
   settings->setValue ("useProxyServer", ui->useProxyServer->isChecked ());
@@ -537,6 +758,12 @@
                       ui->terminal_cursorBlinking->isChecked ());
   settings->setValue ("terminal/cursorUseForegroundColor",
                       ui->terminal_cursorUseForegroundColor->isChecked ());
+  settings->setValue ("terminal/focus_after_command",
+                      ui->terminal_focus_command->isChecked ());
+  settings->setValue ("terminal/print_debug_location",
+                      ui->terminal_print_dbg_location->isChecked ());
+  settings->setValue ("terminal/history_buffer",
+                      ui->terminal_history_buffer->value ());
 
   // the cursor
   QString cursorType;
@@ -547,7 +774,6 @@
     case 2: cursorType = "underline";  break;
     }
   settings->setValue ("terminal/cursorType", cursorType);
-  settings->sync ();
 
 #ifdef HAVE_QSCINTILLA
   // editor styles: create lexer, get dialog contents, and write settings
@@ -576,13 +802,34 @@
   lexer = new QsciLexerBash ();
   write_lexer_settings (lexer,settings);
   delete lexer;
+  lexer = new octave_txt_lexer ();
+  write_lexer_settings (lexer,settings);
+  delete lexer;
 #endif
 
+  // Workspace
   write_workspace_colors (settings);
+  // hide tool tips
+  settings->setValue ("workspaceview/hide_tool_tips",
+                      ui->cb_hide_tool_tips->isChecked ());
 
+  // Terminal
   write_terminal_colors (settings);
 
+  // shortcuts
+  settings->setValue ("shortcuts/prevent_readline_conflicts",
+                      ui->cb_prevent_readline_conflicts->isChecked ());
+  int set = 0;
+  if (ui->rb_sc_set2->isChecked ())
+    set = 1;
+  settings->setValue ("shortcuts/set",set);
+  shortcut_manager::write_shortcuts (0, settings);  // 0: write both sets
+
+  // settings dialog's geometry
   settings->setValue ("settings/last_tab",ui->tabWidget->currentIndex ());
+  settings->setValue ("settings/geometry",saveGeometry ());
+
+  settings->sync ();
 }
 
 #ifdef HAVE_QSCINTILLA
@@ -666,6 +913,7 @@
 
   settings->setValue (
     "settings/last_editor_styles_tab",ui->tabs_editor_lexers->currentIndex ());
+  settings->sync ();
 }
 #endif
 
@@ -703,3 +951,86 @@
     }
   settings->sync ();
 }
+
+
+// internal slots
+
+void
+settings_dialog::button_clicked (QAbstractButton *button)
+{
+  QDialogButtonBox::ButtonRole button_role = ui->button_box->buttonRole (button);
+
+  if (button_role == QDialogButtonBox::ApplyRole ||
+      button_role == QDialogButtonBox::AcceptRole)
+    {
+      write_changed_settings ();
+      emit apply_new_settings ();
+    }
+
+  if (button_role == QDialogButtonBox::RejectRole ||
+      button_role == QDialogButtonBox::AcceptRole)
+    close ();
+}
+
+void
+settings_dialog::get_dir (QLineEdit *line_edit, const QString& title)
+{
+  QString dir = QFileDialog::getExistingDirectory(this,
+                title, line_edit->text (),
+                QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks);
+  line_edit->setText (dir);
+}
+
+void
+settings_dialog::get_octave_dir ()
+{
+  get_dir (ui->le_octave_dir, tr ("Set Octave Startup Directory"));
+}
+
+void
+settings_dialog::get_file_browser_dir ()
+{
+  get_dir (ui->le_file_browser_dir, tr ("Set File Browser Startup Directory"));
+}
+
+void
+settings_dialog::set_disabled_pref_file_browser_dir (bool disable)
+{
+  ui->cb_restore_file_browser_dir->setDisabled (disable);
+
+  if (! disable)
+    {
+      ui->le_file_browser_dir->setDisabled (ui->cb_restore_file_browser_dir->isChecked ());
+      ui->pb_file_browser_dir->setDisabled (ui->cb_restore_file_browser_dir->isChecked ());
+    }
+  else
+    {
+      ui->le_file_browser_dir->setDisabled (disable);
+      ui->pb_file_browser_dir->setDisabled (disable);
+    }
+}
+
+// slots for import/export of shortcut sets
+void
+settings_dialog::import_shortcut_set1 ()
+{
+  shortcut_manager::import_export (true,1);
+}
+
+void
+settings_dialog::export_shortcut_set1 ()
+{
+  shortcut_manager::import_export (false,1);
+}
+
+void
+settings_dialog::import_shortcut_set2 ()
+{
+  shortcut_manager::import_export (true,2);
+}
+
+void
+settings_dialog::export_shortcut_set2 ()
+{
+  shortcut_manager::import_export (false,2);
+}
--- a/libgui/src/settings-dialog.h	Fri Feb 06 08:31:09 2015 -0800
+++ b/libgui/src/settings-dialog.h	Fri Feb 06 08:31:49 2015 -0800
@@ -25,6 +25,7 @@
 
 #include <QDialog>
 #include <QSettings>
+#include <QLineEdit>
 
 #include "color-picker.h"
 
@@ -43,7 +44,25 @@
   explicit settings_dialog (QWidget * parent,
                             const QString& desired_tab = QString ());
   ~settings_dialog ();
-  void write_changed_settings ();
+  void show_tab (const QString&);
+
+signals:
+  void apply_new_settings ();
+
+private slots:
+  void get_octave_dir ();
+  void get_file_browser_dir ();
+  void get_dir (QLineEdit*, const QString&);
+  void set_disabled_pref_file_browser_dir (bool disable);
+
+  // slots for dialog's buttons
+  void button_clicked (QAbstractButton *button);
+
+  // slots for import/export-buttons of shortcut sets
+  void import_shortcut_set1 ();
+  void export_shortcut_set1 ();
+  void import_shortcut_set2 ();
+  void export_shortcut_set2 ();
 
 private:
   Ui::settings_dialog * ui;
@@ -55,12 +74,18 @@
          MaxStyleNumber = 128 };
 #endif
 
+  void write_changed_settings ();
+
   void read_workspace_colors (QSettings *settings);
   void write_workspace_colors (QSettings *settings);
 
   void read_terminal_colors (QSettings *settings);
   void write_terminal_colors (QSettings *settings);
 
+  color_picker *_widget_title_bg_color;
+  color_picker *_widget_title_bg_color_active;
+  color_picker *_widget_title_fg_color;
+  color_picker *_widget_title_fg_color_active;
   color_picker *_editor_current_line_color;
 };
 
--- a/libgui/src/settings-dialog.ui	Fri Feb 06 08:31:09 2015 -0800
+++ b/libgui/src/settings-dialog.ui	Fri Feb 06 08:31:49 2015 -0800
@@ -9,20 +9,14 @@
    <rect>
     <x>0</x>
     <y>0</y>
-    <width>700</width>
+    <width>720</width>
     <height>480</height>
    </rect>
   </property>
   <property name="minimumSize">
    <size>
-    <width>700</width>
-    <height>480</height>
-   </size>
-  </property>
-  <property name="maximumSize">
-   <size>
-    <width>700</width>
-    <height>480</height>
+    <width>400</width>
+    <height>400</height>
    </size>
   </property>
   <property name="windowTitle">
@@ -31,8 +25,14 @@
   <layout class="QVBoxLayout" name="verticalLayout_2">
    <item>
     <widget class="QTabWidget" name="tabWidget">
+     <property name="minimumSize">
+      <size>
+       <width>0</width>
+       <height>0</height>
+      </size>
+     </property>
      <property name="currentIndex">
-      <number>6</number>
+      <number>3</number>
      </property>
      <widget class="QWidget" name="tab_general">
       <property name="enabled">
@@ -41,154 +41,402 @@
       <attribute name="title">
        <string>General</string>
       </attribute>
-      <widget class="QWidget" name="verticalLayoutWidget">
-       <property name="geometry">
-        <rect>
-         <x>9</x>
-         <y>10</y>
-         <width>651</width>
-         <height>371</height>
-        </rect>
-       </property>
-       <layout class="QVBoxLayout" name="verticalLayout_7">
-        <item>
-         <layout class="QGridLayout" name="gridLayout">
-          <item row="3" column="0">
-           <widget class="QLabel" name="label_9">
-            <property name="text">
-             <string>Icon set for dock widgets</string>
-            </property>
-           </widget>
-          </item>
-          <item row="1" column="0">
-           <widget class="QLabel" name="label_2">
-            <property name="text">
-             <string>Language (requires restart)</string>
-            </property>
-           </widget>
-          </item>
-          <item row="2" column="0">
-           <widget class="QLabel" name="label_8">
-            <property name="text">
-             <string>Icon size</string>
-            </property>
-           </widget>
-          </item>
-          <item row="2" column="2">
-           <layout class="QHBoxLayout" name="horizontalLayout_6">
-            <item>
-             <widget class="QSpinBox" name="toolbar_icon_size">
-              <property name="minimum">
-               <number>16</number>
-              </property>
-              <property name="maximum">
-               <number>32</number>
-              </property>
-              <property name="singleStep">
-               <number>4</number>
-              </property>
-              <property name="value">
-               <number>24</number>
-              </property>
-             </widget>
-            </item>
-            <item>
-             <spacer name="horizontalSpacer_4">
-              <property name="orientation">
-               <enum>Qt::Horizontal</enum>
-              </property>
-              <property name="sizeHint" stdset="0">
-               <size>
-                <width>40</width>
-                <height>20</height>
-               </size>
-              </property>
-             </spacer>
-            </item>
-           </layout>
-          </item>
-          <item row="1" column="2">
-           <layout class="QHBoxLayout" name="horizontalLayout_8">
-            <item>
-             <widget class="QComboBox" name="comboBox_language">
-              <property name="insertPolicy">
-               <enum>QComboBox::InsertAtBottom</enum>
-              </property>
-             </widget>
-            </item>
-            <item>
-             <spacer name="horizontalSpacer_3">
-              <property name="orientation">
-               <enum>Qt::Horizontal</enum>
-              </property>
-              <property name="sizeHint" stdset="0">
-               <size>
-                <width>40</width>
-                <height>20</height>
-               </size>
-              </property>
-             </spacer>
-            </item>
-           </layout>
-          </item>
-          <item row="3" column="2">
-           <layout class="QHBoxLayout" name="horizontalLayout_9">
-            <item>
-             <widget class="QRadioButton" name="general_icon_octave">
-              <property name="text">
-               <string>Octave logo only</string>
-              </property>
-              <property name="checked">
-               <bool>true</bool>
-              </property>
-             </widget>
-            </item>
-            <item>
-             <widget class="QRadioButton" name="general_icon_letter">
-              <property name="text">
-               <string>Letter icons</string>
-              </property>
-             </widget>
-            </item>
-            <item>
-             <widget class="QRadioButton" name="general_icon_graphic">
-              <property name="text">
-               <string>Graphic icons</string>
-              </property>
-             </widget>
-            </item>
-            <item>
-             <spacer name="horizontalSpacer_6">
-              <property name="orientation">
-               <enum>Qt::Horizontal</enum>
-              </property>
-              <property name="sizeHint" stdset="0">
-               <size>
-                <width>40</width>
-                <height>20</height>
-               </size>
-              </property>
-             </spacer>
-            </item>
-           </layout>
-          </item>
-         </layout>
-        </item>
-        <item>
-         <spacer name="verticalSpacer_4">
-          <property name="orientation">
-           <enum>Qt::Vertical</enum>
+      <layout class="QVBoxLayout" name="verticalLayout_10">
+       <item>
+        <widget class="QScrollArea" name="scrollArea_2">
+         <property name="widgetResizable">
+          <bool>true</bool>
+         </property>
+         <widget class="QWidget" name="scrollAreaWidgetContents_2">
+          <property name="geometry">
+           <rect>
+            <x>0</x>
+            <y>0</y>
+            <width>678</width>
+            <height>378</height>
+           </rect>
           </property>
-          <property name="sizeHint" stdset="0">
-           <size>
-            <width>20</width>
-            <height>40</height>
-           </size>
-          </property>
-         </spacer>
-        </item>
-       </layout>
-      </widget>
+          <layout class="QVBoxLayout" name="verticalLayout_17">
+           <item>
+            <widget class="QGroupBox" name="groupBox">
+             <property name="title">
+              <string>Interface</string>
+             </property>
+             <layout class="QVBoxLayout" name="verticalLayout_21">
+              <item>
+               <layout class="QGridLayout" name="gridLayout">
+                <item row="4" column="0">
+                 <widget class="QLabel" name="label_15">
+                  <property name="text">
+                   <string>Dock widget title bar</string>
+                  </property>
+                  <property name="alignment">
+                   <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
+                  </property>
+                 </widget>
+                </item>
+                <item row="1" column="1">
+                 <layout class="QHBoxLayout" name="horizontalLayout_8">
+                  <item>
+                   <widget class="QComboBox" name="comboBox_language">
+                    <property name="insertPolicy">
+                     <enum>QComboBox::InsertAtBottom</enum>
+                    </property>
+                   </widget>
+                  </item>
+                  <item>
+                   <spacer name="horizontalSpacer_3">
+                    <property name="orientation">
+                     <enum>Qt::Horizontal</enum>
+                    </property>
+                    <property name="sizeHint" stdset="0">
+                     <size>
+                      <width>40</width>
+                      <height>20</height>
+                     </size>
+                    </property>
+                   </spacer>
+                  </item>
+                 </layout>
+                </item>
+                <item row="2" column="0">
+                 <widget class="QLabel" name="label_8">
+                  <property name="text">
+                   <string>Icon size</string>
+                  </property>
+                  <property name="alignment">
+                   <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
+                  </property>
+                 </widget>
+                </item>
+                <item row="6" column="0">
+                 <widget class="QCheckBox" name="cb_prompt_to_exit">
+                  <property name="text">
+                   <string>Confirm before exiting</string>
+                  </property>
+                 </widget>
+                </item>
+                <item row="2" column="1">
+                 <layout class="QHBoxLayout" name="horizontalLayout_6">
+                  <item>
+                   <widget class="QSpinBox" name="toolbar_icon_size">
+                    <property name="minimum">
+                     <number>16</number>
+                    </property>
+                    <property name="maximum">
+                     <number>32</number>
+                    </property>
+                    <property name="singleStep">
+                     <number>4</number>
+                    </property>
+                    <property name="value">
+                     <number>24</number>
+                    </property>
+                   </widget>
+                  </item>
+                  <item>
+                   <spacer name="horizontalSpacer_4">
+                    <property name="orientation">
+                     <enum>Qt::Horizontal</enum>
+                    </property>
+                    <property name="sizeHint" stdset="0">
+                     <size>
+                      <width>40</width>
+                      <height>20</height>
+                     </size>
+                    </property>
+                   </spacer>
+                  </item>
+                 </layout>
+                </item>
+                <item row="1" column="0">
+                 <widget class="QLabel" name="label_2">
+                  <property name="text">
+                   <string>Language (requires restart)</string>
+                  </property>
+                 </widget>
+                </item>
+                <item row="3" column="1">
+                 <layout class="QHBoxLayout" name="horizontalLayout_9">
+                  <item>
+                   <widget class="QRadioButton" name="general_icon_octave">
+                    <property name="text">
+                     <string>Octave logo only</string>
+                    </property>
+                    <property name="checked">
+                     <bool>true</bool>
+                    </property>
+                   </widget>
+                  </item>
+                  <item>
+                   <widget class="QRadioButton" name="general_icon_letter">
+                    <property name="text">
+                     <string>Letter icons</string>
+                    </property>
+                   </widget>
+                  </item>
+                  <item>
+                   <widget class="QRadioButton" name="general_icon_graphic">
+                    <property name="text">
+                     <string>Graphic icons</string>
+                    </property>
+                   </widget>
+                  </item>
+                  <item>
+                   <spacer name="horizontalSpacer_6">
+                    <property name="orientation">
+                     <enum>Qt::Horizontal</enum>
+                    </property>
+                    <property name="sizeHint" stdset="0">
+                     <size>
+                      <width>40</width>
+                      <height>20</height>
+                     </size>
+                    </property>
+                   </spacer>
+                  </item>
+                 </layout>
+                </item>
+                <item row="3" column="0">
+                 <widget class="QLabel" name="label_9">
+                  <property name="text">
+                   <string>Icon set for dock widgets</string>
+                  </property>
+                 </widget>
+                </item>
+                <item row="5" column="0">
+                 <widget class="QCheckBox" name="cb_status_bar">
+                  <property name="text">
+                   <string>Show status bar</string>
+                  </property>
+                  <property name="checked">
+                   <bool>true</bool>
+                  </property>
+                 </widget>
+                </item>
+                <item row="4" column="1">
+                 <layout class="QHBoxLayout" name="horizontalLayout_4">
+                  <item>
+                   <layout class="QGridLayout" name="gridLayout_13">
+                    <item row="1" column="2">
+                     <widget class="QLabel" name="label_fgtitle">
+                      <property name="enabled">
+                       <bool>false</bool>
+                      </property>
+                      <property name="text">
+                       <string>Text inactive</string>
+                      </property>
+                      <property name="alignment">
+                       <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+                      </property>
+                     </widget>
+                    </item>
+                    <item row="1" column="9">
+                     <widget class="QLabel" name="label_fgtitle_active">
+                      <property name="enabled">
+                       <bool>false</bool>
+                      </property>
+                      <property name="text">
+                       <string>Active</string>
+                      </property>
+                      <property name="alignment">
+                       <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+                      </property>
+                     </widget>
+                    </item>
+                    <item row="0" column="0">
+                     <widget class="QCheckBox" name="cb_widget_custom_style">
+                      <property name="text">
+                       <string>Custom style</string>
+                      </property>
+                     </widget>
+                    </item>
+                    <item row="0" column="7">
+                     <spacer name="horizontalSpacer_23">
+                      <property name="orientation">
+                       <enum>Qt::Horizontal</enum>
+                      </property>
+                      <property name="sizeType">
+                       <enum>QSizePolicy::Fixed</enum>
+                      </property>
+                      <property name="sizeHint" stdset="0">
+                       <size>
+                        <width>12</width>
+                        <height>20</height>
+                       </size>
+                      </property>
+                     </spacer>
+                    </item>
+                    <item row="0" column="1">
+                     <spacer name="horizontalSpacer_22">
+                      <property name="orientation">
+                       <enum>Qt::Horizontal</enum>
+                      </property>
+                      <property name="sizeType">
+                       <enum>QSizePolicy::Fixed</enum>
+                      </property>
+                      <property name="sizeHint" stdset="0">
+                       <size>
+                        <width>40</width>
+                        <height>20</height>
+                       </size>
+                      </property>
+                     </spacer>
+                    </item>
+                    <item row="0" column="9">
+                     <widget class="QLabel" name="label_bgtitle_active">
+                      <property name="enabled">
+                       <bool>false</bool>
+                      </property>
+                      <property name="text">
+                       <string>Active</string>
+                      </property>
+                      <property name="alignment">
+                       <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+                      </property>
+                     </widget>
+                    </item>
+                    <item row="1" column="4">
+                     <layout class="QHBoxLayout" name="layout_widget_fgtitle"/>
+                    </item>
+                    <item row="0" column="4">
+                     <layout class="QHBoxLayout" name="layout_widget_bgtitle"/>
+                    </item>
+                    <item row="0" column="2">
+                     <widget class="QLabel" name="label_bgtitle">
+                      <property name="enabled">
+                       <bool>false</bool>
+                      </property>
+                      <property name="text">
+                       <string>Background inactive</string>
+                      </property>
+                      <property name="alignment">
+                       <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+                      </property>
+                     </widget>
+                    </item>
+                    <item row="0" column="10">
+                     <layout class="QHBoxLayout" name="layout_widget_bgtitle_active"/>
+                    </item>
+                    <item row="1" column="10">
+                     <layout class="QHBoxLayout" name="layout_widget_fgtitle_active"/>
+                    </item>
+                   </layout>
+                  </item>
+                  <item>
+                   <spacer name="horizontalSpacer_21">
+                    <property name="orientation">
+                     <enum>Qt::Horizontal</enum>
+                    </property>
+                    <property name="sizeHint" stdset="0">
+                     <size>
+                      <width>40</width>
+                      <height>20</height>
+                     </size>
+                    </property>
+                   </spacer>
+                  </item>
+                 </layout>
+                </item>
+               </layout>
+              </item>
+             </layout>
+            </widget>
+           </item>
+           <item>
+            <widget class="QGroupBox" name="groupBox_2">
+             <property name="title">
+              <string>Octave Startup</string>
+             </property>
+             <layout class="QVBoxLayout" name="verticalLayout_22">
+              <item>
+               <widget class="QLabel" name="label_18">
+                <property name="text">
+                 <string>These preferences are applied after the startup files like .octaverc.</string>
+                </property>
+               </widget>
+              </item>
+              <item>
+               <layout class="QGridLayout" name="gridLayout_9">
+                <item row="0" column="5">
+                 <spacer name="horizontalSpacer">
+                  <property name="orientation">
+                   <enum>Qt::Horizontal</enum>
+                  </property>
+                  <property name="sizeHint" stdset="0">
+                   <size>
+                    <width>40</width>
+                    <height>20</height>
+                   </size>
+                  </property>
+                 </spacer>
+                </item>
+                <item row="1" column="5">
+                 <spacer name="horizontalSpacer_5">
+                  <property name="orientation">
+                   <enum>Qt::Horizontal</enum>
+                  </property>
+                  <property name="sizeHint" stdset="0">
+                   <size>
+                    <width>40</width>
+                    <height>20</height>
+                   </size>
+                  </property>
+                 </spacer>
+                </item>
+                <item row="0" column="0">
+                 <widget class="QLabel" name="label_17">
+                  <property name="text">
+                   <string>Startup path</string>
+                  </property>
+                 </widget>
+                </item>
+                <item row="1" column="3">
+                 <widget class="QPushButton" name="pb_octave_dir">
+                  <property name="sizePolicy">
+                   <sizepolicy hsizetype="Minimum" vsizetype="Minimum">
+                    <horstretch>0</horstretch>
+                    <verstretch>0</verstretch>
+                   </sizepolicy>
+                  </property>
+                  <property name="text">
+                   <string>Browse</string>
+                  </property>
+                 </widget>
+                </item>
+                <item row="0" column="1">
+                 <widget class="QCheckBox" name="cb_restore_octave_dir">
+                  <property name="text">
+                   <string>Restore last Octave directory of previous session</string>
+                  </property>
+                 </widget>
+                </item>
+                <item row="1" column="1">
+                 <widget class="QLineEdit" name="le_octave_dir"/>
+                </item>
+               </layout>
+              </item>
+             </layout>
+            </widget>
+           </item>
+           <item>
+            <spacer name="verticalSpacer">
+             <property name="orientation">
+              <enum>Qt::Vertical</enum>
+             </property>
+             <property name="sizeHint" stdset="0">
+              <size>
+               <width>20</width>
+               <height>40</height>
+              </size>
+             </property>
+            </spacer>
+           </item>
+          </layout>
+         </widget>
+        </widget>
+       </item>
+      </layout>
      </widget>
      <widget class="QWidget" name="tab_editor">
       <attribute name="title">
@@ -196,961 +444,1672 @@
       </attribute>
       <layout class="QVBoxLayout" name="verticalLayout_6">
        <item>
-        <layout class="QVBoxLayout" name="verticalLayout_9">
-         <property name="spacing">
-          <number>4</number>
+        <widget class="QScrollArea" name="scrollArea">
+         <property name="widgetResizable">
+          <bool>true</bool>
          </property>
-         <item>
-          <layout class="QGridLayout" name="editor_common_settings_grid">
-           <property name="spacing">
-            <number>6</number>
-           </property>
-           <item row="2" column="0">
-            <widget class="QCheckBox" name="editor_ws_checkbox">
-             <property name="text">
-              <string>Show whitespace</string>
-             </property>
-            </widget>
-           </item>
-           <item row="1" column="0">
-            <widget class="QCheckBox" name="editor_showLineNumbers">
-             <property name="enabled">
-              <bool>true</bool>
-             </property>
-             <property name="text">
-              <string>Show line numbers</string>
-             </property>
-            </widget>
-           </item>
-           <item row="0" column="0">
-            <widget class="QCheckBox" name="editor_longWindowTitle">
-             <property name="text">
-              <string>Show complete path in window title</string>
-             </property>
-            </widget>
-           </item>
-           <item row="2" column="1">
-            <widget class="QCheckBox" name="editor_ws_indent_checkbox">
-             <property name="enabled">
-              <bool>false</bool>
-             </property>
-             <property name="text">
-              <string>Do not show whitespace used for indentation</string>
-             </property>
-            </widget>
-           </item>
-           <item row="3" column="0">
-            <widget class="QCheckBox" name="editor_highlightCurrentLine">
-             <property name="enabled">
-              <bool>true</bool>
-             </property>
-             <property name="text">
-              <string>Highlight current line</string>
-             </property>
-            </widget>
-           </item>
-           <item row="3" column="1">
-            <layout class="QGridLayout" name="editor_grid_current_line" rowstretch="0" columnstretch="0,0,0,0,0">
-             <property name="horizontalSpacing">
-              <number>12</number>
-             </property>
-             <property name="verticalSpacing">
-              <number>0</number>
-             </property>
-             <item row="0" column="1">
-              <widget class="QLabel" name="editor_label_cl_color">
-               <property name="enabled">
-                <bool>false</bool>
+         <widget class="QWidget" name="scrollAreaWidgetContents">
+          <property name="geometry">
+           <rect>
+            <x>0</x>
+            <y>0</y>
+            <width>662</width>
+            <height>661</height>
+           </rect>
+          </property>
+          <layout class="QVBoxLayout" name="verticalLayout_16">
+           <item>
+            <layout class="QVBoxLayout" name="verticalLayout_9">
+             <item>
+              <layout class="QGridLayout" name="editor_common_settings_grid">
+               <property name="horizontalSpacing">
+                <number>6</number>
                </property>
-               <property name="text">
-                <string>Color</string>
+               <item row="6" column="2">
+                <layout class="QHBoxLayout" name="horizontalLayout_3">
+                 <item>
+                  <widget class="QLabel" name="editor_long_line_column_text">
+                   <property name="text">
+                    <string>After Column</string>
+                   </property>
+                  </widget>
+                 </item>
+                 <item>
+                  <widget class="QSpinBox" name="editor_long_line_column">
+                   <property name="minimum">
+                    <number>2</number>
+                   </property>
+                   <property name="maximum">
+                    <number>256</number>
+                   </property>
+                   <property name="value">
+                    <number>80</number>
+                   </property>
+                  </widget>
+                 </item>
+                 <item>
+                  <spacer name="horizontalSpacer_7">
+                   <property name="orientation">
+                    <enum>Qt::Horizontal</enum>
+                   </property>
+                   <property name="sizeHint" stdset="0">
+                    <size>
+                     <width>40</width>
+                     <height>20</height>
+                    </size>
+                   </property>
+                  </spacer>
+                 </item>
+                </layout>
+               </item>
+               <item row="3" column="0">
+                <widget class="QCheckBox" name="editor_ws_checkbox">
+                 <property name="text">
+                  <string>Show whitespace</string>
+                 </property>
+                </widget>
+               </item>
+               <item row="2" column="0">
+                <widget class="QCheckBox" name="editor_showLineNumbers">
+                 <property name="enabled">
+                  <bool>true</bool>
+                 </property>
+                 <property name="text">
+                  <string>Show line numbers</string>
+                 </property>
+                </widget>
+               </item>
+               <item row="1" column="0">
+                <widget class="QCheckBox" name="editor_longWindowTitle">
+                 <property name="sizePolicy">
+                  <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
+                   <horstretch>0</horstretch>
+                   <verstretch>0</verstretch>
+                  </sizepolicy>
+                 </property>
+                 <property name="text">
+                  <string>Show complete path in window title</string>
+                 </property>
+                </widget>
+               </item>
+               <item row="3" column="2">
+                <widget class="QCheckBox" name="editor_ws_indent_checkbox">
+                 <property name="enabled">
+                  <bool>false</bool>
+                 </property>
+                 <property name="text">
+                  <string>Do not show whitespace used for indentation</string>
+                 </property>
+                </widget>
+               </item>
+               <item row="5" column="0">
+                <widget class="QCheckBox" name="editor_highlightCurrentLine">
+                 <property name="enabled">
+                  <bool>true</bool>
+                 </property>
+                 <property name="text">
+                  <string>Highlight current line</string>
+                 </property>
+                </widget>
+               </item>
+               <item row="5" column="2">
+                <layout class="QGridLayout" name="editor_grid_current_line" rowstretch="0" columnstretch="0,0,0,0,0">
+                 <property name="horizontalSpacing">
+                  <number>12</number>
+                 </property>
+                 <property name="verticalSpacing">
+                  <number>0</number>
+                 </property>
+                 <item row="0" column="1">
+                  <widget class="QLabel" name="editor_label_cl_color">
+                   <property name="enabled">
+                    <bool>false</bool>
+                   </property>
+                   <property name="text">
+                    <string>Color</string>
+                   </property>
+                  </widget>
+                 </item>
+                 <item row="0" column="3">
+                  <spacer name="horizontalSpacer_11">
+                   <property name="orientation">
+                    <enum>Qt::Horizontal</enum>
+                   </property>
+                   <property name="sizeType">
+                    <enum>QSizePolicy::Fixed</enum>
+                   </property>
+                   <property name="sizeHint" stdset="0">
+                    <size>
+                     <width>80</width>
+                     <height>20</height>
+                    </size>
+                   </property>
+                  </spacer>
+                 </item>
+                 <item row="0" column="4">
+                  <spacer name="horizontalSpacer_9">
+                   <property name="orientation">
+                    <enum>Qt::Horizontal</enum>
+                   </property>
+                   <property name="sizeHint" stdset="0">
+                    <size>
+                     <width>40</width>
+                     <height>20</height>
+                    </size>
+                   </property>
+                  </spacer>
+                 </item>
+                </layout>
+               </item>
+               <item row="1" column="4">
+                <spacer name="horizontalSpacer_12">
+                 <property name="orientation">
+                  <enum>Qt::Horizontal</enum>
+                 </property>
+                 <property name="sizeHint" stdset="0">
+                  <size>
+                   <width>40</width>
+                   <height>20</height>
+                  </size>
+                 </property>
+                </spacer>
+               </item>
+               <item row="1" column="2">
+                <layout class="QGridLayout" name="gridLayout_6">
+                 <item row="0" column="0">
+                  <widget class="QLabel" name="editor_lbl_min_tab_width">
+                   <property name="text">
+                    <string>Tab width min.</string>
+                   </property>
+                  </widget>
+                 </item>
+                 <item row="0" column="3">
+                  <widget class="QSpinBox" name="editor_notebook_tab_width_min">
+                   <property name="minimum">
+                    <number>80</number>
+                   </property>
+                   <property name="maximum">
+                    <number>600</number>
+                   </property>
+                   <property name="singleStep">
+                    <number>20</number>
+                   </property>
+                   <property name="value">
+                    <number>160</number>
+                   </property>
+                  </widget>
+                 </item>
+                 <item row="0" column="6">
+                  <spacer name="horizontalSpacer_25">
+                   <property name="orientation">
+                    <enum>Qt::Horizontal</enum>
+                   </property>
+                   <property name="sizeHint" stdset="0">
+                    <size>
+                     <width>40</width>
+                     <height>20</height>
+                    </size>
+                   </property>
+                  </spacer>
+                 </item>
+                 <item row="0" column="5">
+                  <widget class="QSpinBox" name="editor_notebook_tab_width_max">
+                   <property name="minimum">
+                    <number>180</number>
+                   </property>
+                   <property name="maximum">
+                    <number>600</number>
+                   </property>
+                   <property name="singleStep">
+                    <number>20</number>
+                   </property>
+                   <property name="value">
+                    <number>300</number>
+                   </property>
+                  </widget>
+                 </item>
+                 <item row="0" column="4">
+                  <widget class="QLabel" name="editor_lbl_max_tab_width">
+                   <property name="text">
+                    <string>max.</string>
+                   </property>
+                  </widget>
+                 </item>
+                </layout>
+               </item>
+               <item row="1" column="1">
+                <spacer name="horizontalSpacer_24">
+                 <property name="orientation">
+                  <enum>Qt::Horizontal</enum>
+                 </property>
+                 <property name="sizeType">
+                  <enum>QSizePolicy::Fixed</enum>
+                 </property>
+                 <property name="sizeHint" stdset="0">
+                  <size>
+                   <width>10</width>
+                   <height>0</height>
+                  </size>
+                 </property>
+                </spacer>
+               </item>
+               <item row="6" column="0">
+                <widget class="QCheckBox" name="editor_long_line_marker">
+                 <property name="toolTip">
+                  <string>This works well for monospaced fonts. The line is drawn at a position based on the width of a space character in the default font. It may not work very well if styles use proportional fonts or if varied font sizes or bold, italic and normal texts are used.</string>
+                 </property>
+                 <property name="text">
+                  <string>Draw a long  line marker</string>
+                 </property>
+                 <property name="checked">
+                  <bool>true</bool>
+                 </property>
+                </widget>
+               </item>
+               <item row="7" column="0">
+                <widget class="QCheckBox" name="cb_code_folding">
+                 <property name="text">
+                  <string>Enable Code Folding</string>
+                 </property>
+                 <property name="checked">
+                  <bool>true</bool>
+                 </property>
+                </widget>
+               </item>
+               <item row="8" column="0">
+                <widget class="QCheckBox" name="cb_edit_status_bar">
+                 <property name="text">
+                  <string>Show status bar</string>
+                 </property>
+                 <property name="checked">
+                  <bool>true</bool>
+                 </property>
+                </widget>
+               </item>
+               <item row="4" column="0">
+                <widget class="QCheckBox" name="cb_show_eol">
+                 <property name="text">
+                  <string>Show eol characters</string>
+                 </property>
+                </widget>
+               </item>
+               <item row="4" column="2">
+                <layout class="QHBoxLayout" name="horizontalLayout_17">
+                 <item>
+                  <widget class="QLabel" name="label_22">
+                   <property name="text">
+                    <string>Default eol mode</string>
+                   </property>
+                  </widget>
+                 </item>
+                 <item>
+                  <widget class="QComboBox" name="combo_eol_mode">
+                   <property name="sizeAdjustPolicy">
+                    <enum>QComboBox::AdjustToContents</enum>
+                   </property>
+                   <property name="minimumContentsLength">
+                    <number>7</number>
+                   </property>
+                   <item>
+                    <property name="text">
+                     <string>Windows (CRLF)</string>
+                    </property>
+                   </item>
+                   <item>
+                    <property name="text">
+                     <string>Mac (CR)</string>
+                    </property>
+                   </item>
+                   <item>
+                    <property name="text">
+                     <string>Unix (LF)</string>
+                    </property>
+                   </item>
+                  </widget>
+                 </item>
+                 <item>
+                  <spacer name="horizontalSpacer_17">
+                   <property name="orientation">
+                    <enum>Qt::Horizontal</enum>
+                   </property>
+                   <property name="sizeHint" stdset="0">
+                    <size>
+                     <width>40</width>
+                     <height>20</height>
+                    </size>
+                   </property>
+                  </spacer>
+                 </item>
+                </layout>
+               </item>
+               <item row="9" column="0">
+                <widget class="QCheckBox" name="cb_show_hscrollbar">
+                 <property name="enabled">
+                  <bool>true</bool>
+                 </property>
+                 <property name="text">
+                  <string>Show horizontal scroll bar</string>
+                 </property>
+                 <property name="checked">
+                  <bool>true</bool>
+                 </property>
+                </widget>
+               </item>
+              </layout>
+             </item>
+             <item>
+              <widget class="Line" name="line">
+               <property name="orientation">
+                <enum>Qt::Horizontal</enum>
                </property>
               </widget>
              </item>
-             <item row="0" column="3">
-              <spacer name="horizontalSpacer_11">
+             <item>
+              <layout class="QGridLayout" name="gridLayout_4">
+               <property name="verticalSpacing">
+                <number>0</number>
+               </property>
+               <item row="0" column="0">
+                <widget class="QLabel" name="label_13">
+                 <property name="text">
+                  <string>Indent width</string>
+                 </property>
+                </widget>
+               </item>
+               <item row="0" column="5">
+                <spacer name="horizontalSpacer_14">
+                 <property name="orientation">
+                  <enum>Qt::Horizontal</enum>
+                 </property>
+                 <property name="sizeType">
+                  <enum>QSizePolicy::Fixed</enum>
+                 </property>
+                 <property name="sizeHint" stdset="0">
+                  <size>
+                   <width>10</width>
+                   <height>0</height>
+                  </size>
+                 </property>
+                </spacer>
+               </item>
+               <item row="2" column="4">
+                <widget class="QCheckBox" name="editor_tab_ind_checkbox">
+                 <property name="text">
+                  <string>Tab indents line</string>
+                 </property>
+                </widget>
+               </item>
+               <item row="0" column="4">
+                <widget class="QCheckBox" name="editor_auto_ind_checkbox">
+                 <property name="text">
+                  <string>Auto indentation</string>
+                 </property>
+                </widget>
+               </item>
+               <item row="0" column="2">
+                <widget class="QSpinBox" name="editor_ind_width_spinbox">
+                 <property name="minimum">
+                  <number>1</number>
+                 </property>
+                 <property name="maximum">
+                  <number>32</number>
+                 </property>
+                 <property name="value">
+                  <number>2</number>
+                 </property>
+                </widget>
+               </item>
+               <item row="2" column="0">
+                <widget class="QLabel" name="label_14">
+                 <property name="text">
+                  <string>Tab width</string>
+                 </property>
+                </widget>
+               </item>
+               <item row="0" column="6">
+                <widget class="QCheckBox" name="editor_ind_guides_checkbox">
+                 <property name="text">
+                  <string>Show indentation guides</string>
+                 </property>
+                </widget>
+               </item>
+               <item row="2" column="2">
+                <widget class="QSpinBox" name="editor_tab_width_spinbox">
+                 <property name="minimum">
+                  <number>1</number>
+                 </property>
+                 <property name="maximum">
+                  <number>32</number>
+                 </property>
+                </widget>
+               </item>
+               <item row="2" column="6">
+                <widget class="QCheckBox" name="editor_bs_unind_checkbox">
+                 <property name="text">
+                  <string>Backspace unindents line</string>
+                 </property>
+                </widget>
+               </item>
+               <item row="0" column="10">
+                <spacer name="horizontalSpacer_13">
+                 <property name="orientation">
+                  <enum>Qt::Horizontal</enum>
+                 </property>
+                 <property name="sizeHint" stdset="0">
+                  <size>
+                   <width>40</width>
+                   <height>20</height>
+                  </size>
+                 </property>
+                </spacer>
+               </item>
+               <item row="2" column="10">
+                <spacer name="horizontalSpacer_20">
+                 <property name="orientation">
+                  <enum>Qt::Horizontal</enum>
+                 </property>
+                 <property name="sizeHint" stdset="0">
+                  <size>
+                   <width>40</width>
+                   <height>20</height>
+                  </size>
+                 </property>
+                </spacer>
+               </item>
+               <item row="0" column="3">
+                <spacer name="horizontalSpacer_10">
+                 <property name="orientation">
+                  <enum>Qt::Horizontal</enum>
+                 </property>
+                 <property name="sizeType">
+                  <enum>QSizePolicy::Fixed</enum>
+                 </property>
+                 <property name="sizeHint" stdset="0">
+                  <size>
+                   <width>10</width>
+                   <height>0</height>
+                  </size>
+                 </property>
+                </spacer>
+               </item>
+               <item row="3" column="4">
+                <widget class="QCheckBox" name="editor_ind_uses_tabs_checkbox">
+                 <property name="text">
+                  <string>Indentation uses tabs</string>
+                 </property>
+                </widget>
+               </item>
+              </layout>
+             </item>
+             <item>
+              <widget class="Line" name="line_2">
                <property name="orientation">
                 <enum>Qt::Horizontal</enum>
                </property>
-               <property name="sizeType">
-                <enum>QSizePolicy::Fixed</enum>
-               </property>
-               <property name="sizeHint" stdset="0">
-                <size>
-                 <width>80</width>
-                 <height>20</height>
-                </size>
-               </property>
-              </spacer>
+              </widget>
              </item>
-             <item row="0" column="4">
-              <spacer name="horizontalSpacer_9">
+             <item>
+              <layout class="QGridLayout" name="gridLayout_2">
+               <item row="1" column="1">
+                <layout class="QHBoxLayout" name="horizontalLayout_2">
+                 <property name="spacing">
+                  <number>6</number>
+                 </property>
+                 <property name="bottomMargin">
+                  <number>4</number>
+                 </property>
+                 <item>
+                  <widget class="QLabel" name="label_16">
+                   <property name="text">
+                    <string>Auto completion</string>
+                   </property>
+                  </widget>
+                 </item>
+                </layout>
+               </item>
+               <item row="2" column="1">
+                <layout class="QGridLayout" name="gridLayout_3">
+                 <item row="0" column="1">
+                  <spacer name="horizontalSpacer_15">
+                   <property name="orientation">
+                    <enum>Qt::Horizontal</enum>
+                   </property>
+                   <property name="sizeType">
+                    <enum>QSizePolicy::Fixed</enum>
+                   </property>
+                   <property name="sizeHint" stdset="0">
+                    <size>
+                     <width>10</width>
+                     <height>0</height>
+                    </size>
+                   </property>
+                  </spacer>
+                 </item>
+                 <item row="0" column="0">
+                  <widget class="QCheckBox" name="editor_checkbox_ac_keywords">
+                   <property name="enabled">
+                    <bool>true</bool>
+                   </property>
+                   <property name="text">
+                    <string>Match keywords</string>
+                   </property>
+                   <property name="checked">
+                    <bool>true</bool>
+                   </property>
+                  </widget>
+                 </item>
+                 <item row="2" column="0">
+                  <widget class="QCheckBox" name="editor_checkbox_ac_case">
+                   <property name="enabled">
+                    <bool>true</bool>
+                   </property>
+                   <property name="text">
+                    <string>Case sensitive</string>
+                   </property>
+                   <property name="checked">
+                    <bool>true</bool>
+                   </property>
+                  </widget>
+                 </item>
+                 <item row="1" column="0">
+                  <widget class="QCheckBox" name="editor_checkbox_ac_document">
+                   <property name="enabled">
+                    <bool>true</bool>
+                   </property>
+                   <property name="text">
+                    <string>Match words in document</string>
+                   </property>
+                  </widget>
+                 </item>
+                 <item row="2" column="2">
+                  <widget class="QCheckBox" name="editor_checkbox_ac_replace">
+                   <property name="enabled">
+                    <bool>true</bool>
+                   </property>
+                   <property name="text">
+                    <string>Replace word by suggested one</string>
+                   </property>
+                  </widget>
+                 </item>
+                 <item row="0" column="3">
+                  <spacer name="horizontalSpacer_8">
+                   <property name="orientation">
+                    <enum>Qt::Horizontal</enum>
+                   </property>
+                   <property name="sizeHint" stdset="0">
+                    <size>
+                     <width>40</width>
+                     <height>20</height>
+                    </size>
+                   </property>
+                  </spacer>
+                 </item>
+                 <item row="2" column="3">
+                  <spacer name="horizontalSpacer_19">
+                   <property name="orientation">
+                    <enum>Qt::Horizontal</enum>
+                   </property>
+                   <property name="sizeHint" stdset="0">
+                    <size>
+                     <width>40</width>
+                     <height>20</height>
+                    </size>
+                   </property>
+                  </spacer>
+                 </item>
+                 <item row="0" column="2">
+                  <layout class="QHBoxLayout" name="horizontalLayout_14">
+                   <item>
+                    <widget class="QCheckBox" name="editor_checkbox_ac_builtins">
+                     <property name="enabled">
+                      <bool>false</bool>
+                     </property>
+                     <property name="text">
+                      <string>With Octave builtins</string>
+                     </property>
+                    </widget>
+                   </item>
+                   <item>
+                    <widget class="QCheckBox" name="editor_checkbox_ac_functions">
+                     <property name="enabled">
+                      <bool>false</bool>
+                     </property>
+                     <property name="text">
+                      <string>With Octave functions</string>
+                     </property>
+                    </widget>
+                   </item>
+                  </layout>
+                 </item>
+                </layout>
+               </item>
+               <item row="3" column="1">
+                <layout class="QGridLayout" name="gridLayout_10">
+                 <item row="0" column="2">
+                  <widget class="QLabel" name="editor_label_ac_threshold">
+                   <property name="enabled">
+                    <bool>false</bool>
+                   </property>
+                   <property name="text">
+                    <string>Number of characters before list is shwon: </string>
+                   </property>
+                  </widget>
+                 </item>
+                 <item row="0" column="3">
+                  <widget class="QSpinBox" name="editor_spinbox_ac_threshold">
+                   <property name="enabled">
+                    <bool>false</bool>
+                   </property>
+                   <property name="toolTip">
+                    <string/>
+                   </property>
+                   <property name="whatsThis">
+                    <string/>
+                   </property>
+                   <property name="suffix">
+                    <string/>
+                   </property>
+                   <property name="minimum">
+                    <number>1</number>
+                   </property>
+                   <property name="maximum">
+                    <number>6</number>
+                   </property>
+                   <property name="value">
+                    <number>2</number>
+                   </property>
+                  </widget>
+                 </item>
+                 <item row="0" column="4">
+                  <spacer name="horizontalSpacer_2">
+                   <property name="orientation">
+                    <enum>Qt::Horizontal</enum>
+                   </property>
+                   <property name="sizeHint" stdset="0">
+                    <size>
+                     <width>40</width>
+                     <height>20</height>
+                    </size>
+                   </property>
+                  </spacer>
+                 </item>
+                 <item row="0" column="0">
+                  <widget class="QCheckBox" name="editor_codeCompletion">
+                   <property name="enabled">
+                    <bool>true</bool>
+                   </property>
+                   <property name="text">
+                    <string>Show completion list automatically</string>
+                   </property>
+                   <property name="checked">
+                    <bool>false</bool>
+                   </property>
+                  </widget>
+                 </item>
+                 <item row="0" column="1">
+                  <spacer name="horizontalSpacer_31">
+                   <property name="orientation">
+                    <enum>Qt::Horizontal</enum>
+                   </property>
+                   <property name="sizeType">
+                    <enum>QSizePolicy::Fixed</enum>
+                   </property>
+                   <property name="sizeHint" stdset="0">
+                    <size>
+                     <width>10</width>
+                     <height>0</height>
+                    </size>
+                   </property>
+                  </spacer>
+                 </item>
+                </layout>
+               </item>
+              </layout>
+             </item>
+             <item>
+              <widget class="Line" name="line_3">
                <property name="orientation">
                 <enum>Qt::Horizontal</enum>
                </property>
-               <property name="sizeHint" stdset="0">
-                <size>
-                 <width>40</width>
-                 <height>20</height>
-                </size>
+              </widget>
+             </item>
+             <item>
+              <layout class="QVBoxLayout" name="verticalLayout_11">
+               <property name="topMargin">
+                <number>0</number>
+               </property>
+               <property name="bottomMargin">
+                <number>0</number>
                </property>
-              </spacer>
+               <item>
+                <widget class="QCheckBox" name="editor_restoreSession">
+                 <property name="sizePolicy">
+                  <sizepolicy hsizetype="Minimum" vsizetype="Fixed">
+                   <horstretch>0</horstretch>
+                   <verstretch>0</verstretch>
+                  </sizepolicy>
+                 </property>
+                 <property name="text">
+                  <string>Restore editor tabs from previous session on startup</string>
+                 </property>
+                </widget>
+               </item>
+               <item>
+                <widget class="QCheckBox" name="editor_create_new file">
+                 <property name="sizePolicy">
+                  <sizepolicy hsizetype="Minimum" vsizetype="Fixed">
+                   <horstretch>0</horstretch>
+                   <verstretch>0</verstretch>
+                  </sizepolicy>
+                 </property>
+                 <property name="text">
+                  <string>Create nonexistent files without prompting</string>
+                 </property>
+                </widget>
+               </item>
+               <item>
+                <widget class="QCheckBox" name="editor_reload_changed_files">
+                 <property name="text">
+                  <string>Reload externally changed files without prompt</string>
+                 </property>
+                </widget>
+               </item>
+              </layout>
+             </item>
+             <item>
+              <widget class="Line" name="line_4">
+               <property name="orientation">
+                <enum>Qt::Horizontal</enum>
+               </property>
+              </widget>
+             </item>
+             <item>
+              <layout class="QHBoxLayout" name="horizontalLayout">
+               <item>
+                <widget class="QCheckBox" name="useCustomFileEditor">
+                 <property name="enabled">
+                  <bool>true</bool>
+                 </property>
+                 <property name="text">
+                  <string>Use custom file editor</string>
+                 </property>
+                </widget>
+               </item>
+               <item>
+                <widget class="QLabel" name="customEditorLabel">
+                 <property name="enabled">
+                  <bool>false</bool>
+                 </property>
+                 <property name="text">
+                  <string>command line (%f=file, %l=line):</string>
+                 </property>
+                </widget>
+               </item>
+               <item>
+                <widget class="QLineEdit" name="customFileEditor">
+                 <property name="enabled">
+                  <bool>false</bool>
+                 </property>
+                 <property name="text">
+                  <string>emacs +%l %f </string>
+                 </property>
+                </widget>
+               </item>
+              </layout>
              </item>
             </layout>
            </item>
-           <item row="0" column="2">
-            <spacer name="horizontalSpacer_12">
+           <item>
+            <spacer name="verticalSpacer_4">
              <property name="orientation">
-              <enum>Qt::Horizontal</enum>
+              <enum>Qt::Vertical</enum>
              </property>
              <property name="sizeHint" stdset="0">
               <size>
-               <width>40</width>
-               <height>20</height>
-              </size>
-             </property>
-            </spacer>
-           </item>
-           <item row="1" column="2">
-            <spacer name="horizontalSpacer_16">
-             <property name="orientation">
-              <enum>Qt::Horizontal</enum>
-             </property>
-             <property name="sizeHint" stdset="0">
-              <size>
-               <width>40</width>
-               <height>20</height>
-              </size>
-             </property>
-            </spacer>
-           </item>
-           <item row="2" column="2">
-            <spacer name="horizontalSpacer_17">
-             <property name="orientation">
-              <enum>Qt::Horizontal</enum>
-             </property>
-             <property name="sizeHint" stdset="0">
-              <size>
-               <width>40</width>
-               <height>20</height>
-              </size>
-             </property>
-            </spacer>
-           </item>
-           <item row="3" column="2">
-            <spacer name="horizontalSpacer_18">
-             <property name="orientation">
-              <enum>Qt::Horizontal</enum>
-             </property>
-             <property name="sizeHint" stdset="0">
-              <size>
-               <width>40</width>
-               <height>20</height>
+               <width>20</width>
+               <height>40</height>
               </size>
              </property>
             </spacer>
            </item>
           </layout>
-         </item>
+         </widget>
+        </widget>
+       </item>
+      </layout>
+     </widget>
+     <widget class="QWidget" name="tab_editor_styles">
+      <property name="sizePolicy">
+       <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
+        <horstretch>0</horstretch>
+        <verstretch>0</verstretch>
+       </sizepolicy>
+      </property>
+      <attribute name="title">
+       <string>Editor Styles</string>
+      </attribute>
+      <layout class="QVBoxLayout" name="verticalLayout_12">
+       <item>
+        <layout class="QVBoxLayout" name="verticalLayout_5">
          <item>
-          <widget class="Line" name="line">
-           <property name="orientation">
-            <enum>Qt::Horizontal</enum>
+          <widget class="QLabel" name="label_10">
+           <property name="sizePolicy">
+            <sizepolicy hsizetype="Expanding" vsizetype="Preferred">
+             <horstretch>0</horstretch>
+             <verstretch>0</verstretch>
+            </sizepolicy>
+           </property>
+           <property name="frameShape">
+            <enum>QFrame::NoFrame</enum>
+           </property>
+           <property name="text">
+            <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Select font, font size (as a difference from the default size), font style (&lt;b&gt;b&lt;/b&gt;old, &lt;b&gt;i&lt;/b&gt;talic, &lt;b&gt;u&lt;/b&gt;nderline), text color and background color (for the latter, the color pink (255,0,255) is a placeholder for the default background color).&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
+           </property>
+           <property name="scaledContents">
+            <bool>false</bool>
+           </property>
+           <property name="alignment">
+            <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
+           </property>
+           <property name="wordWrap">
+            <bool>true</bool>
+           </property>
+           <property name="margin">
+            <number>4</number>
            </property>
           </widget>
          </item>
          <item>
-          <layout class="QGridLayout" name="gridLayout_4">
-           <property name="verticalSpacing">
-            <number>0</number>
-           </property>
-           <item row="0" column="3">
-            <spacer name="horizontalSpacer_10">
-             <property name="orientation">
-              <enum>Qt::Horizontal</enum>
-             </property>
-             <property name="sizeType">
-              <enum>QSizePolicy::Fixed</enum>
-             </property>
-             <property name="sizeHint" stdset="0">
-              <size>
-               <width>10</width>
-               <height>0</height>
-              </size>
-             </property>
-            </spacer>
-           </item>
-           <item row="0" column="0">
-            <widget class="QLabel" name="label_13">
-             <property name="text">
-              <string>Indent width</string>
-             </property>
-            </widget>
-           </item>
-           <item row="2" column="4">
-            <widget class="QCheckBox" name="editor_tab_ind_checkbox">
-             <property name="text">
-              <string>Tab indents line</string>
-             </property>
-            </widget>
-           </item>
-           <item row="0" column="4">
-            <widget class="QCheckBox" name="editor_auto_ind_checkbox">
-             <property name="text">
-              <string>Auto indentation</string>
-             </property>
-            </widget>
-           </item>
-           <item row="0" column="2">
-            <widget class="QSpinBox" name="editor_ind_width_spinbox">
-             <property name="minimum">
-              <number>1</number>
-             </property>
-             <property name="maximum">
-              <number>32</number>
-             </property>
-             <property name="value">
-              <number>2</number>
-             </property>
-            </widget>
-           </item>
-           <item row="2" column="0">
-            <widget class="QLabel" name="label_14">
-             <property name="text">
-              <string>Tab width</string>
-             </property>
-            </widget>
-           </item>
-           <item row="0" column="6">
-            <widget class="QCheckBox" name="editor_ind_guides_checkbox">
-             <property name="text">
-              <string>Show indentation guides</string>
-             </property>
-            </widget>
-           </item>
-           <item row="2" column="2">
-            <widget class="QSpinBox" name="editor_tab_width_spinbox">
-             <property name="minimum">
-              <number>1</number>
-             </property>
-             <property name="maximum">
-              <number>32</number>
-             </property>
-            </widget>
-           </item>
-           <item row="2" column="6">
-            <widget class="QCheckBox" name="editor_bs_unind_checkbox">
-             <property name="text">
-              <string>Backspace unindents line</string>
-             </property>
-            </widget>
-           </item>
-           <item row="0" column="10">
-            <spacer name="horizontalSpacer_13">
-             <property name="orientation">
-              <enum>Qt::Horizontal</enum>
-             </property>
-             <property name="sizeHint" stdset="0">
-              <size>
-               <width>40</width>
-               <height>20</height>
-              </size>
-             </property>
-            </spacer>
-           </item>
-           <item row="0" column="5">
-            <spacer name="horizontalSpacer_14">
-             <property name="orientation">
-              <enum>Qt::Horizontal</enum>
-             </property>
-             <property name="sizeType">
-              <enum>QSizePolicy::Fixed</enum>
-             </property>
-             <property name="sizeHint" stdset="0">
-              <size>
-               <width>10</width>
-               <height>0</height>
-              </size>
-             </property>
-            </spacer>
-           </item>
-           <item row="2" column="10">
-            <spacer name="horizontalSpacer_20">
-             <property name="orientation">
-              <enum>Qt::Horizontal</enum>
-             </property>
-             <property name="sizeHint" stdset="0">
-              <size>
-               <width>40</width>
-               <height>20</height>
-              </size>
-             </property>
-            </spacer>
-           </item>
-          </layout>
-         </item>
-         <item>
-          <widget class="Line" name="line_2">
-           <property name="orientation">
-            <enum>Qt::Horizontal</enum>
+          <widget class="QTabWidget" name="tabs_editor_lexers">
+           <property name="sizePolicy">
+            <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
+             <horstretch>0</horstretch>
+             <verstretch>0</verstretch>
+            </sizepolicy>
            </property>
           </widget>
          </item>
-         <item>
-          <layout class="QGridLayout" name="gridLayout_2">
-           <property name="verticalSpacing">
-            <number>0</number>
-           </property>
-           <item row="0" column="0">
-            <widget class="QCheckBox" name="editor_codeCompletion">
-             <property name="enabled">
-              <bool>true</bool>
-             </property>
-             <property name="text">
-              <string>Code completion</string>
-             </property>
-             <property name="checked">
-              <bool>false</bool>
-             </property>
-            </widget>
-           </item>
-           <item row="0" column="2">
-            <layout class="QHBoxLayout" name="horizontalLayout_2">
-             <property name="spacing">
-              <number>6</number>
-             </property>
+        </layout>
+       </item>
+      </layout>
+     </widget>
+     <widget class="QWidget" name="tab_terminal">
+      <attribute name="title">
+       <string>Terminal</string>
+      </attribute>
+      <layout class="QVBoxLayout" name="verticalLayout_14">
+       <item>
+        <widget class="QScrollArea" name="scrollArea_3">
+         <property name="widgetResizable">
+          <bool>true</bool>
+         </property>
+         <widget class="QWidget" name="scrollAreaWidgetContents_4">
+          <property name="geometry">
+           <rect>
+            <x>0</x>
+            <y>0</y>
+            <width>678</width>
+            <height>378</height>
+           </rect>
+          </property>
+          <layout class="QVBoxLayout" name="verticalLayout_7">
+           <item>
+            <layout class="QVBoxLayout" name="verticalLayout_8">
              <item>
-              <widget class="QLabel" name="editor_label_ac_threshold">
-               <property name="enabled">
-                <bool>false</bool>
-               </property>
-               <property name="text">
-                <string># of characters typed before completion list displayed</string>
-               </property>
-              </widget>
-             </item>
-             <item>
-              <widget class="QSpinBox" name="editor_spinbox_ac_threshold">
-               <property name="enabled">
-                <bool>false</bool>
-               </property>
-               <property name="toolTip">
-                <string/>
-               </property>
-               <property name="whatsThis">
-                <string/>
-               </property>
-               <property name="suffix">
-                <string/>
-               </property>
-               <property name="minimum">
-                <number>1</number>
-               </property>
-               <property name="maximum">
-                <number>6</number>
-               </property>
-               <property name="value">
-                <number>2</number>
-               </property>
-              </widget>
-             </item>
-             <item>
-              <spacer name="horizontalSpacer_2">
-               <property name="orientation">
-                <enum>Qt::Horizontal</enum>
-               </property>
+              <layout class="QGridLayout" name="gridLayout_7">
                <property name="sizeHint" stdset="0">
                 <size>
                  <width>40</width>
                  <height>20</height>
                 </size>
                </property>
-              </spacer>
+               <item row="1" column="2">
+                <layout class="QHBoxLayout" name="horizontalLayout_13">
+                 <item>
+                  <widget class="QCheckBox" name="terminal_cursorUseForegroundColor">
+                   <property name="text">
+                    <string>Use foreground color</string>
+                   </property>
+                  </widget>
+                 </item>
+                 <item>
+                  <widget class="QCheckBox" name="terminal_cursorBlinking">
+                   <property name="text">
+                    <string>Cursor blinking</string>
+                   </property>
+                  </widget>
+                 </item>
+                </layout>
+               </item>
+               <item row="1" column="0">
+                <layout class="QHBoxLayout" name="horizontalLayout_7">
+                 <item>
+                  <widget class="QLabel" name="label">
+                   <property name="text">
+                    <string>Cursor type:</string>
+                   </property>
+                  </widget>
+                 </item>
+                 <item>
+                  <widget class="QComboBox" name="terminal_cursorType"/>
+                 </item>
+                </layout>
+               </item>
+               <item row="0" column="0">
+                <layout class="QHBoxLayout" name="horizontalLayout_11">
+                 <item>
+                  <widget class="QLabel" name="label_11">
+                   <property name="text">
+                    <string>Font</string>
+                   </property>
+                  </widget>
+                 </item>
+                 <item>
+                  <widget class="QFontComboBox" name="terminal_fontName">
+                   <property name="editable">
+                    <bool>false</bool>
+                   </property>
+                   <property name="fontFilters">
+                    <set>QFontComboBox::MonospacedFonts</set>
+                   </property>
+                  </widget>
+                 </item>
+                </layout>
+               </item>
+               <item row="0" column="2">
+                <layout class="QHBoxLayout" name="horizontalLayout_12">
+                 <item>
+                  <widget class="QLabel" name="label_12">
+                   <property name="text">
+                    <string>Font size</string>
+                   </property>
+                  </widget>
+                 </item>
+                 <item>
+                  <widget class="QSpinBox" name="terminal_fontSize">
+                   <property name="minimum">
+                    <number>2</number>
+                   </property>
+                   <property name="maximum">
+                    <number>96</number>
+                   </property>
+                   <property name="value">
+                    <number>10</number>
+                   </property>
+                  </widget>
+                 </item>
+                 <item>
+                  <spacer name="horizontalSpacer_27">
+                   <property name="orientation">
+                    <enum>Qt::Horizontal</enum>
+                   </property>
+                   <property name="sizeHint" stdset="0">
+                    <size>
+                     <width>40</width>
+                     <height>20</height>
+                    </size>
+                   </property>
+                  </spacer>
+                 </item>
+                </layout>
+               </item>
+               <item row="2" column="2">
+                <layout class="QHBoxLayout" name="horizontalLayout_5">
+                 <property name="topMargin">
+                  <number>0</number>
+                 </property>
+                 <item>
+                  <widget class="QSpinBox" name="terminal_history_buffer">
+                   <property name="minimum">
+                    <number>0</number>
+                   </property>
+                   <property name="maximum">
+                    <number>5000</number>
+                   </property>
+                   <property name="singleStep">
+                    <number>20</number>
+                   </property>
+                   <property name="value">
+                    <number>1000</number>
+                   </property>
+                  </widget>
+                 </item>
+                 <item>
+                  <widget class="QLabel" name="label_20">
+                   <property name="text">
+                    <string>(Changing buffer size clears history)</string>
+                   </property>
+                  </widget>
+                 </item>
+                 <item>
+                  <spacer name="horizontalSpacer_16">
+                   <property name="orientation">
+                    <enum>Qt::Horizontal</enum>
+                   </property>
+                   <property name="sizeHint" stdset="0">
+                    <size>
+                     <width>40</width>
+                     <height>20</height>
+                    </size>
+                   </property>
+                  </spacer>
+                 </item>
+                </layout>
+               </item>
+               <item row="2" column="0">
+                <widget class="QLabel" name="label_19">
+                 <property name="minimumSize">
+                  <size>
+                   <width>100</width>
+                   <height>20</height>
+                  </size>
+                 </property>
+                 <property name="text">
+                  <string>History buffer Size</string>
+                 </property>
+                </widget>
+               </item>
+               <item row="0" column="1">
+                <spacer name="horizontalSpacer_28">
+                 <property name="orientation">
+                  <enum>Qt::Horizontal</enum>
+                 </property>
+                 <property name="sizeType">
+                  <enum>QSizePolicy::Fixed</enum>
+                 </property>
+                 <property name="sizeHint" stdset="0">
+                  <size>
+                   <width>20</width>
+                   <height>20</height>
+                  </size>
+                 </property>
+                </spacer>
+               </item>
+              </layout>
              </item>
-            </layout>
-           </item>
-           <item row="1" column="2">
-            <layout class="QGridLayout" name="gridLayout_3">
-             <property name="verticalSpacing">
-              <number>0</number>
-             </property>
-             <item row="0" column="1">
-              <spacer name="horizontalSpacer_15">
+             <item>
+              <layout class="QGridLayout" name="gridLayout_15">
+               <item row="0" column="0">
+                <widget class="QCheckBox" name="terminal_focus_command">
+                 <property name="text">
+                  <string>Set focus to terminal when running a command from within another widget</string>
+                 </property>
+                </widget>
+               </item>
+               <item row="1" column="0">
+                <widget class="QCheckBox" name="terminal_print_dbg_location">
+                 <property name="text">
+                  <string>Print debug location in terminal window in addition to the marker in the editor</string>
+                 </property>
+                </widget>
+               </item>
+              </layout>
+             </item>
+             <item>
+              <widget class="Line" name="line_7">
                <property name="orientation">
                 <enum>Qt::Horizontal</enum>
                </property>
-               <property name="sizeType">
-                <enum>QSizePolicy::Fixed</enum>
-               </property>
-               <property name="sizeHint" stdset="0">
-                <size>
-                 <width>10</width>
-                 <height>0</height>
-                </size>
-               </property>
-              </spacer>
-             </item>
-             <item row="0" column="0">
-              <widget class="QCheckBox" name="editor_checkbox_ac_keywords">
-               <property name="enabled">
-                <bool>false</bool>
-               </property>
-               <property name="text">
-                <string>Match keywords</string>
-               </property>
-               <property name="checked">
-                <bool>true</bool>
-               </property>
-              </widget>
-             </item>
-             <item row="1" column="0">
-              <widget class="QCheckBox" name="editor_checkbox_ac_case">
-               <property name="enabled">
-                <bool>false</bool>
-               </property>
-               <property name="text">
-                <string>Case sensitive</string>
-               </property>
-               <property name="checked">
-                <bool>true</bool>
-               </property>
               </widget>
              </item>
-             <item row="1" column="2">
-              <widget class="QCheckBox" name="editor_checkbox_ac_replace">
-               <property name="enabled">
-                <bool>false</bool>
+             <item>
+              <widget class="QGroupBox" name="terminal_colors_box">
+               <property name="minimumSize">
+                <size>
+                 <width>0</width>
+                 <height>81</height>
+                </size>
                </property>
-               <property name="text">
-                <string>Replace word by suggested one</string>
+               <property name="title">
+                <string>Terminal Colors</string>
                </property>
               </widget>
              </item>
-             <item row="0" column="3">
-              <spacer name="horizontalSpacer_8">
+             <item>
+              <widget class="Line" name="line_5">
+               <property name="minimumSize">
+                <size>
+                 <width>0</width>
+                 <height>0</height>
+                </size>
+               </property>
                <property name="orientation">
                 <enum>Qt::Horizontal</enum>
                </property>
-               <property name="sizeHint" stdset="0">
-                <size>
-                 <width>40</width>
-                 <height>20</height>
-                </size>
-               </property>
-              </spacer>
-             </item>
-             <item row="0" column="2">
-              <widget class="QCheckBox" name="editor_checkbox_ac_document">
-               <property name="enabled">
-                <bool>false</bool>
-               </property>
-               <property name="text">
-                <string>Match words in document</string>
-               </property>
               </widget>
              </item>
-             <item row="1" column="3">
-              <spacer name="horizontalSpacer_19">
+             <item>
+              <widget class="Line" name="line_6">
                <property name="orientation">
                 <enum>Qt::Horizontal</enum>
                </property>
-               <property name="sizeHint" stdset="0">
-                <size>
-                 <width>40</width>
-                 <height>20</height>
-                </size>
-               </property>
-              </spacer>
+              </widget>
              </item>
             </layout>
            </item>
-           <item row="0" column="1">
-            <spacer name="horizontalSpacer_7">
+           <item>
+            <spacer name="verticalSpacer_3">
              <property name="orientation">
-              <enum>Qt::Horizontal</enum>
+              <enum>Qt::Vertical</enum>
              </property>
              <property name="sizeType">
-              <enum>QSizePolicy::Fixed</enum>
+              <enum>QSizePolicy::Expanding</enum>
              </property>
              <property name="sizeHint" stdset="0">
               <size>
-               <width>10</width>
-               <height>0</height>
+               <width>20</width>
+               <height>40</height>
               </size>
              </property>
             </spacer>
            </item>
           </layout>
-         </item>
-         <item>
-          <widget class="Line" name="line_3">
-           <property name="orientation">
-            <enum>Qt::Horizontal</enum>
-           </property>
-          </widget>
-         </item>
-         <item>
-          <layout class="QVBoxLayout" name="verticalLayout_11">
-           <property name="topMargin">
-            <number>0</number>
-           </property>
-           <property name="bottomMargin">
-            <number>0</number>
-           </property>
-           <item>
-            <widget class="QCheckBox" name="editor_restoreSession">
-             <property name="sizePolicy">
-              <sizepolicy hsizetype="Minimum" vsizetype="Fixed">
-               <horstretch>0</horstretch>
-               <verstretch>0</verstretch>
-              </sizepolicy>
-             </property>
-             <property name="text">
-              <string>Restore editor tabs from previous session on startup</string>
-             </property>
-            </widget>
-           </item>
-           <item>
-            <widget class="QCheckBox" name="editor_create_new file">
-             <property name="sizePolicy">
-              <sizepolicy hsizetype="Minimum" vsizetype="Fixed">
-               <horstretch>0</horstretch>
-               <verstretch>0</verstretch>
-              </sizepolicy>
-             </property>
-             <property name="text">
-              <string>Create nonexistent files without prompting</string>
-             </property>
-            </widget>
-           </item>
-          </layout>
-         </item>
-        </layout>
-       </item>
-       <item>
-        <widget class="Line" name="line_4">
-         <property name="orientation">
-          <enum>Qt::Horizontal</enum>
-         </property>
+         </widget>
         </widget>
        </item>
-       <item>
-        <spacer name="verticalSpacer">
-         <property name="orientation">
-          <enum>Qt::Vertical</enum>
-         </property>
-         <property name="sizeType">
-          <enum>QSizePolicy::Expanding</enum>
-         </property>
-         <property name="sizeHint" stdset="0">
-          <size>
-           <width>20</width>
-           <height>40</height>
-          </size>
-         </property>
-        </spacer>
-       </item>
-       <item>
-        <layout class="QVBoxLayout" name="verticalLayout_10">
-         <property name="topMargin">
-          <number>0</number>
-         </property>
-         <property name="bottomMargin">
-          <number>0</number>
-         </property>
-         <item>
-          <layout class="QHBoxLayout" name="horizontalLayout">
-           <item>
-            <widget class="QCheckBox" name="useCustomFileEditor">
-             <property name="enabled">
-              <bool>true</bool>
-             </property>
-             <property name="text">
-              <string>Use custom file editor</string>
-             </property>
-            </widget>
-           </item>
-           <item>
-            <widget class="QLabel" name="customEditorLabel">
-             <property name="enabled">
-              <bool>false</bool>
-             </property>
-             <property name="text">
-              <string>command line (%f=file, %l=line):</string>
-             </property>
-            </widget>
-           </item>
-           <item>
-            <widget class="QLineEdit" name="customFileEditor">
-             <property name="enabled">
-              <bool>false</bool>
-             </property>
-             <property name="text">
-              <string>emacs</string>
-             </property>
-            </widget>
-           </item>
-          </layout>
-         </item>
-        </layout>
-       </item>
       </layout>
      </widget>
-     <widget class="QWidget" name="tab_editor_styles">
-      <attribute name="title">
-       <string>Editor Styles</string>
-      </attribute>
-      <widget class="QWidget" name="verticalLayoutWidget_4">
-       <property name="geometry">
-        <rect>
-         <x>0</x>
-         <y>0</y>
-         <width>651</width>
-         <height>401</height>
-        </rect>
-       </property>
-       <layout class="QVBoxLayout" name="verticalLayout_5">
-        <item>
-         <widget class="QLabel" name="label_10">
-          <property name="maximumSize">
-           <size>
-            <width>676</width>
-            <height>16777215</height>
-           </size>
-          </property>
-          <property name="frameShape">
-           <enum>QFrame::NoFrame</enum>
-          </property>
-          <property name="text">
-           <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Select font, font size (as a difference from the default size), font style (&lt;b&gt;b&lt;/b&gt;old, &lt;b&gt;i&lt;/b&gt;talic, &lt;b&gt;u&lt;/b&gt;nderline), text color and background color (for the latter, the color pink (255,0,255) is a placeholder for the default background color).&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
-          </property>
-          <property name="scaledContents">
-           <bool>false</bool>
-          </property>
-          <property name="alignment">
-           <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
-          </property>
-          <property name="wordWrap">
-           <bool>true</bool>
-          </property>
-          <property name="margin">
-           <number>4</number>
-          </property>
-         </widget>
-        </item>
-        <item>
-         <widget class="QTabWidget" name="tabs_editor_lexers">
-          <property name="maximumSize">
-           <size>
-            <width>676</width>
-            <height>351</height>
-           </size>
-          </property>
-         </widget>
-        </item>
-       </layout>
-      </widget>
-     </widget>
-     <widget class="QWidget" name="tab_terminal">
-      <attribute name="title">
-       <string>Terminal</string>
-      </attribute>
-      <widget class="QWidget" name="horizontalLayoutWidget">
-       <property name="geometry">
-        <rect>
-         <x>10</x>
-         <y>50</y>
-         <width>631</width>
-         <height>31</height>
-        </rect>
-       </property>
-       <layout class="QHBoxLayout" name="horizontalLayout_3">
-        <item>
-         <widget class="QLabel" name="label">
-          <property name="text">
-           <string>Cursor type:</string>
-          </property>
-         </widget>
-        </item>
-        <item>
-         <widget class="QComboBox" name="terminal_cursorType"/>
-        </item>
-        <item>
-         <spacer name="horizontalSpacer">
-          <property name="orientation">
-           <enum>Qt::Horizontal</enum>
-          </property>
-          <property name="sizeHint" stdset="0">
-           <size>
-            <width>40</width>
-            <height>20</height>
-           </size>
-          </property>
-         </spacer>
-        </item>
-        <item>
-         <widget class="QCheckBox" name="terminal_cursorBlinking">
-          <property name="text">
-           <string>Cursor blinking</string>
-          </property>
-         </widget>
-        </item>
-        <item>
-         <widget class="QCheckBox" name="terminal_cursorUseForegroundColor">
-          <property name="text">
-           <string>Use foreground color</string>
-          </property>
-         </widget>
-        </item>
-       </layout>
-      </widget>
-      <widget class="QWidget" name="verticalLayoutWidget_3">
-       <property name="geometry">
-        <rect>
-         <x>10</x>
-         <y>90</y>
-         <width>631</width>
-         <height>291</height>
-        </rect>
-       </property>
-       <layout class="QVBoxLayout" name="verticalLayout_8">
-        <item>
-         <widget class="Line" name="line_6">
-          <property name="orientation">
-           <enum>Qt::Horizontal</enum>
-          </property>
-         </widget>
-        </item>
-        <item>
-         <widget class="QGroupBox" name="terminal_colors_box">
-          <property name="minimumSize">
-           <size>
-            <width>0</width>
-            <height>81</height>
-           </size>
-          </property>
-          <property name="title">
-           <string>Terminal Colors</string>
-          </property>
-         </widget>
-        </item>
-        <item>
-         <widget class="Line" name="line_5">
-          <property name="minimumSize">
-           <size>
-            <width>0</width>
-            <height>0</height>
-           </size>
-          </property>
-          <property name="orientation">
-           <enum>Qt::Horizontal</enum>
-          </property>
-         </widget>
-        </item>
-        <item>
-         <spacer name="verticalSpacer_3">
-          <property name="orientation">
-           <enum>Qt::Vertical</enum>
-          </property>
-          <property name="sizeHint" stdset="0">
-           <size>
-            <width>20</width>
-            <height>40</height>
-           </size>
-          </property>
-         </spacer>
-        </item>
-       </layout>
-      </widget>
-      <widget class="QWidget" name="layoutWidget">
-       <property name="geometry">
-        <rect>
-         <x>10</x>
-         <y>10</y>
-         <width>631</width>
-         <height>31</height>
-        </rect>
-       </property>
-       <layout class="QHBoxLayout" name="horizontalLayout_5">
-        <item>
-         <widget class="QLabel" name="label_11">
-          <property name="text">
-           <string>Font</string>
-          </property>
-         </widget>
-        </item>
-        <item>
-         <widget class="QFontComboBox" name="terminal_fontName">
-          <property name="editable">
-           <bool>false</bool>
-          </property>
-          <property name="fontFilters">
-           <set>QFontComboBox::MonospacedFonts</set>
-          </property>
-         </widget>
-        </item>
-        <item>
-         <widget class="QLabel" name="label_12">
-          <property name="text">
-           <string>Font size</string>
-          </property>
-         </widget>
-        </item>
-        <item>
-         <widget class="QSpinBox" name="terminal_fontSize">
-          <property name="minimum">
-           <number>2</number>
-          </property>
-          <property name="maximum">
-           <number>96</number>
-          </property>
-          <property name="value">
-           <number>10</number>
-          </property>
-         </widget>
-        </item>
-        <item>
-         <spacer name="horizontalSpacer_5">
-          <property name="orientation">
-           <enum>Qt::Horizontal</enum>
-          </property>
-          <property name="sizeHint" stdset="0">
-           <size>
-            <width>40</width>
-            <height>20</height>
-           </size>
-          </property>
-         </spacer>
-        </item>
-       </layout>
-      </widget>
-     </widget>
      <widget class="QWidget" name="tab_file_browser">
       <attribute name="title">
        <string>File Browser</string>
       </attribute>
       <layout class="QVBoxLayout" name="verticalLayout_3">
        <item>
-        <widget class="QCheckBox" name="showFileSize">
-         <property name="text">
-          <string>Show file size</string>
-         </property>
-        </widget>
-       </item>
-       <item>
-        <widget class="QCheckBox" name="showFileType">
-         <property name="text">
-          <string>Show file type</string>
+        <widget class="QScrollArea" name="scrollArea_4">
+         <property name="widgetResizable">
+          <bool>true</bool>
          </property>
-        </widget>
-       </item>
-       <item>
-        <widget class="QCheckBox" name="showLastModified">
-         <property name="text">
-          <string>Show date of last modification</string>
-         </property>
-        </widget>
-       </item>
-       <item>
-        <widget class="QCheckBox" name="showHiddenFiles">
-         <property name="text">
-          <string>Show hidden files</string>
-         </property>
+         <widget class="QWidget" name="scrollAreaWidgetContents_5">
+          <property name="geometry">
+           <rect>
+            <x>0</x>
+            <y>0</y>
+            <width>678</width>
+            <height>378</height>
+           </rect>
+          </property>
+          <layout class="QVBoxLayout" name="verticalLayout_18">
+           <item>
+            <widget class="QGroupBox" name="groupBox_3">
+             <property name="title">
+              <string>Display</string>
+             </property>
+             <layout class="QVBoxLayout" name="verticalLayout_23">
+              <item>
+               <layout class="QGridLayout" name="gridLayout_11">
+                <property name="topMargin">
+                 <number>0</number>
+                </property>
+                <item row="1" column="0">
+                 <widget class="QCheckBox" name="showFileType">
+                  <property name="text">
+                   <string>Show file type</string>
+                  </property>
+                 </widget>
+                </item>
+                <item row="3" column="0">
+                 <widget class="QCheckBox" name="showHiddenFiles">
+                  <property name="text">
+                   <string>Show hidden files</string>
+                  </property>
+                 </widget>
+                </item>
+                <item row="0" column="0">
+                 <widget class="QCheckBox" name="showFileSize">
+                  <property name="text">
+                   <string>Show file size</string>
+                  </property>
+                 </widget>
+                </item>
+                <item row="2" column="0">
+                 <widget class="QCheckBox" name="showLastModified">
+                  <property name="text">
+                   <string>Show date of last modification</string>
+                  </property>
+                 </widget>
+                </item>
+                <item row="4" column="0">
+                 <widget class="QCheckBox" name="useAlternatingRowColors">
+                  <property name="text">
+                   <string>Alternating row colors</string>
+                  </property>
+                 </widget>
+                </item>
+               </layout>
+              </item>
+             </layout>
+            </widget>
+           </item>
+           <item>
+            <widget class="QGroupBox" name="groupBox_4">
+             <property name="title">
+              <string>Behavior</string>
+             </property>
+             <layout class="QVBoxLayout" name="verticalLayout_24">
+              <item>
+               <layout class="QGridLayout" name="gridLayout_8">
+                <item row="4" column="0">
+                 <widget class="QCheckBox" name="sync_octave_directory">
+                  <property name="text">
+                   <string>Synchronize Octave working directory with file browser</string>
+                  </property>
+                 </widget>
+                </item>
+                <item row="5" column="0">
+                 <layout class="QGridLayout" name="lo_file_browser_startup">
+                  <item row="0" column="0">
+                   <widget class="QLabel" name="lbl_file_browser_dir">
+                    <property name="text">
+                     <string>Startup path</string>
+                    </property>
+                   </widget>
+                  </item>
+                  <item row="1" column="1">
+                   <widget class="QLineEdit" name="le_file_browser_dir"/>
+                  </item>
+                  <item row="0" column="1">
+                   <widget class="QCheckBox" name="cb_restore_file_browser_dir">
+                    <property name="text">
+                     <string>Restore last directory of previous session</string>
+                    </property>
+                   </widget>
+                  </item>
+                  <item row="1" column="2">
+                   <widget class="QPushButton" name="pb_file_browser_dir">
+                    <property name="text">
+                     <string>Browse</string>
+                    </property>
+                   </widget>
+                  </item>
+                  <item row="0" column="3">
+                   <spacer name="horizontalSpacer_29">
+                    <property name="orientation">
+                     <enum>Qt::Horizontal</enum>
+                    </property>
+                    <property name="sizeHint" stdset="0">
+                     <size>
+                      <width>40</width>
+                      <height>20</height>
+                     </size>
+                    </property>
+                   </spacer>
+                  </item>
+                  <item row="1" column="3">
+                   <spacer name="horizontalSpacer_30">
+                    <property name="orientation">
+                     <enum>Qt::Horizontal</enum>
+                    </property>
+                    <property name="sizeHint" stdset="0">
+                     <size>
+                      <width>40</width>
+                      <height>20</height>
+                     </size>
+                    </property>
+                   </spacer>
+                  </item>
+                 </layout>
+                </item>
+               </layout>
+              </item>
+             </layout>
+            </widget>
+           </item>
+           <item>
+            <spacer name="verticalSpacer_2">
+             <property name="orientation">
+              <enum>Qt::Vertical</enum>
+             </property>
+             <property name="sizeHint" stdset="0">
+              <size>
+               <width>20</width>
+               <height>360</height>
+              </size>
+             </property>
+            </spacer>
+           </item>
+          </layout>
+         </widget>
         </widget>
        </item>
-       <item>
-        <widget class="QCheckBox" name="sync_octave_directory">
-         <property name="text">
-          <string>Synchronize Octave working directory with file browser</string>
-         </property>
-        </widget>
-       </item>
-       <item>
-        <widget class="QCheckBox" name="useAlternatingRowColors">
-         <property name="text">
-          <string>Alternating row colors</string>
-         </property>
-        </widget>
-       </item>
-       <item>
-        <spacer name="verticalSpacer_2">
-         <property name="orientation">
-          <enum>Qt::Vertical</enum>
-         </property>
-         <property name="sizeHint" stdset="0">
-          <size>
-           <width>20</width>
-           <height>360</height>
-          </size>
-         </property>
-        </spacer>
-       </item>
       </layout>
      </widget>
      <widget class="QWidget" name="tab_workspace">
       <attribute name="title">
        <string>Workspace</string>
       </attribute>
-      <widget class="QWidget" name="verticalLayoutWidget_6">
-       <property name="geometry">
-        <rect>
-         <x>10</x>
-         <y>8</y>
-         <width>631</width>
-         <height>381</height>
-        </rect>
-       </property>
-       <layout class="QVBoxLayout" name="verticalLayout_13">
-        <item>
-         <widget class="QGroupBox" name="workspace_colors_box">
-          <property name="enabled">
-           <bool>true</bool>
+      <layout class="QVBoxLayout" name="verticalLayout_15">
+       <item>
+        <widget class="QScrollArea" name="scrollArea_5">
+         <property name="widgetResizable">
+          <bool>true</bool>
+         </property>
+         <widget class="QWidget" name="scrollAreaWidgetContents_6">
+          <property name="geometry">
+           <rect>
+            <x>0</x>
+            <y>0</y>
+            <width>678</width>
+            <height>378</height>
+           </rect>
           </property>
-          <property name="sizePolicy">
-           <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
-            <horstretch>0</horstretch>
-            <verstretch>0</verstretch>
-           </sizepolicy>
-          </property>
-          <property name="minimumSize">
-           <size>
-            <width>0</width>
-            <height>81</height>
-           </size>
-          </property>
-          <property name="title">
-           <string>Storage Class Colors</string>
+          <layout class="QVBoxLayout" name="verticalLayout_19">
+           <item>
+            <layout class="QGridLayout" name="gridLayout_14">
+             <property name="topMargin">
+              <number>0</number>
+             </property>
+             <item row="0" column="0">
+              <widget class="QGroupBox" name="workspace_colors_box">
+               <property name="enabled">
+                <bool>true</bool>
+               </property>
+               <property name="sizePolicy">
+                <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
+                 <horstretch>0</horstretch>
+                 <verstretch>0</verstretch>
+                </sizepolicy>
+               </property>
+               <property name="minimumSize">
+                <size>
+                 <width>0</width>
+                 <height>81</height>
+                </size>
+               </property>
+               <property name="title">
+                <string>Colors for variable attributes </string>
+               </property>
+              </widget>
+             </item>
+             <item row="1" column="0">
+              <widget class="QCheckBox" name="cb_hide_tool_tips">
+               <property name="text">
+                <string>Hide tool tip</string>
+               </property>
+              </widget>
+             </item>
+            </layout>
+           </item>
+           <item>
+            <spacer name="verticalSpacer_6">
+             <property name="orientation">
+              <enum>Qt::Vertical</enum>
+             </property>
+             <property name="sizeHint" stdset="0">
+              <size>
+               <width>20</width>
+               <height>40</height>
+              </size>
+             </property>
+            </spacer>
+           </item>
+          </layout>
+         </widget>
+        </widget>
+       </item>
+      </layout>
+     </widget>
+     <widget class="QWidget" name="tab_shortcuts">
+      <attribute name="title">
+       <string>Shortcuts</string>
+      </attribute>
+      <layout class="QVBoxLayout" name="verticalLayout_27">
+       <item>
+        <widget class="QScrollArea" name="scrollArea_7">
+         <property name="widgetResizable">
+          <bool>true</bool>
+         </property>
+         <widget class="QWidget" name="scrollAreaWidgetContents_8">
+          <property name="geometry">
+           <rect>
+            <x>0</x>
+            <y>0</y>
+            <width>678</width>
+            <height>378</height>
+           </rect>
           </property>
-         </widget>
-        </item>
-        <item>
-         <widget class="Line" name="line_8">
-          <property name="minimumSize">
-           <size>
-            <width>0</width>
-            <height>1</height>
-           </size>
-          </property>
-          <property name="orientation">
-           <enum>Qt::Horizontal</enum>
-          </property>
+          <layout class="QVBoxLayout" name="verticalLayout_25">
+           <item>
+            <layout class="QVBoxLayout" name="verticalLayout_26">
+             <property name="sizeConstraint">
+              <enum>QLayout::SetDefaultConstraint</enum>
+             </property>
+             <property name="topMargin">
+              <number>0</number>
+             </property>
+             <item>
+              <layout class="QHBoxLayout" name="horizontalLayout_15">
+               <item>
+                <widget class="QCheckBox" name="cb_prevent_readline_conflicts">
+                 <property name="toolTip">
+                  <string>Select this option to prevent conflicts with readline shortcuts</string>
+                 </property>
+                 <property name="text">
+                  <string>Disable global shortcuts when terminal window has focus</string>
+                 </property>
+                 <property name="checked">
+                  <bool>true</bool>
+                 </property>
+                </widget>
+               </item>
+              </layout>
+             </item>
+             <item>
+              <widget class="Line" name="line_9">
+               <property name="orientation">
+                <enum>Qt::Horizontal</enum>
+               </property>
+              </widget>
+             </item>
+             <item>
+              <layout class="QGridLayout" name="gridLayout_12">
+               <property name="topMargin">
+                <number>10</number>
+               </property>
+               <item row="3" column="0">
+                <layout class="QHBoxLayout" name="horizontalLayout_16">
+                 <property name="topMargin">
+                  <number>0</number>
+                 </property>
+                </layout>
+               </item>
+               <item row="1" column="2">
+                <widget class="QRadioButton" name="rb_sc_set2">
+                 <property name="text">
+                  <string>Use this set</string>
+                 </property>
+                </widget>
+               </item>
+               <item row="0" column="0">
+                <widget class="QLabel" name="label_23">
+                 <property name="text">
+                  <string>Set 1:</string>
+                 </property>
+                </widget>
+               </item>
+               <item row="1" column="4">
+                <widget class="QPushButton" name="btn_export_shortcut_set2">
+                 <property name="text">
+                  <string>Export</string>
+                 </property>
+                </widget>
+               </item>
+               <item row="1" column="3">
+                <widget class="QPushButton" name="btn_import_shortcut_set2">
+                 <property name="text">
+                  <string>Import</string>
+                 </property>
+                </widget>
+               </item>
+               <item row="0" column="2">
+                <widget class="QRadioButton" name="rb_sc_set1">
+                 <property name="text">
+                  <string>Use this set</string>
+                 </property>
+                 <property name="checked">
+                  <bool>true</bool>
+                 </property>
+                </widget>
+               </item>
+               <item row="0" column="5">
+                <spacer name="horizontalSpacer_26">
+                 <property name="orientation">
+                  <enum>Qt::Horizontal</enum>
+                 </property>
+                 <property name="sizeHint" stdset="0">
+                  <size>
+                   <width>40</width>
+                   <height>20</height>
+                  </size>
+                 </property>
+                </spacer>
+               </item>
+               <item row="0" column="4">
+                <widget class="QPushButton" name="btn_export_shortcut_set1">
+                 <property name="text">
+                  <string>Export</string>
+                 </property>
+                </widget>
+               </item>
+               <item row="0" column="3">
+                <widget class="QPushButton" name="btn_import_shortcut_set1">
+                 <property name="text">
+                  <string>Import</string>
+                 </property>
+                </widget>
+               </item>
+               <item row="1" column="0">
+                <widget class="QLabel" name="label_24">
+                 <property name="text">
+                  <string>Set 2:</string>
+                 </property>
+                </widget>
+               </item>
+               <item row="0" column="1">
+                <spacer name="horizontalSpacer_33">
+                 <property name="orientation">
+                  <enum>Qt::Horizontal</enum>
+                 </property>
+                 <property name="sizeType">
+                  <enum>QSizePolicy::Fixed</enum>
+                 </property>
+                 <property name="sizeHint" stdset="0">
+                  <size>
+                   <width>20</width>
+                   <height>20</height>
+                  </size>
+                 </property>
+                </spacer>
+               </item>
+              </layout>
+             </item>
+             <item>
+              <widget class="QLabel" name="label_21">
+               <property name="text">
+                <string>Edit an actual shortcut by double clicking into the related cell</string>
+               </property>
+              </widget>
+             </item>
+             <item>
+              <layout class="QHBoxLayout" name="horizontalLayout_10">
+               <property name="topMargin">
+                <number>0</number>
+               </property>
+               <item>
+                <widget class="QTreeWidget" name="shortcuts_treewidget">
+                 <property name="sizePolicy">
+                  <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
+                   <horstretch>0</horstretch>
+                   <verstretch>0</verstretch>
+                  </sizepolicy>
+                 </property>
+                 <property name="sizeIncrement">
+                  <size>
+                   <width>0</width>
+                   <height>0</height>
+                  </size>
+                 </property>
+                 <property name="baseSize">
+                  <size>
+                   <width>0</width>
+                   <height>0</height>
+                  </size>
+                 </property>
+                 <property name="alternatingRowColors">
+                  <bool>true</bool>
+                 </property>
+                 <property name="animated">
+                  <bool>false</bool>
+                 </property>
+                 <property name="allColumnsShowFocus">
+                  <bool>false</bool>
+                 </property>
+                 <property name="headerHidden">
+                  <bool>false</bool>
+                 </property>
+                 <property name="columnCount">
+                  <number>5</number>
+                 </property>
+                 <attribute name="headerCascadingSectionResizes">
+                  <bool>false</bool>
+                 </attribute>
+                 <attribute name="headerDefaultSectionSize">
+                  <number>120</number>
+                 </attribute>
+                 <attribute name="headerHighlightSections">
+                  <bool>false</bool>
+                 </attribute>
+                 <attribute name="headerMinimumSectionSize">
+                  <number>64</number>
+                 </attribute>
+                 <attribute name="headerStretchLastSection">
+                  <bool>true</bool>
+                 </attribute>
+                 <column>
+                  <property name="text">
+                   <string>Action</string>
+                  </property>
+                  <property name="font">
+                   <font>
+                    <italic>false</italic>
+                   </font>
+                  </property>
+                 </column>
+                 <column>
+                  <property name="text">
+                   <string>Set 1 Default</string>
+                  </property>
+                 </column>
+                 <column>
+                  <property name="text">
+                   <string>Set 1 Actual</string>
+                  </property>
+                 </column>
+                 <column>
+                  <property name="text">
+                   <string>Set 2 Default</string>
+                  </property>
+                  <property name="font">
+                   <font>
+                    <italic>false</italic>
+                   </font>
+                  </property>
+                 </column>
+                 <column>
+                  <property name="text">
+                   <string>Set 2 Actual</string>
+                  </property>
+                 </column>
+                </widget>
+               </item>
+              </layout>
+             </item>
+            </layout>
+           </item>
+          </layout>
          </widget>
-        </item>
-        <item>
-         <spacer name="verticalSpacer_6">
-          <property name="orientation">
-           <enum>Qt::Vertical</enum>
-          </property>
-          <property name="sizeHint" stdset="0">
-           <size>
-            <width>20</width>
-            <height>40</height>
-           </size>
-          </property>
-         </spacer>
-        </item>
-       </layout>
-      </widget>
+        </widget>
+       </item>
+      </layout>
      </widget>
      <widget class="QWidget" name="tab_network">
       <attribute name="title">
@@ -1158,146 +2117,165 @@
       </attribute>
       <layout class="QVBoxLayout" name="verticalLayout_4">
        <item>
-        <layout class="QVBoxLayout" name="verticalLayout">
-         <item>
-          <widget class="QCheckBox" name="checkbox_allow_web_connect">
-           <property name="text">
-            <string>Allow Octave to connect to the Octave web site to display current news and information</string>
-           </property>
-          </widget>
-         </item>
-         <item>
-          <layout class="QGridLayout" name="gridLayout_5">
-           <item row="1" column="1">
-            <widget class="QLabel" name="label_4">
-             <property name="enabled">
-              <bool>false</bool>
-             </property>
-             <property name="text">
-              <string>Hostname:</string>
-             </property>
-            </widget>
-           </item>
-           <item row="0" column="2">
-            <widget class="QComboBox" name="proxyType">
-             <property name="enabled">
-              <bool>false</bool>
-             </property>
+        <widget class="QScrollArea" name="scrollArea_6">
+         <property name="widgetResizable">
+          <bool>true</bool>
+         </property>
+         <widget class="QWidget" name="scrollAreaWidgetContents_7">
+          <property name="geometry">
+           <rect>
+            <x>0</x>
+            <y>0</y>
+            <width>678</width>
+            <height>378</height>
+           </rect>
+          </property>
+          <layout class="QVBoxLayout" name="verticalLayout_20">
+           <item>
+            <layout class="QVBoxLayout" name="verticalLayout">
              <item>
-              <property name="text">
-               <string>HttpProxy</string>
-              </property>
+              <widget class="QCheckBox" name="checkbox_allow_web_connect">
+               <property name="text">
+                <string>Allow Octave to connect to the Octave web site to display current news and information</string>
+               </property>
+              </widget>
              </item>
              <item>
-              <property name="text">
-               <string>Socks5Proxy</string>
-              </property>
+              <layout class="QGridLayout" name="gridLayout_5">
+               <item row="1" column="1">
+                <widget class="QLabel" name="label_4">
+                 <property name="enabled">
+                  <bool>false</bool>
+                 </property>
+                 <property name="text">
+                  <string>Hostname:</string>
+                 </property>
+                </widget>
+               </item>
+               <item row="0" column="2">
+                <widget class="QComboBox" name="proxyType">
+                 <property name="enabled">
+                  <bool>false</bool>
+                 </property>
+                 <item>
+                  <property name="text">
+                   <string>HttpProxy</string>
+                  </property>
+                 </item>
+                 <item>
+                  <property name="text">
+                   <string>Socks5Proxy</string>
+                  </property>
+                 </item>
+                </widget>
+               </item>
+               <item row="3" column="1">
+                <widget class="QLabel" name="label_6">
+                 <property name="enabled">
+                  <bool>false</bool>
+                 </property>
+                 <property name="text">
+                  <string>Username:</string>
+                 </property>
+                </widget>
+               </item>
+               <item row="0" column="0">
+                <widget class="QCheckBox" name="useProxyServer">
+                 <property name="text">
+                  <string>Use proxy server</string>
+                 </property>
+                </widget>
+               </item>
+               <item row="0" column="1">
+                <widget class="QLabel" name="label_3">
+                 <property name="enabled">
+                  <bool>false</bool>
+                 </property>
+                 <property name="text">
+                  <string>Proxy type:</string>
+                 </property>
+                </widget>
+               </item>
+               <item row="2" column="1">
+                <widget class="QLabel" name="label_5">
+                 <property name="enabled">
+                  <bool>false</bool>
+                 </property>
+                 <property name="text">
+                  <string>Port:</string>
+                 </property>
+                </widget>
+               </item>
+               <item row="4" column="1">
+                <widget class="QLabel" name="label_7">
+                 <property name="enabled">
+                  <bool>false</bool>
+                 </property>
+                 <property name="text">
+                  <string>Password:</string>
+                 </property>
+                </widget>
+               </item>
+               <item row="1" column="2">
+                <widget class="QLineEdit" name="proxyHostName">
+                 <property name="enabled">
+                  <bool>false</bool>
+                 </property>
+                </widget>
+               </item>
+               <item row="2" column="2">
+                <widget class="QLineEdit" name="proxyPort">
+                 <property name="enabled">
+                  <bool>false</bool>
+                 </property>
+                </widget>
+               </item>
+               <item row="3" column="2">
+                <widget class="QLineEdit" name="proxyUserName">
+                 <property name="enabled">
+                  <bool>false</bool>
+                 </property>
+                </widget>
+               </item>
+               <item row="4" column="2">
+                <widget class="QLineEdit" name="proxyPassword">
+                 <property name="enabled">
+                  <bool>false</bool>
+                 </property>
+                 <property name="echoMode">
+                  <enum>QLineEdit::Password</enum>
+                 </property>
+                </widget>
+               </item>
+              </layout>
              </item>
-            </widget>
-           </item>
-           <item row="3" column="1">
-            <widget class="QLabel" name="label_6">
-             <property name="enabled">
-              <bool>false</bool>
-             </property>
-             <property name="text">
-              <string>Username:</string>
-             </property>
-            </widget>
+            </layout>
            </item>
-           <item row="0" column="0">
-            <widget class="QCheckBox" name="useProxyServer">
-             <property name="text">
-              <string>Use proxy server</string>
-             </property>
-            </widget>
-           </item>
-           <item row="0" column="1">
-            <widget class="QLabel" name="label_3">
-             <property name="enabled">
-              <bool>false</bool>
-             </property>
-             <property name="text">
-              <string>Proxy type:</string>
-             </property>
-            </widget>
-           </item>
-           <item row="2" column="1">
-            <widget class="QLabel" name="label_5">
-             <property name="enabled">
-              <bool>false</bool>
-             </property>
-             <property name="text">
-              <string>Port:</string>
+           <item>
+            <spacer name="verticalSpacer_5">
+             <property name="orientation">
+              <enum>Qt::Vertical</enum>
              </property>
-            </widget>
-           </item>
-           <item row="4" column="1">
-            <widget class="QLabel" name="label_7">
-             <property name="enabled">
-              <bool>false</bool>
-             </property>
-             <property name="text">
-              <string>Password:</string>
-             </property>
-            </widget>
-           </item>
-           <item row="1" column="2">
-            <widget class="QLineEdit" name="proxyHostName">
-             <property name="enabled">
-              <bool>false</bool>
+             <property name="sizeHint" stdset="0">
+              <size>
+               <width>20</width>
+               <height>40</height>
+              </size>
              </property>
-            </widget>
-           </item>
-           <item row="2" column="2">
-            <widget class="QLineEdit" name="proxyPort">
-             <property name="enabled">
-              <bool>false</bool>
-             </property>
-            </widget>
-           </item>
-           <item row="3" column="2">
-            <widget class="QLineEdit" name="proxyUserName">
-             <property name="enabled">
-              <bool>false</bool>
-             </property>
-            </widget>
-           </item>
-           <item row="4" column="2">
-            <widget class="QLineEdit" name="proxyPassword">
-             <property name="enabled">
-              <bool>false</bool>
-             </property>
-             <property name="echoMode">
-              <enum>QLineEdit::Password</enum>
-             </property>
-            </widget>
+            </spacer>
            </item>
           </layout>
-         </item>
-        </layout>
-       </item>
-       <item>
-        <spacer name="verticalSpacer_5">
-         <property name="orientation">
-          <enum>Qt::Vertical</enum>
-         </property>
-         <property name="sizeHint" stdset="0">
-          <size>
-           <width>20</width>
-           <height>40</height>
-          </size>
-         </property>
-        </spacer>
+         </widget>
+        </widget>
        </item>
       </layout>
      </widget>
     </widget>
    </item>
    <item>
-    <widget class="QDialogButtonBox" name="buttonBox">
+    <widget class="QDialogButtonBox" name="button_box">
      <property name="standardButtons">
-      <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
+      <set>QDialogButtonBox::Apply|QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
      </property>
     </widget>
    </item>
@@ -1482,38 +2460,6 @@
    </hints>
   </connection>
   <connection>
-   <sender>buttonBox</sender>
-   <signal>accepted()</signal>
-   <receiver>settings_dialog</receiver>
-   <slot>accept()</slot>
-   <hints>
-    <hint type="sourcelabel">
-     <x>299</x>
-     <y>366</y>
-    </hint>
-    <hint type="destinationlabel">
-     <x>299</x>
-     <y>199</y>
-    </hint>
-   </hints>
-  </connection>
-  <connection>
-   <sender>buttonBox</sender>
-   <signal>rejected()</signal>
-   <receiver>settings_dialog</receiver>
-   <slot>reject()</slot>
-   <hints>
-    <hint type="sourcelabel">
-     <x>299</x>
-     <y>366</y>
-    </hint>
-    <hint type="destinationlabel">
-     <x>299</x>
-     <y>199</y>
-    </hint>
-   </hints>
-  </connection>
-  <connection>
    <sender>useCustomFileEditor</sender>
    <signal>toggled(bool)</signal>
    <receiver>customEditorLabel</receiver>
@@ -1562,54 +2508,6 @@
    </hints>
   </connection>
   <connection>
-   <sender>editor_codeCompletion</sender>
-   <signal>toggled(bool)</signal>
-   <receiver>editor_checkbox_ac_keywords</receiver>
-   <slot>setEnabled(bool)</slot>
-   <hints>
-    <hint type="sourcelabel">
-     <x>83</x>
-     <y>170</y>
-    </hint>
-    <hint type="destinationlabel">
-     <x>238</x>
-     <y>201</y>
-    </hint>
-   </hints>
-  </connection>
-  <connection>
-   <sender>editor_codeCompletion</sender>
-   <signal>toggled(bool)</signal>
-   <receiver>editor_checkbox_ac_document</receiver>
-   <slot>setEnabled(bool)</slot>
-   <hints>
-    <hint type="sourcelabel">
-     <x>83</x>
-     <y>170</y>
-    </hint>
-    <hint type="destinationlabel">
-     <x>390</x>
-     <y>201</y>
-    </hint>
-   </hints>
-  </connection>
-  <connection>
-   <sender>editor_codeCompletion</sender>
-   <signal>toggled(bool)</signal>
-   <receiver>editor_checkbox_ac_replace</receiver>
-   <slot>setEnabled(bool)</slot>
-   <hints>
-    <hint type="sourcelabel">
-     <x>83</x>
-     <y>170</y>
-    </hint>
-    <hint type="destinationlabel">
-     <x>427</x>
-     <y>229</y>
-    </hint>
-   </hints>
-  </connection>
-  <connection>
    <sender>editor_highlightCurrentLine</sender>
    <signal>toggled(bool)</signal>
    <receiver>editor_label_cl_color</receiver>
@@ -1626,22 +2524,6 @@
    </hints>
   </connection>
   <connection>
-   <sender>editor_codeCompletion</sender>
-   <signal>toggled(bool)</signal>
-   <receiver>editor_checkbox_ac_case</receiver>
-   <slot>setEnabled(bool)</slot>
-   <hints>
-    <hint type="sourcelabel">
-     <x>83</x>
-     <y>172</y>
-    </hint>
-    <hint type="destinationlabel">
-     <x>525</x>
-     <y>203</y>
-    </hint>
-   </hints>
-  </connection>
-  <connection>
    <sender>editor_ws_checkbox</sender>
    <signal>toggled(bool)</signal>
    <receiver>editor_ws_indent_checkbox</receiver>
@@ -1657,5 +2539,261 @@
     </hint>
    </hints>
   </connection>
+  <connection>
+   <sender>cb_widget_custom_style</sender>
+   <signal>toggled(bool)</signal>
+   <receiver>label_bgtitle</receiver>
+   <slot>setEnabled(bool)</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>228</x>
+     <y>156</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>380</x>
+     <y>156</y>
+    </hint>
+   </hints>
+  </connection>
+  <connection>
+   <sender>cb_widget_custom_style</sender>
+   <signal>toggled(bool)</signal>
+   <receiver>label_fgtitle</receiver>
+   <slot>setEnabled(bool)</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>228</x>
+     <y>156</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>496</x>
+     <y>156</y>
+    </hint>
+   </hints>
+  </connection>
+  <connection>
+   <sender>cb_restore_octave_dir</sender>
+   <signal>toggled(bool)</signal>
+   <receiver>le_octave_dir</receiver>
+   <slot>setDisabled(bool)</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>270</x>
+     <y>255</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>270</x>
+     <y>285</y>
+    </hint>
+   </hints>
+  </connection>
+  <connection>
+   <sender>cb_restore_octave_dir</sender>
+   <signal>toggled(bool)</signal>
+   <receiver>pb_octave_dir</receiver>
+   <slot>setDisabled(bool)</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>270</x>
+     <y>255</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>467</x>
+     <y>285</y>
+    </hint>
+   </hints>
+  </connection>
+  <connection>
+   <sender>cb_restore_file_browser_dir</sender>
+   <signal>toggled(bool)</signal>
+   <receiver>le_file_browser_dir</receiver>
+   <slot>setDisabled(bool)</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>250</x>
+     <y>294</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>250</x>
+     <y>324</y>
+    </hint>
+   </hints>
+  </connection>
+  <connection>
+   <sender>cb_restore_file_browser_dir</sender>
+   <signal>toggled(bool)</signal>
+   <receiver>pb_file_browser_dir</receiver>
+   <slot>setDisabled(bool)</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>250</x>
+     <y>294</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>426</x>
+     <y>324</y>
+    </hint>
+   </hints>
+  </connection>
+  <connection>
+   <sender>editor_longWindowTitle</sender>
+   <signal>toggled(bool)</signal>
+   <receiver>editor_lbl_min_tab_width</receiver>
+   <slot>setEnabled(bool)</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>145</x>
+     <y>72</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>343</x>
+     <y>72</y>
+    </hint>
+   </hints>
+  </connection>
+  <connection>
+   <sender>editor_longWindowTitle</sender>
+   <signal>toggled(bool)</signal>
+   <receiver>editor_notebook_tab_width_max</receiver>
+   <slot>setEnabled(bool)</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>145</x>
+     <y>72</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>437</x>
+     <y>72</y>
+    </hint>
+   </hints>
+  </connection>
+  <connection>
+   <sender>editor_longWindowTitle</sender>
+   <signal>toggled(bool)</signal>
+   <receiver>editor_lbl_max_tab_width</receiver>
+   <slot>setEnabled(bool)</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>145</x>
+     <y>72</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>439</x>
+     <y>72</y>
+    </hint>
+   </hints>
+  </connection>
+  <connection>
+   <sender>editor_longWindowTitle</sender>
+   <signal>toggled(bool)</signal>
+   <receiver>editor_notebook_tab_width_min</receiver>
+   <slot>setEnabled(bool)</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>145</x>
+     <y>72</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>393</x>
+     <y>72</y>
+    </hint>
+   </hints>
+  </connection>
+  <connection>
+   <sender>editor_long_line_marker</sender>
+   <signal>toggled(bool)</signal>
+   <receiver>editor_long_line_column</receiver>
+   <slot>setEnabled(bool)</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>145</x>
+     <y>187</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>355</x>
+     <y>187</y>
+    </hint>
+   </hints>
+  </connection>
+  <connection>
+   <sender>editor_long_line_marker</sender>
+   <signal>toggled(bool)</signal>
+   <receiver>editor_long_line_column_text</receiver>
+   <slot>setEnabled(bool)</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>145</x>
+     <y>187</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>302</x>
+     <y>187</y>
+    </hint>
+   </hints>
+  </connection>
+  <connection>
+   <sender>editor_checkbox_ac_keywords</sender>
+   <signal>toggled(bool)</signal>
+   <receiver>editor_checkbox_ac_builtins</receiver>
+   <slot>setEnabled(bool)</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>118</x>
+     <y>231</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>296</x>
+     <y>231</y>
+    </hint>
+   </hints>
+  </connection>
+  <connection>
+   <sender>editor_checkbox_ac_keywords</sender>
+   <signal>toggled(bool)</signal>
+   <receiver>editor_checkbox_ac_functions</receiver>
+   <slot>setEnabled(bool)</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>118</x>
+     <y>231</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>446</x>
+     <y>231</y>
+    </hint>
+   </hints>
+  </connection>
+  <connection>
+   <sender>cb_widget_custom_style</sender>
+   <signal>toggled(bool)</signal>
+   <receiver>label_bgtitle_active</receiver>
+   <slot>setEnabled(bool)</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>260</x>
+     <y>190</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>525</x>
+     <y>190</y>
+    </hint>
+   </hints>
+  </connection>
+  <connection>
+   <sender>cb_widget_custom_style</sender>
+   <signal>toggled(bool)</signal>
+   <receiver>label_fgtitle_active</receiver>
+   <slot>setEnabled(bool)</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>260</x>
+     <y>190</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>533</x>
+     <y>214</y>
+    </hint>
+   </hints>
+  </connection>
  </connections>
 </ui>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libgui/src/shortcut-manager.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,728 @@
+/*
+
+Copyright (C) 2014 Torsten <ttl@justmail.de>
+
+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 <QtCore>
+#include <QMessageBox>
+#include <QDebug>
+#include <QGridLayout>
+#include <QVBoxLayout>
+#include <QDialogButtonBox>
+#include <QPushButton>
+#include <QLineEdit>
+#include <QCheckBox>
+#include <QHeaderView>
+#include <QAction>
+#include <QFileDialog>
+
+#include "error.h"
+#include "resource-manager.h"
+#include "shortcut-manager.h"
+#include "singleton-cleanup.h"
+
+shortcut_manager *shortcut_manager::instance = 0;
+
+shortcut_manager::shortcut_manager ()
+{
+  setObjectName ("Shortcut_Manager");
+
+  // Mac: don't let Qt interpret CMD key ("Meta" in Qt terminology) as Ctrl
+#if defined (Q_OS_MAC)
+  QCoreApplication::setAttribute (Qt::AA_MacDontSwapCtrlAndMeta, true);
+#endif
+
+  _settings = resource_manager::get_settings ();
+}
+
+shortcut_manager::~shortcut_manager ()
+{
+}
+
+bool
+shortcut_manager::instance_ok (void)
+{
+  bool retval = true;
+
+  if (! instance)
+    {
+      instance = new shortcut_manager ();
+
+      if (instance)
+        singleton_cleanup_list::add (cleanup_instance);
+    }
+
+  if (! instance)
+    {
+      ::error ("unable to create shortcut_manager object!");
+
+      retval = false;
+    }
+
+  return retval;
+}
+
+void
+shortcut_manager::do_init_data ()
+{
+  QKeySequence ctrl;
+  int prefix;
+#if defined (Q_OS_MAC)
+  // Use CMD key as an equivalent of Ctrl key on other platforms
+  ctrl =  Qt::MetaModifier;
+  // Some of octave default shortcuts on windows/linux are already defined
+  // as system wide shortcuts on Mac Os X (almost all Function keys).
+  // Prefix those with Option (Alt) modifier to avoid conflicts.
+  prefix = Qt::AltModifier;
+#else
+  ctrl = Qt::ControlModifier;
+  prefix = Qt::NoModifier;
+#endif
+
+  QKeySequence ctrl_shift = ctrl + Qt::ShiftModifier;
+  QKeySequence ctrl_alt = ctrl + Qt::AltModifier;
+
+  // actions of the main window
+
+  // file
+  init (tr ("New File"), "main_file:new_file", QKeySequence::New);
+  init (tr ("New Function"), "main_file:new_function",
+        QKeySequence (ctrl_shift + Qt::Key_N));
+  init (tr ("New Figure"), "main_file:new_figure", QKeySequence ());
+  init (tr ("Open File"), "main_file:open_file", QKeySequence::Open);
+  init (tr ("Load Workspace"), "main_file:load_workspace", QKeySequence ());
+  init (tr ("Save Workspace As"), "main_file:save_workspace", QKeySequence ());
+  init (tr ("Preferences"), "main_file:preferences", QKeySequence ());
+  init (tr ("Exit Octave"), "main_file:exit", QKeySequence::Quit);
+
+  // edit
+  init (tr ("Copy"), "main_edit:copy", QKeySequence::Copy);
+  init (tr ("Paste"), "main_edit:paste", QKeySequence::Paste);
+  init (tr ("Undo"), "main_edit:undo", QKeySequence::Undo);
+  init (tr ("Select All"), "main_edit:select_all", QKeySequence ());
+  init (tr ("Clear Clipboard"), "main_edit:clear_clipboard", QKeySequence ());
+  init (tr ("Find in Files"), "main_edit:find_in_files",
+        QKeySequence (ctrl_shift + Qt::Key_F));
+  init (tr ("Clear Command Window"), "main_edit:clear_command_window",
+        QKeySequence ());
+  init (tr ("Clear Command History"), "main_edit:clear_history",
+        QKeySequence ());
+  init (tr ("Clear Workspace"), "main_edit:clear_workspace", QKeySequence ());
+
+  // debug
+  init (tr ("Step Over"), "main_debug:step_over",
+        QKeySequence (prefix + Qt::Key_F10));
+  init (tr ("Step Into"), "main_debug:step_into",
+        QKeySequence (prefix + Qt::Key_F11));
+  init (tr ("Step Out"), "main_debug:step_out",
+        QKeySequence (prefix + Qt::ShiftModifier + Qt::Key_F11));
+  init (tr ("Continue"), "main_debug:continue",
+        QKeySequence (prefix + Qt::Key_F5));
+  init (tr ("Quit Debug Mode"), "main_debug:quit",
+        QKeySequence (prefix + Qt::ShiftModifier + Qt::Key_F5));
+
+  // window
+  init (tr ("Show Command Window"), "main_window:show_command",
+        prefix + ctrl_shift + Qt::Key_0);
+  init (tr ("Show Command History"), "main_window:show_history",
+        prefix + ctrl_shift + Qt::Key_1);
+  init (tr ("Show File Browser"), "main_window:show_file_browser",
+        prefix + ctrl_shift + Qt::Key_2);
+  init (tr ("Show Workspace"), "main_window:show_workspace",
+        prefix + ctrl_shift + Qt::Key_3);
+  init (tr ("Show Editor"), "main_window:show_editor",
+        prefix + ctrl_shift + Qt::Key_4);
+  init (tr ("Show Documentation"), "main_window:show_doc",
+        prefix + ctrl_shift + Qt::Key_5);
+  init (tr ("Command Window"), "main_window:command",
+        prefix + ctrl + Qt::Key_0);
+  init (tr ("Command History"), "main_window:history",
+        prefix + ctrl + Qt::Key_1);
+  init (tr ("File Browser"), "main_window:file_browser",
+        prefix + ctrl + Qt::Key_2);
+  init (tr ("Workspace"), "main_window:workspace",
+        prefix + ctrl + Qt::Key_3);
+  init (tr ("Editor"), "main_window:editor",
+        prefix + ctrl + Qt::Key_4);
+  init (tr ("Documentation"), "main_window:doc",
+        prefix + ctrl + Qt::Key_5);
+  init (tr ("Reset Window Layout"), "main_window:reset", QKeySequence ());
+
+  // help
+  init (tr ("Show Ondisk Documentation"), "main_help:ondisk_doc", QKeySequence ());
+  init (tr ("Show Online Documentation"), "main_help:online_doc", QKeySequence ());
+  init (tr ("Report a Bug"), "main_help:report_bug", QKeySequence ());
+  init (tr ("Octave Packages"), "main_help:packages", QKeySequence ());
+  init (tr ("Share Code"), "main_help:agora", QKeySequence ());
+  init (tr ("Contribute to Octave"), "main_help:contribute", QKeySequence ());
+  init (tr ("Octave Developer Resources"), "main_help:developer", QKeySequence ());
+  init (tr ("About Octave"), "main_help:about", QKeySequence ());
+
+  // news
+  init (tr ("Release Notes"), "main_news:release_notes", QKeySequence ());
+  init (tr ("Community News"), "main_news:community_news", QKeySequence ());
+
+  // actions of the editor
+
+  // file
+  init (tr ("Edit Function"), "editor_file:edit_function",
+        QKeySequence (ctrl + Qt::Key_E));
+  init (tr ("Save File"), "editor_file:save", QKeySequence::Save);
+  init (tr ("Save File As"), "editor_file:save_as", QKeySequence::SaveAs);
+  init (tr ("Close"), "editor_file:close", QKeySequence::Close);
+  init (tr ("Close All"), "editor_file:close_all", QKeySequence ());
+  init (tr ("Close Other"), "editor_file:close_other", QKeySequence ());
+  init (tr ("Print"), "editor_file:print", QKeySequence::Print);
+
+  // edit
+  init (tr ("Undo"), "editor_edit:undo", QKeySequence::Undo);
+  init (tr ("Redo"), "editor_edit:redo", QKeySequence::Redo);
+  init (tr ("Copy"), "editor_edit:copy", QKeySequence::Copy);
+  init (tr ("Cut"), "editor_edit:cut", QKeySequence::Cut);
+  init (tr ("Paste"), "editor_edit:paste", QKeySequence::Paste);
+  init (tr ("Select All"), "editor_edit:select_all", QKeySequence::SelectAll);
+  init (tr ("Find and Replace"), "editor_edit:find_replace",
+        QKeySequence::Find);
+  init (tr ("Delete to Start of Word"), "editor_edit:delete_start_word",
+        QKeySequence::DeleteStartOfWord);
+  init (tr ("Delete to End of Word"), "editor_edit:delete_end_word",
+        QKeySequence::DeleteEndOfWord);
+  init (tr ("Delete to Start of Line"), "editor_edit:delete_start_line",
+        QKeySequence (ctrl_shift + Qt::Key_Backspace));
+  init (tr ("Delete to End of Line"), "editor_edit:delete_end_line",
+        QKeySequence (ctrl_shift + Qt::Key_Delete));
+  init (tr ("Delete Line"), "editor_edit:delete_line",
+        QKeySequence (ctrl_shift + Qt::Key_L));
+  init (tr ("Copy Line"), "editor_edit:copy_line",
+        QKeySequence (ctrl_shift + Qt::Key_C));
+  init (tr ("Cut Line"), "editor_edit:cut_line",
+        QKeySequence (ctrl_shift + Qt::Key_X));
+  init (tr ("Duplicate Selection/Line"), "editor_edit:duplicate_selection",
+        QKeySequence (ctrl + Qt::Key_D));
+  init (tr ("Transpose Line"), "editor_edit:transpose_line",
+        QKeySequence (ctrl + Qt::Key_T));
+  init (tr ("Completion List"), "editor_edit:completion_list",
+        QKeySequence (ctrl + Qt::Key_Space));
+
+  init (tr ("Comment Selection"), "editor_edit:comment_selection",
+        QKeySequence (ctrl + Qt::Key_R));
+  init (tr ("Uncomment Selection"), "editor_edit:uncomment_selection",
+        QKeySequence (ctrl_shift + Qt::Key_R));
+  init (tr ("Uppercase Selection"), "editor_edit:upper_case",
+        QKeySequence (ctrl + Qt::Key_U));
+  init (tr ("Lowercase Selection"), "editor_edit:lower_case",
+        QKeySequence (ctrl_alt + Qt::Key_U));
+
+#if defined (Q_OS_MAC)
+  init (tr ("Indent Selection"), "editor_edit:indent_selection",
+        QKeySequence (prefix + Qt::Key_Tab));
+  init (tr ("Unindent Selection"), "editor_edit:unindent_selection",
+        QKeySequence (prefix + Qt::ShiftModifier + Qt::Key_Tab));
+#else
+  init (tr ("Indent Selection"), "editor_edit:indent_selection",
+        QKeySequence (ctrl + Qt::Key_Tab));
+  init (tr ("Unindent Selection"), "editor_edit:unindent_selection",
+        QKeySequence (ctrl_shift + Qt::Key_Tab));
+#endif
+
+  init (tr ("Convert Line Ednings to Windows"), "editor_edit:conv_eol_winows",
+        QKeySequence ());
+  init (tr ("Convert Line Ednings to Unix"), "editor_edit:conv_eol_unix",
+        QKeySequence ());
+  init (tr ("Convert Line Ednings to Mac"), "editor_edit:conv_eol_mac",
+        QKeySequence ());
+
+  init (tr ("Goto Line"), "editor_edit:goto_line",
+        QKeySequence (ctrl + Qt::Key_G));
+  init (tr ("Move to Matching Brace"), "editor_edit:move_to_brace",
+        QKeySequence (ctrl + Qt::Key_M));
+  init (tr ("Select to Matching Brace"), "editor_edit:select_to_brace",
+        QKeySequence (ctrl_shift + Qt::Key_M));
+  init (tr ("Toggle Bookmark"), "editor_edit:toggle_bookmark",
+        QKeySequence (prefix + Qt::Key_F7));
+  init (tr ("Next Bookmark"), "editor_edit:next_bookmark",
+        QKeySequence (prefix + Qt::Key_F2));
+  init (tr ("Previous Bookmark"), "editor_edit:previous_bookmark",
+        QKeySequence (prefix + Qt::SHIFT + Qt::Key_F2));
+  init (tr ("Remove All Bookmark"), "editor_edit:remove_bookmark",
+        QKeySequence ());
+
+  init (tr ("Preferences"), "editor_edit:preferences", QKeySequence ());
+  init (tr ("Styles Preferences"), "editor_edit:styles_preferences",
+        QKeySequence ());
+
+  // view
+  init (tr ("Show Line Numbers"), "editor_view:show_line_numbers", QKeySequence ());
+  init (tr ("Show White Spaces"), "editor_view:show_white_spaces", QKeySequence ());
+  init (tr ("Show Line Endings"), "editor_view:show_eol_chars", QKeySequence ());
+  init (tr ("Show Indentation Guides"), "editor_view:show_ind_guides", QKeySequence ());
+  init (tr ("Show Long Line Marker"), "editor_view:show_long_line", QKeySequence ());
+  init (tr ("Zoom In"), "editor_view:zoom_in", QKeySequence::ZoomIn);
+  init (tr ("Zoom Out"), "editor_view:zoom_out", QKeySequence::ZoomOut);
+#if defined (Q_OS_MAC)
+  init (tr ("Zoom Normal"), "editor_view:zoom_normal",
+        QKeySequence (ctrl + Qt::Key_Underscore));
+#else
+  init (tr ("Zoom Normal"), "editor_view:zoom_normal",
+        QKeySequence (ctrl_alt + Qt::Key_0));
+#endif
+
+  // debug
+  init (tr ("Toggle Breakpoint"), "editor_debug:toggle_breakpoint",
+        QKeySequence ());
+  init (tr ("Next Breakpoint"), "editor_debug:next_breakpoint",
+        QKeySequence ());
+  init (tr ("Previous Breakpoint"), "editor_debug:previous_breakpoint",
+        QKeySequence ());
+  init (tr ("Remove All Breakpoints"), "editor_debug:remove_breakpoints",
+        QKeySequence ());
+
+  // run
+  init (tr ("Run File"), "editor_run:run_file",
+        QKeySequence (prefix + Qt::Key_F5) );
+  init (tr ("Run Selection"), "editor_run:run_selection",
+        QKeySequence (prefix + Qt::Key_F9) );
+
+  // help
+  init (tr ("Help on Keyword"), "editor_help:help_keyword", QKeySequence::HelpContents);
+  init (tr ("Document on Keyword"), "editor_help:doc_keyword", QKeySequence (Qt::SHIFT + Qt::Key_F1));
+}
+
+void
+shortcut_manager::init (QString description, QString key, QKeySequence def_sc)
+{
+  QKeySequence actual_0 = QKeySequence (_settings->value ("shortcuts/"+key, def_sc).toString ());
+  QKeySequence actual_1 = QKeySequence (_settings->value ("shortcuts/"+key+"_1", def_sc).toString ());
+
+  // append the new shortcut to the list
+  shortcut_t shortcut_info;
+  shortcut_info.description = description;
+  shortcut_info.settings_key = key;
+  shortcut_info.actual_sc [0] = actual_0;
+  shortcut_info.actual_sc [1] = actual_1;
+  shortcut_info.default_sc [0] = def_sc;
+  shortcut_info.default_sc [1] = def_sc;  // TODO: Different defaults
+  _sc << shortcut_info;
+
+  // insert shortcut prepended by widget in order check for duplicates later
+  QString widget = key.section ('_',0,0);  // get widget that uses the shortcut
+  if (! actual_0.isEmpty ())
+    _shortcut_hash[widget + ":" + actual_0.toString ()] = _sc.count ();  // offset of 1 to avoid 0
+  if (! actual_1.isEmpty ())
+    _shortcut_hash[widget + "_1:" + actual_1.toString ()] = _sc.count ();  // offset of 1 to avoid 0
+  _action_hash[key] = _sc.count ();  // offset of 1 to avoid 0
+}
+
+void
+shortcut_manager::do_fill_treewidget (QTreeWidget *tree_view)
+{
+  _dialog = 0;
+  _level_hash.clear ();
+
+  tree_view->header ()->setResizeMode (QHeaderView::ResizeToContents);
+
+  QTreeWidgetItem *main = new QTreeWidgetItem (tree_view);
+  main->setText (0, tr ("Main"));
+  main->setExpanded (true);
+  QTreeWidgetItem *main_file = new QTreeWidgetItem (main);
+  main_file->setText (0, tr ("File"));
+  QTreeWidgetItem *main_edit = new QTreeWidgetItem (main);
+  main_edit->setText (0, tr ("Edit"));
+  QTreeWidgetItem *main_debug = new QTreeWidgetItem (main);
+  main_debug->setText (0, tr ("Debug"));
+  QTreeWidgetItem *main_window = new QTreeWidgetItem (main);
+  main_window->setText (0, tr ("Window"));
+  QTreeWidgetItem *main_help = new QTreeWidgetItem (main);
+  main_help->setText (0, tr ("Help"));
+  QTreeWidgetItem *main_news = new QTreeWidgetItem (main);
+  main_news->setText (0, tr ("News"));
+
+  _level_hash["main_file"]   = main_file;
+  _level_hash["main_edit"]   = main_edit;
+  _level_hash["main_debug"]   = main_debug;
+  _level_hash["main_window"]   = main_window;
+  _level_hash["main_help"]   = main_help;
+  _level_hash["main_news"]   = main_news;
+
+  QTreeWidgetItem *editor = new QTreeWidgetItem (tree_view);
+  editor->setText (0, tr ("Editor"));
+  editor->setExpanded (true);
+  QTreeWidgetItem *editor_file = new QTreeWidgetItem (editor);
+  editor_file->setText (0, tr ("File"));
+  QTreeWidgetItem *editor_edit = new QTreeWidgetItem (editor);
+  editor_edit->setText (0, tr ("Edit"));
+  QTreeWidgetItem *editor_view = new QTreeWidgetItem (editor);
+  editor_view->setText (0, tr ("View"));
+  QTreeWidgetItem *editor_debug = new QTreeWidgetItem (editor);
+  editor_debug->setText (0, tr ("Debug"));
+  QTreeWidgetItem *editor_run = new QTreeWidgetItem (editor);
+  editor_run->setText (0, tr ("Run"));
+  QTreeWidgetItem *editor_help = new QTreeWidgetItem (editor);
+  editor_help->setText (0, tr ("Help"));
+
+  _level_hash["editor_file"] = editor_file;
+  _level_hash["editor_edit"] = editor_edit;
+  _level_hash["editor_view"] = editor_view;
+  _level_hash["editor_debug"] = editor_debug;
+  _level_hash["editor_run"] = editor_run;
+  _level_hash["editor_help"] = editor_help;
+
+  connect (tree_view, SIGNAL (itemDoubleClicked (QTreeWidgetItem*, int)),
+           this, SLOT (handle_double_clicked (QTreeWidgetItem*, int)));
+
+  for (int i = 0; i < _sc.count (); i++)
+    {
+      shortcut_t sc = _sc.at (i);
+
+      QTreeWidgetItem* section = _level_hash[sc.settings_key.section(':',0,0)];
+      QTreeWidgetItem* tree_item = new QTreeWidgetItem (section);
+
+      // set a slightly transparent foreground for default columns
+      QColor fg = QColor (tree_item->foreground (1).color ());
+      fg.setAlpha (128);
+      tree_item->setForeground (1, QBrush (fg));
+      tree_item->setForeground (3, QBrush (fg));
+
+      // write the shortcuts
+      tree_item->setText (0, sc.description);
+      tree_item->setText (1, sc.default_sc [0]);
+      tree_item->setText (2, sc.actual_sc [0]);
+      tree_item->setText (3, sc.default_sc [1]);
+      tree_item->setText (4, sc.actual_sc [1]);
+
+      _item_index_hash[tree_item] = i + 1; // index+1 to avoid 0
+      _index_item_hash[i] = tree_item;
+    }
+
+}
+
+// write one or all actual shortcut set(s) into a settings file
+void
+shortcut_manager::do_write_shortcuts (int set, QSettings* settings)
+{
+  if (set)
+    {
+      // set is not zero, only write the desired set (index = set-1)
+      // into the settings file that the user has selected for this export
+      for (int i = 0; i < _sc.count (); i++)  // loop over all shortcuts
+        {
+          settings->setValue("shortcuts/"+_sc.at (i).settings_key,
+                             _sc.at (i).actual_sc[set-1].toString ());
+        }
+    }
+  else
+    {
+      // set is zero, write all sets into the normal octave settings file
+      // (this is only the case when called from the closing settings dialog)
+      for (int i = 0; i < _sc.count (); i++)  // loop over all shortcuts
+        {
+          settings->setValue("shortcuts/"+_sc.at (i).settings_key,
+                             _sc.at (i).actual_sc[0].toString ());
+          settings->setValue("shortcuts/"+_sc.at (i).settings_key+"_1",
+                            _sc.at (i).actual_sc[1].toString ());
+        }
+      delete _dialog;  // the dialog for key sequences can be removed now
+    }
+
+  settings->sync ();    // sync the settings file
+}
+
+void
+shortcut_manager::do_set_shortcut (QAction* action, const QString& key)
+{
+  int set = _settings->value ("shortcuts/set",0).toInt ();
+  int index;
+
+  index = _action_hash[key] - 1;
+
+  QString key_set = key;
+  if (set == 1)
+    key_set = key+"_1";
+
+  if (index > -1 && index < _sc.count ())
+    action->setShortcut (QKeySequence (
+      _settings->value ("shortcuts/" + key_set, _sc.at (index).default_sc[set]).toString ()));
+  else
+    qDebug () << "Key: " << key_set << " not found in _action_hash";
+}
+
+void
+shortcut_manager::handle_double_clicked (QTreeWidgetItem* item, int col)
+{
+  switch (col)
+    {
+      case 2:
+      case 4:
+        _selected_set = col/2 - 1;
+        break;
+
+      default:
+        return;
+    }
+
+  int i = _item_index_hash[item];
+  if (i == 0)
+    return;  // top-level-item clicked
+
+  shortcut_dialog (i-1); // correct to index starting at 0
+}
+
+void
+shortcut_manager::shortcut_dialog (int index)
+{
+  if (! _dialog)
+    {
+      _dialog = new QDialog (this);
+
+      _dialog->setWindowTitle (tr ("Enter new Shortcut for Set %1")
+                               .arg (_selected_set + 1));
+
+      QVBoxLayout *box = new QVBoxLayout(_dialog);
+
+      QLabel *help = new QLabel (tr ("Apply the desired shortcut or click "
+                                     "on the right button to reset the "
+                                     "shortcut to its default."));
+      help->setWordWrap (true);
+      box->addWidget (help);
+
+      QCheckBox *direct = new QCheckBox (tr ("Enter shortcut directly by performing it"));
+      direct->setCheckState (Qt::Checked);
+      box->addWidget (direct);
+
+      QGridLayout *grid = new QGridLayout();
+
+      QLabel *actual = new QLabel (tr ("Actual shortcut"));
+      _edit_actual = new enter_shortcut (_dialog);
+      _edit_actual->setAlignment (Qt::AlignHCenter);
+      grid->addWidget (actual, 0, 0);
+      grid->addWidget (_edit_actual, 0, 1);
+
+      QLabel *def = new QLabel (tr ("Default shortcut"));
+      _label_default = new QLabel (_dialog);
+      _label_default->setAlignment (Qt::AlignHCenter);
+      grid->addWidget (def, 1, 0);
+      grid->addWidget (_label_default, 1, 1);
+
+      QPushButton *set_default = new QPushButton (tr ("Set to default"));
+      grid->addWidget (set_default, 0, 2);
+      connect (set_default, SIGNAL (clicked ()),
+               this, SLOT (shortcut_dialog_set_default ()));
+
+      box->addLayout (grid);
+
+      QDialogButtonBox *button_box = new QDialogButtonBox (QDialogButtonBox::Ok
+                                                   | QDialogButtonBox::Cancel);
+      QList<QAbstractButton *> buttons = button_box->buttons ();
+      for (int i = 0; i < buttons.count (); i++)
+        buttons.at (i)->setShortcut (QKeySequence ());
+      connect(button_box, SIGNAL (accepted ()), _dialog, SLOT (accept ()));
+      connect(button_box, SIGNAL (rejected ()), _dialog, SLOT (reject ()));
+      box->addWidget (button_box);
+
+      _dialog->setLayout (box);
+
+      connect (direct, SIGNAL (stateChanged (int)),
+               _edit_actual, SLOT (handle_direct_shortcut (int)));
+      connect (_dialog, SIGNAL (finished (int)),
+               this, SLOT (shortcut_dialog_finished (int)));
+
+    }
+
+  _edit_actual->setText (_sc.at (index).actual_sc[_selected_set]);
+  _label_default->setText (_sc.at (index).default_sc[_selected_set]);
+  _handled_index = index;
+
+  _edit_actual->setFocus ();
+  _dialog->setFocusProxy (_edit_actual);
+  _dialog->exec ();
+}
+
+void
+shortcut_manager::shortcut_dialog_finished (int result)
+{
+  if (result == QDialog::Rejected)
+    return;
+
+  // check for duplicate
+
+  // get the widget for which this shortcut is defined
+  QString widget = _sc.at (_handled_index).settings_key.section ('_',0,0);
+  // and look for shortcut
+  QString sep = ":";
+  if (_selected_set)
+    sep = "_1:";
+
+  int double_index = _shortcut_hash[widget + sep + _edit_actual->text()] - 1;
+
+  if (double_index >= 0 && double_index != _handled_index)
+    {
+      int ret = QMessageBox::warning(this, tr("Double Shortcut"),
+                  tr ("The chosen shortcut\n  \"%1\"\n"
+                      "is already used for the action\n  \"%2\".\n"
+                      "Do you want to use the shortcut anyhow removing it "
+                      "from the previous action?")
+                     .arg (_edit_actual->text())
+                     .arg (_sc.at (double_index).description),
+                  QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes);
+
+      if (ret == QMessageBox::Yes)
+        {
+          shortcut_t double_shortcut = _sc.at (double_index);
+          double_shortcut.actual_sc[_selected_set] = QKeySequence ();
+          _sc.replace (double_index, double_shortcut);
+          _index_item_hash[double_index]->setText ((_selected_set + 1)*2, QKeySequence ());
+        }
+      else
+        return;
+    }
+
+  shortcut_t shortcut = _sc.at (_handled_index);
+  if (! shortcut.actual_sc[_selected_set].isEmpty ())
+    _shortcut_hash.remove (widget + sep + shortcut.actual_sc[_selected_set].toString ());
+  shortcut.actual_sc[_selected_set] = _edit_actual->text();
+  _sc.replace (_handled_index, shortcut);
+
+  _index_item_hash[_handled_index]->setText ((_selected_set + 1)*2,
+                                             shortcut.actual_sc[_selected_set]);
+
+  if (! shortcut.actual_sc[_selected_set].isEmpty ())
+    _shortcut_hash[widget + sep + shortcut.actual_sc[_selected_set].toString ()] =
+        _handled_index + 1;
+}
+
+void
+shortcut_manager::shortcut_dialog_set_default ()
+{
+  _edit_actual->setText (_label_default->text ());
+}
+
+// import a shortcut set from a given settings file and refresh the tree view
+void
+shortcut_manager::import_shortcuts (int set, QSettings *settings)
+{
+  for (int i = 0; i < _sc.count (); i++)
+    {
+      // update the list of all shortcuts
+      shortcut_t sc = _sc.at (i);           // make a copy
+      sc.actual_sc[set-1] = QKeySequence (  // get new shortcut from settings
+        settings->value ("shortcuts/"+sc.settings_key,sc.actual_sc[set-1]).
+                        toString ());       // and use the old one as default
+      _sc.replace (i,sc);                   // replace the old with the new one
+
+      // update the tree view
+      QTreeWidgetItem* tree_item = _index_item_hash[i]; // get related tree item
+      tree_item->setText (2*set, sc.actual_sc [set-1]); // display new shortcut
+    }
+}
+
+// import or export of shortcut sets,
+// called from settings dialog when related buttons are clicked
+void
+shortcut_manager::do_import_export (bool import, int set)
+{
+  QString file;
+
+  // get the file name to read or write the shortcuts,
+  // the default extension is .osc (octave shortcuts)
+  if (import)
+    {
+      file = QFileDialog::getOpenFileName (this,
+              tr ("Import shortcut set %1 from file ...").arg (set), QString (),
+              tr ("Octave Shortcut Files (*.osc);;All Files (*)"));
+    }
+  else
+    {
+      file = QFileDialog::getSaveFileName (this,
+              tr ("Export shortcut set %1 into file ...").arg (set), QString (),
+              tr ("Octave Shortcut Files (*.osc);;All Files (*)"));
+    }
+
+  // create a settings object related to this file
+  QSettings *osc_settings = new QSettings (file, QSettings::IniFormat);
+  if (osc_settings)
+    {
+      // the settings object was successfully created: carry on
+      if (import)
+        import_shortcuts (set, osc_settings);   // import (special action)
+      else
+        do_write_shortcuts (set, osc_settings); // export, like saving settings
+    }
+  else
+    qWarning () << tr ("Failed to open %1 as octave shortcut file"). arg (file);
+
+}
+
+
+// enter_shortcut:
+// class derived from QLineEdit for directly entering key sequences which
+enter_shortcut::enter_shortcut (QWidget *p) : QLineEdit (p)
+{
+  _direct_shortcut = true;      // the shortcut is directly entered
+}
+
+enter_shortcut::~enter_shortcut ()
+{
+}
+
+// slot for checkbox whether the shortcut is directly entered or not
+void
+enter_shortcut::handle_direct_shortcut (int state)
+{
+  if (state)
+    _direct_shortcut = true;  // the shortcut is directly entered
+  else
+    _direct_shortcut = false; // the shortcut has to be written as text
+}
+
+// new keyPressEvent
+void
+enter_shortcut::keyPressEvent (QKeyEvent *e)
+{
+  if (! _direct_shortcut)
+    {
+      QLineEdit::keyPressEvent (e);
+      return;
+    }
+
+  if (e->type () == QEvent::KeyPress)
+    {
+      int key = e->key ();
+
+      if (key == Qt::Key_unknown || key == 0)
+        return;
+
+      Qt::KeyboardModifiers modifiers = e->modifiers ();
+
+      if(modifiers & Qt::ShiftModifier)
+        key += Qt::SHIFT;
+      if(modifiers & Qt::ControlModifier)
+        key += Qt::CTRL;
+      if(modifiers & Qt::AltModifier)
+        key += Qt::ALT;
+      if(modifiers & Qt::MetaModifier)
+        key += Qt::META;
+
+      setText (QKeySequence(key));
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libgui/src/shortcut-manager.h	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,150 @@
+/*
+
+Copyright (C) 2014 Torsten <ttl@justmail.de>
+
+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/>.
+
+*/
+
+#ifndef SHORTCUT_MANAGER_H
+#define SHORTCUT_MANAGER_H
+
+#include <QWidget>
+#include <QTreeWidget>
+#include <QLineEdit>
+#include <QKeyEvent>
+#include <QLabel>
+#include <QSettings>
+
+class enter_shortcut : public QLineEdit
+{
+  Q_OBJECT
+
+public:
+  enter_shortcut (QWidget *p = 0);
+  ~enter_shortcut ();
+
+  virtual void  keyPressEvent (QKeyEvent *e);
+
+public slots:
+  void handle_direct_shortcut (int);
+
+private:
+  bool _direct_shortcut;
+
+};
+
+
+class shortcut_manager : public QWidget
+{
+  Q_OBJECT
+
+public:
+  shortcut_manager ();
+  ~shortcut_manager ();
+
+  static void init_data ()
+  {
+    if (instance_ok ())
+      instance->do_init_data ();
+  }
+
+  static void write_shortcuts (int set, QSettings *settings)
+  {
+    if (instance_ok ())
+      instance->do_write_shortcuts (set, settings);
+  }
+
+  static void set_shortcut (QAction *action, const QString& key)
+  {
+    if (instance_ok ())
+      instance->do_set_shortcut (action, key);
+  }
+
+  static void fill_treewidget (QTreeWidget *tree_view)
+  {
+    if (instance_ok ())
+      instance->do_fill_treewidget (tree_view);
+  }
+
+  static void import_export (bool import, int set)
+  {
+    if (instance_ok ())
+      instance->do_import_export (import, set);
+  }
+
+public slots:
+
+signals:
+
+protected:
+
+protected slots:
+
+  void handle_double_clicked (QTreeWidgetItem*, int);
+  void shortcut_dialog_finished (int);
+  void shortcut_dialog_set_default ();
+
+private:
+
+  static shortcut_manager *instance;
+  static void cleanup_instance (void) { delete instance; instance = 0; }
+
+  // No copying!
+
+  shortcut_manager (const shortcut_manager&);
+  shortcut_manager& operator = (const shortcut_manager&);
+
+  static bool instance_ok (void);
+
+  void init (QString, QString, QKeySequence);
+  void do_init_data ();
+  void do_write_shortcuts (int set, QSettings *settings);
+  void do_set_shortcut (QAction *action, const QString& key);
+  void do_fill_treewidget (QTreeWidget *tree_view);
+  void do_import_export (bool import, int set);
+  void shortcut_dialog (int);
+  void import_shortcuts (int set, QSettings *settings);
+
+  struct shortcut_t
+  {
+    QString description;
+    QString settings_key;
+    QKeySequence actual_sc[2];
+    QKeySequence default_sc[2];
+    QTreeWidgetItem *tree_item;
+  };
+
+  QList<shortcut_t> _sc;
+  QHash<QString, int> _shortcut_hash;
+  QHash<QString, int> _action_hash;
+  QHash <QString, QTreeWidgetItem*> _level_hash;
+  QHash<int, QTreeWidgetItem*> _index_item_hash;
+  QHash<QTreeWidgetItem*, int> _item_index_hash;
+
+  QDialog *_dialog;
+  enter_shortcut *_edit_actual;
+  QLabel *_label_default;
+  int _handled_index;
+
+  QSettings *_settings;
+  int _selected_set;
+
+};
+
+
+#endif // SHORTCUT_MANAGER_H
--- a/libgui/src/workspace-model.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/libgui/src/workspace-model.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -39,7 +39,7 @@
   _columnNames.append (tr ("Class"));
   _columnNames.append (tr ("Dimension"));
   _columnNames.append (tr ("Value"));
-  _columnNames.append (tr ("Storage Class"));
+  _columnNames.append (tr ("Attribute"));
 
   for (int i = 0; i < resource_manager::storage_class_chars ().length (); i++)
     _storage_class_colors.append (QColor (Qt::white));
@@ -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 ())
             {
@@ -244,8 +244,6 @@
   _complex_flags = complex_flags;
 
   update_table ();
-
-  emit model_changed ();
 }
 
 void
@@ -253,8 +251,6 @@
 {
   clear_data ();
   update_table ();
-
-  emit model_changed ();
 }
 
 void
--- a/libgui/src/workspace-view.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/libgui/src/workspace-view.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -35,9 +35,12 @@
 #include <QVBoxLayout>
 #include <QPushButton>
 #include <QMenu>
+#include <QLabel>
+#include <QCompleter>
 
 #include "workspace-view.h"
 #include "resource-manager.h"
+#include "symtab.h"
 
 workspace_view::workspace_view (QWidget *p)
   : octave_dock_widget (p), view (new QTableView (this))
@@ -47,8 +50,26 @@
   set_title (tr ("Workspace"));
   setStatusTip (tr ("View the variables in the active workspace."));
 
+  _filter = new QComboBox (this);
+  _filter->setToolTip (tr ("Enter text to filter the workspace"));
+  _filter->setEditable (true);
+  _filter->setMaxCount (MaxFilterHistory);
+  _filter->setInsertPolicy (QComboBox::NoInsert);
+  _filter->setSizeAdjustPolicy (
+            QComboBox::AdjustToMinimumContentsLengthWithIcon);
+  QSizePolicy sizePol (QSizePolicy::Expanding, QSizePolicy::Maximum);
+  _filter->setSizePolicy (sizePol);
+  _filter->completer ()->setCaseSensitivity (Qt::CaseSensitive);
+
+  QLabel *filter_label = new QLabel (tr ("Filter"));
+
+  _filter_checkbox = new QCheckBox ();
+
   view->setWordWrap (false);
   view->setContextMenuPolicy (Qt::CustomContextMenu);
+  view->setShowGrid (false);
+  (view->verticalHeader) ()->hide ();
+  view->setAlternatingRowColors (true);
   view_previous_row_count = 0;
 
   // Set an empty widget, so we can assign a layout to it.
@@ -56,6 +77,11 @@
 
   // Create a new layout and add widgets to it.
   QVBoxLayout *vbox_layout = new QVBoxLayout ();
+  QHBoxLayout *hbox_layout = new QHBoxLayout ();
+  hbox_layout->addWidget (filter_label);
+  hbox_layout->addWidget (_filter_checkbox);
+  hbox_layout->addWidget (_filter);
+  vbox_layout->addLayout (hbox_layout);
   vbox_layout->addWidget (view);
   vbox_layout->setMargin (2);
 
@@ -67,12 +93,26 @@
   QSettings *settings = resource_manager::get_settings ();
 
   // Initialize column order and width of the workspace
-
   view->horizontalHeader ()->restoreState (
     settings->value ("workspaceview/column_state").toByteArray ());
 
+  // Init state of the filter
+  _filter->addItems (settings->value ("workspaceview/mru_list").toStringList ());
+
+  bool filter_state =
+            settings->value ("workspaceview/filter_active", false).toBool ();
+  _filter_checkbox->setChecked (filter_state);
+  filter_activate (filter_state);
+
   // Connect signals and slots.
 
+  connect (_filter, SIGNAL (editTextChanged (const QString&)),
+           this, SLOT (filter_update (const QString&)));
+  connect (_filter_checkbox, SIGNAL (toggled (bool)),
+           this, SLOT (filter_activate (bool)));
+  connect (_filter->lineEdit (), SIGNAL (editingFinished ()),
+           this, SLOT (update_filter_history ()));
+
   connect (view, SIGNAL (customContextMenuRequested (const QPoint&)),
            this, SLOT (contextmenu_requested (const QPoint&)));
 
@@ -87,13 +127,23 @@
 
   settings->setValue ("workspaceview/column_state",
                       view->horizontalHeader ()->saveState ());
+  settings->setValue ("workspaceview/filter_active",
+                      _filter_checkbox->isChecked ());
+
+  QStringList mru;
+  for (int i = 0; i < _filter->count (); i++)
+    mru.append (_filter->itemText (i));
+  settings->setValue ("workspaceview/mru_list", mru);
 
   settings->sync ();
 }
 
 void workspace_view::setModel (workspace_model *model)
 {
-  view->setModel (model);
+  _filter_model.setSourceModel (model);
+  _filter_model.setFilterKeyColumn(0);
+
+  view->setModel (&_filter_model);
   _model = model;
 }
 
@@ -105,28 +155,69 @@
 }
 
 void
+workspace_view::filter_update (const QString& expression)
+{
+  _filter_model.setFilterWildcard (expression);
+  handle_model_changed ();
+}
+
+void
+workspace_view::filter_activate (bool state)
+{
+  _filter->setEnabled (state);
+  _filter_model.setDynamicSortFilter (state);
+
+  if (state)
+    filter_update (_filter->currentText ());
+  else
+    filter_update (QString ());
+}
+
+void
+workspace_view::update_filter_history ()
+{
+  QString text = _filter->currentText ();   // get current text
+  int index = _filter->findText (text);     // and its actual index
+
+  if (index > -1)
+    _filter->removeItem (index);    // remove if already existing
+
+  _filter->insertItem (0, text);    // (re)insert at beginning
+  _filter->setCurrentIndex (0);
+}
+
+QString
+workspace_view::get_var_name (QModelIndex index)
+{
+  index = index.sibling (index.row (), 0);
+  QAbstractItemModel *m = view->model ();
+  QMap<int, QVariant> item_data = m->itemData (index);
+
+  return item_data[0].toString ();
+}
+
+void
 workspace_view::contextmenu_requested (const QPoint& qpos)
 {
   QMenu menu (this);
 
   QModelIndex index = view->indexAt (qpos);
-  QAbstractItemModel *m = view->model ();
 
   // if it isnt Local, Glocal etc, allow the ctx menu
   if (index.isValid () && index.column () == 0)
     {
-      index = index.sibling (index.row (), 0);
-
-      QMap<int, QVariant> item_data = m->itemData (index);
+      QString var_name = get_var_name (index);
 
-      QString var_name = item_data[0].toString ();
+      menu.addAction (tr ("Copy name"), this,
+                      SLOT (handle_contextmenu_copy ()));
 
-      menu.addAction (tr ("Copy"), this,
-                      SLOT (handle_contextmenu_copy ()));
+      menu.addAction (tr ("Copy value"), this,
+                      SLOT (handle_contextmenu_copy_value ()));
 
       QAction *rename = menu.addAction (tr ("Rename"), this,
                                         SLOT (handle_contextmenu_rename ()));
 
+      QAbstractItemModel *m = view->model ();
       const workspace_model *wm = static_cast<const workspace_model *> (m);
 
       if (! wm->is_top_level ())
@@ -157,13 +248,7 @@
 
   if (index.isValid ())
     {
-      index = index.sibling (index.row (), 0);
-
-      QAbstractItemModel *m = view->model ();
-
-      QMap<int, QVariant> item_data = m->itemData (index);
-
-      QString var_name = item_data[0].toString ();
+      QString var_name = get_var_name (index);
 
       QClipboard *clipboard = QApplication::clipboard ();
 
@@ -172,19 +257,31 @@
 }
 
 void
+workspace_view::handle_contextmenu_copy_value (void)
+{
+  QModelIndex index = view->currentIndex ();
+
+  if (index.isValid ())
+    {
+      QString var_name = get_var_name (index);
+
+      octave_value val = symbol_table::varval (var_name.toStdString ());
+      std::ostringstream buf;
+      val.print_raw (buf, true);
+
+      QClipboard *clipboard = QApplication::clipboard ();
+      clipboard->setText (QString::fromStdString (buf.str ()));
+    }
+}
+
+void
 workspace_view::handle_contextmenu_rename (void)
 {
   QModelIndex index = view->currentIndex ();
 
   if (index.isValid ())
     {
-      index = index.sibling (index.row (), 0);
-
-      QAbstractItemModel *m = view->model ();
-
-      QMap<int, QVariant> item_data = m->itemData (index);
-
-      QString var_name = item_data[0].toString ();
+      QString var_name = get_var_name (index);
 
       QInputDialog* inputDialog = new QInputDialog ();
 
@@ -197,7 +294,10 @@
                                  QLineEdit::Normal, var_name, &ok);
 
       if (ok && ! new_name.isEmpty ())
-        m->setData (index, new_name, Qt::EditRole);
+        {
+          QAbstractItemModel *m = view->model ();
+          m->setData (index, new_name, Qt::EditRole);
+        }
     }
 }
 
@@ -226,13 +326,7 @@
 
   if (index.isValid ())
     {
-      index = index.sibling (index.row (), 0);
-
-      QAbstractItemModel *m = view->model ();
-
-      QMap<int, QVariant> item_data = m->itemData (index);
-
-      QString var_name = item_data[0].toString ();
+      QString var_name = get_var_name (index);
 
       emit command_requested (cmdname + " (" + var_name + ");");
     }
@@ -241,11 +335,12 @@
 void
 workspace_view::handle_model_changed (void)
 {
+//  view->resizeRowsToContents ();
   // Just modify those rows that have been added rather than go through
   // the whole list.  For-loop test will handle when number of rows reduced.
   QFontMetrics fm = view->fontMetrics ();
   int row_height =  fm.height ();
-  int new_row_count = view->model ()->rowCount ();
+  int new_row_count = _filter_model.rowCount ();
   for (int i = view_previous_row_count; i < new_row_count; i++)
     view->setRowHeight (i, row_height);
   view_previous_row_count = new_row_count;
@@ -257,16 +352,22 @@
   _model->notice_settings (settings); // update colors of model first
 
   QString tool_tip;
-  tool_tip  = QString (tr ("View the variables in the active workspace.<br>"));
-  tool_tip += QString (tr ("Colors for the storage class:"));
-  for (int i = 0; i < resource_manager::storage_class_chars ().length (); i++)
+
+  if (!settings->value ("workspaceview/hide_tool_tips",false).toBool ())
     {
-      tool_tip +=
-        QString ("<div style=\"background-color:%1;color:#000000\">%2</div>")
-        .arg (_model->storage_class_color (i).name ())
-        .arg (resource_manager::storage_class_names ().at (i));
+      tool_tip  = QString (tr ("View the variables in the active workspace.<br>"));
+      tool_tip += QString (tr ("Colors for variable attributes:"));
+      for (int i = 0; i < resource_manager::storage_class_chars ().length (); i++)
+        {
+          tool_tip +=
+            QString ("<div style=\"background-color:%1;color:#000000\">%2</div>")
+            .arg (_model->storage_class_color (i).name ())
+            .arg (resource_manager::storage_class_names ().at (i));
+        }
     }
+
   setToolTip (tool_tip);
+
 }
 
 void
@@ -276,3 +377,10 @@
     handle_contextmenu_copy ();
 }
 
+void
+workspace_view::selectAll ()
+{
+  if (view->hasFocus ())
+    view->selectAll ();
+}
+
--- a/libgui/src/workspace-view.h	Fri Feb 06 08:31:09 2015 -0800
+++ b/libgui/src/workspace-view.h	Fri Feb 06 08:31:49 2015 -0800
@@ -27,6 +27,9 @@
 #include <QItemDelegate>
 #include <QTableView>
 #include <QSemaphore>
+#include <QComboBox>
+#include <QSortFilterProxyModel>
+#include <QCheckBox>
 
 #include "octave-dock-widget.h"
 #include "workspace-model.h"
@@ -62,6 +65,7 @@
 
   // context menu slots
   void handle_contextmenu_copy (void);
+  void handle_contextmenu_copy_value (void);
   void handle_contextmenu_rename (void);
   void handle_contextmenu_disp (void);
   void handle_contextmenu_plot (void);
@@ -70,14 +74,25 @@
   void handle_model_changed (void);
 
   void copyClipboard ();
+  void selectAll ();
+
+  void filter_update (const QString& expression);
+  void filter_activate (bool enable);
+  void update_filter_history ();
 
 private:
 
   void relay_contextmenu_command (const QString& cmdname);
 
+  QString get_var_name (QModelIndex index);
   QTableView *view;
   int view_previous_row_count;
   workspace_model *_model;
+
+  QSortFilterProxyModel _filter_model;
+  QCheckBox *_filter_checkbox;
+  QComboBox *_filter;
+  enum { MaxFilterHistory = 10 };
 };
 
 #endif
--- a/libinterp/Makefile.am	Fri Feb 06 08:31:09 2015 -0800
+++ b/libinterp/Makefile.am	Fri Feb 06 08:31:49 2015 -0800
@@ -32,7 +32,8 @@
   -I$(srcdir)/operators \
   -Iparse-tree -I$(srcdir)/parse-tree \
   -Icorefcn -I$(srcdir)/corefcn \
-  -I$(top_builddir)/libgnu -I$(top_srcdir)/libgnu
+  -I$(top_builddir)/libgnu -I$(top_srcdir)/libgnu \
+  $(HDF5_CPPFLAGS)
 
 AM_CFLAGS += $(WARN_CFLAGS)
 
--- a/libinterp/corefcn/Cell.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/libinterp/corefcn/Cell.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -212,6 +212,12 @@
   return retval;
 }
 
+/*
+%!test
+%! a = {"foo", "bar"};
+%! assert (a(), a)
+*/
+
 void
 Cell::assign (const octave_value_list& idx_arg, const Cell& rhs,
               const octave_value& fill_val)
@@ -248,6 +254,12 @@
   return -1;
 }
 
+/*
+%!error <wrong type argument 'cell array'> nnz ({0, 1, 2})
+%!error <wrong type argument 'cell array'> nnz (cell ())
+%!error <wrong type argument 'cell array'> nnz ({"foo", "bar"})
+*/
+
 Cell
 Cell::column (octave_idx_type i) const
 {
--- a/libinterp/corefcn/Cell.h	Fri Feb 06 08:31:09 2015 -0800
+++ b/libinterp/corefcn/Cell.h	Fri Feb 06 08:31:49 2015 -0800
@@ -27,7 +27,6 @@
 #include <string>
 
 #include "Array.h"
-#include "oct-alloc.h"
 #include "str-vec.h"
 #include "ov.h"
 
--- a/libinterp/corefcn/__contourc__.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/libinterp/corefcn/__contourc__.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -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 Feb 06 08:31:09 2015 -0800
+++ b/libinterp/corefcn/__pchip_deriv__.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -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 Feb 06 08:31:09 2015 -0800
+++ b/libinterp/corefcn/balance.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -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 Feb 06 08:31:09 2015 -0800
+++ b/libinterp/corefcn/besselj.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -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 Feb 06 08:31:09 2015 -0800
+++ b/libinterp/corefcn/betainc.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -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 Feb 06 08:31:09 2015 -0800
+++ b/libinterp/corefcn/bitfcns.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -159,6 +159,10 @@
                               octave_float_scalar::static_class_name () &&
                               args(1).class_name () !=
                               octave_bool::static_class_name ());
+          bool arg0_is_bool = args(0).class_name () ==
+                              octave_bool::static_class_name ();
+          bool arg1_is_bool = args(1).class_name () ==
+                              octave_bool::static_class_name ();
           bool arg0_is_float = args(0).class_name () ==
                                octave_float_scalar::static_class_name ();
           bool arg1_is_float = args(1).class_name () ==
@@ -166,12 +170,12 @@
 
           if (! (arg0_is_int || arg1_is_int))
             {
-              if (! (arg0_is_float || arg1_is_float))
+              if (arg0_is_bool && arg1_is_bool)
                 {
-                  uint64NDArray x (args(0).array_value ());
-                  uint64NDArray y (args(1).array_value ());
+                  boolNDArray x (args(0).bool_array_value ());
+                  boolNDArray y (args(1).bool_array_value ());
                   if (! error_state)
-                    retval = bitopx (fname, x, y).array_value ();
+                    retval = bitopx (fname, x, y).bool_array_value ();
                 }
               else if (arg0_is_float && arg1_is_float)
                 {
@@ -180,6 +184,13 @@
                   if (! error_state)
                     retval = bitopx (fname, x, y).float_array_value ();
                 }
+              else if (! (arg0_is_float || arg1_is_float))
+                {
+                  uint64NDArray x (args(0).array_value ());
+                  uint64NDArray y (args(1).array_value ());
+                  if (! error_state)
+                    retval = bitopx (fname, x, y).array_value ();
+                }
               else
                 {
                   int p = (arg0_is_float ? 1 : 0);
@@ -377,6 +388,27 @@
   return bitop ("bitxor", args);
 }
 
+/*
+%!assert (bitand (true, false), false)
+%!assert (bitor  (true, false), true)
+%!assert (bitxor (true, false), true)
+
+%!assert (bitand (true, true), true)
+%!assert (bitor  (true, true), true)
+%!assert (bitxor (true, true), false)
+
+%!assert (bitand (true, 5), 1)
+
+%!assert (bitand (true, false), false)
+%!assert (bitand (true, true), true)
+%!assert (bitand (true, false), false)
+%!assert (bitand (true, false), false)
+
+## Test idx_arg.length () == 0
+%!error <size of X and Y must match> bitand ([0 0 0], [1 0])
+%!error <size of X and Y must match> bitand ([0; 0; 0], [0 0 0])
+*/
+
 template <typename T>
 static int64_t
 max_mantissa_value ()
@@ -595,7 +627,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")
         {
@@ -621,6 +653,19 @@
   return retval;
 }
 
+/*
+%!assert (bitshift (uint8  (16), 1),  uint8 ( 32))
+%!assert (bitshift (uint16 (16), 2), uint16 ( 64))
+%!assert (bitshift (uint32 (16), 3), uint32 (128))
+%!assert (bitshift (uint64 (16), 4), uint64 (256))
+%!assert (bitshift (uint8 (255), 1), uint8 (254))
+
+%!error <expecting integer as second argument> bitshift (16, 1.5)
+%!error bitshift (16, {1})
+%!error <N must be a scalar integer> bitshift (10, [-2 -1 0 1 2], [1 1 1 1 1])
+%!error <N must be positive> bitshift (10, [-2 -1 0 1 2], -1)
+*/
+
 DEFUN (bitmax, args, ,
        "-*- texinfo -*-\n\
 @deftypefn  {Built-in Function} {} bitmax ()\n\
--- a/libinterp/corefcn/bsxfun.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/libinterp/corefcn/bsxfun.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -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 Feb 06 08:31:49 2015 -0800
@@ -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 Feb 06 08:31:49 2015 -0800
@@ -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 Feb 06 08:31:09 2015 -0800
+++ b/libinterp/corefcn/cellfun.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -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/colloc.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/libinterp/corefcn/colloc.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -38,8 +38,8 @@
        "-*- texinfo -*-\n\
 @deftypefn {Built-in Function} {[@var{r}, @var{amat}, @var{bmat}, @var{q}] =} colloc (@var{n}, \"left\", \"right\")\n\
 Compute derivative and integral weight matrices for orthogonal\n\
-collocation using the subroutines given in J. Villadsen and\n\
-M. L. Michelsen, @cite{Solution of Differential Equation Models by\n\
+collocation using the subroutines given in @nospell{J. Villadsen} and\n\
+@nospell{M. L. Michelsen}, @cite{Solution of Differential Equation Models by\n\
 Polynomial Approximation}.\n\
 @end deftypefn")
 {
--- a/libinterp/corefcn/cutils.c	Fri Feb 06 08:31:09 2015 -0800
+++ b/libinterp/corefcn/cutils.c	Fri Feb 06 08:31:49 2015 -0800
@@ -53,8 +53,3 @@
   nanosleep (&delay, &remaining);
 }
 
-int
-octave_raw_vsnprintf (char *buf, size_t n, const char *fmt, va_list args)
-{
-  return vsnprintf (buf, n, fmt, args);
-}
--- a/libinterp/corefcn/cutils.h	Fri Feb 06 08:31:09 2015 -0800
+++ b/libinterp/corefcn/cutils.h	Fri Feb 06 08:31:49 2015 -0800
@@ -33,9 +33,6 @@
 
 OCTINTERP_API void octave_usleep (unsigned int useconds);
 
-OCTINTERP_API int
-octave_raw_vsnprintf (char *buf, size_t n, const char *fmt, va_list args);
-
 #ifdef __cplusplus
 }
 #endif
--- a/libinterp/corefcn/data.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/libinterp/corefcn/data.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -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 ())
@@ -575,8 +576,7 @@
 
 DEFUN (rem, args, ,
        "-*- texinfo -*-\n\
-@deftypefn  {Mapping Function} {} rem (@var{x}, @var{y})\n\
-@deftypefnx {Mapping Function} {} fmod (@var{x}, @var{y})\n\
+@deftypefn {Mapping Function} {} rem (@var{x}, @var{y})\n\
 Return the remainder of the division @code{@var{x} / @var{y}}, computed\n\
 using the expression\n\
 \n\
@@ -621,7 +621,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);
@@ -676,11 +676,11 @@
 }
 
 /*
-%!assert (size (fmod (zeros (0, 2), zeros (0, 2))), [0, 2])
-%!assert (size (fmod (rand (2, 3, 4), zeros (2, 3, 4))), [2, 3, 4])
-%!assert (size (fmod (rand (2, 3, 4), 1)), [2, 3, 4])
-%!assert (size (fmod (1, rand (2, 3, 4))), [2, 3, 4])
-%!assert (size (fmod (1, 2)), [1, 1])
+%!assert (size (rem (zeros (0, 2), zeros (0, 2))), [0, 2])
+%!assert (size (rem (rand (2, 3, 4), zeros (2, 3, 4))), [2, 3, 4])
+%!assert (size (rem (rand (2, 3, 4), 1)), [2, 3, 4])
+%!assert (size (rem (1, rand (2, 3, 4))), [2, 3, 4])
+%!assert (size (rem (1, 2)), [1, 1])
 
 %!assert (rem ([1, 2, 3; -1, -2, -3], 2), [1, 0, 1; -1, 0, -1])
 %!assert (rem ([1, 2, 3; -1, -2, -3], 2 * ones (2, 3)),[1, 0, 1; -1, 0, -1])
@@ -726,8 +726,6 @@
 %!assert (rem (0.94, 0.01), 0.0);
 */
 
-DEFALIAS (fmod, rem)
-
 DEFUN (mod, args, ,
        "-*- texinfo -*-\n\
 @deftypefn {Mapping Function} {} mod (@var{x}, @var{y})\n\
@@ -780,7 +778,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);
@@ -1207,7 +1205,7 @@
           else if (str == "double")
             isdouble = true;
           else
-            error ("sum: unrecognized string argument");
+            error ("cumsum: unrecognized string argument");
           nargin --;
         }
     }
@@ -1262,7 +1260,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);
@@ -1332,8 +1330,8 @@
 @deftypefnx {Built-in Function} {@var{v} =} diag (@var{M}, @var{k})\n\
 Return a diagonal matrix with vector @var{v} on diagonal @var{k}.  The\n\
 second argument is optional.  If it is positive, the vector is placed on\n\
-the @var{k}-th super-diagonal.  If it is negative, it is placed on the\n\
-@var{-k}-th sub-diagonal.  The default value of @var{k} is 0, and the\n\
+the @var{k}-th superdiagonal.  If it is negative, it is placed on the\n\
+@var{-k}-th subdiagonal.  The default value of @var{k} is 0, and the\n\
 vector is placed on the main diagonal.  For example:\n\
 \n\
 @example\n\
@@ -1438,6 +1436,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 +1461,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 +1612,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 +1649,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
@@ -1928,7 +2087,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)
@@ -1942,12 +2101,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)
                 {
@@ -2406,8 +2565,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])
@@ -2447,6 +2606,27 @@
 Return the generalized transpose for an N-D array object @var{A}.\n\
 The permutation vector @var{perm} must contain the elements\n\
 @code{1:ndims (A)} (in any order, but each element must appear only once).\n\
+\n\
+The @var{N}th dimension of @var{A} gets remapped to dimension \n\
+@code{@var{PERM}(@var{N})}.  For example:\n\
+\n\
+@example\n\
+@group\n\
+@var{x} = zeros ([2, 3, 5, 7]);\n\
+size (@var{x})\n\
+   @result{}  2   3   5   7\n\
+\n\
+size (permute (@var{x}, [2, 1, 3, 4]))\n\
+   @result{}  3   2   5   7\n\
+\n\
+size (permute (@var{x}, [1, 3, 4, 2]))\n\
+   @result{}  2   5   7   3\n\
+\n\
+## The identity permutation\n\
+size (permute (@var{x}, [1, 2, 3, 4]))\n\
+   @result{}  2   3   5   7\n\
+@end group\n\
+@end example\n\
 @seealso{ipermute}\n\
 @end deftypefn")
 {
@@ -2693,7 +2873,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")
 {
@@ -2769,12 +2949,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\
@@ -2788,8 +2972,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\
@@ -2816,7 +3000,7 @@
           else if (str == "extra")
             isextra = true;
           else
-            error ("sum: unrecognized string argument");
+            error ("sum: unrecognized type argument '%s'", str.c_str ());
           nargin --;
         }
     }
@@ -2883,7 +3067,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);
@@ -2893,7 +3077,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);
@@ -2926,11 +3111,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)
@@ -2981,10 +3161,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, ,
@@ -3495,6 +3683,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\
@@ -3545,6 +3891,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)
 {
@@ -4690,7 +5077,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\
@@ -5436,7 +5823,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));
@@ -5485,9 +5872,10 @@
 
 DEFUN (not, args, ,
        "-*- texinfo -*-\n\
-@deftypefn {Built-in Function} {} not (@var{x})\n\
-Return the logical NOT of @var{x}.  This function is equivalent to\n\
-@code{! x}.\n\
+@deftypefn {Built-in Function} {@var{z} =} not (@var{x})\n\
+Return the logical NOT of @var{x}.\n\
+\n\
+This function is equivalent to the operator syntax @w{@code{! x}}.\n\
 @seealso{and, or, xor}\n\
 @end deftypefn")
 {
@@ -5826,12 +6214,13 @@
 
 DEFUN (and, args, ,
        "-*- texinfo -*-\n\
-@deftypefn  {Built-in Function} {} and (@var{x}, @var{y})\n\
-@deftypefnx {Built-in Function} {} and (@var{x1}, @var{x2}, @dots{})\n\
+@deftypefn  {Built-in Function} {@var{z} =} and (@var{x}, @var{y})\n\
+@deftypefnx {Built-in Function} {@var{z} =} and (@var{x1}, @var{x2}, @dots{})\n\
 Return the logical AND of @var{x} and @var{y}.\n\
-This function is equivalent to @w{@code{x & y}}.\n\
-If more arguments are given, the logical and is applied\n\
-cumulatively from left to right:\n\
+\n\
+This function is equivalent to the operator syntax @w{@code{x & y}}.  If\n\
+more than two arguments are given, the logical AND is applied cumulatively\n\
+from left to right:\n\
 \n\
 @example\n\
 (@dots{}((x1 & x2) & x3) & @dots{})\n\
@@ -5847,12 +6236,13 @@
 
 DEFUN (or, args, ,
        "-*- texinfo -*-\n\
-@deftypefn  {Built-in Function} {} or (@var{x}, @var{y})\n\
-@deftypefnx {Built-in Function} {} or (@var{x1}, @var{x2}, @dots{})\n\
+@deftypefn  {Built-in Function} {@var{z} =} or (@var{x}, @var{y})\n\
+@deftypefnx {Built-in Function} {@var{z} =} or (@var{x1}, @var{x2}, @dots{})\n\
 Return the logical OR of @var{x} and @var{y}.\n\
-This function is equivalent to @w{@code{x | y}}.\n\
-If more arguments are given, the logical or is applied\n\
-cumulatively from left to right:\n\
+\n\
+This function is equivalent to the operator syntax @w{@code{x | y}}.  If\n\
+more than two arguments are given, the logical OR is applied cumulatively\n\
+from left to right:\n\
 \n\
 @example\n\
 (@dots{}((x1 | x2) | x3) | @dots{})\n\
@@ -6465,18 +6855,20 @@
   // FIXME: shouldn't these modes be scoped inside a class?
   sortmode smode = UNSORTED;
 
-  std::string mode = arg.string_value ();
-
-  if (error_state)
-    error ("issorted: expecting %s argument to be a character string", argn);
-  else if (mode == "ascending")
-    smode = ASCENDING;
-  else if (mode == "descending")
-    smode = DESCENDING;
-  else if (mode == "either")
-    smode = UNSORTED;
+  if (arg.is_string ())
+    {
+      std::string mode = arg.string_value ();
+      if (mode == "ascending")
+        smode = ASCENDING;
+      else if (mode == "descending")
+        smode = DESCENDING;
+      else if (mode == "either")
+        smode = UNSORTED;
+      else
+        error ("issorted: MODE must be \"ascending\", \"descending\", or \"either\"");
+    }
   else
-    error ("issorted: MODE must be \"ascending\", \"descending\", or \"either\"");
+    error ("issorted: expecting %s argument to be a string", argn);
 
   return smode;
 }
@@ -6520,17 +6912,16 @@
       if (nargin == 3)
         smode = get_sort_mode_option (args(2), "third");
 
-      std::string tmp = args(1).string_value ();
-
-      if (! error_state)
+      if (args(1).is_string ())
         {
+          std::string tmp = args(1).string_value ();
           if (tmp == "rows")
             by_rows = true;
           else
             smode = get_sort_mode_option (args(1), "second");
         }
       else
-        error ("expecting second argument to be character string");
+        error ("issorted: second argument must be a string");
 
       if (error_state)
         return retval;
@@ -6653,7 +7044,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);
@@ -6797,7 +7188,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 ())
             {
@@ -6824,7 +7216,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);
@@ -6879,7 +7271,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 ();
@@ -6958,7 +7351,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))
@@ -6968,14 +7362,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;
             }
@@ -7052,7 +7448,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 ())
@@ -7330,7 +7727,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);
@@ -7417,7 +7815,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 Feb 06 08:31:09 2015 -0800
+++ b/libinterp/corefcn/debug.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -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;
-                }
+          while (std::getline (fs, text) && line <= end)
+          {
+            if (line >= start)
+              os << line << "\t" << text << "\n";
 
-              if (line >= start)
-                {
-                  os << ch;
-                }
-
-              if (ch == '\n')
-                {
-                  line++;
-                  isnewline = true;
-                }
-            }
+            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\
@@ -1401,7 +1462,7 @@
                 }
             }
           else
-            error ("dbstep: input argument must be a character string");
+            error ("dbstep: input argument must be a string");
         }
       else
         {
@@ -1485,3 +1546,38 @@
 
   return retval;
 }
+
+DEFUN (db_next_breakpoint_quiet, args, ,
+       "-*- texinfo -*-\n\
+@deftypefn  {Built-in Function} {} db_next_breakpoint_quiet ()\n\
+@deftypefnx {Built-in Function} {} db_next_breakpoint_quiet (@var{flag})\n\
+Disable line info printing at the next breakpoint.  With a logical\n\
+argument, set the state on or off.\n\
+@end deftypefn")
+{
+  octave_value retval;
+
+  int nargin = args.length ();
+
+  if (nargin == 0 || nargin == 1)
+    {
+      bool state = true;
+
+      if (nargin == 1)
+        {
+          state = args(0).bool_value ();
+
+          if (error_state)
+            {
+              gripe_wrong_type_arg ("db_next_breakpoint", args(0), true);
+              return retval;
+            }
+        }
+
+      tree_evaluator::quiet_breakpoint_flag = state;
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
--- a/libinterp/corefcn/defaults.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/libinterp/corefcn/defaults.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -74,6 +74,7 @@
 std::string Vlocal_api_fcn_file_dir;
 std::string Vlocal_fcn_file_dir;
 
+std::string Voct_data_dir;
 std::string Voct_etc_dir;
 std::string Voct_locale_dir;
 
@@ -219,6 +220,12 @@
 }
 
 static void
+set_default_oct_data_dir (void)
+{
+  Voct_data_dir = subst_octave_home (OCTAVE_OCTDATADIR);
+}
+
+static void
 set_default_oct_etc_dir (void)
 {
   Voct_etc_dir = subst_octave_home (OCTAVE_OCTETCDIR);
@@ -435,6 +442,7 @@
   set_default_local_api_fcn_file_dir ();
   set_default_local_fcn_file_dir ();
 
+  set_default_oct_data_dir ();
   set_default_oct_etc_dir ();
   set_default_oct_locale_dir ();
 
@@ -594,7 +602,8 @@
 DEFUNX ("OCTAVE_VERSION", FOCTAVE_VERSION, args, ,
         "-*- texinfo -*-\n\
 @deftypefn {Built-in Function} {} OCTAVE_VERSION ()\n\
-Return the version number of Octave, as a string.\n\
+Return the version number of Octave as a string.\n\
+@seealso{ver, version}\n\
 @end deftypefn")
 {
   octave_value retval;
--- a/libinterp/corefcn/defaults.in.h	Fri Feb 06 08:31:09 2015 -0800
+++ b/libinterp/corefcn/defaults.in.h	Fri Feb 06 08:31:49 2015 -0800
@@ -148,6 +148,10 @@
 #define OCTAVE_MANDIR %OCTAVE_MANDIR%
 #endif
 
+#ifndef OCTAVE_OCTDATADIR
+#define OCTAVE_OCTDATADIR %OCTAVE_OCTDATADIR%
+#endif
+
 #ifndef OCTAVE_OCTFILEDIR
 #define OCTAVE_OCTFILEDIR %OCTAVE_OCTFILEDIR%
 #endif
@@ -202,6 +206,7 @@
 extern OCTINTERP_API std::string Vlocal_api_fcn_file_dir;
 extern OCTINTERP_API std::string Vlocal_fcn_file_dir;
 
+extern OCTINTERP_API std::string Voct_data_dir;
 extern OCTINTERP_API std::string Voct_etc_dir;
 extern OCTINTERP_API std::string Voct_locale_dir;
 
--- a/libinterp/corefcn/dirfns.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/libinterp/corefcn/dirfns.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -608,7 +608,7 @@
         [2,1] = file2\n\
       @}\n\
 @end example\n\
-@seealso{ls, dir, readdir, what, fnmatch}\n\
+@seealso{ls, dir, readdir, what}\n\
 @end deftypefn")
 {
   octave_value retval;
@@ -634,7 +634,7 @@
 
 /*
 %!test
-%! tmpdir = tmpnam;
+%! tmpdir = tempname;
 %! filename = {"file1", "file2", "file3", "myfile1", "myfile1b"};
 %! if (mkdir (tmpdir))
 %!   cwd = pwd;
@@ -664,7 +664,7 @@
 %! assert (result3, {"file1"; "file2"});
 */
 
-DEFUNX ("fnmatch", Ffnmatch, args, ,
+DEFUN (__fnmatch__, args, ,
         "-*- texinfo -*-\n\
 @deftypefn {Built-in Function} {} fnmatch (@var{pattern}, @var{string})\n\
 Return true or false for each element of @var{string} that matches any of\n\
--- a/libinterp/corefcn/display.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/libinterp/corefcn/display.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -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 Feb 06 08:31:09 2015 -0800
+++ b/libinterp/corefcn/dlmread.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -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;
@@ -483,7 +491,7 @@
 
 /*
 %!shared file
-%! file = tmpnam ();
+%! file = tempname ();
 %! fid = fopen (file, "wt");
 %! fwrite (fid, "1, 2, 3\n4, 5, 6\n7, 8, 9\n10, 11, 12");
 %! fclose (fid);
@@ -502,7 +510,7 @@
 %! unlink (file);
 
 %!shared file
-%! file = tmpnam ();
+%! file = tempname ();
 %! fid = fopen (file, "wt");
 %! fwrite (fid, "1, 2, 3\n4+4i, 5, 6\n7, 8, 9\n10, 11, 12");
 %! fclose (fid);
--- a/libinterp/corefcn/dot.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/libinterp/corefcn/dot.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -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 ())
@@ -245,10 +247,12 @@
 %! x = [2, 1; 2, 1];
 %! y = [-0.5, 2; 0.5, -2];
 %! assert (dot (x, y), [0 0]);
+%! assert (dot (single (x), single (y)), single ([0 0]));
 
 %!test
 %! x = [1+i, 3-i; 1-i, 3-i];
 %! assert (dot (x, x), [4, 20]);
+%! assert (dot (single (x), single (x)), single ([4, 20]));
 
 %!test
 %! x = int8 ([1 2]);
@@ -301,13 +305,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;
@@ -390,4 +399,24 @@
 %! z(:,:,1) = [7 10; 15 22];
 %! z(:,:,2) = [2 2; 2 2];
 %! assert (blkmm (x,x), z);
+%! assert (blkmm (single (x), single (x)), single (z));
+%! assert (blkmm (x, single (x)), single (z));
+
+%!test
+%! x(:,:,1) = [1 2; 3 4];
+%! x(:,:,2) = [1i 1i; 1i 1i];
+%! z(:,:,1) = [7 10; 15 22];
+%! z(:,:,2) = [-2 -2; -2 -2];
+%! assert (blkmm (x,x), z);
+%! assert (blkmm (single (x), single (x)), single (z));
+%! assert (blkmm (x, single (x)), single (z));
+
+%% Test input validation
+%!error blkmm ()
+%!error blkmm (1)
+%!error blkmm (1,2,3)
+%!error <A and B dimensions don't match> blkmm (ones (2,2), ones (3,3))
+%!error <A and B must be numeric> blkmm ({1,2}, [3,4])
+%!error <A and B must be numeric> blkmm ([3,4], {1,2})
 */
+
--- a/libinterp/corefcn/eig.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/libinterp/corefcn/eig.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -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/ellipj.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/libinterp/corefcn/ellipj.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -67,7 +67,7 @@
 return @code{NaN}.\n\
 @end enumerate\n\
 \n\
-Reference: Milton Abramowitz and Irene A Stegun,\n\
+Reference: Milton @nospell{Abramowitz} and Irene A @nospell{Stegun},\n\
 @cite{Handbook of Mathematical Functions}, Chapter 16 (Sections 16.4, 16.13,\n\
 and 16.15), Dover, 1965.\n\
 \n\
@@ -919,6 +919,15 @@
 %! assert (cn, C, 8*eps);
 %! assert (dn, D, 8*eps);
 
+%!test
+%! ## Test continuity of dn when cn is near zero (bug #43344)
+%! m = 0.5;
+%! u = ellipke (0.5);
+%! x = [-1e-3, -1e-12, 0, 1e-12, 1e-3];
+%! [~, ~, dn] = ellipj (u + x, m);
+%! D = 1/sqrt (2) * ones (size (x));
+%! assert (dn, D, 1e-6);
+
 %!error ellipj ()
 %!error ellipj (1)
 %!error ellipj (1,2,3,4)
--- a/libinterp/corefcn/error.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/libinterp/corefcn/error.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -27,6 +27,7 @@
 #include <cstdarg>
 #include <cstring>
 
+#include <iomanip>
 #include <iostream>
 #include <sstream>
 #include <string>
@@ -40,6 +41,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"
@@ -61,13 +63,12 @@
 
 // TRUE means that Octave will try to display a stack trace when a
 // warning is encountered.
-static bool Vbacktrace_on_warning = false;
+static bool Vbacktrace_on_warning = true;
 
 // 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.
@@ -170,13 +171,8 @@
 
   std::string msg_string = output_buf.str ();
 
-  if (! warning_state)
-    {
-      // This is the first warning in a possible series.
-
-      Vlast_warning_id = id;
-      Vlast_warning_message = msg_string;
-    }
+  Vlast_warning_id = id;
+  Vlast_warning_message = msg_string;
 
   if (! Vquiet_warning)
     {
@@ -267,6 +263,70 @@
     }
 }
 
+static void
+pr_where_2 (const char *fmt, va_list args)
+{
+  if (fmt)
+    {
+      if (*fmt)
+        {
+          size_t len = strlen (fmt);
+
+          if (len > 0)
+            {
+              if (fmt[len - 1] == '\n')
+                {
+                  if (len > 1)
+                    {
+                      char *tmp_fmt = strsave (fmt);
+                      tmp_fmt[len - 1] = '\0';
+                      verror (false, std::cerr, 0, "", tmp_fmt, args);
+                      delete [] tmp_fmt;
+                    }
+                }
+              else
+                verror (false, std::cerr, 0, "", fmt, args);
+            }
+        }
+    }
+  else
+    panic ("pr_where_2: invalid format");
+}
+
+static void
+pr_where_1 (const char *fmt, ...)
+{
+  va_list args;
+  va_start (args, fmt);
+  pr_where_2 (fmt, args);
+  va_end (args);
+}
+
+static void
+pr_where (const char *who)
+{
+  std::list<octave_call_stack::stack_frame> frames
+    = octave_call_stack::backtrace_frames ();
+
+  size_t nframes = frames.size ();
+
+  if (nframes > 0)
+    pr_where_1 ("%s: called from\n", who);
+
+  for (std::list<octave_call_stack::stack_frame>::const_iterator p = frames.begin ();
+       p != frames.end (); p++)
+    {
+      const octave_call_stack::stack_frame& elt = *p;
+
+      std::string fcn_name = elt.fcn_name ();
+      int line = elt.line ();
+      int column = elt.column ();
+
+      pr_where_1 ("    %s at line %d column %d\n",
+                  fcn_name.c_str (), line, column);
+    }
+}
+
 // Note that we don't actually print any message if the error string
 // is just "" or "\n".  This allows error ("") and error ("\n") to
 // just set the error state.
@@ -381,82 +441,16 @@
 }
 
 static void
-pr_where_2 (const char *fmt, va_list args)
-{
-  if (fmt)
-    {
-      if (*fmt)
-        {
-          size_t len = strlen (fmt);
-
-          if (len > 0)
-            {
-              if (fmt[len - 1] == '\n')
-                {
-                  if (len > 1)
-                    {
-                      char *tmp_fmt = strsave (fmt);
-                      tmp_fmt[len - 1] = '\0';
-                      verror (false, std::cerr, 0, "", tmp_fmt, args);
-                      delete [] tmp_fmt;
-                    }
-                }
-              else
-                verror (false, std::cerr, 0, "", fmt, args);
-            }
-        }
-    }
-  else
-    panic ("pr_where_2: invalid format");
-}
-
-static void
-pr_where_1 (const char *fmt, ...)
-{
-  va_list args;
-  va_start (args, fmt);
-  pr_where_2 (fmt, args);
-  va_end (args);
-}
-
-static void
-pr_where (const char *who)
-{
-  octave_idx_type curr_frame = -1;
-
-  octave_map stk = octave_call_stack::backtrace (0, curr_frame);
-
-  octave_idx_type nframes_to_display = stk.numel ();
-
-  if (nframes_to_display > 0)
-    {
-      pr_where_1 ("%s: called from\n", who);
-
-      Cell names = stk.contents ("name");
-      Cell lines = stk.contents ("line");
-      Cell columns = stk.contents ("column");
-
-      for (octave_idx_type i = 0; i < nframes_to_display; i++)
-        {
-          octave_value name = names(i);
-          octave_value line = lines(i);
-          octave_value column = columns(i);
-
-          std::string nm = name.string_value ();
-
-          pr_where_1 ("    %s at line %d column %d\n", nm.c_str (),
-                      line.int_value (), column.int_value ());
-        }
-    }
-}
-
-static void
 error_2 (const char *id, const char *fmt, va_list args, bool with_cfn = false)
 {
   int init_state = error_state;
 
   error_1 (std::cerr, "error", id, fmt, args, with_cfn);
 
+  if (error_state != -2 && ! symbol_table::at_top_level ()
+      && ! discard_error_messages)
+    pr_where ("error");
+
   if ((interactive || forced_interactive)
       && Vdebug_on_error && init_state == 0
       && octave_call_stack::caller_user_code ())
@@ -467,7 +461,9 @@
 
       error_state = 0;
 
-      pr_where ("error");
+      tree_evaluator::debug_mode = true;
+
+      tree_evaluator::current_frame = octave_call_stack::current_frame ();
 
       do_keyboard (octave_value_list ());
     }
@@ -657,6 +653,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 ());
         }
     }
@@ -1217,6 +1217,127 @@
   return retval;
 }
 
+static std::string
+default_warning_state (void)
+{
+  std::string retval = "on";
+
+  Cell ident = warning_options.contents ("identifier");
+  Cell state = warning_options.contents ("state");
+
+  octave_idx_type nel = ident.numel ();
+
+  for (octave_idx_type i = 0; i < nel; i++)
+    {
+      if (ident(i).string_value () == "all")
+        {
+          retval = state(i).string_value ();
+          break;
+        }
+    }
+
+  return retval;
+}
+
+static void
+display_warning_options (std::ostream& os)
+{
+  Cell ident = warning_options.contents ("identifier");
+  Cell state = warning_options.contents ("state");
+
+  octave_idx_type nel = ident.numel ();
+
+  std::string all_state = default_warning_state ();
+
+  if (all_state == "on")
+    os << "By default, warnings are enabled.";
+  else if (all_state == "off")
+    os << "By default, warnings are disabled.";
+  else if (all_state == "error")
+    os << "By default, warnings are treated as errors.";
+  else
+    panic_impossible ();
+
+  if (nel > 1)
+    os << "\n\n";
+
+  // The state for all is always supposed to be first in the list.
+
+  for (octave_idx_type i = 1; i < nel; i++)
+    {
+      std::string tid = ident(i).string_value ();
+      std::string tst = state(i).string_value ();
+
+      os << std::setw (7) << tst << "  " << tid << "\n";
+    }
+
+  os << std::endl;
+}
+
+static void
+set_warning_option (const std::string& state, const std::string& ident)
+{
+  if (ident == "all")
+    {
+      initialize_warning_options (state);
+      return;
+    }
+
+  std::string all_state = default_warning_state ();
+
+  if (state != "on" && state != "off" && state != "error")
+    error ("invalid warning state: %s", state.c_str ());
+
+  Cell tid = warning_options.contents ("identifier");
+  Cell tst = warning_options.contents ("state");
+
+  octave_idx_type nel = tid.numel ();
+
+  for (octave_idx_type i = 0; i < nel; i++)
+    {
+      if (tid(i).string_value () == ident)
+        {
+          // We found it in the current list of options.  If the state
+          // for "all" is same as arg1, we can simply remove the item
+          // from the list.
+
+          if (state == all_state)
+            {
+              for (i = i + 1; i < nel; i++)
+                {
+                  tid(i-1) = tid(i);
+                  tst(i-1) = tst(i);
+                }
+
+              tid.resize (dim_vector (1, nel-1));
+              tst.resize (dim_vector (1, nel-1));
+            }
+          else
+            tst(i) = state;
+
+          warning_options.clear ();
+
+          warning_options.assign ("identifier", tid);
+          warning_options.assign ("state", tst);
+
+          return;
+        }
+    }
+
+  // The option wasn't already in the list.  Append it.
+
+  tid.resize (dim_vector (1, nel+1));
+  tst.resize (dim_vector (1, nel+1));
+
+  tid(nel) = ident;
+  tst(nel) = state;
+
+  warning_options.clear ();
+
+  warning_options.assign ("identifier", tid);
+  warning_options.assign ("state", tst);
+}
+
 DEFUN (warning, args, nargout,
        "-*- texinfo -*-\n\
 @deftypefn  {Built-in Function} {} warning (@var{template}, @dots{})\n\
@@ -1225,6 +1346,7 @@
 @deftypefnx {Built-in Function} {} warning (\"off\", @var{id})\n\
 @deftypefnx {Built-in Function} {} warning (\"query\", @var{id})\n\
 @deftypefnx {Built-in Function} {} warning (\"error\", @var{id})\n\
+@deftypefnx {Built-in Function} {} warning (@var{state}, \"backtrace\")\n\
 @deftypefnx {Built-in Function} {} warning (@var{state}, @var{id}, \"local\")\n\
 Format the optional arguments under the control of the template string\n\
 @var{template} using the same rules as the @code{printf} family of\n\
@@ -1255,6 +1377,11 @@
 @end group\n\
 @end example\n\
 \n\
+If the state is @qcode{\"on\"} or @qcode{\"off\"} and the third argument\n\
+is @qcode{\"backtrace\"}, then a stack trace is printed along with the\n\
+warning message when warnings occur inside function calls.  This option\n\
+is enabled by default.\n\
+\n\
 If the state is @qcode{\"on\"}, @qcode{\"off\"}, or @qcode{\"error\"}\n\
 and the third argument is @qcode{\"local\"}, then the warning state\n\
 will be set temporarily, until the end of the current function.\n\
@@ -1465,49 +1592,7 @@
                   if (arg2 == "last")
                     arg2 = Vlast_warning_id;
 
-                  if (arg2 == "all")
-                    initialize_warning_options (arg1);
-                  else
-                    {
-                      Cell ident = warning_options.contents ("identifier");
-                      Cell state = warning_options.contents ("state");
-
-                      octave_idx_type nel = ident.numel ();
-
-                      bool found = false;
-
-                      for (octave_idx_type i = 0; i < nel; i++)
-                        {
-                          if (ident(i).string_value () == arg2)
-                            {
-                              // FIXME: if state for "all" is  same as arg1,
-                              //        we can simply remove the item
-                              //        from the list.
-
-                              state(i) = arg1;
-                              warning_options.assign ("state", state);
-                              found = true;
-                              break;
-                            }
-                        }
-
-                      if (! found)
-                        {
-                          // FIXME: if state for "all" is same as arg1,
-                          //        we don't need to do anything.
-
-                          ident.resize (dim_vector (1, nel+1));
-                          state.resize (dim_vector (1, nel+1));
-
-                          ident(nel) = arg2;
-                          state(nel) = arg1;
-
-                          warning_options.clear ();
-
-                          warning_options.assign ("identifier", ident);
-                          warning_options.assign ("state", state);
-                        }
-                    }
+                  set_warning_option (arg1, arg2);
 
                   done = true;
                 }
@@ -1544,7 +1629,10 @@
     }
   else if (argc == 1)
     {
-      retval = warning_options;
+      if (nargout > 0)
+        retval = warning_options;
+      else
+        display_warning_options (octave_stdout);
 
       done = true;
     }
@@ -1559,7 +1647,25 @@
           octave_map m = arg.map_value ();
 
           if (m.contains ("identifier") && m.contains ("state"))
-            warning_options = m;
+            {
+              // Simply step through the struct elements one at a time.
+
+              Cell ident = m.contents ("identifier");
+              Cell state = m.contents ("state");
+
+              octave_idx_type nel = ident.numel ();
+
+              for (octave_idx_type i = 0; i < nel; i++)
+                {
+                  std::string tst = state(i).string_value ();
+                  std::string tid = ident(i).string_value ();
+
+                  if (error_state)
+                    return retval;
+
+                  set_warning_option (tst, tid);
+                }
+            }
           else
             error ("warning: expecting structure with fields 'identifier' and 'state'");
 
@@ -1614,7 +1720,7 @@
 void
 disable_warning (const std::string& id)
 {
-  set_warning_state (id, "off");
+  set_warning_option ("off", id);
 }
 
 void
@@ -1636,9 +1742,6 @@
   disable_warning ("Octave:str-to-num");
   disable_warning ("Octave:mixed-string-concat");
   disable_warning ("Octave:variable-switch-label");
-
-  // This should be an error unless we are in maximum braindamage mode.
-  set_warning_state ("Octave:noninteger-range-as-index", "error");
 }
 
 DEFUN (lasterror, args, ,
@@ -1855,7 +1958,7 @@
             }
         }
       else
-        error ("lasterr: expecting arguments to be character strings");
+        error ("lasterr: all arguments must be strings");
     }
   else
     print_usage ();
@@ -1902,7 +2005,7 @@
             }
         }
       else
-        error ("lastwarn: expecting arguments to be character strings");
+        error ("lastwarn: all arguments must be strings");
     }
   else
     print_usage ();
@@ -1910,7 +2013,7 @@
   return retval;
 }
 
-DEFUN (usage, args, ,
+DEFUN (__usage__, args, ,
        "-*- texinfo -*-\n\
 @deftypefn {Built-in Function} {} usage (@var{msg})\n\
 Print the message @var{msg}, prefixed by the string @samp{usage: }, and\n\
@@ -2008,6 +2111,12 @@
   return Vlast_error_id;
 }
 
+octave_map
+last_error_stack (void)
+{
+  return Vlast_error_stack;
+}
+
 std::string
 last_warning_message (void)
 {
--- a/libinterp/corefcn/error.h	Fri Feb 06 08:31:09 2015 -0800
+++ b/libinterp/corefcn/error.h	Fri Feb 06 08:31:49 2015 -0800
@@ -26,6 +26,7 @@
 #include <cstdarg>
 #include <string>
 
+class octave_map;
 class octave_value_list;
 class unwind_protect;
 
@@ -137,6 +138,7 @@
 // Helper functions to pass last error and warning messages and ids
 extern OCTINTERP_API std::string last_error_message (void);
 extern OCTINTERP_API std::string last_error_id (void);
+extern OCTINTERP_API octave_map last_error_stack (void);
 extern OCTINTERP_API std::string last_warning_message (void);
 extern OCTINTERP_API std::string last_warning_id (void);
 
--- a/libinterp/corefcn/file-io.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/libinterp/corefcn/file-io.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -240,10 +240,17 @@
        "-*- texinfo -*-\n\
 @deftypefn  {Built-in Function} {} fclose (@var{fid})\n\
 @deftypefnx {Built-in Function} {} fclose (\"all\")\n\
-Close the specified file.  If successful, @code{fclose} returns 0,\n\
-otherwise, it returns -1.  The second form of the @code{fclose} call closes\n\
-all open files except @code{stdout}, @code{stderr}, and @code{stdin}.\n\
-@seealso{fopen, freport}\n\
+@deftypefnx {Built-in Function} {@var{status} =} fclose (\"all\")\n\
+Close the file specified by the file descriptor @var{fid}.\n\
+\n\
+If successful, @code{fclose} returns 0, otherwise, it returns -1.  The\n\
+second form of the @code{fclose} call closes all open files except\n\
+@code{stdout}, @code{stderr}, and @code{stdin}.\n\
+\n\
+Programming Note: When using @qcode{\"all\"} the file descriptors associated\n\
+with gnuplot will also be closed.  This will prevent further plotting with\n\
+gnuplot until Octave is closed and restarted.\n\
+@seealso{fopen, fflush, freport}\n\
 @end deftypefn")
 {
   octave_value retval = -1;
@@ -261,8 +268,9 @@
 DEFUN (fclear, args, ,
        "-*- texinfo -*-\n\
 @deftypefn {Built-in Function} {} fclear (@var{fid})\n\
-Clear the stream state for the specified file.\n\
-@seealso{fopen}\n\
+Clear the stream state for the file specified by the file descriptor\n\
+@var{fid}.\n\
+@seealso{ferror, fopen}\n\
 @end deftypefn")
 {
   octave_value retval;
@@ -271,7 +279,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");
 
@@ -287,13 +295,15 @@
 DEFUN (fflush, args, ,
        "-*- texinfo -*-\n\
 @deftypefn {Built-in Function} {} fflush (@var{fid})\n\
-Flush output to @var{fid}.  This is useful for ensuring that all\n\
-pending output makes it to the screen before some other event occurs.\n\
-For example, it is always a good idea to flush the standard output\n\
-stream before calling @code{input}.\n\
+Flush output to file descriptor @var{fid}.\n\
 \n\
 @code{fflush} returns 0 on success and an OS dependent error value\n\
 (@minus{}1 on Unix) on error.\n\
+\n\
+Programming Note: Flushing is useful for ensuring that all pending output\n\
+makes it to the screen before some other event occurs.  For example, it is\n\
+always a good idea to flush the standard output stream before calling\n\
+@code{input}.\n\
 @seealso{fopen, fclose}\n\
 @end deftypefn")
 {
@@ -305,7 +315,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)
         {
@@ -335,8 +345,7 @@
 or @var{len} characters have been read.  The characters read, excluding\n\
 the possible trailing newline, are returned as a string.\n\
 \n\
-If @var{len} is omitted, @code{fgetl} reads until the next newline\n\
-character.\n\
+If @var{len} is omitted, @code{fgetl} reads until the next newline character.\n\
 \n\
 If there are no more characters to read, @code{fgetl} returns @minus{}1.\n\
 \n\
@@ -386,8 +395,7 @@
 or @var{len} characters have been read.  The characters read, including\n\
 the possible trailing newline, are returned as a string.\n\
 \n\
-If @var{len} is omitted, @code{fgets} reads until the next newline\n\
-character.\n\
+If @var{len} is omitted, @code{fgets} reads until the next newline character.\n\
 \n\
 If there are no more characters to read, @code{fgets} returns @minus{}1.\n\
 \n\
@@ -434,7 +442,9 @@
 @deftypefn  {Built-in Function} {@var{nlines} =} fskipl (@var{fid})\n\
 @deftypefnx {Built-in Function} {@var{nlines} =} fskipl (@var{fid}, @var{count})\n\
 @deftypefnx {Built-in Function} {@var{nlines} =} fskipl (@var{fid}, Inf)\n\
-Read and skip @var{count} lines from the file descriptor @var{fid}.\n\
+Read and skip @var{count} lines from the file specified by the file\n\
+descriptor @var{fid}.\n\
+\n\
 @code{fskipl} discards characters until an end-of-line is encountered exactly\n\
 @var{count}-times, or until the end-of-file marker is found.\n\
 \n\
@@ -500,23 +510,8 @@
 
           file_stat fs (fname);
 
-          if (! (md & std::ios::out
-                 || octave_env::absolute_pathname (fname)
-                 || octave_env::rooted_relative_pathname (fname)))
-            {
-              if (! fs.exists ())
-                {
-                  std::string tmp
-                    = octave_env::make_absolute (load_path::find_file (fname));
-
-                  if (! tmp.empty ())
-                    {
-                      warning_with_id ("Octave:fopen-file-in-path",
-                                       "fopen: file found in load path");
-                      fname = tmp;
-                    }
-                }
-            }
+          if (! (md & std::ios::out))
+            fname = find_data_file_in_load_path ("fopen", fname);
 
           if (! fs.is_dir ())
             {
@@ -562,18 +557,20 @@
 
   fid = -1;
 
-  std::string name = tc_name.string_value ();
-
-  if (! error_state)
+  if (tc_name.is_string ())
     {
-      std::string mode = tc_mode.string_value ();
+      std::string name = tc_name.string_value ();
 
-      if (! error_state)
+      if (tc_mode.is_string ())
         {
-          std::string arch = tc_arch.string_value ();
+          std::string mode = tc_mode.string_value ();
 
-          if (! error_state)
-            retval = do_stream_open (name, mode, arch, fid);
+          if (tc_arch.is_string ())
+            {
+              std::string arch = tc_arch.string_value ();
+
+              retval = do_stream_open (name, mode, arch, fid);
+            }
           else
             ::error ("%s: architecture type must be a string", fcn);
         }
@@ -588,7 +585,10 @@
 
 DEFUN (fopen, args, nargout,
        "-*- texinfo -*-\n\
-@deftypefn  {Built-in Function} {[@var{fid}, @var{msg}] =} fopen (@var{name}, @var{mode}, @var{arch})\n\
+@deftypefn  {Built-in Function} {@var{fid} =} fopen (@var{name})\n\
+@deftypefnx {Built-in Function} {@var{fid} =} fopen (@var{name}, @var{mode})\n\
+@deftypefnx {Built-in Function} {@var{fid} =} fopen (@var{name}, @var{mode}, @var{arch})\n\
+@deftypefnx {Built-in Function} {[@var{fid}, @var{msg}] =} fopen (@dots{})\n\
 @deftypefnx {Built-in Function} {@var{fid_list} =} fopen (\"all\")\n\
 @deftypefnx {Built-in Function} {[@var{file}, @var{mode}, @var{arch}] =} fopen (@var{fid})\n\
 The first form of the @code{fopen} function opens the named file with\n\
@@ -627,7 +627,7 @@
 The possible values @samp{mode} may have are\n\
 \n\
 @table @asis\n\
-@item @samp{r}\n\
+@item @samp{r} (default)\n\
 Open a file for reading.\n\
 \n\
 @item @samp{w}\n\
@@ -652,7 +652,7 @@
 @qcode{\"b\"} to open in binary mode.  On Windows and Macintosh systems, text\n\
 mode reading and writing automatically converts linefeeds to the\n\
 appropriate line end character for the system (carriage-return linefeed\n\
-on Windows, carriage-return on Macintosh).  The default if no mode is\n\
+on Windows, carriage-return on Macintosh).  The default when no mode is\n\
 specified is binary mode.\n\
 \n\
 Additionally, you may append a @qcode{\"z\"} to the mode string to open a\n\
@@ -663,8 +663,8 @@
 for the file.  Valid values for @var{arch} are:\n\
 \n\
 @table @samp\n\
-@item native\n\
-The format of the current machine (this is the default).\n\
+@item native (default)\n\
+The format of the current machine.\n\
 \n\
 @item ieee-be\n\
 IEEE big endian format.\n\
@@ -753,15 +753,15 @@
 @group\n\
 freport ()\n\
 \n\
-     @print{}  number  mode  name\n\
-     @print{}\n\
-     @print{}       0     r  stdin\n\
-     @print{}       1     w  stdout\n\
-     @print{}       2     w  stderr\n\
-     @print{}       3     r  myfile\n\
+     @print{}  number  mode  arch       name\n\
+     @print{}  ------  ----  ----       ----\n\
+     @print{}     0     r    ieee-le    stdin\n\
+     @print{}     1     w    ieee-le    stdout\n\
+     @print{}     2     w    ieee-le    stderr\n\
+     @print{}     3     r    ieee-le    myfile\n\
 @end group\n\
 @end example\n\
-@seealso{fopen, fclose}\n\
+@seealso{fopen, fclose, is_valid_file_id}\n\
 @end deftypefn")
 {
   octave_value_list retval;
@@ -778,10 +778,13 @@
 
 DEFUN (frewind, args, nargout,
        "-*- texinfo -*-\n\
-@deftypefn {Built-in Function} {} frewind (@var{fid})\n\
-Move the file pointer to the beginning of the file @var{fid}, returning\n\
-0 for success, and -1 if an error was encountered.  It is equivalent to\n\
-@code{fseek (@var{fid}, 0, SEEK_SET)}.\n\
+@deftypefn  {Built-in Function} {} frewind (@var{fid})\n\
+@deftypefnx {Built-in Function} {@var{status} =} frewind (@var{fid})\n\
+Move the file pointer to the beginning of the file specified by file\n\
+descriptor @var{fid}.\n\
+\n\
+@code{frewind} returns 0 for success, and -1 if an error is encountered.  It\n\
+is equivalent to @code{fseek (@var{fid}, 0, SEEK_SET)}.\n\
 @seealso{fseek, ftell, fopen}\n\
 @end deftypefn")
 {
@@ -812,7 +815,7 @@
 @deftypefn  {Built-in Function} {} fseek (@var{fid}, @var{offset})\n\
 @deftypefnx {Built-in Function} {} fseek (@var{fid}, @var{offset}, @var{origin})\n\
 @deftypefnx {Built-in Function} {@var{status} =} fseek (@dots{})\n\
-Set the file pointer to any location within the file @var{fid}.\n\
+Set the file pointer to the location @var{offset} within the file @var{fid}.\n\
 \n\
 The pointer is positioned @var{offset} characters from the @var{origin},\n\
 which may be one of the predefined variables @w{@code{SEEK_CUR}} (current\n\
@@ -822,7 +825,7 @@
 be positive, negative, or zero but not all combinations of @var{origin} and\n\
 @var{offset} can be realized.\n\
 \n\
-Return 0 on success and -1 on error.\n\
+@code{fseek} returns 0 on success and -1 on error.\n\
 @seealso{fskipl, frewind, ftell, fopen}\n\
 @end deftypefn")
 {
@@ -850,10 +853,10 @@
 
 DEFUN (ftell, args, ,
        "-*- texinfo -*-\n\
-@deftypefn {Built-in Function} {} ftell (@var{fid})\n\
-Return the position of the file pointer as the number of characters\n\
-from the beginning of the file @var{fid}.\n\
-@seealso{fseek, feof, fopen}\n\
+@deftypefn {Built-in Function} {@var{pos} =} ftell (@var{fid})\n\
+Return the position of the file pointer as the number of characters from the\n\
+beginning of the file specified by file descriptor @var{fid}.\n\
+@seealso{fseek, frewind, feof, fopen}\n\
 @end deftypefn")
 {
   octave_value retval = -1;
@@ -875,10 +878,16 @@
 
 DEFUN (fprintf, args, nargout,
        "-*- texinfo -*-\n\
-@deftypefn {Built-in Function} {} fprintf (@var{fid}, @var{template}, @dots{})\n\
-This function is just like @code{printf}, except that the output is\n\
-written to the stream @var{fid} instead of @code{stdout}.\n\
-If @var{fid} is omitted, the output is written to @code{stdout}.\n\
+@deftypefn  {Built-in Function} {} fprintf (@var{fid}, @var{template}, @dots{})\n\
+@deftypefnx {Built-in Function} {} fprintf (@var{template}, @dots{})\n\
+@deftypefnx {Built-in Function} {@var{numbytes} =} fprintf (@dots{})\n\
+This function is equivalent to @code{printf}, except that the output is\n\
+written to the file descriptor @var{fid} instead of @code{stdout}.\n\
+\n\
+If @var{fid} is omitted, the output is written to @code{stdout} making the\n\
+function exactly equivalent to @code{printf}.\n\
+\n\
+The optional output returns the number of bytes written to the file.\n\
 @seealso{fputs, fdisp, fwrite, fscanf, printf, sprintf, fopen}\n\
 @end deftypefn")
 {
@@ -986,10 +995,15 @@
 
 DEFUN (fputs, args, ,
        "-*- texinfo -*-\n\
-@deftypefn {Built-in Function} {} fputs (@var{fid}, @var{string})\n\
-Write a string to a file with no formatting.\n\
+@deftypefn  {Built-in Function} {} fputs (@var{fid}, @var{string})\n\
+@deftypefnx {Built-in Function} {@var{status} =} fputs (@var{fid}, @var{string})\n\
+Write the string @var{string} to the file with file descriptor @var{fid}.\n\
 \n\
-Return a non-negative number on success and EOF on error.\n\
+The string is written to the file with no additional formatting.  Use\n\
+@code{fdisp} instead to automatically append a newline character appropriate\n\
+for the local machine.\n\
+\n\
+Return a non-negative number on success or EOF on error.\n\
 @seealso{fdisp, fprintf, fwrite, fopen}\n\
 @end deftypefn")
 {
@@ -1014,9 +1028,13 @@
 
 DEFUN (puts, args, ,
        "-*- texinfo -*-\n\
-@deftypefn {Built-in Function} {} puts (@var{string})\n\
+@deftypefn  {Built-in Function} {} puts (@var{string})\n\
+@deftypefnx {Built-in Function} {@var{status} =} puts (@var{string})\n\
 Write a string to the standard output with no formatting.\n\
 \n\
+The string is written verbatim to the standard output.  Use @code{disp} to\n\
+automatically append a newline character appropriate for the local machine.\n\
+\n\
 Return a non-negative number on success and EOF on error.\n\
 @seealso{fputs, disp}\n\
 @end deftypefn")
@@ -1327,8 +1345,7 @@
 @deftypefnx {Built-in Function} {[@var{v1}, @var{v2}, @dots{}, @var{count}, @var{errmsg}]] =} scanf (@var{template}, \"C\")\n\
 This is equivalent to calling @code{fscanf} with @var{fid} = @code{stdin}.\n\
 \n\
-It is currently not useful to call @code{scanf} in interactive\n\
-programs.\n\
+It is currently not useful to call @code{scanf} in interactive programs.\n\
 @seealso{fscanf, sscanf, printf}\n\
 @end deftypefn")
 {
@@ -1338,7 +1355,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);
 }
@@ -1356,10 +1373,10 @@
 
   if (! error_state)
     {
-      std::string prec = prec_arg.string_value ();
+      if (prec_arg.is_string ())
+        {
+          std::string prec = prec_arg.string_value ();
 
-      if (! error_state)
-        {
           int block_size = 1;
           oct_data_conv::data_type input_type;
           oct_data_conv::data_type output_type;
@@ -1373,10 +1390,10 @@
 
               if (! error_state)
                 {
-                  std::string arch = arch_arg.string_value ();
+                  if (arch_arg.is_string ())
+                    {
+                      std::string arch = arch_arg.string_value ();
 
-                  if (! error_state)
-                    {
                       oct_mach_info::float_format flt_fmt
                         = oct_mach_info::string_to_float_format (arch);
 
@@ -1404,9 +1421,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 file specified by the file descriptor @var{fid}.\n\
 \n\
 The optional argument @var{size} specifies the amount of data to read\n\
 and may be one of\n\
@@ -1548,19 +1569,19 @@
 The optional argument @var{arch} is a string specifying the data format\n\
 for the file.  Valid values are\n\
 \n\
-@table @code\n\
+@table @asis\n\
 @item @qcode{\"native\"}\n\
 The format of the current machine.\n\
 \n\
-@item \"ieee-be\"\n\
+@item @qcode{\"ieee-be\"}\n\
 IEEE big endian.\n\
 \n\
-@item \"ieee-le\"\n\
+@item @qcode{\"ieee-le\"}\n\
 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")
 {
@@ -1622,10 +1643,10 @@
 {
   int retval = -1;
 
-  std::string prec = prec_arg.string_value ();
+  if (prec_arg.is_string ())
+    {
+      std::string prec = prec_arg.string_value ();
 
-  if (! error_state)
-    {
       int block_size = 1;
       oct_data_conv::data_type output_type;
 
@@ -1637,10 +1658,10 @@
 
           if (! error_state)
             {
-              std::string arch = arch_arg.string_value ();
+              if (arch_arg.is_string ())
+                {
+                  std::string arch = arch_arg.string_value ();
 
-              if (! error_state)
-                {
                   oct_mach_info::float_format flt_fmt
                     = oct_mach_info::string_to_float_format (arch);
 
@@ -1665,10 +1686,14 @@
 
 DEFUN (fwrite, args, ,
        "-*- texinfo -*-\n\
-@deftypefn {Built-in Function} {@var{count} =} fwrite (@var{fid}, @var{data}, @var{precision}, @var{skip}, @var{arch})\n\
-Write data in binary form of type @var{precision} to the specified file\n\
-ID @var{fid}, returning the number of values successfully written to the\n\
-file.\n\
+@deftypefn  {Built-in Function} {} fwrite (@var{fid}, @var{data})\n\
+@deftypefnx {Built-in Function} {} fwrite (@var{fid}, @var{data}, @var{precision})\n\
+@deftypefnx {Built-in Function} {} fwrite (@var{fid}, @var{data}, @var{precision}, @var{skip})\n\
+@deftypefnx {Built-in Function} {} fwrite (@var{fid}, @var{data}, @var{precision}, @var{skip}, @var{arch})\n\
+@deftypefnx {Built-in Function} {@var{count} =} fwrite (@dots{})\n\
+Write data in binary form to the file specified by the file descriptor\n\
+@var{fid}, returning the number of values @var{count} successfully written\n\
+to the file.\n\
 \n\
 The argument @var{data} is a matrix of values that are to be written to\n\
 the file.  The values are extracted in column-major order.\n\
@@ -1726,12 +1751,14 @@
 
 DEFUNX ("feof", Ffeof, args, ,
         "-*- texinfo -*-\n\
-@deftypefn {Built-in Function} {} feof (@var{fid})\n\
-Return 1 if an end-of-file condition has been encountered for a given\n\
-file and 0 otherwise.  Note that it will only return 1 if the end of the\n\
-file has already been encountered, not if the next read operation will\n\
-result in an end-of-file condition.\n\
-@seealso{fread, fopen}\n\
+@deftypefn {Built-in Function} {@var{status} =} feof (@var{fid})\n\
+Return 1 if an end-of-file condition has been encountered for the file\n\
+specified by file descriptor @var{fid} and 0 otherwise.\n\
+\n\
+Note that @code{feof} will only return 1 if the end of the file has already\n\
+been encountered, not if the next read operation will result in an\n\
+end-of-file condition.\n\
+@seealso{fread, frewind, fseek, fclear, fopen}\n\
 @end deftypefn")
 {
   octave_value retval = -1;
@@ -1753,15 +1780,22 @@
 
 DEFUNX ("ferror", Fferror, args, ,
         "-*- texinfo -*-\n\
-@deftypefn  {Built-in Function} {[@var{err}, @var{msg}] =} ferror (@var{fid})\n\
-@deftypefnx {Built-in Function} {[@var{err}, @var{msg}] =} ferror (@var{fid}, \"clear\")\n\
-Return 1 if an error condition has been encountered for the file ID\n\
-@var{fid} and 0 otherwise.  Note that it will only return 1 if an error\n\
-has already been encountered, not if the next operation will result in\n\
-an error condition.\n\
+@deftypefn  {Built-in Function} {@var{msg} =} ferror (@var{fid})\n\
+@deftypefnx {Built-in Function} {[@var{msg}, @var{err}] =} ferror (@var{fid})\n\
+@deftypefnx {Built-in Function} {[@var{dots}] =} ferror (@var{fid}, \"clear\")\n\
+Query the error status of the stream specified by file descriptor @var{fid}\n\
+\n\
+If an error condition exists then return a string @var{msg} describing the\n\
+error.  Otherwise, return an empty string @qcode{\"\"}.\n\
 \n\
-The second argument is optional.  If it is supplied, also clear the\n\
-error condition.\n\
+The optional second output is a numeric indication of the error status.\n\
+@var{err} is 1 if an error condition has been encountered and 0 otherwise.\n\
+\n\
+Note that @code{ferror} indicates if an error has already occurred, not\n\
+whether the next operation will result in an error condition.\n\
+\n\
+The second input @qcode{\"clear\"} is optional.  If supplied, the error\n\
+state on the stream will be cleared.\n\
 @seealso{fclear, fopen}\n\
 @end deftypefn")
 {
@@ -1833,6 +1867,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;
@@ -1841,14 +1876,14 @@
 
   if (nargin == 2)
     {
-      std::string name = args(0).string_value ();
-
-      if (! error_state)
+      if (args(0).is_string ())
         {
-          std::string mode = args(1).string_value ();
+          std::string name = args(0).string_value ();
 
-          if (! error_state)
+          if (args(1).is_string ())
             {
+              std::string mode = args(1).string_value ();
+
               if (mode == "r")
                 {
                   octave_stream ips = octave_iprocstream::create (name);
@@ -1879,8 +1914,10 @@
 DEFUNX ("pclose", Fpclose, args, ,
         "-*- texinfo -*-\n\
 @deftypefn {Built-in Function} {} pclose (@var{fid})\n\
-Close a file identifier that was opened by @code{popen}.  You may also\n\
-use @code{fclose} for the same purpose.\n\
+Close a file identifier that was opened by @code{popen}.\n\
+\n\
+The function @code{fclose} may also be used for the same purpose.\n\
+@seealso{fclose, popen}\n\
 @end deftypefn")
 {
   octave_value retval = -1;
@@ -1895,23 +1932,23 @@
   return retval;
 }
 
-DEFUNX ("tmpnam", Ftmpnam, args, ,
-        "-*- texinfo -*-\n\
-@c List other forms of function in documentation index\n\
-@findex octave_tmp_file_name\n\
-\n\
-@deftypefn  {Built-in Function} {} tmpnam ()\n\
-@deftypefnx {Built-in Function} {} tmpnam (@var{dir})\n\
-@deftypefnx {Built-in Function} {} tmpnam (@var{dir}, @var{prefix})\n\
+DEFUN (tempname, args, ,
+       "-*- texinfo -*-\n\
+@deftypefn  {Built-in Function} {@var{fname} =} tempname ()\n\
+@deftypefnx {Built-in Function} {@var{fname} =} tempname (@var{dir})\n\
+@deftypefnx {Built-in Function} {@var{fname} =} tempname (@var{dir}, @var{prefix})\n\
 Return a unique temporary file name as a string.\n\
 \n\
 If @var{prefix} is omitted, a value of @qcode{\"oct-\"} is used.\n\
 If @var{dir} is also omitted, the default directory for temporary files\n\
-is used.  If @var{dir} is provided, it must exist, otherwise the default\n\
-directory for temporary files is used.  Since the named file is not\n\
-opened, by @code{tmpnam}, it is possible (though relatively unlikely)\n\
-that it will not be available by the time your program attempts to open it.\n\
-@seealso{tmpfile, mkstemp, P_tmpdir}\n\
+(@code{P_tmpdir}) is used.  If @var{dir} is provided, it must exist,\n\
+otherwise the default directory for temporary files is used.\n\
+\n\
+Programming Note: Because the named file is not opened by @code{tempname},\n\
+it is possible, though relatively unlikely, that it will not be available\n\
+by the time your program attempts to open it.  If this is a concern,\n\
+see @code{tmpfile}.\n\
+@seealso{mkstemp, tempdir, P_tmpdir, tmpfile}\n\
 @end deftypefn")
 {
   octave_value retval;
@@ -1920,20 +1957,25 @@
 
   if (len < 3)
     {
-      std::string dir = len > 0 ? args(0).string_value () : std::string ();
-
-      if (! error_state)
+      std::string dir;
+      if (len > 0)
         {
-          std::string pfx
-            = len > 1 ? args(1).string_value () : std::string ("oct-");
+          if (args(0).is_string ())
+            dir = args(0).string_value ();
+          else
+            ::error ("DIR must be a string");
+        }
 
-          if (! error_state)
-            retval = octave_tempnam (dir, pfx);
+      std::string pfx ("oct-");
+      if (len > 1)
+        {
+          if (args(1).is_string ())
+            pfx = args(1).string_value ();
           else
             ::error ("PREFIX must be a string");
         }
-      else
-        ::error ("DIR argument must be a string");
+
+      retval = octave_tempnam (dir, pfx);
     }
   else
     print_usage ();
@@ -1941,20 +1983,67 @@
   return retval;
 }
 
-DEFALIAS (octave_tmp_file_name, tmpnam);
+/*
+%!test
+%! if (ispc ())
+%!   envname = "TMP";
+%! else
+%!   envname = "TMPDIR";
+%! endif
+%! envdir = getenv (envname);
+%! unsetenv (envname);
+%! unwind_protect
+%!   ## Test 0-argument form
+%!   fname = tempname ();
+%!   [tmpdir, tmpfname] = fileparts (fname);
+%!   assert (tmpdir, P_tmpdir);
+%!   assert (tmpfname (1:4), "oct-");
+%!   ## Test 1-argument form
+%!   tmp_tmpdir = [P_tmpdir filesep() substr(tmpfname, -5)];
+%!   mkdir (tmp_tmpdir) || error ("Unable to create tmp dir");
+%!   setenv (envname, P_tmpdir);
+%!   fname = tempname (tmp_tmpdir);
+%!   [tmpdir, tmpfname] = fileparts (fname);
+%!   assert (tmpdir, tmp_tmpdir);
+%!   assert (tmpfname (1:4), "oct-");
+%!   ## Test 1-argument form w/null tmpdir
+%!   fname = tempname ("");
+%!   [tmpdir, tmpfname] = fileparts (fname);
+%!   assert (tmpdir, P_tmpdir);
+%!   assert (tmpfname (1:4), "oct-");
+%!   ## Test 2-argument form
+%!   fname = tempname (tmp_tmpdir, "pfx-");
+%!   [tmpdir, tmpfname] = fileparts (fname);
+%!   assert (tmpdir, tmp_tmpdir);
+%!   assert (tmpfname (1:4), "pfx-");
+%!   ## Test 2-argument form w/null prefix
+%!   fname = tempname (tmp_tmpdir, "");
+%!   [tmpdir, tmpfname] = fileparts (fname);
+%!   assert (tmpdir, tmp_tmpdir);
+%!   assert (tmpfname (1:4), "file");
+%! unwind_protect_cleanup
+%!   rmdir (tmp_tmpdir);
+%!   if (isempty (envdir))
+%!     unsetenv (envname);
+%!   else
+%!     setenv (envname, envdir);
+%!   endif
+%! end_unwind_protect
+*/
 
 DEFUN (tmpfile, args, ,
        "-*- texinfo -*-\n\
 @deftypefn {Built-in Function} {[@var{fid}, @var{msg}] =} tmpfile ()\n\
 Return the file ID corresponding to a new temporary file with a unique\n\
-name.  The file is opened in binary read/write (@qcode{\"w+b\"}) mode.\n\
-The file will be deleted automatically when it is closed or when Octave\n\
-exits.\n\
+name.\n\
+\n\
+The file is opened in binary read/write (@qcode{\"w+b\"}) mode and will be\n\
+deleted automatically when it is closed or when Octave exits.\n\
 \n\
 If successful, @var{fid} is a valid file ID and @var{msg} is an empty\n\
 string.  Otherwise, @var{fid} is -1 and @var{msg} contains a\n\
 system-dependent error message.\n\
-@seealso{tmpnam, mkstemp, P_tmpdir}\n\
+@seealso{tempname, mkstemp, tempdir, P_tmpdir}\n\
 @end deftypefn")
 {
   octave_value_list retval;
@@ -1996,23 +2085,25 @@
 
 DEFUN (mkstemp, args, ,
        "-*- texinfo -*-\n\
-@deftypefn {Built-in Function} {[@var{fid}, @var{name}, @var{msg}] =} mkstemp (@var{template}, @var{delete})\n\
-Return the file ID corresponding to a new temporary file with a unique\n\
-name created from @var{template}.  The last six characters of @var{template}\n\
-must be @code{XXXXXX} and these are replaced with a string that makes the\n\
-filename unique.  The file is then created with mode read/write and\n\
-permissions that are system dependent (on GNU/Linux systems, the permissions\n\
-will be 0600 for versions of glibc 2.0.7 and later).  The file is opened\n\
-in binary mode and with the @w{@code{O_EXCL}} flag.\n\
+@deftypefn  {Built-in Function} {[@var{fid}, @var{name}, @var{msg}] =} mkstemp (\"@var{template}\")\n\
+@deftypefnx {Built-in Function} {[@var{fid}, @var{name}, @var{msg}] =} mkstemp (\"@var{template}\", @var{delete})\n\
+Return the file descriptor @var{fid} corresponding to a new temporary file\n\
+with a unique name created from @var{template}.\n\
 \n\
-If the optional argument @var{delete} is supplied and is true,\n\
-the file will be deleted automatically when Octave exits.\n\
+The last six characters of @var{template} must be @qcode{\"XXXXXX\"} and\n\
+these are replaced with a string that makes the filename unique.  The file\n\
+is then created with mode read/write and permissions that are system\n\
+dependent (on GNU/Linux systems, the permissions will be 0600 for versions of\n\
+glibc 2.0.7 and later).  The file is opened in binary mode and with the\n\
+@w{@code{O_EXCL}} flag.\n\
 \n\
-If successful, @var{fid} is a valid file ID, @var{name} is the name of\n\
-the file, and @var{msg} is an empty string.  Otherwise, @var{fid}\n\
-is -1, @var{name} is empty, and @var{msg} contains a system-dependent\n\
-error message.\n\
-@seealso{tmpfile, tmpnam, P_tmpdir}\n\
+If the optional argument @var{delete} is supplied and is true, the file will\n\
+be deleted automatically when Octave exits.\n\
+\n\
+If successful, @var{fid} is a valid file ID, @var{name} is the name of the\n\
+file, and @var{msg} is an empty string.  Otherwise, @var{fid} is -1,\n\
+@var{name} is empty, and @var{msg} contains a system-dependent error message.\n\
+@seealso{tempname, tempdir, P_tmpdir, tmpfile, fopen}\n\
 @end deftypefn")
 {
   octave_value_list retval;
@@ -2025,10 +2116,10 @@
 
   if (nargin == 1 || nargin == 2)
     {
-      std::string tmpl8 = args(0).string_value ();
+      if (args(0).is_string ())
+        {
+          std::string tmpl8 = args(0).string_value ();
 
-      if (! error_state)
-        {
           OCTAVE_LOCAL_BUFFER (char, tmp, tmpl8.size () + 1);
           strcpy (tmp, tmpl8.c_str ());
 
@@ -2112,10 +2203,12 @@
 DEFUNX ("umask", Fumask, args, ,
         "-*- texinfo -*-\n\
 @deftypefn {Built-in Function} {} umask (@var{mask})\n\
-Set the permission mask for file creation.  The parameter @var{mask}\n\
-is an integer, interpreted as an octal number.  If successful,\n\
-returns the previous value of the mask (as an integer to be\n\
+Set the permission mask for file creation.\n\
+\n\
+The parameter @var{mask} is an integer, interpreted as an octal number.  If\n\
+successful, returns the previous value of the mask (as an integer to be\n\
 interpreted as an octal number); otherwise an error message is printed.\n\
+@seealso{fopen, mkdir}\n\
 @end deftypefn")
 {
   octave_value_list retval;
@@ -2174,8 +2267,14 @@
 DEFUNX ("P_tmpdir", FP_tmpdir, args, ,
         "-*- texinfo -*-\n\
 @deftypefn {Built-in Function} {} P_tmpdir ()\n\
-Return the default name of the directory for temporary files on\n\
-this system.  The name of this directory is system dependent.\n\
+Return the name of the host system's @strong{default} directory for\n\
+temporary files.\n\
+\n\
+Programming Note: The value returned by @code{P_tmpdir} is always the\n\
+default location.  This value may not agree with that returned from\n\
+@code{tempdir} if the user has overriden the default with the @env{TMPDIR}\n\
+environment variable.\n\
+@seealso{tempdir, tempname, mkstemp, tmpfile}\n\
 @end deftypefn")
 {
   octave_value retval;
@@ -2198,8 +2297,8 @@
 @deftypefn  {Built-in Function} {} SEEK_SET ()\n\
 @deftypefnx {Built-in Function} {} SEEK_CUR ()\n\
 @deftypefnx {Built-in Function} {} SEEK_END ()\n\
-Return the numerical value to pass to @code{fseek} to perform\n\
-one of the following actions:\n\
+Return the numerical value to pass to @code{fseek} to perform one of the\n\
+following actions:\n\
 \n\
 @table @code\n\
 @item SEEK_SET\n\
@@ -2259,7 +2358,8 @@
         "-*- texinfo -*-\n\
 @deftypefn {Built-in Function} {} stdin ()\n\
 Return the numeric value corresponding to the standard input stream.\n\
-When Octave is used interactively, this is filtered through the command\n\
+\n\
+When Octave is used interactively, stdin is filtered through the command\n\
 line editing functions.\n\
 @seealso{stdout, stderr}\n\
 @end deftypefn")
@@ -2271,6 +2371,7 @@
         "-*- texinfo -*-\n\
 @deftypefn {Built-in Function} {} stdout ()\n\
 Return the numeric value corresponding to the standard output stream.\n\
+\n\
 Data written to the standard output is normally filtered through the pager.\n\
 @seealso{stdin, stderr}\n\
 @end deftypefn")
@@ -2282,8 +2383,9 @@
         "-*- texinfo -*-\n\
 @deftypefn {Built-in Function} {} stderr ()\n\
 Return the numeric value corresponding to the standard error stream.\n\
-Even if paging is turned on, the standard error is not sent to the\n\
-pager.  It is useful for error messages and prompts.\n\
+\n\
+Even if paging is turned on, the standard error is not sent to the pager.\n\
+It is useful for error messages and prompts.\n\
 @seealso{stdin, stdout}\n\
 @end deftypefn")
 {
--- a/libinterp/corefcn/filter.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/libinterp/corefcn/filter.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -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 Feb 06 08:31:09 2015 -0800
+++ b/libinterp/corefcn/find.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -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;
@@ -88,9 +89,8 @@
 {
   octave_value_list retval ((nargout == 0 ? 1 : nargout), Matrix ());
 
-
+  octave_idx_type nr = v.rows ();
   octave_idx_type nc = v.cols ();
-  octave_idx_type nr = v.rows ();
   octave_idx_type nz = v.nnz ();
 
   // Search in the default range.
@@ -138,21 +138,20 @@
   count = (n_to_find > v.cidx (end_nc) - v.cidx (start_nc) ?
            v.cidx (end_nc) - v.cidx (start_nc) : n_to_find);
 
-  // If the original argument was a row vector, force a row vector of
-  // the overall indices to be returned.  But see below for scalar
-  // case...
+  octave_idx_type result_nr;
+  octave_idx_type result_nc;
 
-  octave_idx_type result_nr = count;
-  octave_idx_type result_nc = 1;
-
-  bool scalar_arg = false;
-
-  if (v.rows () == 1)
+  // Default case is to return a column vector, however, if the original
+  // argument was a row vector, then force return of a row vector.
+  if (nr == 1)
     {
       result_nr = 1;
       result_nc = count;
-
-      scalar_arg = (v.columns () == 1);
+    }
+  else
+    {
+      result_nr = count;
+      result_nc = 1;
     }
 
   Matrix idx (result_nr, result_nc);
@@ -164,11 +163,10 @@
 
   if (count > 0)
     {
-      // Search for elements to return.  Only search the region where
-      // there are elements to be found using the count that we want
-      // to find.
+      // 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)
@@ -182,14 +180,19 @@
               break;
           }
     }
-  else if (scalar_arg)
+  else
     {
-      idx.resize (0, 0);
+      // No items found.  Fixup return dimensions for Matlab compatibility.
+      // The behavior to match is documented in Array.cc (Array<T>::find).
+      if ((nr == 0 && nc == 0) || (nr == 1 && nc == 1))
+        {
+          idx.resize (0, 0);
 
-      i_idx.resize (0, 0);
-      j_idx.resize (0, 0);
+          i_idx.resize (0, 0);
+          j_idx.resize (0, 0);
 
-      val.resize (dim_vector (0, 0));
+          val.resize (dim_vector (0, 0));
+        }
     }
 
   switch (nargout)
@@ -231,6 +234,7 @@
   // There are far fewer special cases to handle for a PermMatrix.
   octave_value_list retval ((nargout == 0 ? 1 : nargout), Matrix ());
 
+  octave_idx_type nr = v.rows ();
   octave_idx_type nc = v.cols ();
   octave_idx_type start_nc, count;
 
@@ -238,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)
@@ -252,8 +255,6 @@
       count = n_to_find;
     }
 
-  bool scalar_arg = (v.rows () == 1 && v.cols () == 1);
-
   Matrix idx (count, 1);
   Matrix i_idx (count, 1);
   Matrix j_idx (count, 1);
@@ -262,42 +263,34 @@
 
   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 if (scalar_arg)
+  else
     {
-      // Same odd compatibility case as the other overrides.
-      idx.resize (0, 0);
-      i_idx.resize (0, 0);
-      j_idx.resize (0, 0);
-      val.resize (dim_vector (0, 0));
+      // FIXME: Is this case even possible?  A scalar permutation matrix seems
+      // to devolve to a scalar full matrix, at least from the Octave command
+      // line.  Perhaps this function could be called internally from C++ with
+      // such a matrix.
+      // No items found.  Fixup return dimensions for Matlab compatibility.
+      // The behavior to match is documented in Array.cc (Array<T>::find).
+      if ((nr == 0 && nc == 0) || (nr == 1 && nc == 1))
+        {
+          idx.resize (0, 0);
+
+          i_idx.resize (0, 0);
+          j_idx.resize (0, 0);
+
+          val.resize (dim_vector (0, 0));
+        }
     }
 
   switch (nargout)
@@ -383,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/gammainc.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/libinterp/corefcn/gammainc.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -57,7 +57,8 @@
 \n\
 @end ifnottex\n\
 with the limiting value of 1 as @var{x} approaches infinity.\n\
-The standard notation is @math{P(a,x)}, e.g., Abramowitz and Stegun (6.5.1).\n\
+The standard notation is @math{P(a,x)}, e.g., @nospell{Abramowitz} and\n\
+@nospell{Stegun} (6.5.1).\n\
 \n\
 If @var{a} is scalar, then @code{gammainc (@var{x}, @var{a})} is returned\n\
 for each element of @var{x} and vice versa.\n\
@@ -72,7 +73,7 @@
 @example\n\
 gammainc (@var{x}, @var{a}) @equiv{} 1 - gammainc (@var{x}, @var{a}, \"upper\")\n\
 @end example\n\
-@seealso{gamma, lgamma}\n\
+@seealso{gamma, gammaln}\n\
 @end deftypefn")
 {
   octave_value retval;
--- a/libinterp/corefcn/gcd.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/libinterp/corefcn/gcd.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -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++)
@@ -436,25 +441,16 @@
        "-*- texinfo -*-\n\
 @deftypefn  {Built-in Function} {@var{g} =} gcd (@var{a1}, @var{a2}, @dots{})\n\
 @deftypefnx {Built-in Function} {[@var{g}, @var{v1}, @dots{}] =} gcd (@var{a1}, @var{a2}, @dots{})\n\
-\n\
-Compute the greatest common divisor of @var{a1}, @var{a2}, @dots{}.  If more\n\
-than one argument is given all arguments must be the same size or scalar.\n\
-In this case the greatest common divisor is calculated for each element\n\
-individually.  All elements must be ordinary or Gaussian (complex)\n\
-integers.  Note that for Gaussian integers, the gcd is not unique up to\n\
-units (multiplication by 1, -1, @var{i} or -@var{i}), so an arbitrary\n\
-greatest common divisor amongst four possible is returned.\n\
+Compute the greatest common divisor of @var{a1}, @var{a2}, @dots{}.\n\
 \n\
-Example code:\n\
+If more than one argument is given then all arguments must be the same size\n\
+or scalar.  In this case the greatest common divisor is calculated for each\n\
+element individually.  All elements must be ordinary or Gaussian (complex)\n\
+integers.  Note that for Gaussian integers, the gcd is only unique up to a\n\
+phase factor (multiplication by 1, -1, i, or -i), so an arbitrary greatest\n\
+common divisor amongst four possible is returned.\n\
 \n\
-@example\n\
-@group\n\
-gcd ([15, 9], [20, 18])\n\
-   @result{}  5  9\n\
-@end group\n\
-@end example\n\
-\n\
-Optional return arguments @var{v1}, etc., contain integer vectors such\n\
+Optional return arguments @var{v1}, @dots{}, contain integer vectors such\n\
 that,\n\
 \n\
 @tex\n\
@@ -468,7 +464,16 @@
 \n\
 @end ifnottex\n\
 \n\
-@seealso{lcm, factor}\n\
+Example code:\n\
+\n\
+@example\n\
+@group\n\
+gcd ([15, 9], [20, 18])\n\
+   @result{}  5  9\n\
+@end group\n\
+@end example\n\
+\n\
+@seealso{lcm, factor, isprime}\n\
 @end deftypefn")
 {
   octave_value_list retval;
@@ -520,6 +525,19 @@
 %!assert (gcd (uint64 (200), uint64 (300), uint64 (50), uint64 (35)), uint64 (5))
 %!assert (gcd (18-i, -29+3i), -3-4i)
 
+%!test
+%! p = [953 967];
+%! u = [953 + i*971, 967 + i*977];
+%! [d, k(1), k(2)] = gcd (p(1), p(2));
+%! [z, w(1), w(2)] = gcd (u(1), u(2));
+%! assert (d, 1)
+%! assert (sum (p.*k), d)
+%! assert (abs (z), sqrt (2))
+%! assert (abs (sum (u.*w)), sqrt (2))
+
+%!error <all values must be integers> gcd (1/2, 2);
+%!error <all complex parts must be integers> gcd (e + i*pi, 1);
+
 %!error gcd ()
 
 %!test
--- a/libinterp/corefcn/givens.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/libinterp/corefcn/givens.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -32,10 +32,12 @@
 
 DEFUN (givens, args, nargout,
        "-*- texinfo -*-\n\
-@deftypefn  {Built-in Function} {@var{g} =} givens (@var{x}, @var{y})\n\
+@deftypefn  {Built-in Function} {@var{G} =} givens (@var{x}, @var{y})\n\
 @deftypefnx {Built-in Function} {[@var{c}, @var{s}] =} givens (@var{x}, @var{y})\n\
+Compute the Givens rotation matrix @var{G}.\n\
+\n\
 @tex\n\
-Return a $2\\times 2$ orthogonal matrix\n\
+The Givens matrix is a $2\\times 2$ orthogonal matrix\n\
 $$\n\
  G = \\left[\\matrix{c & s\\cr -s'& c\\cr}\\right]\n\
 $$\n\
@@ -46,11 +48,20 @@
 with $x$ and $y$ scalars.\n\
 @end tex\n\
 @ifnottex\n\
-Return a 2 by 2 orthogonal matrix\n\
-@code{@var{g} = [@var{c} @var{s}; -@var{s}' @var{c}]} such that\n\
-@code{@var{g} [@var{x}; @var{y}] = [*; 0]} with @var{x} and @var{y} scalars.\n\
+The Givens matrix is a 2 by 2 orthogonal matrix\n\
+\n\
+@code{@var{g} = [@var{c} @var{s}; -@var{s}' @var{c}]}\n\
+\n\
+such that\n\
+\n\
+@code{@var{g} [@var{x}; @var{y}] = [*; 0]}\n\
+\n\
+with @var{x} and @var{y} scalars.\n\
 @end ifnottex\n\
 \n\
+If two output arguments are requested, return the factors @var{c} and\n\
+@var{s} rather than the Givens rotation matrix.\n\
+\n\
 For example:\n\
 \n\
 @example\n\
@@ -60,6 +71,7 @@
        -0.70711   0.70711\n\
 @end group\n\
 @end example\n\
+@seealso{planerot}\n\
 @end deftypefn")
 {
   octave_value_list retval;
@@ -97,10 +109,6 @@
                           retval(1) = result (0, 1);
                           retval(0) = result (0, 0);
                           break;
-
-                        default:
-                          error ("givens: invalid number of output arguments");
-                          break;
                         }
                     }
                 }
@@ -127,10 +135,6 @@
                           retval(1) = result (0, 1);
                           retval(0) = result (0, 0);
                           break;
-
-                        default:
-                          error ("givens: invalid number of output arguments");
-                          break;
                         }
                     }
                 }
@@ -160,10 +164,6 @@
                           retval(1) = result (0, 1);
                           retval(0) = result (0, 0);
                           break;
-
-                        default:
-                          error ("givens: invalid number of output arguments");
-                          break;
                         }
                     }
                 }
@@ -190,10 +190,6 @@
                           retval(1) = result (0, 1);
                           retval(0) = result (0, 0);
                           break;
-
-                        default:
-                          error ("givens: invalid number of output arguments");
-                          break;
                         }
                     }
                 }
@@ -211,4 +207,5 @@
 
 %!error givens ()
 %!error givens (1)
+%!error [a,b,c] = givens (1, 1)
 */
--- a/libinterp/corefcn/gl-render.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/libinterp/corefcn/gl-render.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -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 ();
@@ -2529,6 +2652,8 @@
   if (props.get_string ().is_empty ())
     return;
 
+  set_font (props);
+
   Matrix pos = xform.scale (props.get_data_position ());
   const Matrix bbox = props.get_extent_matrix ();
 
@@ -2552,7 +2677,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 +2698,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 +2731,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 +2769,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 +2793,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 +2850,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);
 }
@@ -2743,18 +2888,18 @@
   text_renderer.set_font (props.get ("fontname").string_value (),
                           props.get ("fontweight").string_value (),
                           props.get ("fontangle").string_value (),
-                          props.get ("fontsize").double_value ());
+                          props.get ("fontsize_points").double_value ());
 #endif
 }
 
 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 +2927,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 +3079,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 +3143,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 +3202,7 @@
       }
       break;
     default:
-      warning ("opengl_renderer: unsupported marker '%s'",
-               marker.c_str ());
+      warning ("opengl_renderer: unsupported marker '%s'", marker.c_str ());
       break;
     }
 
@@ -3106,7 +3250,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 Feb 06 08:31:09 2015 -0800
+++ b/libinterp/corefcn/gl-render.h	Fri Feb 06 08:31:49 2015 -0800
@@ -40,6 +40,12 @@
 #include <OpenGL/glu.h>
 #endif
 
+#ifdef HAVE_GL_GLEXT_H
+#include <GL/glext.h>
+#elif defined HAVE_OPENGL_GLEXT_H || defined HAVE_FRAMEWORK_OPENGL
+#include <OpenGL/glext.h>
+#endif
+
 #include "graphics.h"
 #include "txt-eng-ft.h"
 
@@ -93,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,
@@ -200,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 Feb 06 08:31:09 2015 -0800
+++ b/libinterp/corefcn/gl2ps-renderer.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -24,15 +24,19 @@
 #include <config.h>
 #endif
 
+#include "error.h"
+#include "gl2ps-renderer.h"
+
 #ifdef HAVE_GL2PS_H
 
 #include <cstdio>
 
 #include "lo-mappers.h"
 #include "oct-locbuf.h"
+#include "unwind-prot.h"
 
-#include "gl2ps-renderer.h"
 #include "gl2ps.h"
+#include "sysdep.h"
 
 void
 glps_renderer::draw (const graphics_object& go, const std::string print_cmd)
@@ -44,7 +48,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 +57,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 +72,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 +99,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 +174,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);
@@ -170,7 +186,7 @@
 {
   opengl_renderer::set_font (props);
 
-  fontsize = props.get ("fontsize").double_value ();
+  fontsize = props.get ("fontsize_points").double_value ();
 
   caseless_str fn = props.get ("fontname").string_value ();
   fontname = "";
@@ -195,7 +211,7 @@
   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 +241,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;
@@ -253,4 +270,34 @@
                 alignment_to_mode (halign, valign), props.get_rotation ());
 }
 
+static void
+safe_pclose (FILE *f)
+{
+  if (f)
+    octave_pclose (f);
+}
+
 #endif
+
+void
+gl2ps_print (const graphics_object& fig, const std::string& cmd,
+             const std::string& term)
+{
+#ifdef HAVE_GL2PS_H
+
+  unwind_protect frame;
+
+  FILE *fp = octave_popen (cmd.c_str (), "w");
+
+  frame.add_fcn (safe_pclose, fp);
+
+  glps_renderer rend (fp, term);
+
+  rend.draw (fig, cmd);
+
+#else
+
+  error ("print: printing not available without gl2ps library");
+
+#endif
+}
--- a/libinterp/corefcn/gl2ps-renderer.h	Fri Feb 06 08:31:09 2015 -0800
+++ b/libinterp/corefcn/gl2ps-renderer.h	Fri Feb 06 08:31:49 2015 -0800
@@ -23,6 +23,8 @@
 #if !defined (octave_gl2ps_renderer_h)
 #define octave_gl2ps_renderer_h 1
 
+#include "graphics.h"
+
 #ifdef HAVE_GL2PS_H
 
 #include "gl-render.h"
@@ -86,4 +88,8 @@
 
 #endif  // HAVE_GL2PS_H
 
+extern OCTINTERP_API void
+gl2ps_print (const graphics_object& fig, const std::string& cmd,
+             const std::string& term);
+
 #endif
--- a/libinterp/corefcn/graphics.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/libinterp/corefcn/graphics.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -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,38 @@
   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[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
@@ -2671,6 +2818,22 @@
     }
 }
 
+/*
+## test defaults are set in the order they were stored
+%!test
+%! set(0, "defaultfigureunits", "normalized");
+%! set(0, "defaultfigureposition", [0.7 0 0.3 0.3]);
+%! hf = figure ("visible", "off");
+%! tol = 20 * eps;
+%! unwind_protect
+%!   assert (get (hf, "position"), [0.7 0 0.3 0.3], tol);
+%! unwind_protect_cleanup
+%!   close (hf);
+%!   set(0, "defaultfigureunits", "remove");
+%!   set(0, "defaultfigureposition", "remove");
+%! end_unwind_protect
+*/
+
 octave_value
 base_properties::get_dynamic (const caseless_str& name) const
 {
@@ -2772,7 +2935,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 +2964,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 +3134,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 +3157,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 +3174,8 @@
                 }
             }
         }
-      if (retval != "")
+
+      if (! retval.empty ())
         retval += "\n";
     }
   else
@@ -2985,6 +3184,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 +3221,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 +3247,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 +3287,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 +3317,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 +3633,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 ());
 }
 
 // ---------------------------------------------------------------------
@@ -3300,6 +3688,38 @@
 }
 
 void
+figure::properties::adopt (const graphics_handle& h)
+{
+  base_properties::adopt (h);
+
+  if (! get_currentaxes ().ok ())
+    {
+      graphics_object go = gh_manager::get_object (h);
+
+      if (go.type () == "axes")
+        set_currentaxes (h.as_octave_value ());
+    }
+}
+
+/*
+%!test
+%! hf1 = figure ("visible", "off");
+%! ax1 = subplot (1,2,1);
+%! ax2 = subplot (1,2,2);
+%! hf2 = figure ("visible", "off");
+%! unwind_protect
+%!   set (ax2, "parent", hf2);
+%!   assert (get (hf2, "currentaxes"), ax2);
+%!   assert (get (hf1, "currentaxes"), ax1);
+%!   set (ax1, "parent", hf2);
+%!   assert (get (hf2, "currentaxes"), ax2);
+%! unwind_protect_cleanup
+%!   close (hf1);
+%!   close (hf2);
+%! end_unwind_protect
+*/
+
+void
 figure::properties::set_visible (const octave_value& val)
 {
   std::string s = val.string_value ();
@@ -3409,6 +3829,9 @@
           position.run_listeners (POSTSET);
           mark_modified ();
         }
+
+      if (paperpositionmode.is ("auto"))
+        paperposition.set (get_auto_paperposition ());
     }
 }
 
@@ -3628,6 +4051,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 +4235,9 @@
       // between update_papersize and update_papertype
       papersize.set (octave_value (sz));
     }
+
+  if (paperpositionmode.is ("auto"))
+    paperposition.set (get_auto_paperposition ());
 }
 
 void
@@ -3828,6 +4370,9 @@
       std::swap (sz(0), sz(1));
       papersize.set (octave_value (sz));
     }
+
+  if (paperpositionmode.is ("auto"))
+    paperposition.set (get_auto_paperposition ());
 }
 
 /*
@@ -3879,6 +4424,9 @@
       papersize.set (octave_value (sz));
       paperposition.set (octave_value (pos));
     }
+
+  if (paperpositionmode.is ("auto"))
+    paperposition.set (get_auto_paperposition ());
 }
 
 /*
@@ -3984,7 +4532,24 @@
 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 ("outerposition");
+  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);
 }
 
 // ---------------------------------------------------------------------
@@ -4202,28 +4767,23 @@
                                   const std::string& who,
                                   const octave_value& v)
 {
+  if (v.is_string ())
+    {
+      xset (hp.handle_value (), "string", v);
+      return;
+    }
+
   graphics_handle val;
-
-  if (v.is_string ())
-    {
-      val = gh_manager::make_graphics_handle ("text", __myhandle__,
-                                              false, false);
-
-      xset (val, "string", v);
-    }
-  else
-    {
-      graphics_object go = gh_manager::get_object (gh_manager::lookup (v));
-
-      if (go.isa ("text"))
-        val = ::reparent (v, "set", who, __myhandle__, false);
-      else
-        {
-          std::string cname = v.class_name ();
-
-          error ("set: expecting text graphics object or character string for %s property, found %s",
-                 who.c_str (), cname.c_str ());
-        }
+  graphics_object go = gh_manager::get_object (gh_manager::lookup (v));
+
+  if (go.isa ("text"))
+    val = ::reparent (v, "set", who, __myhandle__, false);
+  else
+    {
+      std::string cname = v.class_name ();
+
+      error ("set: expecting text graphics object or character string for %s property, found %s",
+             who.c_str (), cname.c_str ());
     }
 
   if (! error_state)
@@ -4405,27 +4965,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,14 +5038,11 @@
   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);
+  // Disable rotate3d and select pan for 2D axes
+  set_rotate3d (get_rotate3d ());
 }
 
 void
@@ -4508,13 +5080,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 +5288,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 +5314,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 +5377,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 +5484,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 +5600,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 +5623,7 @@
 
   Matrix viewmat = get_view ().matrix_value ();
   nearhoriz = std::abs (viewmat(1)) <= 5;
+  is2D = viewmat(1) == 90;
 
   update_ticklength ();
 }
@@ -5139,7 +5725,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 +5828,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 +5923,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 +6086,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 +6158,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);
@@ -5616,7 +6209,7 @@
   text_renderer.set_font (get ("fontname").string_value (),
                           get ("fontweight").string_value (),
                           get ("fontangle").string_value (),
-                          get ("fontsize").double_value ());
+                          get ("fontsize_points").double_value ());
 #endif
 #endif
 }
@@ -5803,6 +6396,8 @@
         }
       else
         set_xticklabelmode ("manual");
+
+      sync_positions ();
     }
 }
 
@@ -5819,6 +6414,8 @@
         }
       else
         set_yticklabelmode ("manual");
+
+      sync_positions ();
     }
 }
 
@@ -5835,6 +6432,8 @@
         }
       else
         set_zticklabelmode ("manual");
+
+      sync_positions ();
     }
 }
 
@@ -5889,6 +6488,27 @@
 }
 
 void
+axes::properties::set_rotate3d (const octave_value& v)
+{
+  graphics_object parent_obj =
+    gh_manager::get_object (get_parent ());
+
+  int ndim = calc_dimensions (parent_obj);
+  rotate3d.set (v, false, false);
+  if (rotate3d_is ("on"))
+    {
+      // Disable rotate3d for 2D plots
+      if (ndim == 2)
+        {
+          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 +6868,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 +6885,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 +7020,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 +7133,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 +7299,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 +7342,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 +7461,7 @@
   unwind_protect frame;
   frame.protect_var (updating_axis_limits);
 
-  updating_axis_limits = true;
+  updating_axis_limits.insert (get_handle ().value ());
 
   switch (update_type)
     {
@@ -6878,14 +7501,14 @@
 }
 
 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 +7750,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
@@ -7207,6 +7834,40 @@
 }
 
 void
+text::properties::set_fontunits (const octave_value& v)
+{
+  if (! error_state)
+    {
+      caseless_str old_fontunits = get_fontunits ();
+      if (fontunits.set (v, true))
+        {
+          update_fontunits (old_fontunits);
+          mark_modified ();
+        }
+    }
+}
+
+void
+text::properties::update_fontunits (const caseless_str& old_units)
+{
+  caseless_str new_units = get_fontunits ();
+  double parent_height = 0;
+  double fsz = get_fontsize ();
+
+  if (new_units == "normalized")
+    {
+      graphics_object go (gh_manager::get_object (get___myhandle__ ()));
+      graphics_object ax (go.get_ancestor ("axes"));
+
+      parent_height = ax.get_properties ().get_boundingbox (true).elem (3);
+    }
+
+  fsz = convert_font_size (fsz, old_units, new_units, parent_height);
+
+  set_fontsize (octave_value (fsz));
+}
+
+void
 text::properties::update_font (void)
 {
 #ifdef HAVE_FREETYPE
@@ -7214,7 +7875,7 @@
   renderer.set_font (get ("fontname").string_value (),
                      get ("fontweight").string_value (),
                      get ("fontangle").string_value (),
-                     get ("fontsize").double_value ());
+                     get ("fontsize_points").double_value ());
 #endif
   renderer.set_color (get_color_rgb ());
 #endif
@@ -7225,7 +7886,8 @@
 {
 #ifdef HAVE_FREETYPE
 
-  int halign = 0, valign = 0;
+  int halign = 0;
+  int valign = 0;
 
   if (horizontalalignment_is ("center"))
     halign = 1;
@@ -7340,6 +8002,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 +8220,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 +8833,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 +9015,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 +9219,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 +9269,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;
@@ -8579,7 +9450,7 @@
 
 DEFUN (__is_handle_visible__, args, ,
        "-*- texinfo -*-\n\
-@deftypefn {Built-in Function} __is_handle_visible__ (@var{h})\n\
+@deftypefn {Built-in Function} {} __is_handle_visible__ (@var{h})\n\
 Undocumented internal function.\n\
 @end deftypefn")
 {
@@ -8595,12 +9466,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 +9493,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 +9660,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 +9736,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 +9807,7 @@
 }
 
 static std::string
-get_graphics_object_type (const double val)
+get_graphics_object_type (double val)
 {
   std::string retval;
 
@@ -9380,7 +10439,7 @@
     {
       graphics_handle h = octave_NaN;
 
-      const NDArray vals = args (0).array_value ();
+      const NDArray vals = args(0).array_value ();
 
       if (! error_state)
         {
@@ -9585,16 +10644,6 @@
 
 gtk_manager *gtk_manager::instance = 0;
 
-gtk_manager::gtk_manager (void)
-  : dtk (), available_toolkits (), loaded_toolkits ()
-{
-#if defined (HAVE_FLTK)
-  dtk = display_info::display_available () ? "fltk" : "gnuplot";
-#else
-  dtk = "gnuplot";
-#endif
-}
-
 void
 gtk_manager::create_instance (void)
 {
@@ -9609,36 +10658,81 @@
 {
   graphics_toolkit retval;
 
-  const_loaded_toolkits_iterator pl = loaded_toolkits.find (dtk);
-
-  if (pl == loaded_toolkits.end ())
-    {
-      const_available_toolkits_iterator pa = available_toolkits.find (dtk);
-
-      if (pa != available_toolkits.end ())
-        {
-          octave_value_list args;
-          args(0) = dtk;
-          feval ("graphics_toolkit", args);
-
-          if (! error_state)
-            pl = loaded_toolkits.find (dtk);
-
-          if (error_state || pl == loaded_toolkits.end ())
-            error ("failed to load %s graphics toolkit", dtk.c_str ());
+  if (! dtk.empty ())
+    {
+      const_loaded_toolkits_iterator pl = loaded_toolkits.find (dtk);
+
+      if (pl == loaded_toolkits.end ())
+        {
+          const_available_toolkits_iterator pa = available_toolkits.find (dtk);
+
+          if (pa != available_toolkits.end ())
+            {
+              octave_value_list args;
+              args(0) = dtk;
+              feval ("graphics_toolkit", args);
+
+              if (! error_state)
+                pl = loaded_toolkits.find (dtk);
+
+              if (error_state || pl == loaded_toolkits.end ())
+                error ("failed to load %s graphics toolkit", dtk.c_str ());
+              else
+                retval = pl->second;
+            }
           else
-            retval = pl->second;
+            error ("default graphics toolkit '%s' is not available!",
+                   dtk.c_str ());
         }
       else
-        error ("default graphics toolkit '%s' is not available!",
-               dtk.c_str ());
-    }
-  else
-    retval = pl->second;
+        retval = pl->second;
+    }
+  else
+    error ("no graphics toolkits are available!");
 
   return retval;
 }
 
+void
+gtk_manager::do_register_toolkit (const std::string& name)
+{
+  if (dtk.empty () || name == "qt"
+      || (name == "fltk"
+          && available_toolkits.find ("qt") == available_toolkits.end ()))
+    dtk = name;
+
+  available_toolkits.insert (name);
+}
+
+void
+gtk_manager::do_unregister_toolkit (const std::string& name)
+{
+  available_toolkits.erase (name);
+
+  if (dtk == name)
+    {
+      if (available_toolkits.empty ())
+        dtk.clear ();
+      else
+        {
+          const_available_toolkits_iterator pa = available_toolkits.begin ();
+
+          dtk = *pa++;
+
+          while (pa != available_toolkits.end ())
+            {
+              std::string tk_name = *pa++;
+
+              if (tk_name == "qt"
+                  || (tk_name == "fltk"
+                      && (available_toolkits.find ("qt")
+                          == available_toolkits.end ())))
+                dtk = tk_name;
+            }
+        }
+    }
+}
+
 DEFUN (available_graphics_toolkits, , ,
        "-*- texinfo -*-\n\
 @deftypefn {Built-in Function} {} available_graphics_toolkits ()\n\
@@ -9664,12 +10758,13 @@
 
   if (args.length () == 1)
     {
-      std::string name = args(0).string_value ();
-
-      if (! error_state)
-        gtk_manager::register_toolkit (name);
+      if (args(0).is_string ())
+        {
+          std::string name = args(0).string_value ();
+          gtk_manager::register_toolkit (name);
+        }
       else
-        error ("register_graphics_toolkit: expecting character string");
+        error ("register_graphics_toolkit: TOOLKIT must be a string");
     }
   else
     print_usage ();
@@ -9982,8 +11077,8 @@
                                                  POSTSET);
                   else
                     {
-                      caseless_str persistent = args(2).string_value ();
-                      if (persistent.compare ("persistent"))
+                      if (args(2).is_string () &&
+                          args(2).string_value () == "persistent")
                         {
                           go.delete_property_listener (pname, octave_value (),
                                                        PERSISTENT);
@@ -10177,7 +11272,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 Feb 06 08:31:09 2015 -0800
+++ b/libinterp/corefcn/graphics.in.h	Fri Feb 06 08:31:49 2015 -0800
@@ -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);
   }
@@ -1989,10 +1989,76 @@
 
 // ---------------------------------------------------------------------
 
+typedef std::pair <std::string, octave_value> pval_pair;
+
+class pval_vector : public std::vector <pval_pair>
+{
+ public:
+  const_iterator find (const std::string pname) const
+  {
+    const_iterator it;
+
+    for (it = (*this).begin (); it != (*this).end (); it++)
+      if (pname.compare ((*it).first) == 0)
+        return it;
+
+    return (*this).end ();
+  }
+
+  iterator find (const std::string pname)
+  {
+    iterator it;
+
+    for (it = (*this).begin (); it != (*this).end (); it++)
+      if (pname.compare ((*it).first) == 0)
+        return it;
+
+    return (*this).end ();
+  }
+
+  octave_value lookup (const std::string pname) const
+  {
+    octave_value retval;
+
+    const_iterator it = find (pname);
+
+    if (it != (*this).end ())
+     retval = (*it).second;
+
+    return retval;
+  }
+
+  octave_value& operator [] (const std::string pname)
+  {
+    iterator it = find (pname);
+
+    if (it == (*this).end ())
+      {
+        push_back (pval_pair (pname, octave_value ()));
+        return (*this).back ().second;
+      }
+
+    return (*it).second;
+  }
+
+  void erase (const std::string pname)
+  {
+    iterator it = find (pname);
+    if (it != (*this).end ())
+      erase (it);
+  }
+
+  void erase (iterator it)
+  {
+    std::vector <pval_pair>::erase (it);
+  }
+
+};
+
 class property_list
 {
 public:
-  typedef std::map<std::string, octave_value> pval_map_type;
+  typedef pval_vector pval_map_type;
   typedef std::map<std::string, pval_map_type> plist_map_type;
 
   typedef pval_map_type::iterator pval_map_iterator;
@@ -2273,7 +2339,7 @@
 
 private:
 
-  gtk_manager (void);
+  gtk_manager (void) { }
 
   ~gtk_manager (void) { }
 
@@ -2322,15 +2388,9 @@
 
   graphics_toolkit do_get_toolkit (void) const;
 
-  void do_register_toolkit (const std::string& name)
-  {
-    available_toolkits.insert (name);
-  }
-
-  void do_unregister_toolkit (const std::string& name)
-  {
-    available_toolkits.erase (name);
-  }
+  void do_register_toolkit (const std::string& name);
+
+  void do_unregister_toolkit (const std::string& name);
 
   void do_load_toolkit (const graphics_toolkit& tk)
   {
@@ -2600,7 +2660,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);
@@ -2704,8 +2764,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
@@ -2828,16 +2901,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)
@@ -2975,8 +3039,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 (); }
@@ -3096,20 +3175,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.
 
@@ -3117,18 +3186,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 ()
@@ -3138,6 +3207,7 @@
 
   private:
     std::list<graphics_handle> cbo_stack;
+
   };
 
 private:
@@ -3223,6 +3293,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; }
@@ -3231,6 +3306,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;
 
@@ -3289,6 +3372,8 @@
         }
     }
 
+    void adopt (const graphics_handle& h);
+
     void set_position (const octave_value& val,
                        bool do_notify_toolkit = true);
 
@@ -3339,8 +3424,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"
@@ -3352,7 +3437,7 @@
       radio_property renderermode , "{auto}|manual"
       bool_property resize , "on"
       callback_property resizefcn , Matrix ()
-      radio_property selectiontype , "{normal}|open|alt|extend"
+      radio_property selectiontype , "{normal}|open|alternate|extend"
       radio_property toolbar , "none|{auto}|figure"
       radio_property units Su , "inches|centimeters|normalized|points|{pixels}|characters"
       callback_property windowbuttondownfcn , Matrix ()
@@ -3388,6 +3473,14 @@
     }
 
   private:
+    Matrix get_auto_paperposition (void);
+
+    void update_paperpositionmode (void)
+    {
+      if (paperpositionmode.is ("auto"))
+        paperposition.set (get_auto_paperposition ());
+    }
+
     mutable graphics_toolkit toolkit;
   };
 
@@ -3455,6 +3548,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;
 };
@@ -3639,6 +3740,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; }
@@ -3677,11 +3779,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
 
@@ -3690,6 +3792,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.
@@ -3704,7 +3813,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"
@@ -3730,12 +3839,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 ()
@@ -3743,7 +3855,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"
@@ -3802,6 +3914,8 @@
       row_vector_property xmtick h , Matrix ()
       row_vector_property ymtick h , Matrix ()
       row_vector_property zmtick h , Matrix ()
+      // hidden property for text rendering
+      double_property fontsize_points hgr , 0
    END_PROPERTIES
 
   protected:
@@ -3844,11 +3958,13 @@
     void update_layer (void) { update_axes_layout (); }
     void update_yaxislocation (void)
     {
+      sync_positions ();
       update_axes_layout ();
       update_ylabel_position ();
     }
     void update_xaxislocation (void)
     {
+      sync_positions ();
       update_axes_layout ();
       update_xlabel_position ();
     }
@@ -3865,16 +3981,19 @@
     {
       if (xticklabelmode.is ("auto"))
         calc_ticklabels (xtick, xticklabel, xscale.is ("log"));
+      sync_positions ();
     }
     void update_ytick (void)
     {
       if (yticklabelmode.is ("auto"))
         calc_ticklabels (ytick, yticklabel, yscale.is ("log"));
+      sync_positions ();
     }
     void update_ztick (void)
     {
       if (zticklabelmode.is ("auto"))
         calc_ticklabels (ztick, zticklabel, zscale.is ("log"));
+      sync_positions ();
     }
 
     void update_xtickmode (void)
@@ -4106,8 +4225,8 @@
   axes (const graphics_handle& mh, const graphics_handle& p)
     : base_graphics_object (), xproperties (mh, p), default_properties ()
   {
+    xproperties.update_transform ();
     xproperties.override_defaults (*this);
-    xproperties.update_transform ();
   }
 
   ~axes (void) { }
@@ -4139,7 +4258,6 @@
 
   void set_defaults (const std::string& mode)
   {
-    remove_all_listeners ();
     xproperties.set_defaults (*this, mode);
   }
 
@@ -4176,6 +4294,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);
 
@@ -4256,6 +4382,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,13 +4441,13 @@
       radio_property fontangle u , "{normal}|italic|oblique"
       string_property fontname u , OCTAVE_DEFAULT_FONTNAME
       double_property fontsize u , 10
-      radio_property fontunits , "inches|centimeters|normalized|{points}|pixels"
+      radio_property fontunits SU , "inches|centimeters|normalized|{points}|pixels"
       radio_property fontweight u , "light|{normal}|demi|bold"
       radio_property horizontalalignment mu , "{left}|center|right"
       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,13 +4467,15 @@
       radio_property horizontalalignmentmode hu , "{auto}|manual"
       radio_property verticalalignmentmode hu , "{auto}|manual"
       radio_property autopos_tag h , "{none}|xlabel|ylabel|zlabel|title"
+      // hidden property for text rendering
+      double_property fontsize_points hgr , 0
     END_PROPERTIES
 
     Matrix get_data_position (void) const;
     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
 
@@ -4397,6 +4533,7 @@
     void update_verticalalignment (void) { update_text_extent (); }
 
     void update_units (void);
+    void update_fontunits (const caseless_str& old_fontunits);
 
   private:
     std::string cached_units;
@@ -4421,6 +4558,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;
+  }
 };
 
 // ---------------------------------------------------------------------
@@ -4443,18 +4588,21 @@
 
     octave_value get_color_data (void) const;
 
+    void initialize_data (void) { update_cdata (); }
+
     // See the genprops.awk script for an explanation of the
     // properties declarations.
     // 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 ()
@@ -4464,6 +4612,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:
@@ -4500,10 +4650,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 ();
 
@@ -4514,6 +4679,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 ();
 
@@ -4522,6 +4696,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;
@@ -4559,6 +4757,7 @@
     : base_graphics_object (), xproperties (mh, p)
   {
     xproperties.override_defaults (*this);
+    xproperties.initialize_data ();
   }
 
   ~image (void) { }
@@ -4568,6 +4767,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;
+  }
 };
 
 // ---------------------------------------------------------------------
@@ -4580,6 +4787,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
@@ -4609,9 +4824,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"
@@ -4624,11 +4839,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
@@ -4662,17 +4877,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:
@@ -4692,6 +4957,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;
+  }
 };
 
 // ---------------------------------------------------------------------
@@ -4719,11 +4992,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
@@ -4750,11 +5023,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
@@ -4784,6 +5057,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:
@@ -4847,6 +5121,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;
+  }
 };
 
 // ---------------------------------------------------------------------
@@ -4925,6 +5207,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;
+  }
+
 };
 
 // ---------------------------------------------------------------------
@@ -4986,6 +5276,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;
+  }
+
 };
 
 // ---------------------------------------------------------------------
@@ -5033,6 +5331,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;
+  }
+
 };
 
 // ---------------------------------------------------------------------
@@ -5125,6 +5431,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;
+  }
 };
 
 // ---------------------------------------------------------------------
@@ -5192,6 +5506,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;
+  }
 };
 
 // ---------------------------------------------------------------------
@@ -5279,6 +5601,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;
 };
@@ -5331,6 +5661,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;
+  }
+
 };
 
 // ---------------------------------------------------------------------
@@ -5384,16 +5722,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);
 
 // ---------------------------------------------------------------------
 
@@ -5864,12 +6210,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/gripes.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/libinterp/corefcn/gripes.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -245,3 +245,11 @@
   error ("%s: support for %s was disabled when %s was built",
          func.c_str (), feature.c_str (), pkg.c_str ());
 }
+
+void
+gripe_data_file_in_path (const std::string& fcn, const std::string& file)
+{
+  warning_with_id ("Octave:data-file-in-path",
+                   "%s: '%s' found by searching load path",
+                   fcn.c_str (), file.c_str ());
+}
--- a/libinterp/corefcn/gripes.h	Fri Feb 06 08:31:09 2015 -0800
+++ b/libinterp/corefcn/gripes.h	Fri Feb 06 08:31:49 2015 -0800
@@ -131,4 +131,8 @@
 extern OCTINTERP_API void
 gripe_disabled_feature (const std::string& func, const std::string& feature,
                         const std::string& pkg="Octave");
+
+extern OCTINTERP_API void
+gripe_data_file_in_path (const std::string& fcn, const std::string& file);
+
 #endif
--- a/libinterp/corefcn/help.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/libinterp/corefcn/help.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -40,6 +40,7 @@
 #include "file-ops.h"
 #include "file-stat.h"
 #include "oct-env.h"
+#include "oct-locbuf.h"
 #include "str-vec.h"
 
 #include <defaults.h>
@@ -230,7 +231,7 @@
 
   pair_type (")",
     "-*- texinfo -*-\n\
-@deftypefn {Operator} {} )\n\
+@deftypefn {Operator} {})\n\
 Array index or function argument delimiter.\n\
 @end deftypefn"),
 
@@ -1078,7 +1079,7 @@
 
   if (args.length () == 1)
     {
-      const std::string name = args (0).string_value ();
+      const std::string name = args(0).string_value ();
 
       if (! error_state)
         {
@@ -1173,7 +1174,7 @@
 
 DEFUN (__operators__, , ,
        "-*- texinfo -*-\n\
-@deftypefn {Function File} __operators__ ()\n\
+@deftypefn {Function File} {} __operators__ ()\n\
 Undocumented internal function.\n\
 @end deftypefn")
 {
@@ -1185,7 +1186,7 @@
 
 DEFUN (__keywords__, , ,
        "-*- texinfo -*-\n\
-@deftypefn {Function File} __keywords__ ()\n\
+@deftypefn {Function File} {} __keywords__ ()\n\
 Undocumented internal function.\n\
 @end deftypefn")
 {
@@ -1197,7 +1198,7 @@
 
 DEFUN (__builtins__, , ,
        "-*- texinfo -*-\n\
-@deftypefn {Function File} __builtins__ ()\n\
+@deftypefn {Function File} {} __builtins__ ()\n\
 Undocumented internal function.\n\
 @end deftypefn")
 {
@@ -1365,27 +1366,24 @@
 
   if (args.length () == 0)
     retval = Cell (ffl.append (afl));
-  else
+  else if (args(0).is_string ())
     {
-      std::string dir = args (0).string_value ();
+      std::string dir = args(0).string_value ();
+
+      string_vector fl = load_path::files (dir, true);
 
       if (! error_state)
         {
-          string_vector fl = load_path::files (dir, true);
+          // Return a sorted list with unique entries (in case of
+          // .m and .oct versions of the same function in a given
+          // directory, for example).
+          fl.sort (true);
 
-          if (! error_state)
-            {
-              // Return a sorted list with unique entries (in case of
-              // .m and .oct versions of the same function in a given
-              // directory, for example).
-              fl.sort (true);
-
-              retval = Cell (fl);
-            }
+          retval = Cell (fl);
         }
-      else
-        error ("__list_functions__: DIRECTORY argument must be a string");
     }
+  else
+    error ("__list_functions__: DIRECTORY argument must be a string");
 
   return retval;
 }
--- a/libinterp/corefcn/hess.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/libinterp/corefcn/hess.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -58,8 +58,9 @@
 @end ifnottex\n\
 \n\
 The Hessenberg decomposition is usually used as the first step in an\n\
-eigenvalue computation, but has other applications as well (see Golub,\n\
-Nash, and Van Loan, IEEE Transactions on Automatic Control, 1979).\n\
+eigenvalue computation, but has other applications as well\n\
+(see @nospell{Golub, Nash, and Van Loan},\n\
+IEEE Transactions on Automatic Control, 1979).\n\
 @seealso{eig, chol, lu, qr, qz, schur, svd}\n\
 @end deftypefn")
 {
--- a/libinterp/corefcn/input.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/libinterp/corefcn/input.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -188,6 +188,9 @@
   if (! eof && retval.empty ())
     retval = "\n";
 
+  if (command_editor::interrupt (false))
+    retval = "";
+
   return retval;
 }
 
@@ -508,10 +511,12 @@
 {
   unwind_protect frame;
 
+  bool silent = tree_evaluator::quiet_breakpoint_flag;
+  tree_evaluator::quiet_breakpoint_flag = false;
+
   octave_user_code *caller = octave_call_stack::caller_user_code ();
   std::string nm;
-
-  int curr_debug_line = octave_call_stack::current_line ();
+  int curr_debug_line;
 
   bool have_file = false;
 
@@ -523,9 +528,11 @@
         nm = caller->name ();
       else
         have_file = true;
+
+      curr_debug_line = octave_call_stack::caller_user_code_line ();
     }
   else
-    curr_debug_line = -1;
+    curr_debug_line = octave_call_stack::current_line ();
 
   std::ostringstream buf;
 
@@ -543,10 +550,13 @@
           // that we are stopped on the no-op command that marks the
           // end of a function or script.
 
-          buf << "stopped in " << nm;
+          if (! silent)
+            {
+              buf << "stopped in " << nm;
 
-          if (curr_debug_line > 0)
-            buf << " at line " << curr_debug_line;
+              if (curr_debug_line > 0)
+                buf << " at line " << curr_debug_line;
+            }
 
           if (have_file)
             {
@@ -557,15 +567,21 @@
               frame.add_fcn (execute_in_debugger_handler,
                              std::pair<std::string, int> (nm, curr_debug_line));
 
-              std::string line_buf
-                = get_file_line (nm, curr_debug_line);
+              if (! silent)
+                {
+                  std::string line_buf
+                    = get_file_line (nm, curr_debug_line);
 
-              if (! line_buf.empty ())
-                buf << "\n" << curr_debug_line << ": " << line_buf;
+                  if (! line_buf.empty ())
+                    buf << "\n" << curr_debug_line << ": " << line_buf;
+                }
             }
         }
     }
 
+  if (silent)
+    command_editor::erase_empty_line (true);
+
   std::string msg = buf.str ();
 
   if (! msg.empty ())
@@ -594,7 +610,7 @@
 
       if (command_editor::interrupt (false))
         break;
-      else
+       else
         {
           if (retval == 0 && curr_parser.stmt_list)
             {
@@ -749,10 +765,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\
@@ -771,7 +787,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 ();
 
@@ -821,11 +837,11 @@
 
       if (nargin == 1)
         {
-          prompt = args(0).string_value ();
-
-          if (error_state)
+          if (args(0).is_string ())
+            prompt = args(0).string_value ();
+          else
             {
-              error ("yes_or_no: PROMPT must be a character string");
+              error ("yes_or_no: PROMPT must be a string");
               return retval;
             }
         }
@@ -909,6 +925,7 @@
       octave_call_stack::goto_frame_relative (0);
 
       tree_evaluator::debug_mode = true;
+      tree_evaluator::quiet_breakpoint_flag = false;
 
       tree_evaluator::current_frame = octave_call_stack::current_frame ();
 
@@ -1004,6 +1021,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\
@@ -1184,7 +1210,7 @@
           retval = hook_fcn.id ();
         }
       else
-        error ("add_input_event_hook: expecting function handle or character string as first argument");
+        error ("add_input_event_hook: FCN must be a function handle or string");
     }
   else
     print_usage ();
@@ -1409,11 +1435,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\
@@ -1421,8 +1448,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\
@@ -1433,7 +1462,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/inv.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/libinterp/corefcn/inv.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -227,8 +227,7 @@
         }
 
       if (nargout < 2 && (info == -1 || rcond_plus_one_eq_one))
-        warning ("inverse: matrix singular to machine precision, rcond = %g",
-                 (isfloat ? frcond : rcond));
+        gripe_singular_matrix (isfloat ? frcond : rcond);
     }
 
   return retval;
--- a/libinterp/corefcn/jit-typeinfo.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/libinterp/corefcn/jit-typeinfo.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -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
@@ -916,7 +921,7 @@
 
 bool
 jit_operation::signature_cmp
-::operator() (const signature_vec *lhs, const signature_vec *rhs)
+::operator() (const signature_vec *lhs, const signature_vec *rhs) const
 {
   const signature_vec& l = *lhs;
   const signature_vec& r = *rhs;
@@ -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-typeinfo.h	Fri Feb 06 08:31:09 2015 -0800
+++ b/libinterp/corefcn/jit-typeinfo.h	Fri Feb 06 08:31:49 2015 -0800
@@ -372,7 +372,7 @@
 
   struct signature_cmp
   {
-    bool operator() (const signature_vec *lhs, const signature_vec *rhs);
+    bool operator() (const signature_vec *lhs, const signature_vec *rhs) const;
   };
 
   typedef std::map<const signature_vec *, jit_function *, signature_cmp>
--- a/libinterp/corefcn/jit-util.h	Fri Feb 06 08:31:09 2015 -0800
+++ b/libinterp/corefcn/jit-util.h	Fri Feb 06 08:31:49 2015 -0800
@@ -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 Feb 06 08:31:09 2015 -0800
+++ b/libinterp/corefcn/kron.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -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 (dim_vector (na * nb, 1));
+  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));
@@ -299,13 +287,26 @@
 %! x = ones (2);
 %! assert (kron (x, x), ones (4));
 
-%!shared x, y, z
+%!shared x, y, z, p1, p2, d1, d2
 %! x =  [1, 2];
 %! y =  [-1, -2];
 %! z =  [1,  2,  3,  4; 1,  2,  3,  4; 1,  2,  3,  4];
+%! p1 = eye (3)([2, 3, 1], :);  ## Permutation matrix
+%! p2 = [0 1 0; 0 0 1; 1 0 0];  ## Non-permutation equivalent
+%! d1 = diag ([1 2 3]);         ## Diag type matrix
+%! d2 = [1 0 0; 0 2 0; 0 0 3];  ## Non-diag equivalent
 %!assert (kron (1:4, ones (3, 1)), z)
+%!assert (kron (single (1:4), ones (3, 1)), single (z))
+%!assert (kron (sparse (1:4), ones (3, 1)), sparse (z))
+%!assert (kron (complex (1:4), ones (3, 1)), z)
+%!assert (kron (complex (single(1:4)), ones (3, 1)), single(z))
 %!assert (kron (x, y, z), kron (kron (x, y), z))
 %!assert (kron (x, y, z), kron (x, kron (y, z)))
+%!assert (kron (p1, p1), kron (p2, p2))
+%!assert (kron (p1, p2), kron (p2, p1))
+%!assert (kron (d1, d1), kron (d2, d2))
+%!assert (kron (d1, d2), kron (d2, d1))
+
 
 %!assert (kron (diag ([1, 2]), diag ([3, 4])), diag ([3, 4, 6, 8]))
 
--- a/libinterp/corefcn/load-path.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/libinterp/corefcn/load-path.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -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)
 {
@@ -518,6 +569,7 @@
       maybe_add_path_elts (sys_path, Vlocal_fcn_file_dir);
       maybe_add_path_elts (sys_path, Voct_file_dir);
       maybe_add_path_elts (sys_path, Vfcn_file_dir);
+      maybe_add_path_elts (sys_path, Voct_data_dir);
     }
 
   std::string tpath = load_path::command_line_path;
@@ -544,9 +596,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 +736,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 +754,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 +775,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 +819,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 +828,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 +896,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 +909,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 +964,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 +1063,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 +1079,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 +1118,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 +1148,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 +1196,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 +1225,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 +1296,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++)
@@ -1244,7 +1383,7 @@
 
           size_t dir_len = dir.length ();
 
-          if (dname_len >= dir_len
+          if (dname_len > dir_len
               && file_ops::is_dir_sep (dname[dname_len - dir_len - 1])
               && dir.compare (dname.substr (dname_len - dir_len)) == 0)
             {
@@ -1291,7 +1430,7 @@
 
           size_t dir_len = dir.length ();
 
-          if (dname_len >= dir_len
+          if (dname_len > dir_len
               && file_ops::is_dir_sep (dname[dname_len - dir_len - 1])
               && dir.compare (dname.substr (dname_len - dir_len)) == 0)
             {
@@ -1515,6 +1654,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 +1802,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 +1830,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 +1948,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 +1957,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 +2027,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 +2113,7 @@
     {
       retval = dirname;
 
-      string_vector dirlist = dir.read ();
+      string_vector dirlist = dir.read ().sort (false);
 
       octave_idx_type len = dirlist.length ();
 
@@ -1937,7 +2121,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 +2149,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)
@@ -2013,7 +2213,7 @@
       if (! error_state)
         retval = genpath (dirname);
       else
-        error ("genpath: DIR must be a character string");
+        error ("genpath: DIR must be a string");
     }
   else if (nargin > 1)
     {
@@ -2032,7 +2232,7 @@
       if (! error_state)
         retval = genpath (dirname, skip);
       else
-        error ("genpath: all arguments must be character strings");
+        error ("genpath: all arguments must be strings");
     }
   else
     print_usage ();
@@ -2237,10 +2437,10 @@
 
       for (int i = 0; i < nargin; i++)
         {
-          std::string arg = args(i).string_value ();
-
-          if (! error_state)
+          if (args(i).is_string ())
             {
+              std::string arg = args(i).string_value ();
+
               std::list<std::string> dir_elts = split_path (arg);
 
               if (! append)
@@ -2264,7 +2464,7 @@
                 }
             }
           else
-            error ("addpath: all arguments must be character strings");
+            error ("addpath: all arguments must be strings");
         }
 
       if (need_to_update)
@@ -2306,10 +2506,9 @@
 
       for (int i = 0; i < nargin; i++)
         {
-          std::string arg = args(i).string_value ();
-
-          if (! error_state)
+          if (args(i).is_string ())
             {
+              std::string arg = args(i).string_value ();
               std::list<std::string> dir_elts = split_path (arg);
 
               for (std::list<std::string>::const_iterator p = dir_elts.begin ();
@@ -2328,7 +2527,7 @@
                 }
             }
           else
-            error ("addpath: all arguments must be character strings");
+            error ("addpath: all arguments must be strings");
         }
 
       if (need_to_update)
@@ -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 Feb 06 08:31:09 2015 -0800
+++ b/libinterp/corefcn/load-path.h	Fri Feb 06 08:31:49 2015 -0800
@@ -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 Feb 06 08:31:09 2015 -0800
+++ b/libinterp/corefcn/load-save.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -498,26 +498,7 @@
 std::string
 find_file_to_load (const std::string& name, const std::string& orig_name)
 {
-  std::string fname = name;
-
-  if (! (octave_env::absolute_pathname (fname)
-         || octave_env::rooted_relative_pathname (fname)))
-    {
-      file_stat fs (fname);
-
-      if (! (fs.exists () && fs.is_reg ()))
-        {
-          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");
-              fname = tmp;
-            }
-        }
-    }
+  std::string fname = find_data_file_in_load_path ("load", name, true);
 
   size_t dot_pos = fname.rfind (".");
   size_t sep_pos = fname.find_last_of (file_ops::dir_sep_chars ());
@@ -1071,7 +1052,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++)
     {
@@ -1224,7 +1206,7 @@
         char headertext[128];
 
         time (&now);
-        bdt = *gmtime (&now);
+        bdt = *gnulib::gmtime (&now);
         memset (headertext, ' ', 124);
         // ISO 8601 format date
         nstrftime (headertext, 124, "MATLAB 5.0 MAT-file, written by Octave "
@@ -1500,17 +1482,17 @@
 @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\
-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\
-of the scalar structure @var{STRUCT} are saved as if they were variables\n\
-with corresponding names.\n\
-Valid options for the @code{save} command are listed in the following table.\n\
-Options that modify the output format override the format specified by\n\
-@code{save_default_options}.\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,\n\
+Octave saves all the variables in the current scope.  Otherwise, full\n\
+variable names or pattern syntax can be used to specify the variables to\n\
+save.  If the @option{-struct} modifier is used, fields @var{f1} @var{f2}\n\
+@dots{} of the scalar structure @var{STRUCT} are saved as if they were\n\
+variables with corresponding names.  Valid options for the @code{save}\n\
+command are listed in the following table.  Options that modify the output\n\
+format override the format specified by @code{save_default_options}.\n\
 \n\
 If save is invoked using the functional form\n\
 \n\
@@ -1621,8 +1603,6 @@
 {
   octave_value_list retval;
 
-  int argc = args.length ();
-
   string_vector argv = args.make_argv ();
 
   if (error_state)
@@ -1646,7 +1626,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)
@@ -1679,11 +1659,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 Feb 06 08:31:09 2015 -0800
+++ b/libinterp/corefcn/lookup.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -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 Feb 06 08:31:09 2015 -0800
+++ b/libinterp/corefcn/ls-hdf5.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -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 Feb 06 08:31:09 2015 -0800
+++ b/libinterp/corefcn/ls-mat4.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -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 Feb 06 08:31:09 2015 -0800
+++ b/libinterp/corefcn/ls-mat5.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -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 Feb 06 08:31:09 2015 -0800
+++ b/libinterp/corefcn/lu.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -137,7 +137,7 @@
 is embedded into @var{U} to give a return value similar to the full case.\n\
 For both full and sparse matrices, @code{lu} loses the permutation\n\
 information.\n\
-@seealso{luupdate, chol, hess, qr, qz, schur, svd}\n\
+@seealso{luupdate, ilu, chol, hess, qr, qz, schur, svd}\n\
 @end deftypefn")
 {
   octave_value_list retval;
@@ -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 Feb 06 08:31:09 2015 -0800
+++ b/libinterp/corefcn/luinc.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -37,7 +37,7 @@
 #include "ov-re-sparse.h"
 #include "ov-cx-sparse.h"
 
-DEFUN (luinc, args, nargout,
+DEFUN (__luinc__, args, nargout,
        "-*- texinfo -*-\n\
 @deftypefn  {Built-in Function} {[@var{L}, @var{U}, @var{P}, @var{Q}] =} luinc (@var{A}, '0')\n\
 @deftypefnx {Built-in Function} {[@var{L}, @var{U}, @var{P}, @var{Q}] =} luinc (@var{A}, @var{droptol})\n\
@@ -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\
@@ -93,7 +93,7 @@
 \n\
 Given the string argument @qcode{\"vector\"}, @code{luinc} returns the\n\
 values of @var{p} @var{q} as vector values.\n\
-@seealso{sparse, lu}\n\
+@seealso{sparse, lu, ilu, ichol}\n\
 @end deftypefn")
 {
   int nargin = args.length ();
@@ -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 Feb 06 08:31:09 2015 -0800
+++ b/libinterp/corefcn/mappers.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -114,6 +114,20 @@
 %! v = single ([0, pi/6, pi/4, pi/3, pi/2, 2*pi/3, 3*pi/4, 5*pi/6, pi]);
 %! assert (acos (x), v, sqrt (eps ("single")));
 
+## Test values on either side of branch cut
+%!test
+%! rval = 0;
+%! ival = 1.31695789692481635;
+%! obs = acos ([2, 2-i*eps, 2+i*eps]);
+%! exp = [rval + ival*i, rval + ival*i, rval - ival*i];
+%! assert (obs, exp, 2*eps);
+%! rval = pi;
+%! obs = acos ([-2, -2-i*eps, -2+i*eps]);
+%! exp = [rval - ival*i, rval + ival*i, rval - ival*i];
+%! assert (obs, exp, 2*eps);
+%! assert (acos ([2 0]),  [ival*i, pi/2], 2*eps);
+%! assert (acos ([2 0i]), [ival*i, pi/2], 2*eps);
+
 %!error acos ()
 %!error acos (1, 2)
 */
@@ -236,12 +250,32 @@
 }
 
 /*
-%!test
+%!shared rt2, rt3
 %! rt2 = sqrt (2);
 %! rt3 = sqrt (3);
+
+%!test
 %! x = [0, 1/2, rt2/2, rt3/2, 1, rt3/2, rt2/2, 1/2, 0];
 %! v = [0, pi/6, pi/4, pi/3, pi/2, pi/3, pi/4, pi/6, 0];
-%! assert (all (abs (asin (x) - v) < sqrt (eps)));
+%! assert (asin (x), v, sqrt (eps));
+
+%!test
+%! x = single ([0, 1/2, rt2/2, rt3/2, 1, rt3/2, rt2/2, 1/2, 0]);
+%! v = single ([0, pi/6, pi/4, pi/3, pi/2, pi/3, pi/4, pi/6, 0]);
+%! assert (asin (x), v, sqrt (eps ("single")));
+
+## Test values on either side of branch cut
+%!test
+%! rval = pi/2;
+%! ival = 1.31695789692481635;
+%! obs = asin ([2, 2-i*eps, 2+i*eps]);
+%! exp = [rval - ival*i, rval - ival*i, rval + ival*i];
+%! assert (obs, exp, 2*eps);
+%! obs = asin ([-2, -2-i*eps, -2+i*eps]);
+%! exp = [-rval + ival*i, -rval - ival*i, -rval + ival*i];
+%! assert (obs, exp, 2*eps);
+%! assert (asin ([2 0]),  [rval - ival*i, 0], 2*eps);
+%! assert (asin ([2 0i]), [rval - ival*i, 0], 2*eps);
 
 %!error asin ()
 %!error asin (1, 2)
@@ -895,15 +929,15 @@
 
 DEFUN (isfinite, args, ,
        "-*- texinfo -*-\n\
-@deftypefn  {Mapping Function} {} isfinite (@var{x})\n\
-@deftypefnx {Mapping Function} {} finite (@var{x})\n\
+@deftypefn {Mapping Function} {} isfinite (@var{x})\n\
 Return a logical array which is true where the elements of @var{x} are\n\
 finite values and false where they are not.\n\
+\n\
 For example:\n\
 \n\
 @example\n\
 @group\n\
-finite ([13, Inf, NA, NaN])\n\
+isfinite ([13, Inf, NA, NaN])\n\
      @result{} [ 1, 0, 0, 0 ]\n\
 @end group\n\
 @end example\n\
@@ -920,16 +954,16 @@
 }
 
 /*
-%!assert (!finite (Inf))
-%!assert (!finite (NaN))
-%!assert (finite (rand (1,10)))
+%!assert (!isfinite (Inf))
+%!assert (!isfinite (NaN))
+%!assert (isfinite (rand (1,10)))
 
-%!assert (!finite (single (Inf)))
-%!assert (!finite (single (NaN)))
-%!assert (finite (single (rand (1,10))))
+%!assert (!isfinite (single (Inf)))
+%!assert (!isfinite (single (NaN)))
+%!assert (isfinite (single (rand (1,10))))
 
-%!error finite ()
-%!error finite (1, 2)
+%!error isfinite ()
+%!error isfinite (1, 2)
 */
 
 DEFUN (fix, args, ,
@@ -1024,7 +1058,13 @@
 @end example\n\
 \n\
 @end ifnottex\n\
-@seealso{gammainc, lgamma}\n\
+\n\
+Programming Note: The gamma function can grow quite large even for small\n\
+input values.  In many cases it may be preferable to use the natural\n\
+logarithm of the gamma function (@code{gammaln}) in calculations to minimize\n\
+loss of precision.  The final result is then\n\
+@code{exp (@var{result_using_gammaln}).}\n\
+@seealso{gammainc, gammaln, factorial}\n\
 @end deftypefn")
 {
   octave_value retval;
@@ -1574,8 +1614,8 @@
 
 DEFUN (lgamma, args, ,
        "-*- texinfo -*-\n\
-@deftypefn  {Mapping Function} {} lgamma (@var{x})\n\
-@deftypefnx {Mapping Function} {} gammaln (@var{x})\n\
+@deftypefn  {Mapping Function} {} gammaln (@var{x})\n\
+@deftypefnx {Mapping Function} {} lgamma (@var{x})\n\
 Return the natural logarithm of the gamma function of @var{x}.\n\
 @seealso{gamma, gammainc}\n\
 @end deftypefn")
@@ -1592,30 +1632,30 @@
 /*
 %!test
 %! a = -1i*sqrt (-1/(6.4187*6.4187));
-%! assert (lgamma (a), lgamma (real (a)));
+%! assert (gammaln (a), gammaln (real (a)));
 
 %!test
 %! x = [.5, 1, 1.5, 2, 3, 4, 5];
 %! v = [sqrt(pi), 1, .5*sqrt(pi), 1, 2, 6, 24];
-%! assert (lgamma (x), log (v), sqrt (eps))
+%! assert (gammaln (x), log (v), sqrt (eps))
 
 %!test
 %! a = single (-1i*sqrt (-1/(6.4187*6.4187)));
-%! assert (lgamma (a), lgamma (real (a)));
+%! assert (gammaln (a), gammaln (real (a)));
 
 %!test
 %! x = single ([.5, 1, 1.5, 2, 3, 4, 5]);
 %! v = single ([sqrt(pi), 1, .5*sqrt(pi), 1, 2, 6, 24]);
-%! assert (lgamma (x), log (v), sqrt (eps ("single")))
+%! assert (gammaln (x), log (v), sqrt (eps ("single")))
 
 %!test
 %! x = [-1, 0, 1, Inf];
 %! v = [Inf, Inf, 0, Inf];
-%! assert (lgamma (x), v);
-%! assert (lgamma (single (x)), single (v));
+%! assert (gammaln (x), v);
+%! assert (gammaln (single (x)), single (v));
 
-%!error lgamma ()
-%!error lgamma (1,2)
+%!error gammaln ()
+%!error gammaln (1,2)
 */
 
 DEFUN (log, args, ,
@@ -1886,7 +1926,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 +2196,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 +2256,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");
@@ -2225,4 +2283,3 @@
 
 DEFALIAS (gammaln, lgamma);
 
-DEFALIAS (finite, isfinite);
--- a/libinterp/corefcn/matrix_type.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/libinterp/corefcn/matrix_type.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -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 ();
@@ -213,18 +213,18 @@
           else
             {
               // Ok, we're changing the matrix type
-              std::string str_typ = args(1).string_value ();
-
-              // FIXME: why do I have to explicitly call the constructor?
-              MatrixType mattyp = MatrixType ();
-
-              octave_idx_type nl = 0;
-              octave_idx_type nu = 0;
-
-              if (error_state)
+              if (! args(1).is_string ())
                 error ("matrix_type: TYPE must be a string");
               else
                 {
+                  std::string str_typ = args(1).string_value ();
+
+                  // FIXME: why do I have to explicitly call the constructor?
+                  MatrixType mattyp = MatrixType ();
+
+                  octave_idx_type nl = 0;
+                  octave_idx_type nu = 0;
+
                   // Use STL function to convert to lower case
                   std::transform (str_typ.begin (), str_typ.end (),
                                   str_typ.begin (), tolower);
@@ -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");
@@ -416,15 +416,15 @@
           else
             {
               // Ok, we're changing the matrix type
-              std::string str_typ = args(1).string_value ();
-
-              // FIXME: why do I have to explicitly call the constructor?
-              MatrixType mattyp = MatrixType (MatrixType::Unknown, true);
-
-              if (error_state)
+              if (! args(1).is_string ())
                 error ("matrix_type: TYPE must be a string");
               else
                 {
+                  std::string str_typ = args(1).string_value ();
+
+                  // FIXME: why do I have to explicitly call the constructor?
+                  MatrixType mattyp = MatrixType (MatrixType::Unknown, true);
+
                   // Use STL function to convert to lower case
                   std::transform (str_typ.begin (), str_typ.end (),
                                   str_typ.begin (), tolower);
@@ -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 Feb 06 08:31:09 2015 -0800
+++ b/libinterp/corefcn/max.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -155,7 +155,7 @@
 
   octave_value retval;
 
-  if (argx.is_scalar_type () == 1)
+  if (argx.is_scalar_type ())
     {
       ScalarType x = octave_value_extract<ScalarType> (argx);
       ArrayType y = octave_value_extract<ArrayType> (argy);
@@ -167,7 +167,7 @@
       else
         retval = max (x, y);
     }
-  else if (argy.is_scalar_type () == 1)
+  else if (argy.is_scalar_type ())
     {
       ArrayType x = octave_value_extract<ArrayType> (argx);
       ScalarType y = octave_value_extract<ScalarType> (argy);
@@ -210,39 +210,26 @@
 {
   octave_value retval;
 
-  if (argx.is_scalar_type () == 1)
-    {
-      char x = octave_value_extract<char> (argx);
-      charNDArray y = octave_value_extract<charNDArray> (argy);
+  charNDArray x = octave_value_extract<charNDArray> (argx);
+  charNDArray y = octave_value_extract<charNDArray> (argy);
 
-      if (error_state)
-        ;
-      else if (ismin)
-        retval = NDArray (min (x, y));
+  if (error_state)
+    ;
+  else if (ismin)
+    {
+      if (x.numel () == 1)
+        retval = NDArray (min (x(0), y));
+      else if (y.numel () == 1)
+        retval = NDArray (min (x, y(0)));
       else
-        retval = NDArray (max (x, y));
-    }
-  else if (argy.is_scalar_type () == 1)
-    {
-      charNDArray x = octave_value_extract<charNDArray> (argx);
-      char y = octave_value_extract<char> (argy);
-
-      if (error_state)
-        ;
-      else if (ismin)
         retval = NDArray (min (x, y));
-      else
-        retval = NDArray (max (x, y));
     }
   else
     {
-      charNDArray x = octave_value_extract<charNDArray> (argx);
-      charNDArray y = octave_value_extract<charNDArray> (argy);
-
-      if (error_state)
-        ;
-      else if (ismin)
-        retval = NDArray (min (x, y));
+      if (x.numel () == 1)
+        retval = NDArray (max (x(0), y));
+      else if (y.numel () == 1)
+        retval = NDArray (max (x, y(0)));
       else
         retval = NDArray (max (x, y));
     }
@@ -284,7 +271,7 @@
             if (arg.is_range () && (dim == -1 || dim == 1))
               {
                 Range range = arg.range_value ();
-                if (range.nelem () == 0)
+                if (range.nelem () < 1)
                   {
                     retval(0) = arg;
                     if (nargout > 1)
@@ -354,11 +341,18 @@
     }
   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;
+      /*
+      FIXME: This is what should happen when boolNDArray has max()
+      else if (xtyp == btyp_bool && ytyp == btyp_bool)
+        rtyp = btyp_bool;
+      */
       else
         rtyp = btyp_mixed_numeric (xtyp, ytyp);
 
@@ -407,10 +401,21 @@
         MAKE_INT_BRANCH (uint32);
         MAKE_INT_BRANCH (uint64);
 #undef MAKE_INT_BRANCH
+        /*
+        FIXME: This is what should happen when boolNDArray has max()
+        case btyp_bool:
+          retval = do_minmax_bin_op<boolNDArray> (argx, argy, ismin);
+          break;
+        */
         default:
           error ("%s: cannot compute %s (%s, %s)", func, func,
                  argx.type_name ().c_str (), argy.type_name ().c_str ());
         }
+
+      // FIXME: Delete when boolNDArray has max()
+      if (xtyp == btyp_bool && ytyp == btyp_bool)
+        retval(0) = retval(0).bool_array_value ();
+
     }
   else
     print_usage ();
@@ -421,15 +426,23 @@
 DEFUN (min, args, nargout,
        "-*- texinfo -*-\n\
 @deftypefn  {Built-in Function} {} min (@var{x})\n\
-@deftypefnx {Built-in Function} {} min (@var{x}, @var{y})\n\
 @deftypefnx {Built-in Function} {} min (@var{x}, [], @var{dim})\n\
-@deftypefnx {Built-in Function} {} min (@var{x}, @var{y}, @var{dim})\n\
 @deftypefnx {Built-in Function} {[@var{w}, @var{iw}] =} min (@var{x})\n\
-For a vector argument, return the minimum value.  For a matrix\n\
-argument, return the minimum value from each column, as a row\n\
-vector, or over the dimension @var{dim} if defined, in which case @var{y} \n\
-should be set to the empty matrix (it's ignored otherwise).  For two matrices\n\
-(or a matrix and scalar), return the pair-wise minimum.\n\
+@deftypefnx {Built-in Function} {} min (@var{x}, @var{y})\n\
+Find minimum values in the array @var{x}.\n\
+\n\
+For a vector argument, return the minimum value.\n\
+For a matrix argument, return a row vector with the minimum value of each\n\
+column.\n\
+For a multi-dimensional array, @code{min} operates along the first\n\
+non-singleton dimension.\n\
+\n\
+If the optional third argument @var{dim} is present then operate along\n\
+this dimension.  In this case the second argument is ignored and should be\n\
+set to the empty matrix.\n\
+\n\
+For two matrices (or a matrix and a scalar), return the pairwise minimum.\n\
+\n\
 Thus,\n\
 \n\
 @example\n\
@@ -437,7 +450,7 @@
 @end example\n\
 \n\
 @noindent\n\
-returns the smallest element of @var{x}, and\n\
+returns the smallest element of the 2-D matrix @var{x}, and\n\
 \n\
 @example\n\
 @group\n\
@@ -451,7 +464,19 @@
 returns a row vector of the minimum values.\n\
 \n\
 For complex arguments, the magnitude of the elements are used for\n\
-comparison.\n\
+comparison.  If the magnitudes are identical, then the results are ordered\n\
+by phase angle in the range (-pi, pi].  Hence,\n\
+\n\
+@example\n\
+@group\n\
+min ([-1 i 1 -i])\n\
+    @result{} -i\n\
+@end group\n\
+@end example\n\
+\n\
+@noindent\n\
+because all entries have magnitude 1, but -i has the smallest phase angle\n\
+with value -pi/2.\n\
 \n\
 If called with one input and two output arguments,\n\
 @code{min} also returns the first index of the\n\
@@ -471,40 +496,176 @@
 }
 
 /*
+## Test generic double class
 %!assert (min ([1, 4, 2, 3]), 1)
 %!assert (min ([1; -10; 5; -2]), -10)
-%!assert (min ([4, i; -2, 2]), [-2, i])
-%!assert (min (char(42)), 42)
-%!assert (min (char(21), char(3)), 3)
-%!assert (min([char(21), char(3)]), 3)
-%!assert (min([char(100) char(3)], [char(42) char(42)]), [42 3])
+%!assert (min ([4, 2i 4.999; -2, 2, 3+4i]), [-2, 2, 4.999])
+## Special routines for char arrays
+%!assert (min (["abc", "ABC"]), 65)
+%!assert (min (["abc"; "CBA"]), [67 66 65])
+## Special routines for logical arrays
+%!assert (min (logical ([])), logical ([]))
+%!assert (min (logical ([0 0 1 0])), false)
+%!assert (min (logical ([0 0 1 0; 0 1 1 0])), logical ([0 0 1 0]))
+## Single values
+%!assert (min (single ([1, 4, 2, 3])), single (1))
+%!assert (min (single ([1; -10; 5; -2])), single (-10))
+%!assert (min (single ([4, 2i 4.999; -2, 2, 3+4i])), single ([-2, 2, 4.999]))
+## Integer values
+%!assert (min (uint8 ([1, 4, 2, 3])), uint8 (1))
+%!assert (min (uint8 ([1; -10; 5; -2])), uint8 (-10))
+%!assert (min (int8 ([1, 4, 2, 3])), int8 (1))
+%!assert (min (int8 ([1; -10; 5; -2])), int8 (-10))
+%!assert (min (uint16 ([1, 4, 2, 3])), uint16 (1))
+%!assert (min (uint16 ([1; -10; 5; -2])), uint16 (-10))
+%!assert (min (int16 ([1, 4, 2, 3])), int16 (1))
+%!assert (min (int16 ([1; -10; 5; -2])), int16 (-10))
+%!assert (min (uint32 ([1, 4, 2, 3])), uint32 (1))
+%!assert (min (uint32 ([1; -10; 5; -2])), uint32 (-10))
+%!assert (min (int32 ([1, 4, 2, 3])), int32 (1))
+%!assert (min (int32 ([1; -10; 5; -2])), int32 (-10))
+%!assert (min (uint64 ([1, 4, 2, 3])), uint64 (1))
+%!assert (min (uint64 ([1; -10; 5; -2])), uint64 (-10))
+%!assert (min (int64 ([1, 4, 2, 3])), int64 (1))
+%!assert (min (int64 ([1; -10; 5; -2])), int64 (-10))
+## Sparse double values
+%!assert (min (sparse ([1, 4, 2, 3])), sparse (1))
+%!assert (min (sparse ([1; -10; 5; -2])), sparse(-10))
+## FIXME: sparse doesn't order complex values by phase angle
+%!xtest
+%! assert (min (sparse ([4, 2i 4.999; -2, 2, 3+4i])), sparse ([-2, 2, 4.999]));
 
+## Test dimension argument
 %!test
 %! x = reshape (1:8, [2,2,2]);
-%! assert (max (x, [], 1), reshape ([2, 4, 6, 8], [1,2,2]));
-%! assert (max (x, [], 2), reshape ([3, 4, 7, 8], [2,1,2]));
-%! [y, i] = max (x, [], 3);
+%! assert (min (x, [], 1), reshape ([1, 3, 5, 7], [1,2,2]));
+%! assert (min (x, [], 2), reshape ([1, 2, 5, 6], [2,1,2]));
+%! [y, i] = min (x, [], 3);
 %! assert (ndims (y), 2);
-%! assert (y, [5, 7; 6, 8]);
+%! assert (y, [1, 3; 2, 4]);
 %! assert (ndims (i), 2);
-%! assert (i, [2, 2; 2, 2]);
+%! assert (i, [1, 1; 1, 1]);
+
+## Test 2-output forms for various arg types
+## Special routines for char arrays
+%!test
+%! [y, i] = min (["abc", "ABC"]);
+%! assert (y, 65);
+%! assert (i, 4);
+## Special routines for logical arrays
+%!test
+%! x = logical ([0 0 1 0]);
+%! [y, i] = min (x);
+%! assert (y, false);
+%! assert (i, 1);
+## Special handling of ranges
+%!test
+%! rng = 1:2:10;
+%! [y, i] = min (rng);
+%! assert (y, 1);
+%! assert (i, 1);
+%! rng = 10:-2:1;
+%! [y, i] = min (rng);
+%! assert (y, 2);
+%! assert (i, 5);
+
+## Test 2-input calling form for various arg types
+## Test generic double class
+%!test
+%! x = [1, 2, 3, 4];  y = fliplr (x);
+%! assert (min (x, y), [1 2 2 1]);
+%! assert (min (x, 3), [1 2 3 3]);
+%! assert (min (2, x), [1 2 2 2]);
+%! assert (min (x, 2.1i), [1 2 2.1i 2.1i]);
+## FIXME: Ordering of complex results with equal magnitude is not by phase
+##        angle in the 2-input form.  Instead, it is in the order in which it
+##        appears in the argument list.
+%!xtest
+%! x = [1, 2, 3, 4];  y = fliplr (x);
+%! assert (min (x, 2i), [2i 2i 3 4]);
+## Special routines for char arrays
+%!assert (min ("abc", "b"), [97 98 98])
+%!assert (min ("b", "cba"), [98 98 97])
+## Special handling for logical arrays
+%!assert (min ([true false], false), [false false])
+%!assert (min (true, [true false]), [true false])
+## Single values
+%!test
+%! x = single ([1, 2, 3, 4]);  y = fliplr (x);
+%! assert (min (x, y), single ([1 2 2 1]));
+%! assert (min (x, 3), single ([1 2 3 3]));
+%! assert (min (2, x), single ([1 2 2 2]));
+%! assert (min (x, 2.1i), single ([1 2 2.1i 2.1i]));
+## Integer values
+%!test
+%! x = uint8 ([1, 2, 3, 4]);  y = fliplr (x);
+%! assert (min (x, y), uint8 ([1 2 2 1]));
+%! assert (min (x, 3), uint8 ([1 2 3 3]));
+%! assert (min (2, x), uint8 ([1 2 2 2]));
+%! x = int8 ([1, 2, 3, 4]);  y = fliplr (x);
+%! assert (min (x, y), int8 ([1 2 2 1]));
+%! assert (min (x, 3), int8 ([1 2 3 3]));
+%! assert (min (2, x), int8 ([1 2 2 2]));
+%! x = uint16 ([1, 2, 3, 4]);  y = fliplr (x);
+%! assert (min (x, y), uint16 ([1 2 2 1]));
+%! assert (min (x, 3), uint16 ([1 2 3 3]));
+%! assert (min (2, x), uint16 ([1 2 2 2]));
+%! x = int16 ([1, 2, 3, 4]);  y = fliplr (x);
+%! assert (min (x, y), int16 ([1 2 2 1]));
+%! assert (min (x, 3), int16 ([1 2 3 3]));
+%! assert (min (2, x), int16 ([1 2 2 2]));
+%! x = uint32 ([1, 2, 3, 4]);  y = fliplr (x);
+%! assert (min (x, y), uint32 ([1 2 2 1]));
+%! assert (min (x, 3), uint32 ([1 2 3 3]));
+%! assert (min (2, x), uint32 ([1 2 2 2]));
+%! x = int32 ([1, 2, 3, 4]);  y = fliplr (x);
+%! assert (min (x, y), int32 ([1 2 2 1]));
+%! assert (min (x, 3), int32 ([1 2 3 3]));
+%! assert (min (2, x), int32 ([1 2 2 2]));
+%! x = uint64 ([1, 2, 3, 4]);  y = fliplr (x);
+%! assert (min (x, y), uint64 ([1 2 2 1]));
+%! assert (min (x, 3), uint64 ([1 2 3 3]));
+%! assert (min (2, x), uint64 ([1 2 2 2]));
+%! x = int64 ([1, 2, 3, 4]);  y = fliplr (x);
+%! assert (min (x, y), int64 ([1 2 2 1]));
+%! assert (min (x, 3), int64 ([1 2 3 3]));
+%! assert (min (2, x), int64 ([1 2 2 2]));
+## Sparse double values
+%!test
+%! x = sparse ([1, 2, 3, 4]);  y = fliplr (x);
+%! assert (min (x, y), sparse ([1 2 2 1]));
+%! assert (min (x, 3), sparse ([1 2 3 3]));
+%! assert (min (2, x), sparse ([1 2 2 2]));
+%! assert (min (x, 2.1i), sparse ([1 2 2.1i 2.1i]));
 
 %!error min ()
 %!error min (1, 2, 3, 4)
+%!error <DIM must be a valid dimension> min ([1 2; 3 4], [], -3)
+%!warning <second argument is ignored> min ([1 2 3 4], 2, 2);
+%!error <wrong type argument 'cell'> min ({1 2 3 4})
+%!error <cannot compute min \(cell, scalar\)> min ({1, 2, 3}, 2)
 */
 
 DEFUN (max, args, nargout,
        "-*- texinfo -*-\n\
 @deftypefn  {Built-in Function} {} max (@var{x})\n\
-@deftypefnx {Built-in Function} {} max (@var{x}, @var{y})\n\
 @deftypefnx {Built-in Function} {} max (@var{x}, [], @var{dim})\n\
-@deftypefnx {Built-in Function} {} max (@var{x}, @var{y}, @var{dim})\n\
 @deftypefnx {Built-in Function} {[@var{w}, @var{iw}] =} max (@var{x})\n\
-For a vector argument, return the maximum value.  For a matrix\n\
-argument, return the maximum value from each column, as a row\n\
-vector, or over the dimension @var{dim} if defined, in which case @var{y} \n\
-should be set to the empty matrix (it's ignored otherwise).  For two matrices\n\
-(or a matrix and scalar), return the pair-wise maximum.\n\
+@deftypefnx {Built-in Function} {} max (@var{x}, @var{y})\n\
+Find maximum values in the array @var{x}.\n\
+\n\
+For a vector argument, return the maximum value.\n\
+For a matrix argument, return a row vector with the maximum value of each\n\
+column.\n\
+For a multi-dimensional array, @code{max} operates along the first\n\
+non-singleton dimension.\n\
+\n\
+If the optional third argument @var{dim} is present then operate along\n\
+this dimension.  In this case the second argument is ignored and should be\n\
+set to the empty matrix.\n\
+\n\
+For two matrices (or a matrix and a scalar), return the pairwise maximum.\n\
+\n\
 Thus,\n\
 \n\
 @example\n\
@@ -512,7 +673,7 @@
 @end example\n\
 \n\
 @noindent\n\
-returns the largest element of the matrix @var{x}, and\n\
+returns the largest element of the 2-D matrix @var{x}, and\n\
 \n\
 @example\n\
 @group\n\
@@ -522,11 +683,23 @@
 @end example\n\
 \n\
 @noindent\n\
-compares each element of the range @code{2:5} with @code{pi}, and\n\
-returns a row vector of the maximum values.\n\
+compares each element of the range @code{2:5} with @code{pi}, and returns a\n\
+row vector of the maximum values.\n\
 \n\
 For complex arguments, the magnitude of the elements are used for\n\
-comparison.\n\
+comparison.  If the magnitudes are identical, then the results are ordered\n\
+by phase angle in the range (-pi, pi].  Hence,\n\
+\n\
+@example\n\
+@group\n\
+max ([-1 i 1 -i])\n\
+    @result{} -1\n\
+@end group\n\
+@end example\n\
+\n\
+@noindent\n\
+because all entries have magnitude 1, but -1 has the largest phase angle\n\
+with value pi.\n\
 \n\
 If called with one input and two output arguments,\n\
 @code{max} also returns the first index of the\n\
@@ -546,22 +719,157 @@
 }
 
 /*
+## Test generic double class
 %!assert (max ([1, 4, 2, 3]), 4)
 %!assert (max ([1; -10; 5; -2]), 5)
-%!assert (max ([4, i 4.999; -2, 2, 3+4i]), [4, 2, 3+4i])
+%!assert (max ([4, 2i 4.999; -2, 2, 3+4i]), [4, 2i, 3+4i])
+## Special routines for char arrays
+%!assert (max (["abc", "ABC"]), 99)
+%!assert (max (["abc"; "CBA"]), [97 98 99])
+## Special routines for logical arrays
+%!assert (max (logical ([])), logical ([]))
+%!assert (max (logical ([0 0 1 0])), true)
+%!assert (max (logical ([0 0 1 0; 0 1 0 0])), logical ([0 1 1 0]))
+## Single values
+%!assert (max (single ([1, 4, 2, 3])), single (4))
+%!assert (max (single ([1; -10; 5; -2])), single (5))
+%!assert (max (single ([4, 2i 4.999; -2, 2, 3+4i])), single ([4, 2i, 3+4i]))
+## Integer values
+%!assert (max (uint8 ([1, 4, 2, 3])), uint8 (4))
+%!assert (max (uint8 ([1; -10; 5; -2])), uint8 (5))
+%!assert (max (int8 ([1, 4, 2, 3])), int8 (4))
+%!assert (max (int8 ([1; -10; 5; -2])), int8 (5))
+%!assert (max (uint16 ([1, 4, 2, 3])), uint16 (4))
+%!assert (max (uint16 ([1; -10; 5; -2])), uint16 (5))
+%!assert (max (int16 ([1, 4, 2, 3])), int16 (4))
+%!assert (max (int16 ([1; -10; 5; -2])), int16 (5))
+%!assert (max (uint32 ([1, 4, 2, 3])), uint32 (4))
+%!assert (max (uint32 ([1; -10; 5; -2])), uint32 (5))
+%!assert (max (int32 ([1, 4, 2, 3])), int32 (4))
+%!assert (max (int32 ([1; -10; 5; -2])), int32 (5))
+%!assert (max (uint64 ([1, 4, 2, 3])), uint64 (4))
+%!assert (max (uint64 ([1; -10; 5; -2])), uint64 (5))
+%!assert (max (int64 ([1, 4, 2, 3])), int64 (4))
+%!assert (max (int64 ([1; -10; 5; -2])), int64 (5))
+## Sparse double values
+%!assert (max (sparse ([1, 4, 2, 3])), sparse (4))
+%!assert (max (sparse ([1; -10; 5; -2])), sparse(5))
+%!assert (max (sparse ([4, 2i 4.999; -2, 2, 3+4i])), sparse ([4, 2i, 3+4i]))
 
+## Test dimension argument
 %!test
 %! x = reshape (1:8, [2,2,2]);
 %! assert (min (x, [], 1), reshape ([1, 3, 5, 7], [1,2,2]));
 %! assert (min (x, [], 2), reshape ([1, 2, 5, 6], [2,1,2]));
 %! [y, i] = min (x, [], 3);
-%! assert (ndims(y), 2);
+%! assert (ndims (y), 2);
 %! assert (y, [1, 3; 2, 4]);
-%! assert (ndims(i), 2);
+%! assert (ndims (i), 2);
 %! assert (i, [1, 1; 1, 1]);
 
+## Test 2-output forms for various arg types
+## Special routines for char arrays
+%!test
+%! [y, i] = max (["abc", "ABC"]);
+%! assert (y, 99);
+%! assert (i, 3);
+## Special routines for logical arrays
+%!test
+%! x = logical ([0 0 1 0]);
+%! [y, i] = max (x);
+%! assert (y, true);
+%! assert (i, 3);
+## Special handling of ranges
+%!test
+%! rng = 1:2:10;
+%! [y, i] = max (rng);
+%! assert (y, 9);
+%! assert (i, 5);
+%! rng = 10:-2:1;
+%! [y, i] = max (rng);
+%! assert (y, 10);
+%! assert (i, 1);
+
+## Test 2-input calling form for various arg types
+## Test generic double class
+%!test
+%! x = [1, 2, 3, 4];  y = fliplr (x);
+%! assert (max (x, y), [4 3 3 4]);
+%! assert (max (x, 3), [3 3 3 4]);
+%! assert (max (2, x), [2 2 3 4]);
+%! assert (max (x, 2.1i), [2.1i 2.1i 3 4]);
+## FIXME: Ordering of complex results with equal magnitude is not by phase
+##        angle in the 2-input form.  Instead, it is in the order in which it
+##        appears in the argument list.
+%!xtest
+%! x = [1, 2, 3, 4];  y = fliplr (x);
+%! assert (max (x, 2i), [2i 2i 3 4]);
+## Special routines for char arrays
+%!assert (max ("abc", "b"), [98 98 99])
+%!assert (max ("b", "cba"), [99 98 98])
+## Special handling for logical arrays
+%!assert (max ([true false], false), [true false])
+%!assert (max (true, [false false]), [true true])
+## Single values
+%!test
+%! x = single ([1, 2, 3, 4]);  y = fliplr (x);
+%! assert (max (x, y), single ([4 3 3 4]));
+%! assert (max (x, 3), single ([3 3 3 4]));
+%! assert (max (2, x), single ([2 2 3 4]));
+%! assert (max (x, 2.1i), single ([2.1i 2.1i 3 4]));
+## Integer values
+%!test
+%! x = uint8 ([1, 2, 3, 4]);  y = fliplr (x);
+%! assert (max (x, y), uint8 ([4 3 3 4]));
+%! assert (max (x, 3), uint8 ([3 3 3 4]));
+%! assert (max (2, x), uint8 ([2 2 3 4]));
+%! x = int8 ([1, 2, 3, 4]);  y = fliplr (x);
+%! assert (max (x, y), int8 ([4 3 3 4]));
+%! assert (max (x, 3), int8 ([3 3 3 4]));
+%! assert (max (2, x), int8 ([2 2 3 4]));
+%! x = uint16 ([1, 2, 3, 4]);  y = fliplr (x);
+%! assert (max (x, y), uint16 ([4 3 3 4]));
+%! assert (max (x, 3), uint16 ([3 3 3 4]));
+%! assert (max (2, x), uint16 ([2 2 3 4]));
+%! x = int16 ([1, 2, 3, 4]);  y = fliplr (x);
+%! assert (max (x, y), int16 ([4 3 3 4]));
+%! assert (max (x, 3), int16 ([3 3 3 4]));
+%! assert (max (2, x), int16 ([2 2 3 4]));
+%! x = uint32 ([1, 2, 3, 4]);  y = fliplr (x);
+%! assert (max (x, y), uint32 ([4 3 3 4]));
+%! assert (max (x, 3), uint32 ([3 3 3 4]));
+%! assert (max (2, x), uint32 ([2 2 3 4]));
+%! x = int32 ([1, 2, 3, 4]);  y = fliplr (x);
+%! assert (max (x, y), int32 ([4 3 3 4]));
+%! assert (max (x, 3), int32 ([3 3 3 4]));
+%! assert (max (2, x), int32 ([2 2 3 4]));
+%! x = uint64 ([1, 2, 3, 4]);  y = fliplr (x);
+%! assert (max (x, y), uint64 ([4 3 3 4]));
+%! assert (max (x, 3), uint64 ([3 3 3 4]));
+%! assert (max (2, x), uint64 ([2 2 3 4]));
+%! x = int64 ([1, 2, 3, 4]);  y = fliplr (x);
+%! assert (max (x, y), int64 ([4 3 3 4]));
+%! assert (max (x, 3), int64 ([3 3 3 4]));
+%! assert (max (2, x), int64 ([2 2 3 4]));
+## Sparse double values
+%!test
+%! x = sparse ([1, 2, 3, 4]);  y = fliplr (x);
+%! assert (max (x, y), sparse ([4 3 3 4]));
+%! assert (max (x, 3), sparse ([3 3 3 4]));
+%! assert (max (2, x), sparse ([2 2 3 4]));
+%! assert (max (x, 2.1i), sparse ([2.1i 2.1i 3 4]));
+
+## 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)
+%!error <DIM must be a valid dimension> max ([1 2; 3 4], [], -3)
+%!warning <second argument is ignored> max ([1 2 3 4], 2, 2);
+%!error <wrong type argument 'cell'> max ({1 2 3 4})
+%!error <cannot compute max \(cell, scalar\)> max ({1, 2, 3}, 2)
+
 */
 
 template <class ArrayType>
@@ -708,6 +1016,7 @@
 %!assert (cummin ([1, 4, 2, 3]), [1 1 1 1])
 %!assert (cummin ([1; -10; 5; -2]), [1; -10; -10; -10])
 %!assert (cummin ([4, i; -2, 2]), [4, i; -2, i])
+%!assert (cummin ([1 2; NaN 1], 2), [1 1; NaN 1])
 
 %!test
 %! x = reshape (1:8, [2,2,2]);
@@ -719,6 +1028,7 @@
 %! assert (ndims (iw), 3);
 %! assert (iw, ones (2,2,2));
 
+
 %!error cummin ()
 %!error cummin (1, 2, 3)
 */
@@ -762,6 +1072,7 @@
 %!assert (cummax ([1, 4, 2, 3]), [1 4 4 4])
 %!assert (cummax ([1; -10; 5; -2]), [1; 1; 5; 5])
 %!assert (cummax ([4, i 4.9, -2, 2, 3+4i]), [4, 4, 4.9, 4.9, 4.9, 3+4i])
+%!assert (cummax ([1 NaN 0; NaN NaN 1], 2), [1 1 1; NaN NaN 1])
 
 %!test
 %! x = reshape (8:-1:1, [2,2,2]);
--- a/libinterp/corefcn/md5sum.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/libinterp/corefcn/md5sum.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -31,10 +31,10 @@
 #include "defun.h"
 #include "file-stat.h"
 #include "file-ops.h"
-#include "gripes.h"
 #include "load-path.h"
 #include "oct-env.h"
 #include "oct-md5.h"
+#include "utils.h"
 
 DEFUN (md5sum, args, ,
        "-*- texinfo -*-\n\
@@ -64,22 +64,11 @@
             retval = oct_md5 (str);
           else
             {
-              file_stat fs (str);
-
-              if (! fs.exists ())
-                {
-                  std::string tmp
-                    = octave_env::make_absolute (load_path::find_file (str));
+              std::string fname = file_ops::tilde_expand (str);
 
-                  if (! tmp.empty ())
-                    {
-                      warning_with_id ("Octave:md5sum-file-in-path",
-                                       "md5sum: file found in load path");
-                      str = tmp;
-                    }
-                }
+              fname = find_data_file_in_load_path ("md5sum", fname);
 
-              retval = oct_md5_file (str);
+              retval = oct_md5_file (fname);
             }
         }
     }
@@ -91,11 +80,13 @@
 %!assert (md5sum ("abc\0", true), "147a664a2ca9410911e61986d3f0d52a");
 
 %!test
-%! tfile = tmpnam ();
+%! tfile = tempname ();
 %! fid = fopen (tfile, "wb");
 %! fwrite (fid, "abc\0");
 %! fclose (fid);
 %! assert (md5sum (tfile), "147a664a2ca9410911e61986d3f0d52a");
 %! unlink (tfile);
+
+%!error md5sum ();
 */
 
--- a/libinterp/corefcn/module.mk	Fri Feb 06 08:31:09 2015 -0800
+++ b/libinterp/corefcn/module.mk	Fri Feb 06 08:31:49 2015 -0800
@@ -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 \
@@ -75,7 +76,6 @@
   corefcn/ls-utils.h \
   corefcn/mex.h \
   corefcn/mexproto.h \
-  corefcn/mxarray.in.h \
   corefcn/oct-errno.h \
   corefcn/oct-fstrm.h \
   corefcn/oct-handle.h \
@@ -91,6 +91,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 +144,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 \
@@ -241,7 +243,7 @@
   corefcn/strfns.cc \
   corefcn/sub2ind.cc \
   corefcn/svd.cc \
-  corefcn/syl.cc \
+  corefcn/sylvester.cc \
   corefcn/symtab.cc \
   corefcn/syscalls.cc \
   corefcn/sysdep.cc \
@@ -320,7 +322,7 @@
 	mv $@-t $@
 
 corefcn/oct-tex-symbols.cc: corefcn/oct-tex-symbols.in Makefile.am
-	$(AWK) 'BEGIN { print "// DO NOT EDIT. AUTOMATICALLY GENERATED FROM oct-tex-symbols.in."; print "static uint32_t symbol_codes[][2] = {"; count = 0; } END { print "};"; printf("static int num_symbol_codes = %d;\n", count); } /^#/ { } { if (NF == 3) { printf("  { %s, %s },\n", $$2, $$3); count++; } }' $< > $@-t
+	$(AWK) 'BEGIN { print "// DO NOT EDIT. AUTOMATICALLY GENERATED FROM oct-tex-symbols.in."; print "static uint32_t symbol_codes[][2] = {"; count = 0; } END { print "};"; printf("static int num_symbol_codes = %d;\n", count); } !/^#/ && (NF == 3) { printf("  { %s, %s },\n", $$2, $$3); count++; }' $< > $@-t
 	mv $@-t $@
 
 corefcn/txt-eng.cc: corefcn/oct-tex-symbols.cc
@@ -338,7 +340,9 @@
                                  $(FONTCONFIG_CPPFLAGS) \
                                  $(FT2_CPPFLAGS) \
                                  $(HDF5_CPPFLAGS) \
-                                 $(LLVM_CPPFLAGS)
+                                 $(LLVM_CPPFLAGS) \
+                                 $(Z_CPPFLAGS)
+
 corefcn_libcorefcn_la_CXXFLAGS = $(AM_CXXFLAGS) $(LLVM_CXXFLAGS)
 
 corefcn_libtex_parser_la_SOURCES = $(TEX_PARSER_SRC)
--- a/libinterp/corefcn/nproc.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/libinterp/corefcn/nproc.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -87,4 +87,23 @@
 /*
 ## Must always report at least 1 cpu available
 %!assert (nproc () >= 1);
+%!assert (nproc ("all") >= 1);
+%!assert (nproc ("current") >= 1);
+
+%!test
+%! c = nproc ("current");
+%! unwind_protect
+%!   old_val = getenv ("OMP_NUM_THREADS");
+%!   new_val = c + 1;
+%!   setenv ("OMP_NUM_THREADS", num2str (new_val));
+%!   assert (nproc ("overridable"), new_val);
+%! unwind_protect_cleanup
+%!   if (! isempty (old_val))
+%!     setenv ("OMP_NUM_THREADS", old_val);
+%!   else
+%!     unsetenv ("OMP_NUM_THREADS");
+%!   endif
+%! end_unwind_protect
+
+%!error nproc ("no_valid_option");
 */
--- a/libinterp/corefcn/oct-fstrm.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/libinterp/corefcn/oct-fstrm.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -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 Feb 06 08:31:09 2015 -0800
+++ b/libinterp/corefcn/oct-fstrm.h	Fri Feb 06 08:31:49 2015 -0800
@@ -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-hdf5.h	Fri Feb 06 08:31:09 2015 -0800
+++ b/libinterp/corefcn/oct-hdf5.h	Fri Feb 06 08:31:49 2015 -0800
@@ -23,7 +23,7 @@
 #if !defined (octave_oct_hdf5_h)
 #define octave_hdf5_h 1
 
-#if defined (HAVE_HDF5)
+#if defined (HAVE_HDF5_H)
 #include <hdf5.h>
 #endif
 
--- a/libinterp/corefcn/oct-iostrm.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/libinterp/corefcn/oct-iostrm.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -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 Feb 06 08:31:09 2015 -0800
+++ b/libinterp/corefcn/oct-iostrm.h	Fri Feb 06 08:31:49 2015 -0800
@@ -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 Feb 06 08:31:09 2015 -0800
+++ b/libinterp/corefcn/oct-map.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -25,7 +25,9 @@
 #include <config.h>
 #endif
 
+#include "Array-util.h"
 #include "error.h"
+#include "oct-locbuf.h"
 #include "str-vec.h"
 
 #include "oct-map.h"
@@ -117,7 +119,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 +254,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 +813,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 +1308,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 Feb 06 08:31:09 2015 -0800
+++ b/libinterp/corefcn/oct-map.h	Fri Feb 06 08:31:49 2015 -0800
@@ -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 Feb 06 08:31:09 2015 -0800
+++ b/libinterp/corefcn/oct-obj.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -31,11 +31,11 @@
 
 // We are likely to have a lot of octave_value_list objects to allocate,
 // so make the grow_size large.
-DEFINE_OCTAVE_ALLOCATOR2(octave_value_list, 1024);
 
 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 Feb 06 08:31:09 2015 -0800
+++ b/libinterp/corefcn/oct-obj.h	Fri Feb 06 08:31:49 2015 -0800
@@ -27,7 +27,6 @@
 #include <string>
 #include <vector>
 
-#include "oct-alloc.h"
 #include "str-vec.h"
 #include "Array.h"
 
@@ -107,10 +106,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;
   }
@@ -164,7 +169,6 @@
   const octave_value& elem (octave_idx_type n) const
   { return data(n); }
 
-  DECLARE_OCTAVE_ALLOCATOR
 };
 
 // Make it easy to build argument lists for built-in functions or for
--- a/libinterp/corefcn/oct-stdstrm.h	Fri Feb 06 08:31:09 2015 -0800
+++ b/libinterp/corefcn/oct-stdstrm.h	Fri Feb 06 08:31:49 2015 -0800
@@ -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 Feb 06 08:31:09 2015 -0800
+++ b/libinterp/corefcn/oct-stream.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -34,12 +34,12 @@
 #include <sstream>
 #include <string>
 
-#include <Array.h>
-
+#include "Array.h"
 #include "byte-swap.h"
 #include "lo-ieee.h"
 #include "lo-mappers.h"
 #include "lo-utils.h"
+#include "oct-locbuf.h"
 #include "quit.h"
 #include "singleton-cleanup.h"
 #include "str-vec.h"
@@ -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;
 
@@ -4248,6 +4370,8 @@
       buf << "  "
           << std::setiosflags (std::ios::right)
           << std::setw (4) << p->first << "     "
+          // reset necessary in addition to setiosflags since this is one stmt.
+          << std::resetiosflags (std::ios::adjustfield)
           << std::setiosflags (std::ios::left)
           << std::setw (3)
           << octave_stream::mode_as_string (os.mode ())
--- a/libinterp/corefcn/oct-stream.h	Fri Feb 06 08:31:09 2015 -0800
+++ b/libinterp/corefcn/oct-stream.h	Fri Feb 06 08:31:49 2015 -0800
@@ -38,7 +38,6 @@
 #include "data-conv.h"
 #include "lo-utils.h"
 #include "mach-info.h"
-#include "oct-locbuf.h"
 #include "oct-refcount.h"
 
 class
@@ -479,6 +478,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 Feb 06 08:31:09 2015 -0800
+++ b/libinterp/corefcn/oct-strstrm.h	Fri Feb 06 08:31:49 2015 -0800
@@ -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 (); }
 
--- a/libinterp/corefcn/oct-tex-symbols.in	Fri Feb 06 08:31:09 2015 -0800
+++ b/libinterp/corefcn/oct-tex-symbols.in	Fri Feb 06 08:31:49 2015 -0800
@@ -1,12 +1,14 @@
 # List of supported symbols for the TeX interpreter
-# (http://www.mathworks.com/help/matlab/ref/text_props.html):
-# - symbol name
-# - Unicode code
-# - MS symbol code (http://www.kostis.net/charsets/symbol.htm)
-# - Arranged by listings in The TeXbook, Appendix F
-# - Lowercase Greek letters: Greek Upper case: Misc Symbols type Ord: "Large" operators:
-# - Binary operators: Relations: Negated relations: Arrows: Openings: Closings: Alternate names:
-# - Other (not in Appendix F Tables):
+# Reference: http://www.mathworks.com/help/matlab/ref/text_props.html
+#
+# Column 1 : symbol name
+# Column 2 : Unicode code
+# Column 3 : MS symbol code (http://www.kostis.net/charsets/symbol.htm)
+#
+# Arranged by listings in The TeXbook, Appendix F:
+# Greek lower case letters, Greek upper case, Misc Symbols type Ord,
+# "Large" operators, Binary operators, Relations, Negated relations, Arrows,
+# Openings, Closings, Alternate names, and Other (not in Appendix F Tables).
 
 alpha           0x03B1  0xF061
 beta            0x03B2  0xF062
@@ -108,6 +110,6 @@
 rceil           0x2309  0xF0F9
 neq             0x2260  0xF0B9
 ldots           0x2026  0xF0BC
-0               0x2298  0xF0C6
+0               0x2205  0xF0C6
 copyright       0x00A9  0xF0E3
 deg             0x00B0  0xF0B0
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libinterp/corefcn/octave-default-image.h	Fri Feb 06 08:31:49 2015 -0800
@@ -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 Feb 06 08:31:09 2015 -0800
+++ b/libinterp/corefcn/octave-link.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -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/octave-link.h	Fri Feb 06 08:31:09 2015 -0800
+++ b/libinterp/corefcn/octave-link.h	Fri Feb 06 08:31:49 2015 -0800
@@ -110,14 +110,6 @@
       instance->do_post_event (obj, method, arg);
   }
 
-  template <class T, class A, class B>
-  static void post_event (T *obj, void (T::*method) (const A&, const B&),
-                          const A& arg_a, const B& arg_b)
-  {
-    if (enabled ())
-      instance->do_post_event (obj, method, arg_a, arg_b);
-  }
-
   static void entered_readline_hook (void)
   {
     if (enabled ())
--- a/libinterp/corefcn/pager.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/libinterp/corefcn/pager.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -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 Feb 06 08:31:09 2015 -0800
+++ b/libinterp/corefcn/pinv.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -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 Feb 06 08:31:09 2015 -0800
+++ b/libinterp/corefcn/pr-output.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -85,7 +85,7 @@
 static bool plus_format = false;
 
 // First char for > 0, second for < 0, third for == 0.
-static std::string plus_format_chars = "+  ";
+static std::string plus_format_chars = "+- ";
 
 // TRUE means always print in a rational approximation
 static bool rat_format = false;
@@ -596,13 +596,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;
@@ -2105,7 +2103,7 @@
     {
     case 1:
     case 2:
-      octave_print_internal (os, nda.matrix_value (),
+      octave_print_internal (os, Matrix (nda),
                              pr_as_read_syntax, extra_indent);
       break;
 
@@ -2502,11 +2500,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)
@@ -2537,7 +2534,6 @@
               else
                 os << " ...\n";
             }
-          if (! colp) os << ", :";
           os << ")";
         }
       else
@@ -2584,7 +2580,7 @@
     {
     case 1:
     case 2:
-      octave_print_internal (os, nda.matrix_value (),
+      octave_print_internal (os, ComplexMatrix (nda),
                              pr_as_read_syntax, extra_indent);
       break;
 
@@ -2794,7 +2790,7 @@
     {
     case 1:
     case 2:
-      octave_print_internal (os, nda.matrix_value (),
+      octave_print_internal (os, boolMatrix (nda),
                              pr_as_read_syntax, extra_indent);
       break;
 
@@ -2861,7 +2857,7 @@
     {
     case 1:
     case 2:
-      octave_print_internal (os, nda.matrix_value (),
+      octave_print_internal (os, charMatrix (nda),
                              pr_as_read_syntax, extra_indent, pr_as_string);
       break;
 
@@ -3402,8 +3398,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 ();
 }
@@ -3457,7 +3452,7 @@
               rat_format = true;
 
               std::ostringstream buf;
-              args(0).print (buf);
+              arg.print (buf);
               std::string s = buf.str ();
 
               std::list<std::string> lst;
@@ -3519,11 +3514,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 () ? '"' : '\'');
@@ -3560,7 +3556,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");
 
@@ -3568,8 +3564,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");
         }
@@ -3630,20 +3628,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")
                 {
@@ -3684,11 +3687,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")
                 {
@@ -3729,6 +3765,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 ();
@@ -3754,6 +3822,7 @@
           if (--argc > 0)
             {
               arg = argv[idx++];
+              format.append (arg);
 
               if (arg.length () == 3)
                 plus_format_chars = arg;
@@ -3764,7 +3833,7 @@
                 }
             }
           else
-            plus_format_chars = "+  ";
+            plus_format_chars = "+- ";
 
           init_format_state ();
           plus_format = true;
@@ -3792,21 +3861,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\
@@ -3900,18 +3978,19 @@
 integer types).\n\
 \n\
 @table @code\n\
-@item  +\n\
-@itemx + @var{chars}\n\
+@item  \"+\"\n\
+@itemx \"+\" @var{chars}\n\
 @itemx plus\n\
 @itemx plus @var{chars}\n\
-Print a @samp{+} symbol for nonzero matrix elements and a space for zero\n\
-matrix elements.  This format can be very useful for examining the\n\
-structure of a large sparse matrix.\n\
+Print a @samp{+} symbol for matrix elements greater than zero, a\n\
+@samp{-} symbol for elements less than zero and a space for zero matrix\n\
+elements.  This format can be very useful for examining the structure\n\
+of a large sparse matrix.\n\
 \n\
 The optional argument @var{chars} specifies a list of 3 characters to use\n\
 for printing values greater than zero, less than zero and equal to zero.\n\
-For example, with the @samp{+ \"+-.\"} format, @code{[1, 0, -1; -1, 0, 1]}\n\
-is displayed as\n\
+For example, with the @samp{\"+\" \"+-.\"} format,\n\
+@code{[1, 0, -1; -1, 0, 1]} is displayed as\n\
 \n\
 @example\n\
 @group\n\
@@ -3991,6 +4070,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\
@@ -4020,7 +4118,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 Feb 06 08:31:09 2015 -0800
+++ b/libinterp/corefcn/profiler.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -1,5 +1,6 @@
 /*
 
+Copyright (C) 2014 Julien Bect
 Copyright (C) 2012-2013 Daniel Kraft
 
 This file is part of Octave.
@@ -32,29 +33,6 @@
 #include "pager.h"
 #include "profiler.h"
 
-profile_data_accumulator::enter::enter (profile_data_accumulator& a,
-                                        const std::string& f)
-  : acc (a)
-{
-  // FIXME: Add test for f != "" to prevent a blank line showing up
-  //        in profiler statistics.  See bug #39524.  The root cause
-  //        is that the function name is not set for the recurring readline
-  //        hook function.
-  if (acc.is_active () && f != "")
-    {
-      fcn = f;
-      acc.enter_function (fcn);
-    }
-  else
-    fcn = "";
-}
-
-profile_data_accumulator::enter::~enter ()
-{
-  if (fcn != "")
-    acc.exit_function (fcn);
-}
-
 profile_data_accumulator::stats::stats ()
   : time (0.0), calls (0), recursive (false),
     parents (), children ()
@@ -106,7 +84,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.
@@ -419,7 +397,7 @@
 // Enable or disable the profiler data collection.
 DEFUN (__profiler_enable__, args, ,
        "-*- texinfo -*-\n\
-@deftypefn {Function File} __profiler_enable__ ()\n\
+@deftypefn {Function File} {} __profiler_enable__ ()\n\
 Undocumented internal function.\n\
 @end deftypefn")
 {
@@ -445,7 +423,7 @@
 // Clear all collected profiling data.
 DEFUN (__profiler_reset__, args, ,
        "-*- texinfo -*-\n\
-@deftypefn {Function File} __profiler_reset__ ()\n\
+@deftypefn {Function File} {} __profiler_reset__ ()\n\
 Undocumented internal function.\n\
 @end deftypefn")
 {
@@ -463,7 +441,7 @@
 // Query the timings collected by the profiler.
 DEFUN (__profiler_data__, args, nargout,
        "-*- texinfo -*-\n\
-@deftypefn {Function File} __profiler_data__ ()\n\
+@deftypefn {Function File} {} __profiler_data__ ()\n\
 Undocumented internal function.\n\
 @end deftypefn")
 {
--- a/libinterp/corefcn/profiler.h	Fri Feb 06 08:31:09 2015 -0800
+++ b/libinterp/corefcn/profiler.h	Fri Feb 06 08:31:49 2015 -0800
@@ -1,5 +1,6 @@
 /*
 
+Copyright (C) 2014 Julien Bect
 Copyright (C) 2012-2013 Daniel Kraft
 
 This file is part of Octave.
@@ -39,17 +40,40 @@
 
   // This is a utility class that can be used to call the enter/exit
   // functions in a manner protected from stack unwinding.
-  class enter
+  template<class T> class enter
   {
   private:
 
     profile_data_accumulator& acc;
     std::string fcn;
+    bool is_active;
 
   public:
 
-    enter (profile_data_accumulator&, const std::string&);
-    virtual ~enter (void);
+    enter (profile_data_accumulator& a, const T& t) : acc (a)
+    {
+      // A profiling block cannot be active if the profiler is not
+      is_active = acc.is_active ();
+
+      if (is_active)
+        {
+          fcn = t.profiler_name ();
+
+          // NOTE: The test f != "" must be kept to prevent a blank line showing
+          //  up in profiler statistics.  See bug #39524.  The root cause is that
+          //  the function name is not set for the recurring readline hook function.
+          if (fcn == "")
+            is_active = false;  // Inactive profiling block
+          else
+            acc.enter_function (fcn);
+        }
+    }
+
+    ~enter ()
+    {
+      if (is_active)
+        acc.exit_function (fcn);
+    }
 
   private:
 
@@ -181,10 +205,12 @@
 extern OCTINTERP_API profile_data_accumulator profiler;
 
 // Helper macro to profile a block of code.
-#define BEGIN_PROFILER_BLOCK(name) \
+
+#define BEGIN_PROFILER_BLOCK(classname) \
   { \
-    profile_data_accumulator::enter pe (profiler, (name));
+    profile_data_accumulator::enter<classname> pe (profiler, *this);
+
 #define END_PROFILER_BLOCK \
-  }
+  }  // end of block => call pe's destructor
 
 #endif
--- a/libinterp/corefcn/pt-jit.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/libinterp/corefcn/pt-jit.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -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
@@ -956,6 +1132,9 @@
   else
     {
       octave_value val = record.varval ();
+      if (val.is_undefined ())
+        val = symbol_table::find_function (vname);
+
       jit_type *type = jit_typeinfo::type_of (val);
       bounds.push_back (type_bound (type, vname));
 
@@ -1888,10 +2067,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 +2190,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 +2312,8 @@
             std::cout << "jit fail: " << e.what () << std::endl;
         }
 
+      Vjit_failure_count++;
+
       wrapper.erase ();
       raw_fn.erase ();
     }
@@ -2279,6 +2470,9 @@
           if (e.known ())
             std::cout << "jit fail: " << e.what () << std::endl;
         }
+
+      Vjit_failure_count++;
+
     }
 
   if (llvm_function)
@@ -2314,7 +2508,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 +2560,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 +2582,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 Feb 06 08:31:09 2015 -0800
+++ b/libinterp/corefcn/pt-jit.h	Fri Feb 06 08:31:49 2015 -0800
@@ -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 Feb 06 08:31:09 2015 -0800
+++ b/libinterp/corefcn/quad.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -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/quadcc.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/libinterp/corefcn/quadcc.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -25,14 +25,14 @@
 #endif
 
 #include "lo-ieee.h"
-#include "parse.h"
-#include "variables.h"
+#include "oct-locbuf.h"
 
 #include "defun.h"
 #include "error.h"
 #include "oct-obj.h"
+#include "parse.h"
 #include "utils.h"
-
+#include "variables.h"
 
 /* Extended debugging */
 #define DEBUG_QUADCC 0
@@ -1492,9 +1492,9 @@
 @deftypefnx {Function File} {@var{q} =} quadcc (@var{f}, @var{a}, @var{b}, @var{tol}, @var{sing})\n\
 @deftypefnx {Function File} {[@var{q}, @var{err}, @var{nr_points}] =} quadcc (@dots{})\n\
 Numerically evaluate the integral of @var{f} from @var{a} to @var{b}\n\
-using the doubly-adaptive Clenshaw-Curtis quadrature described by P. Gonnet\n\
-in @cite{Increasing the Reliability of Adaptive Quadrature Using Explicit\n\
-Interpolants}.\n\
+using the doubly-adaptive @nospell{Clenshaw-Curtis} quadrature described by\n\
+@nospell{P. Gonnet} in @cite{Increasing the Reliability of Adaptive\n\
+Quadrature Using Explicit Interpolants}.\n\
 @var{f} is a function handle, inline function, or string\n\
 containing the name of the function to evaluate.\n\
 The function @var{f} must be vectorized and must return a vector of output\n\
@@ -1540,14 +1540,14 @@
 and, as such, may be less efficient for a smooth or otherwise\n\
 well-behaved integrand than other methods such as @code{quadgk}.\n\
 \n\
-The algorithm uses Clenshaw-Curtis quadrature rules of increasing\n\
+The algorithm uses @nospell{Clenshaw-Curtis} quadrature rules of increasing\n\
 degree in each interval and bisects the interval if either the\n\
 function does not appear to be smooth or a rule of maximum\n\
 degree has been reached.  The error estimate is computed from the\n\
 L2-norm of the difference between two successive interpolations\n\
 of the integrand over the nodes of the respective quadrature rules.\n\
 \n\
-Reference: P. Gonnet, @cite{Increasing the Reliability of Adaptive\n\
+Reference: @nospell{P. Gonnet}, @cite{Increasing the Reliability of Adaptive\n\
 Quadrature Using Explicit Interpolants}, ACM Transactions on\n\
 Mathematical Software, Vol. 37, Issue 3, Article No. 3, 2010.\n\
 @seealso{quad, quadv, quadl, quadgk, trapz, dblquad, triplequad}\n\
--- a/libinterp/corefcn/qz.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/libinterp/corefcn/qz.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -402,7 +402,7 @@
 
   if (nargin == 2)
     ord_job = 'N';
-  else if (!args(2).is_string ())
+  else if (! args(2).is_string ())
     {
       error ("qz: OPT must be a string");
       return retval;
@@ -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 Feb 06 08:31:09 2015 -0800
+++ b/libinterp/corefcn/rand.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -408,8 +408,8 @@
 vector in Octave's startup files (@pxref{Startup Files}).\n\
 \n\
 To compute the pseudo-random sequence, @code{rand} uses the Mersenne\n\
-Twister with a period of @math{2^{19937}-1} (See M. Matsumoto and\n\
-T. Nishimura,\n\
+Twister with a period of @math{2^{19937}-1} (See\n\
+@nospell{M. Matsumoto and T. Nishimura},\n\
 @cite{Mersenne Twister: A 623-dimensionally equidistributed uniform\n\
 pseudorandom number generator}, ACM Trans. on\n\
 Modeling and Computer Simulation Vol. 8, No. 1, pp. 3-30, January 1998,\n\
@@ -567,17 +567,17 @@
 elements having zero mean and variance one.  The arguments are\n\
 handled the same as the arguments for @code{rand}.\n\
 \n\
-By default, @code{randn} uses the Marsaglia and Tsang ``Ziggurat technique''\n\
-to transform from a uniform to a normal distribution.\n\
+By default, @code{randn} uses the @nospell{Marsaglia and Tsang}\n\
+``Ziggurat technique'' to transform from a uniform to a normal distribution.\n\
 \n\
 The class of the value returned can be controlled by a trailing\n\
 @qcode{\"double\"} or @qcode{\"single\"} argument.  These are the only valid\n\
 classes.\n\
 \n\
-Reference: G. Marsaglia and W.W. Tsang,\n\
+Reference: @nospell{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")
@@ -638,17 +638,17 @@
 Return a matrix with exponentially distributed random elements.  The\n\
 arguments are handled the same as the arguments for @code{rand}.\n\
 \n\
-By default, @code{randn} uses the Marsaglia and Tsang ``Ziggurat technique''\n\
-to transform from a uniform to an exponential distribution.\n\
+By default, @code{randn} uses the @nospell{Marsaglia and Tsang}\n\
+``Ziggurat technique'' to transform from a uniform to a normal distribution.\n\
 \n\
 The class of the value returned can be controlled by a trailing\n\
 @qcode{\"double\"} or @qcode{\"single\"} argument.  These are the only valid\n\
 classes.\n\
 \n\
-Reference: G. Marsaglia and W.W. Tsang,\n\
+Reference: @nospell{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")
@@ -1003,17 +1003,17 @@
 Cambridge University Press, 1992.\n\
 \n\
 @item For matrix @var{l} @leq{} 10, use inversion method.[2]\n\
-E. Stadlober, et al., WinRand source code, available via FTP.\n\
+@nospell{E. Stadlober, et al., WinRand source code}, available via FTP.\n\
 \n\
 @item For matrix @var{l} > 10, use patchwork rejection method.\n\
-E. Stadlober, et al., WinRand source code, available via FTP, or\n\
-H. Zechner, @cite{Efficient sampling from continuous and discrete\n\
+@nospell{E. Stadlober, et al., WinRand source code}, available via FTP, or\n\
+@nospell{H. Zechner}, @cite{Efficient sampling from continuous and discrete\n\
 unimodal distributions}, Doctoral Dissertation, 156pp., Technical\n\
-University Graz, Austria, 1994.\n\
+University @nospell{Graz}, Austria, 1994.\n\
 \n\
 @item For @var{l} > 1e8, use normal approximation.\n\
-L. Montanet, et al., @cite{Review of Particle Properties}, Physical Review\n\
-D 50 p1284, 1994.\n\
+@nospell{L. Montanet}, et al., @cite{Review of Particle Properties},\n\
+Physical Review D 50 p1284, 1994.\n\
 @end table\n\
 \n\
 The class of the value returned can be controlled by a trailing\n\
--- a/libinterp/corefcn/regexp.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/libinterp/corefcn/regexp.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -189,12 +189,13 @@
 
   for (int i = skip; i < nargin; i++)
     {
-      std::string str = args(i).string_value ();
+      std::string str;
 
-      if (error_state)
+      if (args(i).is_string ())
+        str = args(i).string_value ();
+      else
         {
-          error ("%s: optional arguments must be character strings",
-                 who.c_str ());
+          error ("%s: optional arguments must be strings", who.c_str ());
           break;
         }
 
--- a/libinterp/corefcn/schur.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/libinterp/corefcn/schur.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -63,7 +63,7 @@
 @deftypefnx {Built-in Function} {@var{S} =} schur (@var{A}, \"real\")\n\
 @deftypefnx {Built-in Function} {@var{S} =} schur (@var{A}, \"complex\")\n\
 @deftypefnx {Built-in Function} {@var{S} =} schur (@var{A}, @var{opt})\n\
-@deftypefnx {Built-in Function} {[@var{U}, @var{S}] =} schur (@var{A}, @dots{})\n\
+@deftypefnx {Built-in Function} {[@var{U}, @var{S}] =} schur (@dots{})\n\
 @cindex Schur decomposition\n\
 Compute the Schur@tie{}decomposition of @var{A}\n\
 @tex\n\
@@ -143,9 +143,9 @@
 
   if (nargin == 2)
     {
-      ord = args(1).string_value ();
-
-      if (error_state)
+      if (args(1).is_string ())
+        ord = args(1).string_value ();
+      else
         {
           error ("schur: second argument must be a string");
           return retval;
@@ -170,7 +170,7 @@
       if (ord_char != 'U' && ord_char != 'A' && ord_char != 'D'
           && ord_char != 'u' && ord_char != 'a' && ord_char != 'd')
         {
-          warning ("schur: incorrect ordered schur argument '%c'",
+          warning ("schur: incorrect ordered schur argument '%s'",
                    ord.c_str ());
           return retval;
         }
@@ -286,11 +286,13 @@
 %! [u, s] = schur (a);
 %! assert (u' * a * u, s, sqrt (eps ("single")));
 
-%!test
-%! fail ("schur ([1, 2; 3, 4], 2)", "warning");
+%!error schur ()
+%!error schur (1,2,3)
+%!error [a,b,c] = schur (1)
+%!error <argument must be a square matrix> schur ([1, 2, 3; 4, 5, 6])
+%!error <wrong type argument 'cell'> schur ({1})
+%!warning <incorrect ordered schur argument> schur ([1, 2; 3, 4], "bad_opt");
 
-%!error schur ()
-%!error <argument must be a square matrix> schur ([1, 2, 3; 4, 5, 6])
 */
 
 DEFUN (rsf2csf, args, nargout,
--- a/libinterp/corefcn/sparse-xdiv.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/libinterp/corefcn/sparse-xdiv.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -28,6 +28,7 @@
 #include <cassert>
 
 #include "Array-util.h"
+#include "lo-array-gripes.h"
 #include "oct-cmplx.h"
 #include "quit.h"
 #include "error.h"
@@ -43,8 +44,7 @@
 static void
 solve_singularity_warning (double rcond)
 {
-  warning ("matrix singular to machine precision, rcond = %g", rcond);
-  warning ("attempting to find minimum norm solution");
+  gripe_singular_matrix (rcond);
 }
 
 template <class T1, class T2>
@@ -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 Feb 06 08:31:09 2015 -0800
+++ b/libinterp/corefcn/sparse.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -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 Feb 06 08:31:09 2015 -0800
+++ b/libinterp/corefcn/spparms.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -40,7 +40,7 @@
 @deftypefnx {Built-in Function} {[@var{keys}, @var{vals}] =} spparms ()\n\
 @deftypefnx {Built-in Function} {@var{val} =} spparms (@var{key})\n\
 @deftypefnx {Built-in Function} { } spparms (@var{vals})\n\
-@deftypefnx {Built-in Function} { } spparms (\"defaults\")\n\
+@deftypefnx {Built-in Function} { } spparms (\"default\")\n\
 @deftypefnx {Built-in Function} { } spparms (\"tight\")\n\
 @deftypefnx {Built-in Function} { } spparms (@var{key}, @var{val})\n\
 Query or set the parameters used by the sparse solvers and factorization\n\
@@ -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\
@@ -97,7 +97,7 @@
 The value of individual keys can be set with\n\
 @code{spparms (@var{key}, @var{val})}.\n\
 The default values can be restored with the special keyword\n\
-@qcode{\"defaults\"}.  The special keyword @qcode{\"tight\"} can be used to\n\
+@qcode{\"default\"}.  The special keyword @qcode{\"tight\"} can be used to\n\
 set the mmd solvers to attempt a sparser solution at the potential cost of\n\
 longer running time.\n\
 @seealso{chol, colamd, lu, qr, symamd}\n\
@@ -129,8 +129,17 @@
           for (int i = 0; i < len; i++)
             str[i] = tolower (str[i]);
 
-          if (str == "defaults")
-            octave_sparse_params::defaults ();
+          if (str == "defaults" || str == "default")
+            {
+              // FIXME: deprecated in 4.0, remove "defaults" for 4.4 release
+              static bool warned = false;
+              if (! warned && str == "defaults")
+                {
+                  warning ("spparms: use \"default\" instead of \"defaults\"");
+                  warned = true;
+                }
+              octave_sparse_params::defaults ();
+            }
           else if (str == "tight")
             octave_sparse_params::tight ();
           else
@@ -181,7 +190,7 @@
 /*
 %!test
 %! old_vals = spparms ();  # save state
-%! spparms ("defaults");
+%! spparms ("default");
 %! vals = spparms ();
 %! assert (vals, [0 1 1 0 3 3 0.5 1.0 1.0 0.1 0.5 1.0 0.001]');
 %! [keys, vals] = spparms ();
--- a/libinterp/corefcn/sqrtm.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/libinterp/corefcn/sqrtm.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -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)
@@ -205,7 +206,7 @@
 @deftypefnx {Built-in Function} {[@var{s}, @var{error_estimate}] =} sqrtm (@var{A})\n\
 Compute the matrix square root of the square matrix @var{A}.\n\
 \n\
-Ref: N.J. Higham.  @cite{A New sqrtm for @sc{matlab}}.  Numerical\n\
+Ref: @nospell{N.J. Higham}.  @cite{A New sqrtm for @sc{matlab}}.  Numerical\n\
 Analysis Report No. 336, Manchester @nospell{Centre} for Computational\n\
 Mathematics, Manchester, England, January 1999.\n\
 @seealso{expm, logm}\n\
--- a/libinterp/corefcn/str2double.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/libinterp/corefcn/str2double.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -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 Feb 06 08:31:09 2015 -0800
+++ b/libinterp/corefcn/strfind.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -30,6 +30,8 @@
 #include <limits>
 #include <string>
 
+#include "oct-locbuf.h"
+
 #include "Cell.h"
 #include "ov.h"
 #include "defun.h"
@@ -155,7 +157,8 @@
 starting index of every such occurrence in the vector @var{idx}.\n\
 \n\
 If there is no such occurrence, or if @var{pattern} is longer\n\
-than @var{str}, then @var{idx} is the empty array @code{[]}.\n\
+than @var{str}, or if @var{pattern} itself is empty, then @var{idx} is the\n\
+empty array @code{[]}.\n\
 The optional argument @qcode{\"overlaps\"} determines whether the pattern\n\
 can match at every position in @var{str} (true), or only for unique\n\
 occurrences of the complete pattern (false).  The default is true.\n\
@@ -185,7 +188,7 @@
         @}\n\
 @end group\n\
 @end example\n\
-@seealso{findstr, strmatch, regexp, regexpi, find}\n\
+@seealso{findstr, regexp, regexpi, find}\n\
 @end deftypefn")
 {
   octave_value retval;
@@ -209,7 +212,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 ();
@@ -217,10 +221,14 @@
           qs_preprocess (needle, table);
 
           if (argstr.is_string ())
-            retval = octave_value (qs_search (needle,
-                                              argstr.char_array_value (),
-                                              table, overlaps),
-                                   true, true);
+            if (argpat.is_empty ())
+              // Return a null matrix for null pattern for MW compatibility
+              retval = Matrix ();
+            else
+              retval = octave_value (qs_search (needle,
+                                                argstr.char_array_value (),
+                                                table, overlaps),
+                                     true, true);
           else if (argstr.is_cell ())
             {
               const Cell argsc = argstr.cell_value ();
@@ -231,11 +239,15 @@
                 {
                   octave_value argse = argsc(i);
                   if (argse.is_string ())
-                    retc(i)
-                      = octave_value (qs_search (needle,
-                                                 argse.char_array_value (),
-                                                 table, overlaps),
-                                      true, true);
+                    {
+                      if (argpat.is_empty ())
+                        retc(i) = Matrix ();
+                      else
+                        retc(i) = octave_value (qs_search (needle,
+                                                     argse.char_array_value (),
+                                                     table, overlaps),
+                                                true, true);
+                    }
                   else
                     {
                       error ("strfind: each element of CELLSTR must be a string");
@@ -264,11 +276,16 @@
 %!assert (strfind ("abababa", "aba", "overlaps", false), [1, 5])
 %!assert (strfind ({"abababa", "bla", "bla"}, "a"), {[1, 3, 5, 7], 3, 3})
 %!assert (strfind ("Linux _is_ user-friendly. It just isn't ignorant-friendly or idiot-friendly.", "friendly"), [17, 50, 68])
+%!assert (strfind ("abc", ""), [])
+%!assert (strfind ("abc", {"", "b", ""}), {[], 2, []})
+%!assert (strfind ({"abc", "def"}, ""), {[], []})
 
 %!error strfind ()
 %!error strfind ("foo", "bar", 1)
+%!error <unknown option: foobar> strfind ("foo", 100, "foobar", 1)
+%!error <each element of CELLSTR must be a string> strfind ({"A", 1}, "foo")
+%!error <first argument must be a string> strfind (100, "foo")
 %!error <PATTERN must be a string> strfind ("foo", 100)
-%!error <first argument must be a string> strfind (100, "foo")
 */
 
 static Array<char>
@@ -279,7 +296,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 +330,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 +405,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 +460,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 Feb 06 08:31:09 2015 -0800
+++ b/libinterp/corefcn/strfns.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -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 ()));
@@ -912,7 +916,7 @@
 
   if (error_state)
     {
-      error ("list_in_columns: expecting cellstr or char array");
+      error ("list_in_columns: ARG must be a cellstr or char array");
       return retval;
     }
 
@@ -934,18 +938,10 @@
   if (nargin > 2)
     {
       if (args(2).is_string ())
-        {
-          prefix = args(2).string_value ();
-
-          if (error_state)
-            {
-              error ("list_in_columns: PREFIX must be a character string");
-              return retval;
-            }
-        }
+        prefix = args(2).string_value ();
       else
         {
-          error ("list_in_columns: PREFIX must be a character string");
+          error ("list_in_columns: PREFIX must be a string");
           return retval;
         }
     }
--- a/libinterp/corefcn/sub2ind.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/libinterp/corefcn/sub2ind.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -24,6 +24,8 @@
 #include <config.h>
 #endif
 
+#include "Array-util.h"
+#include "oct-locbuf.h"
 #include "quit.h"
 
 #include "defun.h"
--- a/libinterp/corefcn/syl.cc	Fri Feb 06 08:31:09 2015 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,218 +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/>.
-
-*/
-
-// Author: A. S. Hodel <scotte@eng.auburn.edu>
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include "defun.h"
-#include "error.h"
-#include "gripes.h"
-#include "oct-obj.h"
-#include "utils.h"
-
-DEFUN (syl, args, nargout,
-       "-*- texinfo -*-\n\
-@deftypefn {Built-in Function} {@var{x} =} syl (@var{A}, @var{B}, @var{C})\n\
-Solve the Sylvester equation\n\
-@tex\n\
-$$\n\
- A X + X B + C = 0\n\
-$$\n\
-@end tex\n\
-@ifnottex\n\
-\n\
-@example\n\
-A X + X B + C = 0\n\
-@end example\n\
-\n\
-@end ifnottex\n\
-using standard @sc{lapack} subroutines.  For example:\n\
-\n\
-@example\n\
-@group\n\
-syl ([1, 2; 3, 4], [5, 6; 7, 8], [9, 10; 11, 12])\n\
-   @result{} [ -0.50000, -0.66667; -0.66667, -0.50000 ]\n\
-@end group\n\
-@end example\n\
-@end deftypefn")
-{
-  octave_value retval;
-
-  int nargin = args.length ();
-
-  if (nargin != 3 || nargout > 1)
-    {
-      print_usage ();
-      return retval;
-    }
-
-  octave_value arg_a = args(0);
-  octave_value arg_b = args(1);
-  octave_value arg_c = args(2);
-
-  octave_idx_type a_nr = arg_a.rows ();
-  octave_idx_type a_nc = arg_a.columns ();
-
-  octave_idx_type b_nr = arg_b.rows ();
-  octave_idx_type b_nc = arg_b.columns ();
-
-  octave_idx_type c_nr = arg_c.rows ();
-  octave_idx_type c_nc = arg_c.columns ();
-
-  int arg_a_is_empty = empty_arg ("syl", a_nr, a_nc);
-  int arg_b_is_empty = empty_arg ("syl", b_nr, b_nc);
-  int arg_c_is_empty = empty_arg ("syl", c_nr, c_nc);
-
-  bool isfloat = arg_a.is_single_type () || arg_b.is_single_type ()
-                 || arg_c.is_single_type ();
-
-  if (arg_a_is_empty > 0 && arg_b_is_empty > 0 && arg_c_is_empty > 0)
-    if (isfloat)
-      return octave_value (FloatMatrix ());
-    else
-      return octave_value (Matrix ());
-  else if (arg_a_is_empty || arg_b_is_empty || arg_c_is_empty)
-    return retval;
-
-  // Arguments are not empty, so check for correct dimensions.
-
-  if (a_nr != a_nc || b_nr != b_nc)
-    {
-      gripe_square_matrix_required ("syl: first two parameters:");
-      return retval;
-    }
-  else if (a_nr != c_nr || b_nr != c_nc)
-    {
-      gripe_nonconformant ();
-      return retval;
-    }
-
-  // Dimensions look o.k., let's solve the problem.
-  if (isfloat)
-    {
-      if (arg_a.is_complex_type ()
-          || arg_b.is_complex_type ()
-          || arg_c.is_complex_type ())
-        {
-          // Do everything in complex arithmetic;
-
-          FloatComplexMatrix ca = arg_a.float_complex_matrix_value ();
-
-          if (error_state)
-            return retval;
-
-          FloatComplexMatrix cb = arg_b.float_complex_matrix_value ();
-
-          if (error_state)
-            return retval;
-
-          FloatComplexMatrix cc = arg_c.float_complex_matrix_value ();
-
-          if (error_state)
-            return retval;
-
-          retval = Sylvester (ca, cb, cc);
-        }
-      else
-        {
-          // Do everything in real arithmetic.
-
-          FloatMatrix ca = arg_a.float_matrix_value ();
-
-          if (error_state)
-            return retval;
-
-          FloatMatrix cb = arg_b.float_matrix_value ();
-
-          if (error_state)
-            return retval;
-
-          FloatMatrix cc = arg_c.float_matrix_value ();
-
-          if (error_state)
-            return retval;
-
-          retval = Sylvester (ca, cb, cc);
-        }
-    }
-  else
-    {
-      if (arg_a.is_complex_type ()
-          || arg_b.is_complex_type ()
-          || arg_c.is_complex_type ())
-        {
-          // Do everything in complex arithmetic;
-
-          ComplexMatrix ca = arg_a.complex_matrix_value ();
-
-          if (error_state)
-            return retval;
-
-          ComplexMatrix cb = arg_b.complex_matrix_value ();
-
-          if (error_state)
-            return retval;
-
-          ComplexMatrix cc = arg_c.complex_matrix_value ();
-
-          if (error_state)
-            return retval;
-
-          retval = Sylvester (ca, cb, cc);
-        }
-      else
-        {
-          // Do everything in real arithmetic.
-
-          Matrix ca = arg_a.matrix_value ();
-
-          if (error_state)
-            return retval;
-
-          Matrix cb = arg_b.matrix_value ();
-
-          if (error_state)
-            return retval;
-
-          Matrix cc = arg_c.matrix_value ();
-
-          if (error_state)
-            return retval;
-
-          retval = Sylvester (ca, cb, cc);
-        }
-    }
-
-  return retval;
-}
-
-/*
-%!assert (syl ([1, 2; 3, 4], [5, 6; 7, 8], [9, 10; 11, 12]), [-1/2, -2/3; -2/3, -1/2], sqrt (eps))
-%!assert (syl (single ([1, 2; 3, 4]), single ([5, 6; 7, 8]), single ([9, 10; 11, 12])), single ([-1/2, -2/3; -2/3, -1/2]), sqrt (eps ("single")))
-
-%!error syl ()
-%!error syl (1, 2, 3, 4)
-%!error <must be a square matrix> syl ([1, 2; 3, 4], [1, 2, 3; 4, 5, 6], [4, 3])
-*/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libinterp/corefcn/sylvester.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,230 @@
+/*
+
+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/>.
+
+*/
+
+// Author: A. S. Hodel <scotte@eng.auburn.edu>
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "defun.h"
+#include "error.h"
+#include "gripes.h"
+#include "oct-obj.h"
+#include "utils.h"
+
+DEFUN (sylvester, args, nargout,
+       "-*- texinfo -*-\n\
+@deftypefn {Built-in Function} {@var{X} =} syl (@var{A}, @var{B}, @var{C})\n\
+Solve the Sylvester equation\n\
+@tex\n\
+$$\n\
+ A X + X B = C\n\
+$$\n\
+@end tex\n\
+@ifnottex\n\
+\n\
+@example\n\
+A X + X B = C\n\
+@end example\n\
+\n\
+@end ifnottex\n\
+using standard @sc{lapack} subroutines.\n\
+\n\
+For example:\n\
+\n\
+@example\n\
+@group\n\
+sylvester ([1, 2; 3, 4], [5, 6; 7, 8], [9, 10; 11, 12])\n\
+   @result{} [ 0.50000, 0.66667; 0.66667, 0.50000 ]\n\
+@end group\n\
+@end example\n\
+@end deftypefn")
+{
+  octave_value retval;
+
+  int nargin = args.length ();
+
+  if (nargin != 3 || nargout > 1)
+    {
+      print_usage ();
+      return retval;
+    }
+
+  octave_value arg_a = args(0);
+  octave_value arg_b = args(1);
+  octave_value arg_c = args(2);
+
+  octave_idx_type a_nr = arg_a.rows ();
+  octave_idx_type a_nc = arg_a.columns ();
+
+  octave_idx_type b_nr = arg_b.rows ();
+  octave_idx_type b_nc = arg_b.columns ();
+
+  octave_idx_type c_nr = arg_c.rows ();
+  octave_idx_type c_nc = arg_c.columns ();
+
+  int arg_a_is_empty = empty_arg ("sylvester", a_nr, a_nc);
+  int arg_b_is_empty = empty_arg ("sylvester", b_nr, b_nc);
+  int arg_c_is_empty = empty_arg ("sylvester", c_nr, c_nc);
+
+  bool isfloat = arg_a.is_single_type ()
+                 || arg_b.is_single_type ()
+                 || arg_c.is_single_type ();
+
+  if (arg_a_is_empty > 0 && arg_b_is_empty > 0 && arg_c_is_empty > 0)
+    if (isfloat)
+      return octave_value (FloatMatrix ());
+    else
+      return octave_value (Matrix ());
+  else if (arg_a_is_empty || arg_b_is_empty || arg_c_is_empty)
+    return retval;
+
+  // Arguments are not empty, so check for correct dimensions.
+
+  if (a_nr != a_nc)
+    {
+      gripe_square_matrix_required ("sylvester: input A");
+      return retval;
+    }
+  else if (b_nr != b_nc)
+    {
+      gripe_square_matrix_required ("sylvester: input B");
+      return retval;
+    }
+  else if (a_nr != c_nr || b_nr != c_nc)
+    {
+      gripe_nonconformant ();
+      return retval;
+    }
+
+  if (isfloat)
+    {
+      if (arg_a.is_complex_type ()
+          || arg_b.is_complex_type ()
+          || arg_c.is_complex_type ())
+        {
+          // Do everything in complex arithmetic;
+
+          FloatComplexMatrix ca = arg_a.float_complex_matrix_value ();
+
+          if (error_state)
+            return retval;
+
+          FloatComplexMatrix cb = arg_b.float_complex_matrix_value ();
+
+          if (error_state)
+            return retval;
+
+          FloatComplexMatrix cc = arg_c.float_complex_matrix_value ();
+
+          if (error_state)
+            return retval;
+
+          retval = Sylvester (ca, cb, cc);
+        }
+      else
+        {
+          // Do everything in real arithmetic.
+
+          FloatMatrix ca = arg_a.float_matrix_value ();
+
+          if (error_state)
+            return retval;
+
+          FloatMatrix cb = arg_b.float_matrix_value ();
+
+          if (error_state)
+            return retval;
+
+          FloatMatrix cc = arg_c.float_matrix_value ();
+
+          if (error_state)
+            return retval;
+
+          retval = Sylvester (ca, cb, cc);
+        }
+    }
+  else
+    {
+      if (arg_a.is_complex_type ()
+          || arg_b.is_complex_type ()
+          || arg_c.is_complex_type ())
+        {
+          // Do everything in complex arithmetic;
+
+          ComplexMatrix ca = arg_a.complex_matrix_value ();
+
+          if (error_state)
+            return retval;
+
+          ComplexMatrix cb = arg_b.complex_matrix_value ();
+
+          if (error_state)
+            return retval;
+
+          ComplexMatrix cc = arg_c.complex_matrix_value ();
+
+          if (error_state)
+            return retval;
+
+          retval = Sylvester (ca, cb, cc);
+        }
+      else
+        {
+          // Do everything in real arithmetic.
+
+          Matrix ca = arg_a.matrix_value ();
+
+          if (error_state)
+            return retval;
+
+          Matrix cb = arg_b.matrix_value ();
+
+          if (error_state)
+            return retval;
+
+          Matrix cc = arg_c.matrix_value ();
+
+          if (error_state)
+            return retval;
+
+          retval = Sylvester (ca, cb, cc);
+        }
+    }
+
+  return retval;
+}
+
+/*
+%!assert (sylvester ([1, 2; 3, 4], [5, 6; 7, 8], [9, 10; 11, 12]), [1/2, 2/3; 2/3, 1/2], sqrt (eps))
+%!assert (sylvester (single ([1, 2; 3, 4]), single ([5, 6; 7, 8]), single ([9, 10; 11, 12])), single ([1/2, 2/3; 2/3, 1/2]), sqrt (eps ("single")))
+
+%% Test input validation
+%!error sylvester ()
+%!error sylvester (1)
+%!error sylvester (1,2)
+%!error sylvester (1, 2, 3, 4)
+%!error <input A: .* must be a square matrix> sylvester (ones (2,3), ones (2,2), ones (2,2))
+%!error <input B: .* must be a square matrix> sylvester (ones (2,2), ones (2,3), ones (2,2))
+%!error <nonconformant matrices> sylvester (ones (2,2), ones (2,2), ones (3,3))
+*/
--- a/libinterp/corefcn/symtab.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/libinterp/corefcn/symtab.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -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 + "  ";
@@ -1575,10 +1676,9 @@
 
   if (nargin == 1)
     {
-      std::string sval = args(0).string_value ();
-
-      if (! error_state)
+      if (args(0).is_string ())
         {
+          std::string sval = args(0).string_value ();
           if (sval == "all")
             Vignore_function_time_stamp = 2;
           else if (sval == "system")
@@ -1586,7 +1686,7 @@
           else if (sval == "none")
             Vignore_function_time_stamp = 0;
           else
-            error ("ignore_function_time_stamp: expecting argument to be \"all\", \"system\", or \"none\"");
+            error ("ignore_function_time_stamp: argument must be \"all\", \"system\", or \"none\"");
         }
       else
         error ("ignore_function_time_stamp: expecting argument to be character string");
--- a/libinterp/corefcn/symtab.h	Fri Feb 06 08:31:09 2015 -0800
+++ b/libinterp/corefcn/symtab.h	Fri Feb 06 08:31:49 2015 -0800
@@ -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 Feb 06 08:31:09 2015 -0800
+++ b/libinterp/corefcn/syscalls.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -117,6 +117,7 @@
 If successful, @var{fid} is greater than zero and contains the new file\n\
 ID@.  Otherwise, @var{fid} is negative and @var{msg} contains a\n\
 system-dependent error message.\n\
+@seealso{fopen, fclose, fcntl}\n\
 @end deftypefn")
 {
   octave_value_list retval;
@@ -189,10 +190,10 @@
 
   if (nargin == 1 || nargin == 2)
     {
-      std::string exec_file = args(0).string_value ();
+      if (args(0).is_string ())
+        {
+          std::string exec_file = args(0).string_value ();
 
-      if (! error_state)
-        {
           string_vector exec_args;
 
           if (nargin == 2)
@@ -211,7 +212,7 @@
                     exec_args[i+1] = tmp[i];
                 }
               else
-                error ("exec: arguments must be character strings");
+                error ("exec: all arguments must be strings");
             }
           else
             {
@@ -299,10 +300,10 @@
 
   if (nargin >= 1 && nargin <= 3)
     {
-      std::string exec_file = args(0).string_value ();
+      if (args(0).is_string ())
+        {
+          std::string exec_file = args(0).string_value ();
 
-      if (! error_state)
-        {
           string_vector arg_list;
 
           if (nargin >= 2)
@@ -321,7 +322,7 @@
                     arg_list[i+1] = tmp[i];
                 }
               else
-                error ("popen2: arguments must be character strings");
+                error ("popen2: all arguments must be strings");
             }
           else
             {
@@ -366,7 +367,7 @@
                 }
             }
           else
-            error ("popen2: arguments must be character strings");
+            error ("popen2: all arguments must be strings");
         }
       else
         error ("popen2: COMMAND argument must be a string");
@@ -448,8 +449,9 @@
 DEFUNX ("fcntl", Ffcntl, args, ,
         "-*- texinfo -*-\n\
 @deftypefn {Built-in Function} {[@var{err}, @var{msg}] =} fcntl (@var{fid}, @var{request}, @var{arg})\n\
-Change the properties of the open file @var{fid}.  The following values\n\
-may be passed as @var{request}:\n\
+Change the properties of the open file @var{fid}.\n\
+\n\
+The following values may be passed as @var{request}:\n\
 \n\
 @vtable @code\n\
 @item F_DUPFD\n\
@@ -500,6 +502,7 @@
 If successful, @var{err} is 0 and @var{msg} is an empty string.\n\
 Otherwise, @var{err} is nonzero and @var{msg} contains a\n\
 system-dependent error message.\n\
+@seealso{fopen, dup2}\n\
 @end deftypefn")
 {
   octave_value_list retval;
@@ -511,7 +514,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)
         {
@@ -1622,10 +1625,9 @@
 
   if (args.length () == 1)
     {
-      std::string name = args(0).string_value ();
-
-      if (! error_state)
+      if (args(0).is_string ())
         {
+          std::string name = args(0).string_value ();
           std::string msg;
 
           std::string result = octave_canonicalize_file_name (name, msg);
@@ -1635,7 +1637,7 @@
           retval(0) = result;
         }
       else
-        error ("canonicalize_file_name: NAME must be a character string");
+        error ("canonicalize_file_name: NAME must be a string");
     }
   else
     print_usage ();
@@ -1878,7 +1880,7 @@
 
 DEFUNX ("O_TRUNC", FO_TRUNC, args, ,
         "-*- texinfo -*-\n\
-@deftypefn {Built-in Function} O_TRUNC ()\n\
+@deftypefn {Built-in Function} {} O_TRUNC ()\n\
 Return the numerical value of the file status flag that may be\n\
 returned by @code{fcntl} to indicate that if file exists, it should\n\
 be truncated when writing.\n\
@@ -1959,3 +1961,4 @@
 {
   return const_value (args, WCONTINUE);
 }
+
--- a/libinterp/corefcn/sysdep.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/libinterp/corefcn/sysdep.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -106,6 +106,7 @@
 
 #define WIN32_LEAN_AND_MEAN
 #include <tlhelp32.h>
+#include <windows.h>
 
 static void
 w32_set_octave_home (void)
@@ -169,13 +170,51 @@
 {
   w32_set_quiet_shutdown ();
 }
+
+static void
+w32_init (void)
+{
+  w32_set_octave_home ();
+
+  command_editor::prefer_env_winsize (true);
+}
 #endif
 
+DEFUN (__w32_shell_execute__, args, ,
+           "-*- texinfo -*-\n\
+@deftypefn {Loadable Function} {} __w32_shell_execute__ (@var{file})\n\
+Undocumented internal function.\n\
+@end deftypefn")
+{
+  bool retval = false;
+
+#if defined (__WIN32__) && ! defined (_POSIX_VERSION)
+  if (args.length () == 1)
+    {
+      std::string file = args(0).string_value ();
+
+      if (! error_state)
+        {
+          HINSTANCE status = ShellExecute (0, 0, file.c_str (), 0, 0, SW_SHOWNORMAL);
+
+          // ShellExecute returns a value greater than 32 if successful.
+          retval = (reinterpret_cast<ptrdiff_t> (status) > 32);
+        }
+      else
+        error ("__w32_shell_execute__: expecting argument to be a file name");
+    }
+  else
+    print_usage ();
+#endif
+
+  return octave_value (retval);
+}
+
 #if defined (__MINGW32__)
 static void
 MINGW_init (void)
 {
-  w32_set_octave_home ();
+  w32_init ();
 }
 #endif
 
@@ -183,7 +222,7 @@
 static void
 MSVC_init (void)
 {
-  w32_set_octave_home ();
+  w32_init ();
 }
 #endif
 
@@ -555,6 +594,7 @@
 \n\
 @noindent\n\
 returns a string containing the value of your path.\n\
+@seealso{setenv, unsetenv}\n\
 @end deftypefn")
 {
   octave_value retval;
@@ -574,11 +614,20 @@
   return retval;
 }
 
-DEFUN (putenv, args, ,
+/*
+%!assert (ischar (getenv ("OCTAVE_HOME")))
+*/
+
+DEFUN (setenv, args, ,
        "-*- texinfo -*-\n\
-@deftypefn  {Built-in Function} {} putenv (@var{var}, @var{value})\n\
-@deftypefnx {Built-in Function} {} setenv (@var{var}, @var{value})\n\
+@deftypefn  {Built-in Function} {} setenv (@var{var}, @var{value})\n\
+@deftypefnx {Built-in Function} {} setenv (@var{var})\n\
+@deftypefnx {Built-in Function} {} putenv (@dots{})\n\
 Set the value of the environment variable @var{var} to @var{value}.\n\
+\n\
+If no @var{value} is specified then the variable will be assigned the null\n\
+string.\n\
+@seealso{unsetenv, getenv}\n\
 @end deftypefn")
 {
   octave_value_list retval;
@@ -587,20 +636,20 @@
 
   if (nargin == 2 || nargin == 1)
     {
-      std::string var = args(0).string_value ();
+      if (args(0).is_string ())
+        {
+          std::string var = args(0).string_value ();
 
-      if (! error_state)
-        {
           std::string val = (nargin == 2
                              ? args(1).string_value () : std::string ());
 
           if (! error_state)
             octave_env::putenv (var, val);
           else
-            error ("putenv: VALUE must be a string");
+            error ("setenv: VALUE must be a string");
         }
       else
-        error ("putenv: VAR must be a string");
+        error ("setenv: VAR must be a string");
     }
   else
     print_usage ();
@@ -608,13 +657,48 @@
   return retval;
 }
 
-DEFALIAS (setenv, putenv);
+DEFALIAS (putenv, setenv);
 
 /*
-%!assert (ischar (getenv ("OCTAVE_HOME")))
 %!test
 %! setenv ("dummy_variable_that_cannot_matter", "foobar");
 %! assert (getenv ("dummy_variable_that_cannot_matter"), "foobar");
+%! unsetenv ("dummy_variable_that_cannot_matter");
+%! assert (getenv ("dummy_variable_that_cannot_matter"), "");
+*/
+
+DEFUN (unsetenv, args, ,
+       "-*- texinfo -*-\n\
+@deftypefn {Built-in Function} {@var{status} =} unsetenv (@var{var})\n\
+Delete the environment variable @var{var}.\n\
+\n\
+Return 0 if the variable was deleted, or did not exist, and -1 if an error\n\
+occurred.\n\
+@seealso{setenv, getenv}\n\
+@end deftypefn")
+{
+  octave_value retval;
+
+  int nargin = args.length ();
+
+  if (nargin == 1)
+    {
+      std::string tmp = args(0).string_value ();
+
+      if (! error_state)
+        {
+          int status = gnulib::unsetenv (tmp.c_str ());
+          retval = status;
+        }
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+
+/*
+## Test for unsetenv is in setenv test
 */
 
 // FIXME: perhaps kbhit should also be able to print a prompt?
--- a/libinterp/corefcn/time.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/libinterp/corefcn/time.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -123,6 +123,8 @@
 
 /*
 %!assert (time () > 0)
+
+%!error time (1)
 */
 
 DEFUN (gmtime, args, ,
@@ -299,7 +301,9 @@
 %!assert (datestr (datenum (1795, 1, 1), 0), "01-Jan-1795 00:00:00")
 
 %!error mktime ()
+%!error mktime (1)
 %!error mktime (1, 2, 3)
+%!error mktime (struct ("year", "foo"))
 */
 
 DEFUN (strftime, args, ,
@@ -459,10 +463,10 @@
 
   if (args.length () == 2)
     {
-      std::string fmt = args(0).string_value ();
+      if (args(0).is_string ())
+        {
+          std::string fmt = args(0).string_value ();
 
-      if (! error_state)
-        {
           octave_scalar_map map = args(1).scalar_map_value ();
 
           if (! error_state)
@@ -494,6 +498,8 @@
 %!assert (ischar (strftime ("%m%U%w%W%x%y%Y", localtime (time ()))));
 
 %!error strftime ()
+%!error strftime ("foo", 1)
+%!error strftime ("foo", struct ("year", "foo"))
 %!error strftime ("foo", localtime (time ()), 1)
 */
 
@@ -513,14 +519,14 @@
 
   if (args.length () == 2)
     {
-      std::string str = args(0).string_value ();
-
-      if (! error_state)
+      if (args(0).is_string ())
         {
-          std::string fmt = args(1).string_value ();
+          std::string str = args(0).string_value ();
 
-          if (! error_state)
+          if (args(1).is_string ())
             {
+              std::string fmt = args(1).string_value ();
+
               octave_strptime t (str, fmt);
 
               retval(1) = t.characters_converted ();
@@ -537,3 +543,23 @@
 
   return retval;
 }
+
+/*
+%!test
+%! fmt = "%Y-%m-%d %H:%M:%S";
+%! s = strftime (fmt, localtime (time ()));
+%! ts = strptime  (s, fmt);
+%! assert (isstruct (ts));
+%! assert (isfield (ts, "usec"));
+%! assert (isfield (ts, "year"));
+%! assert (isfield (ts, "mon"));
+%! assert (isfield (ts, "mday"));
+%! assert (isfield (ts, "sec"));
+%! assert (isfield (ts, "min"));
+%! assert (isfield (ts, "wday"));
+%! assert (isfield (ts, "hour"));
+%! assert (isfield (ts, "isdst"));
+%! assert (isfield (ts, "yday"));
+
+%!error strptime ()
+*/
--- a/libinterp/corefcn/toplev.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/libinterp/corefcn/toplev.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -104,6 +104,32 @@
 
 octave_call_stack *octave_call_stack::instance = 0;
 
+std::string
+octave_call_stack::stack_frame::fcn_file_name (void) const
+{
+  return m_fcn ? m_fcn->fcn_file_name () : std::string ();
+}
+
+std::string
+octave_call_stack::stack_frame::fcn_name (bool print_subfn) const
+{
+  std::string retval;
+
+  if (m_fcn)
+    {
+      std::string parent_fcn_name = m_fcn->parent_fcn_name ();
+
+      if (print_subfn && ! parent_fcn_name.empty ())
+        retval = parent_fcn_name + Vfilemarker;
+
+      retval += m_fcn->name ();
+    }
+  else
+    retval = "<unknown>";
+
+  return retval;
+}
+
 void
 octave_call_stack::create_instance (void)
 {
@@ -124,8 +150,8 @@
 
   if (! cs.empty ())
     {
-      const call_stack_elt& elt = cs[curr_frame];
-      retval = elt.line;
+      const stack_frame& elt = cs[curr_frame];
+      retval = elt.m_line;
     }
 
   return retval;
@@ -138,8 +164,8 @@
 
   if (! cs.empty ())
     {
-      const call_stack_elt& elt = cs[curr_frame];
-      retval = elt.column;
+      const stack_frame& elt = cs[curr_frame];
+      retval = elt.m_column;
     }
 
   return retval;
@@ -154,15 +180,15 @@
 
   while (p != cs.begin ())
     {
-      const call_stack_elt& elt = *(--p);
+      const stack_frame& elt = *(--p);
 
-      octave_function *f = elt.fcn;
+      octave_function *f = elt.m_fcn;
 
       if (f && f->is_user_code ())
         {
-          if (elt.line > 0)
+          if (elt.m_line > 0)
             {
-              retval = elt.line;
+              retval = elt.m_line;
               break;
             }
         }
@@ -180,15 +206,15 @@
 
   while (p != cs.begin ())
     {
-      const call_stack_elt& elt = *(--p);
+      const stack_frame& elt = *(--p);
 
-      octave_function *f = elt.fcn;
+      octave_function *f = elt.m_fcn;
 
       if (f && f->is_user_code ())
         {
-          if (elt.column)
+          if (elt.m_column)
             {
-              retval = elt.column;
+              retval = elt.m_column;
               break;
             }
         }
@@ -206,7 +232,7 @@
   curr_user_frame = 0;
 
   // Look for the caller of dbstack.
-  size_t frame = cs[curr_frame].prev;
+  size_t xframe = cs[curr_frame].m_prev;
 
   bool found = false;
 
@@ -214,9 +240,9 @@
 
   for (const_reverse_iterator p = cs.rbegin (); p != cs.rend (); p++)
     {
-      octave_function *f = (*p).fcn;
+      octave_function *f = (*p).m_fcn;
 
-      if (--k == frame)
+      if (--k == xframe)
         found = true;
 
       if (f && f->is_user_code ())
@@ -244,9 +270,9 @@
 
   while (p != cs.begin ())
     {
-      const call_stack_elt& elt = *(--p);
+      const stack_frame& elt = *(--p);
 
-      octave_function *f = elt.fcn;
+      octave_function *f = elt.m_fcn;
 
       if (f && f->is_user_code ())
         {
@@ -263,6 +289,29 @@
   return retval;
 }
 
+bool
+octave_call_stack::do_all_scripts (void) const
+{
+  bool retval = true;
+
+  const_iterator p = cs.end ();
+
+  while (p != cs.begin ())
+    {
+      const stack_frame& elt = *(--p);
+
+      octave_function *f = elt.m_fcn;
+
+      if (f && ! f->is_user_script ())
+        {
+          retval = false;
+          break;
+        }
+    }
+
+  return retval;
+}
+
 // Use static fields for the best efficiency.
 // NOTE: C++0x will allow these two to be merged into one.
 static const char *bt_fieldnames[] = { "file", "name", "line",
@@ -276,10 +325,12 @@
   return octave_map (dim_vector (0, 1), bt_fields);
 }
 
-octave_map
-octave_call_stack::do_backtrace (size_t nskip,
-                                 octave_idx_type& curr_user_frame) const
+std::list<octave_call_stack::stack_frame>
+octave_call_stack::do_backtrace_frames (size_t nskip,
+                                        octave_idx_type& curr_user_frame) const
 {
+  std::list<octave_call_stack::stack_frame> retval;
+
   size_t user_code_frames = do_num_user_code_frames (curr_user_frame);
 
   size_t nframes = nskip <= user_code_frames ? user_code_frames - nskip : 0;
@@ -287,6 +338,37 @@
   // Our list is reversed.
   curr_user_frame = nframes - curr_user_frame - 1;
 
+  if (nframes > 0)
+    {
+      for (const_reverse_iterator p = cs.rbegin (); p != cs.rend (); p++)
+        {
+          const stack_frame& elt = *p;
+
+          octave_function *f = elt.m_fcn;
+
+          if (f && f->is_user_code ())
+            {
+              if (nskip > 0)
+                nskip--;
+              else
+                retval.push_back (elt);
+            }
+        }
+    }
+
+  return retval;
+}
+
+octave_map
+octave_call_stack::do_backtrace (size_t nskip,
+                                 octave_idx_type& curr_user_frame,
+                                 bool print_subfn) const
+{
+  std::list<octave_call_stack::stack_frame> frames
+    = do_backtrace_frames (nskip, curr_user_frame);
+
+  size_t nframes = frames.size ();
+
   octave_map retval (dim_vector (nframes, 1), bt_fields);
 
   Cell& file = retval.contents (0);
@@ -296,39 +378,21 @@
   Cell& scope = retval.contents (4);
   Cell& context = retval.contents (5);
 
-  if (nframes > 0)
-    {
-      int k = 0;
+  octave_idx_type k = 0;
 
-      for (const_reverse_iterator p = cs.rbegin (); p != cs.rend (); p++)
-        {
-          const call_stack_elt& elt = *p;
-
-          octave_function *f = elt.fcn;
+  for (std::list<octave_call_stack::stack_frame>::const_iterator p = frames.begin ();
+       p != frames.end (); p++)
+    {
+      const stack_frame& elt = *p;
 
-          if (f && f->is_user_code ())
-            {
-              if (nskip > 0)
-                nskip--;
-              else
-                {
-                  scope(k) = elt.scope;
-                  context(k) = elt.context;
+      scope(k) = elt.m_scope;
+      context(k) = elt.m_context;
+      file(k) = elt.fcn_file_name ();
+      name(k) = elt.fcn_name (print_subfn);
+      line(k) = elt.m_line;
+      column(k) = elt.m_column;
 
-                  file(k) = f->fcn_file_name ();
-                  std::string parent_fcn_name = f->parent_fcn_name ();
-                  if (parent_fcn_name == std::string ())
-                    name(k) = f->name ();
-                  else
-                    name(k) = f->parent_fcn_name () + Vfilemarker + f->name ();
-
-                  line(k) = elt.line;
-                  column(k) = elt.column;
-
-                  k++;
-                }
-            }
-        }
+      k++;
     }
 
   return retval;
@@ -345,21 +409,16 @@
 
       curr_frame = n;
 
-      const call_stack_elt& elt = cs[n];
+      const stack_frame& elt = cs[n];
 
-      symbol_table::set_scope_and_context (elt.scope, elt.context);
+      symbol_table::set_scope_and_context (elt.m_scope, elt.m_context);
 
       if (verbose)
-        {
-          octave_function *f = elt.fcn;
-          std::string nm = f ? f->name () : std::string ("<unknown>");
-
-          octave_stdout << "stopped in " << nm
-                        << " at line " << elt.line
-                        << " column " << elt.column
-                        << " (" << elt.scope << "[" << elt.context << "])"
-                        << std::endl;
-        }
+        octave_stdout << "stopped in " << elt.fcn_name ()
+                      << " at line " << elt.m_line
+                      << " column " << elt.m_column
+                      << " (" << elt.m_scope << "[" << elt.m_context << "])"
+                      << std::endl;
     }
 
   return retval;
@@ -378,20 +437,20 @@
     incr = 1;
 
   // Start looking with the caller of dbup/dbdown/keyboard.
-  size_t frame = cs[curr_frame].prev;
+  size_t xframe = cs[curr_frame].m_prev;
 
   while (true)
     {
-      if ((incr < 0 && frame == 0) || (incr > 0 && frame == cs.size () - 1))
+      if ((incr < 0 && xframe == 0) || (incr > 0 && xframe == cs.size () - 1))
         break;
 
-      frame += incr;
+      xframe += incr;
 
-      const call_stack_elt& elt = cs[frame];
+      const stack_frame& elt = cs[xframe];
 
-      octave_function *f = elt.fcn;
+      octave_function *f = elt.m_fcn;
 
-      if (frame == 0 || (f && f->is_user_code ()))
+      if (xframe == 0 || (f && f->is_user_code ()))
         {
           if (nskip > 0)
             nskip--;
@@ -400,10 +459,10 @@
 
           if (nskip == 0)
             {
-              curr_frame = frame;
-              cs[cs.size () - 1].prev = curr_frame;
+              curr_frame = xframe;
+              cs[cs.size () - 1].m_prev = curr_frame;
 
-              symbol_table::set_scope_and_context (elt.scope, elt.context);
+              symbol_table::set_scope_and_context (elt.m_scope, elt.m_context);
 
               if (verbose)
                 {
@@ -411,7 +470,7 @@
 
                   if (f)
                     buf << "stopped in " << f->name ()
-                        << " at line " << elt.line << std::endl;
+                        << " at line " << elt.m_line << std::endl;
                   else
                     buf << "at top level" << std::endl;
 
@@ -422,6 +481,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
@@ -434,19 +495,19 @@
 void
 octave_call_stack::do_goto_caller_frame (void)
 {
-  size_t frame = curr_frame;
+  size_t xframe = curr_frame;
 
   bool skipped = false;
 
-  while (frame != 0)
+  while (xframe != 0)
     {
-      frame = cs[frame].prev;
+      xframe = cs[xframe].m_prev;
 
-      const call_stack_elt& elt = cs[frame];
+      const stack_frame& elt = cs[xframe];
 
-      octave_function *f = elt.fcn;
+      octave_function *f = elt.m_fcn;
 
-      if (frame == 0 || (f && f->is_user_code ()))
+      if (elt.m_scope == cs[0].m_scope || (f && f->is_user_code ()))
         {
           if (! skipped)
             // We found the current user code frame, so skip it.
@@ -454,14 +515,14 @@
           else
             {
               // We found the caller user code frame.
-              call_stack_elt tmp (elt);
-              tmp.prev = curr_frame;
+              stack_frame tmp (elt);
+              tmp.m_prev = curr_frame;
 
               curr_frame = cs.size ();
 
               cs.push_back (tmp);
 
-              symbol_table::set_scope_and_context (tmp.scope, tmp.context);
+              symbol_table::set_scope_and_context (tmp.m_scope, tmp.m_context);
 
               break;
             }
@@ -472,45 +533,14 @@
 void
 octave_call_stack::do_goto_base_frame (void)
 {
-  call_stack_elt tmp (cs[0]);
-  tmp.prev = curr_frame;
+  stack_frame tmp (cs[0]);
+  tmp.m_prev = curr_frame;
 
   curr_frame = cs.size ();
 
   cs.push_back (tmp);
 
-  symbol_table::set_scope_and_context (tmp.scope, tmp.context);
-}
-
-void
-octave_call_stack::do_backtrace_error_message (void) const
-{
-  if (error_state > 0)
-    {
-      error_state = -1;
-
-      error ("called from:");
-    }
-
-  if (! cs.empty ())
-    {
-      const call_stack_elt& elt = cs.back ();
-
-      octave_function *fcn = elt.fcn;
-
-      std::string fcn_name = "?unknown?";
-
-      if (fcn)
-        {
-          fcn_name = fcn->fcn_file_name ();
-
-          if (fcn_name.empty ())
-            fcn_name = fcn->name ();
-        }
-
-      error ("  %s at line %d, column %d",
-             fcn_name.c_str (), elt.line, elt.column);
-    }
+  symbol_table::set_scope_and_context (tmp.m_scope, tmp.m_context);
 }
 
 void
@@ -589,7 +619,7 @@
                     {
                       if (! (interactive || forced_interactive))
                         {
-                          // We should exit with a non-zero status.
+                          // We should exit with a nonzero status.
                           retval = 1;
                           break;
                         }
@@ -628,6 +658,8 @@
     }
   while (retval == 0);
 
+  octave_stdout << "\n";
+
   if (retval == EOF)
     retval = 0;
 
@@ -756,11 +788,20 @@
 
 DEFUN (quit, args, ,
        "-*- texinfo -*-\n\
-@deftypefn  {Built-in Function} {} exit (@var{status})\n\
+@deftypefn  {Built-in Function} {} exit\n\
+@deftypefnx {Built-in Function} {} exit (@var{status})\n\
+@deftypefnx {Built-in Function} {} quit\n\
 @deftypefnx {Built-in Function} {} quit (@var{status})\n\
-Exit the current Octave session.  If the optional integer value\n\
-@var{status} is supplied, pass that value to the operating system as the\n\
-Octave's exit status.  The default value is zero.\n\
+Exit the current Octave session.\n\
+\n\
+If the optional integer value @var{status} is supplied, pass that value to\n\
+the operating system as Octave's exit status.  The default value is zero.\n\
+\n\
+When exiting, Octave will attempt to run the m-file @file{finish.m} if it\n\
+exists.  User commands to save the workspace or clean up temporary files\n\
+may be placed in that file.  Alternatively, another m-file may be scheduled\n\
+to run using @code{atexit}.\n\
+@seealso{atexit}\n\
 @end deftypefn")
 {
   octave_value_list retval;
@@ -969,10 +1010,10 @@
 
       if (nargin == 3)
         {
-          std::string type_str = args(2).string_value ();
+          if (args(2).is_string ())
+            {
+              std::string type_str = args(2).string_value ();
 
-          if (! error_state)
-            {
               if (type_str == "sync")
                 type = et_sync;
               else if (type_str == "async")
@@ -985,7 +1026,7 @@
             }
           else
             {
-              error ("system: TYPE must be a character string");
+              error ("system: TYPE must be a string");
               return retval;
             }
         }
@@ -1125,7 +1166,9 @@
        "-*- texinfo -*-\n\
 @deftypefn  {Built-in Function} {} atexit (@var{fcn})\n\
 @deftypefnx {Built-in Function} {} atexit (@var{fcn}, @var{flag})\n\
-Register a function to be called when Octave exits.  For example,\n\
+Register a function to be called when Octave exits.\n\
+\n\
+For example,\n\
 \n\
 @example\n\
 @group\n\
@@ -1157,6 +1200,7 @@
 from the list, so if a function was placed in the list multiple\n\
 times with @code{atexit}, it must also be removed from the list\n\
 multiple times.\n\
+@seealso{quit}\n\
 @end deftypefn")
 {
   octave_value_list retval;
@@ -1165,10 +1209,10 @@
 
   if (nargin == 1 || nargin == 2)
     {
-      std::string arg = args(0).string_value ();
+      if (args(0).is_string ())
+        {
+          std::string arg = args(0).string_value ();
 
-      if (! error_state)
-        {
           bool add_mode = true;
 
           if (nargin == 2)
@@ -1205,12 +1249,13 @@
        "-*- texinfo -*-\n\
 @deftypefn  {Built-in Function} {} octave_config_info ()\n\
 @deftypefnx {Built-in Function} {} octave_config_info (@var{option})\n\
-Return a structure containing configuration and installation\n\
-information for Octave.\n\
+Return a structure containing configuration and installation information for\n\
+Octave.\n\
 \n\
 If @var{option} is a string, return the configuration information for the\n\
 specified option.\n\
 \n\
+@seealso{computer}\n\
 @end deftypefn")
 {
   octave_value retval;
@@ -1251,8 +1296,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 },
@@ -1275,8 +1318,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 },
@@ -1289,7 +1330,6 @@
     { false, "F77", OCTAVE_CONF_F77 },
     { false, "F77_FLOAT_STORE_FLAG", OCTAVE_CONF_F77_FLOAT_STORE_FLAG },
     { false, "F77_INTEGER_8_FLAG", OCTAVE_CONF_F77_INTEGER_8_FLAG },
-    { false, "FC", OCTAVE_CONF_FC },
     { false, "FFLAGS", OCTAVE_CONF_FFLAGS },
     { false, "FFTW3_CPPFLAGS", OCTAVE_CONF_FFTW3_CPPFLAGS },
     { false, "FFTW3_LDFLAGS", OCTAVE_CONF_FFTW3_LDFLAGS },
@@ -1404,6 +1444,7 @@
     { true, "man1dir", OCTAVE_MAN1DIR },
     { false, "man1ext", OCTAVE_MAN1EXT },
     { true, "mandir", OCTAVE_MANDIR },
+    { true, "octdatadir", OCTAVE_OCTDATADIR },
     { true, "octfiledir", OCTAVE_OCTFILEDIR },
     { true, "octetcdir", OCTAVE_OCTETCDIR },
     { true, "octincludedir", OCTAVE_OCTINCLUDEDIR },
--- a/libinterp/corefcn/toplev.h	Fri Feb 06 08:31:09 2015 -0800
+++ b/libinterp/corefcn/toplev.h	Fri Feb 06 08:31:49 2015 -0800
@@ -76,41 +76,52 @@
 OCTINTERP_API
 octave_call_stack
 {
-private:
-
-  struct call_stack_elt
-  {
-    call_stack_elt (octave_function *f, symbol_table::scope_id s,
-                    symbol_table::context_id c, size_t p = 0)
-      : fcn (f), line (-1), column (-1), scope (s), context (c), prev (p)
-    { }
-
-    call_stack_elt (const call_stack_elt& elt)
-      : fcn (elt.fcn), line (elt.line), column (elt.column),
-        scope (elt.scope), context (elt.context), prev (elt.prev)
-    { }
-
-    octave_function *fcn;
-    int line;
-    int column;
-    symbol_table::scope_id scope;
-    symbol_table::context_id context;
-    size_t prev;
-  };
-
 protected:
 
   octave_call_stack (void) : cs (), curr_frame (0) { }
 
 public:
 
-  typedef std::deque<call_stack_elt>::iterator iterator;
-  typedef std::deque<call_stack_elt>::const_iterator const_iterator;
+  class stack_frame
+  {
+  public:
+
+    friend class octave_call_stack;
+
+    stack_frame (octave_function *fcn = 0, symbol_table::scope_id scope = 0,
+                 symbol_table::context_id context = 0, size_t prev = 0)
+      : m_fcn (fcn), m_line (-1), m_column (-1), m_scope (scope),
+        m_context (context), m_prev (prev)
+    { }
+
+    stack_frame (const stack_frame& elt)
+      : m_fcn (elt.m_fcn), m_line (elt.m_line), m_column (elt.m_column),
+        m_scope (elt.m_scope), m_context (elt.m_context), m_prev (elt.m_prev)
+    { }
+
+    int line (void) const { return m_line; }
 
-  typedef std::deque<call_stack_elt>::reverse_iterator
-    reverse_iterator;
-  typedef std::deque<call_stack_elt>::const_reverse_iterator
-    const_reverse_iterator;
+    int column (void) const { return m_column; }
+
+    std::string fcn_file_name (void) const;
+
+    std::string fcn_name (bool print_subfn = true) const;
+
+  private:
+
+    octave_function *m_fcn;
+    int m_line;
+    int m_column;
+    symbol_table::scope_id m_scope;
+    symbol_table::context_id m_context;
+    size_t m_prev;
+  };
+
+  typedef std::deque<stack_frame>::iterator iterator;
+  typedef std::deque<stack_frame>::const_iterator const_iterator;
+
+  typedef std::deque<stack_frame>::reverse_iterator reverse_iterator;
+  typedef std::deque<stack_frame>::const_reverse_iterator const_reverse_iterator;
 
   static void create_instance (void);
 
@@ -193,6 +204,12 @@
     return instance_ok () ? instance->do_current_context () : 0;
   }
 
+  /*
+  static stack_frame frame (size_t idx)
+  {
+    return instance_ok () ? instance->do_frame (idx) : stack_frame ();
+  }
+  */
   // Function at location N on the call stack (N == 0 is current), may
   // be built-in.
   static octave_function *element (size_t n)
@@ -206,6 +223,12 @@
     return instance_ok () ? instance->do_caller_user_code (nskip) : 0;
   }
 
+  // Return TRUE if all elements on the call stack are scripts.
+  static bool all_scripts (void)
+  {
+    return instance_ok () ? instance->do_all_scripts () : false;
+  }
+
   static void
   push (octave_function *f,
         symbol_table::scope_id scope = symbol_table::current_scope (),
@@ -269,10 +292,39 @@
       instance->do_goto_base_frame ();
   }
 
-  static octave_map backtrace (size_t nskip, octave_idx_type& curr_user_frame)
+  static octave_map backtrace (size_t nskip = 0)
+  {
+    octave_idx_type curr_user_frame = -1;
+
+    return instance_ok ()
+           ? 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 = true)
   {
     return instance_ok ()
-           ? instance->do_backtrace (nskip, curr_user_frame) : octave_map ();
+           ? instance->do_backtrace (nskip, curr_user_frame, print_subfn)
+           : octave_map ();
+  }
+
+  static std::list<octave_call_stack::stack_frame>
+  backtrace_frames (size_t nskip = 0)
+  {
+    octave_idx_type curr_user_frame = -1;
+
+    return instance_ok ()
+           ? instance->do_backtrace_frames (nskip, curr_user_frame)
+           : std::list<octave_call_stack::stack_frame> ();
+  }
+
+  static std::list<octave_call_stack::stack_frame>
+  backtrace_frames (size_t nskip, octave_idx_type& curr_user_frame)
+  {
+    return instance_ok ()
+           ? instance->do_backtrace_frames (nskip, curr_user_frame)
+           : std::list<octave_call_stack::stack_frame> ();
   }
 
   static octave_map empty_backtrace (void);
@@ -289,16 +341,10 @@
       instance->do_clear ();
   }
 
-  static void backtrace_error_message (void)
-  {
-    if (instance_ok ())
-      instance->do_backtrace_error_message ();
-  }
-
 private:
 
   // The current call stack.
-  std::deque<call_stack_elt> cs;
+  std::deque<stack_frame> cs;
 
   size_t curr_frame;
 
@@ -316,7 +362,7 @@
 
   octave_function *do_caller (void) const
   {
-    return curr_frame > 1 ? cs[curr_frame-1].fcn : cs[0].fcn;
+    return curr_frame > 1 ? cs[curr_frame-1].m_fcn : cs[0].m_fcn;
   }
 
   size_t do_current_frame (void) { return curr_frame; }
@@ -328,23 +374,30 @@
   symbol_table::scope_id do_current_scope (void) const
   {
     return curr_frame > 0 && curr_frame < cs.size ()
-           ? cs[curr_frame].scope : 0;
+           ? cs[curr_frame].m_scope : 0;
   }
 
   symbol_table::context_id do_current_context (void) const
   {
     return curr_frame > 0 && curr_frame < cs.size ()
-           ? cs[curr_frame].context : 0;
+           ? cs[curr_frame].m_context : 0;
   }
 
+  /*  const stack_frame& do_frame (size_t idx)
+  {
+    static stack_frame foobar;
+
+    return idx < cs.size () ? cs[idx] : foobar;
+  }
+  */
   octave_function *do_element (size_t n)
   {
     octave_function *retval = 0;
 
     if (cs.size () > n)
       {
-        call_stack_elt& elt = cs[n];
-        retval = elt.fcn;
+        stack_frame& elt = cs[n];
+        retval = elt.m_fcn;
       }
 
     return retval;
@@ -352,12 +405,14 @@
 
   octave_user_code *do_caller_user_code (size_t nskip) const;
 
-  void do_push (octave_function *f, symbol_table::scope_id scope,
+  bool do_all_scripts (void) const;
+
+  void do_push (octave_function *fcn, symbol_table::scope_id scope,
                 symbol_table::context_id context)
   {
     size_t prev_frame = curr_frame;
     curr_frame = cs.size ();
-    cs.push_back (call_stack_elt (f, scope, context, prev_frame));
+    cs.push_back (stack_frame (fcn, scope, context, prev_frame));
     symbol_table::set_scope_and_context (scope, context);
   }
 
@@ -367,8 +422,8 @@
 
     if (! cs.empty ())
       {
-        const call_stack_elt& elt = cs[curr_frame];
-        retval = elt.fcn;
+        const stack_frame& elt = cs[curr_frame];
+        retval = elt.m_fcn;
       }
 
     return retval;
@@ -378,10 +433,10 @@
   {
     if (! cs.empty ())
       {
-        call_stack_elt& elt = cs.back ();
+        stack_frame& elt = cs.back ();
 
-        elt.line = l;
-        elt.column = c;
+        elt.m_line = l;
+        elt.m_column = c;
       }
   }
 
@@ -389,9 +444,9 @@
   {
     if (! cs.empty ())
       {
-        call_stack_elt& elt = cs.back ();
+        stack_frame& elt = cs.back ();
 
-        elt.line = l;
+        elt.m_line = l;
       }
   }
 
@@ -399,14 +454,18 @@
   {
     if (! cs.empty ())
       {
-        call_stack_elt& elt = cs.back ();
+        stack_frame& elt = cs.back ();
 
-        elt.column = c;
+        elt.m_column = c;
       }
   }
 
+  std::list<octave_call_stack::stack_frame>
+  do_backtrace_frames (size_t nskip, octave_idx_type& curr_user_frame) const;
+
   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);
 
@@ -420,17 +479,15 @@
   {
     if (cs.size () > 1)
       {
-        const call_stack_elt& elt = cs.back ();
-        curr_frame = elt.prev;
+        const stack_frame& elt = cs.back ();
+        curr_frame = elt.m_prev;
         cs.pop_back ();
-        const call_stack_elt& new_elt = cs[curr_frame];
-        symbol_table::set_scope_and_context (new_elt.scope, new_elt.context);
+        const stack_frame& new_elt = cs[curr_frame];
+        symbol_table::set_scope_and_context (new_elt.m_scope, new_elt.m_context);
       }
   }
 
   void do_clear (void) { cs.clear (); }
-
-  void do_backtrace_error_message (void) const;
 };
 
 // Call a function with exceptions handled to avoid problems with
--- a/libinterp/corefcn/tril.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/libinterp/corefcn/tril.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -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
@@ -364,7 +367,7 @@
 diagonal; above for positive @var{k} and below for negative @var{k}.\n\
 \n\
 The absolute value of @var{k} must not be greater than the number of\n\
-sub-diagonals or super-diagonals.\n\
+subdiagonals or superdiagonals.\n\
 \n\
 For example:\n\
 \n\
--- a/libinterp/corefcn/txt-eng-ft.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/libinterp/corefcn/txt-eng-ft.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -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 Feb 06 08:31:09 2015 -0800
+++ b/libinterp/corefcn/txt-eng-ft.h	Fri Feb 06 08:31:49 2015 -0800
@@ -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/typecast.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/libinterp/corefcn/typecast.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -90,10 +90,12 @@
 
 DEFUN (typecast, args, ,
        "-*- texinfo -*-\n\
-@deftypefn {Built-in Function} {} typecast (@var{x}, @var{class})\n\
+@deftypefn {Built-in Function} {@var{y} =} typecast (@var{x}, \"@var{class}\")\n\
 Return a new array @var{y} resulting from interpreting the data of\n\
-@var{x} in memory as data of the numeric class @var{class}.  Both the class\n\
-of @var{x} and @var{class} must be one of the built-in numeric classes:\n\
+@var{x} in memory as data of the numeric class @var{class}.\n\
+\n\
+Both the class of @var{x} and @var{class} must be one of the built-in\n\
+numeric classes:\n\
 \n\
 @example\n\
 @group\n\
@@ -120,7 +122,7 @@
 consecutive pairs of real numbers.  The sizes of integer types are given by\n\
 their bit counts.  Both logical and char are typically one byte wide;\n\
 however, this is not guaranteed by C++.  If your system is IEEE conformant,\n\
-single and double should be 4 bytes and 8 bytes wide, respectively.\n\
+single and double will be 4 bytes and 8 bytes wide, respectively.\n\
 @qcode{\"logical\"} is not allowed for @var{class}.  If the input is a row\n\
 vector, the return value is a row vector, otherwise it is a column vector.  \n\
 If the bit length of @var{x} is not divisible by that of @var{class}, an\n\
@@ -135,7 +137,7 @@
 @result{} [   1,   0, 255, 255]\n\
 @end group\n\
 @end example\n\
-@seealso{cast, bitunpack, bitpack, swapbytes}\n\
+@seealso{cast, bitpack, bitunpack, swapbytes}\n\
 @end deftypefn")
 {
   octave_value retval;
@@ -297,12 +299,17 @@
 DEFUN (bitpack, args, ,
        "-*- texinfo -*-\n\
 @deftypefn {Built-in Function} {@var{y} =} bitpack (@var{x}, @var{class})\n\
-Return a new array @var{y} resulting from interpreting an array\n\
+Return a new array @var{y} resulting from interpreting the logical array\n\
 @var{x} as raw bit patterns for data of the numeric class @var{class}.\n\
+\n\
 @var{class} must be one of the built-in numeric classes:\n\
 \n\
 @example\n\
 @group\n\
+\"double\"\n\
+\"single\"\n\
+\"double complex\"\n\
+\"single complex\"\n\
 \"char\"\n\
 \"int8\"\n\
 \"int16\"\n\
@@ -312,8 +319,6 @@
 \"uint16\"\n\
 \"uint32\"\n\
 \"uint64\"\n\
-\"double\"\n\
-\"single\"\n\
 @end group\n\
 @end example\n\
 \n\
@@ -327,7 +332,11 @@
 {
   octave_value retval;
 
-  if (args.length () == 2 && args(0).is_bool_type ())
+  if (args.length () != 2)
+    print_usage ();
+  else if (! args(0).is_bool_type ())
+    error ("bitpack: X must be a logical array");
+  else
     {
       boolNDArray bitp = args(0).bool_array_value ();
 
@@ -371,8 +380,6 @@
       if (! error_state && retval.is_undefined ())
         error ("bitpack: cannot pack to %s class", numclass.c_str ());
     }
-  else
-    print_usage ();
 
   return retval;
 }
@@ -407,11 +414,15 @@
 DEFUN (bitunpack, args, ,
        "-*- texinfo -*-\n\
 @deftypefn {Built-in Function} {@var{y} =} bitunpack (@var{x})\n\
-Return an array @var{y} corresponding to the raw bit patterns of\n\
-@var{x}.  @var{x} must belong to one of the built-in numeric classes:\n\
+Return a logical array @var{y} corresponding to the raw bit patterns of\n\
+@var{x}.\n\
+\n\
+@var{x} must belong to one of the built-in numeric classes:\n\
 \n\
 @example\n\
 @group\n\
+\"double\"\n\
+\"single\"\n\
 \"char\"\n\
 \"int8\"\n\
 \"int16\"\n\
@@ -421,8 +432,6 @@
 \"uint16\"\n\
 \"uint32\"\n\
 \"uint64\"\n\
-\"double\"\n\
-\"single\"\n\
 @end group\n\
 @end example\n\
 \n\
--- a/libinterp/corefcn/urlwrite.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/libinterp/corefcn/urlwrite.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -346,36 +346,36 @@
       return retval;
     }
 
+  if (! args(0).is_string ())
+    {
+      error ("urlwrite: URL must be a string");
+      return retval;
+    }
+
   std::string url = args(0).string_value ();
 
-  if (error_state)
+  if (! args(1).is_string ())
     {
-      error ("urlwrite: URL must be a character string");
+      error ("urlwrite: LOCALFILE must be a string");
       return retval;
     }
 
   // name to store the file if download is succesful
   std::string filename = args(1).string_value ();
 
-  if (error_state)
-    {
-      error ("urlwrite: LOCALFILE must be a character string");
-      return retval;
-    }
-
   std::string method;
   Array<std::string> param;
 
   if (nargin == 4)
     {
-      method = args(2).string_value ();
-
-      if (error_state)
+      if (! args(2).is_string ())
         {
-          error ("urlwrite: METHOD must be \"get\" or \"post\"");
+          error ("urlwrite: METHOD must be a string");
           return retval;
         }
 
+      method = args(2).string_value ();
+
       if (method != "get" && method != "post")
         {
           error ("urlwrite: METHOD must be \"get\" or \"post\"");
@@ -386,12 +386,11 @@
 
       if (error_state)
         {
-          error ("urlwrite: parameters (PARAM) for get and post requests must be given as a cell array of character strings");
+          error ("urlwrite: parameters (PARAM) for get and post requests must be given as a cell array of strings");
           return retval;
         }
 
-
-      if (param.numel () % 2 == 1 )
+      if (param.numel () % 2 == 1)
         {
           error ("urlwrite: number of elements in PARAM must be even");
           return retval;
@@ -498,33 +497,33 @@
   int nargin = args.length ();
 
   // verify arguments
-  if (nargin != 1  && nargin != 3)
+  if (nargin != 1 && nargin != 3)
     {
       print_usage ();
       return retval;
     }
 
-  std::string url = args(0).string_value ();
-
-  if (error_state)
+  if (! args(0).is_string ())
     {
-      error ("urlread: URL must be a character string");
+      error ("urlread: URL must be a string");
       return retval;
     }
 
+  std::string url = args(0).string_value ();
+
   std::string method;
   Array<std::string> param;
 
   if (nargin == 3)
     {
-      method = args(1).string_value ();
-
-      if (error_state)
+      if (! args(1).is_string ())
         {
-          error ("urlread: METHOD must be \"get\" or \"post\"");
+          error ("urlread: METHOD must be a string");
           return retval;
         }
 
+      method = args(1).string_value ();
+
       if (method != "get" && method != "post")
         {
           error ("urlread: METHOD must be \"get\" or \"post\"");
@@ -535,11 +534,11 @@
 
       if (error_state)
         {
-          error ("urlread: parameters (PARAM) for get and post requests must be given as a cell array of character strings");
+          error ("urlread: parameters (PARAM) for get and post requests must be given as a cell array of strings");
           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 Feb 06 08:31:09 2015 -0800
+++ b/libinterp/corefcn/utils.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -38,8 +38,6 @@
 
 #include "vasnprintf.h"
 
-#include "quit.h"
-
 #include "dir-ops.h"
 #include "file-ops.h"
 #include "file-stat.h"
@@ -47,7 +45,9 @@
 #include "lo-utils.h"
 #include "oct-cmplx.h"
 #include "oct-env.h"
+#include "oct-locbuf.h"
 #include "pathsearch.h"
+#include "quit.h"
 #include "str-vec.h"
 
 #include "Cell.h"
@@ -121,6 +121,7 @@
 %!assert (isvarname ("1foo"), false)
 %!assert (isvarname (""), false)
 %!assert (isvarname (12), false)
+%!assert (isvarname ("foo+bar"), false)
 
 %!error isvarname ()
 %!error isvarname ("foo", "bar");
@@ -238,7 +239,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 +304,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;
@@ -355,6 +356,8 @@
 
 %!error file_in_loadpath ()
 %!error file_in_loadpath ("foo", "bar", 1)
+%!error file_in_loadpath ([])
+%!error file_in_loadpath ("plot.m", "bar")
 */
 
 DEFUN (file_in_path, args, ,
@@ -380,7 +383,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;
@@ -389,10 +392,10 @@
 
   if (nargin == 2 || nargin == 3)
     {
-      std::string path = args(0).string_value ();
+      if (args(0).is_string ())
+        {
+          std::string path = args(0).string_value ();
 
-      if (! error_state)
-        {
           string_vector names = args(1).all_strings ();
 
           if (! error_state && names.length () > 0)
@@ -439,6 +442,9 @@
 %!error file_in_path ()
 %!error file_in_path ("foo")
 %!error file_in_path ("foo", "bar", "baz", 1)
+%!error file_in_path ([])
+%!error file_in_path (path (), [])
+%!error file_in_path (path (), "plot.m", "bar")
 */
 
 std::string
@@ -452,6 +458,44 @@
   return octave_env::make_absolute (load_path::find_file (nm));
 }
 
+std::string
+find_data_file_in_load_path  (const std::string& fcn,
+                              const std::string& file,
+                              bool require_regular_file)
+{
+  std::string fname = file;
+
+  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);
+
+      bool local_file_ok
+        = fs.exists () && (fs.is_reg () || ! require_regular_file);
+
+      if (! local_file_ok)
+        {
+          // Not directly found; search load path.
+
+          std::string tmp
+            = octave_env::make_absolute (load_path::find_file (fname));
+
+          if (! tmp.empty ())
+            {
+              gripe_data_file_in_path (fcn, tmp);
+
+              fname = tmp;
+            }
+        }
+    }
+
+  return fname;
+}
+
 // See if there is an function file in the path.  If so, return the
 // full path to the file.
 
@@ -680,14 +724,24 @@
 %!assert (do_string_escapes ("foo\\nbar"), ["foo", char(10), "bar"])
 %!assert ("foo\nbar", ["foo", char(10), "bar"])
 
-%!assert (do_string_escapes ('\a\b\f\n\r\t\v'), "\a\b\f\n\r\t\v")
-%!assert (do_string_escapes ("\\a\\b\\f\\n\\r\\t\\v"), "\a\b\f\n\r\t\v")
-%!assert (do_string_escapes ("\\a\\b\\f\\n\\r\\t\\v"),
-%!        char ([7, 8, 12, 10, 13, 9, 11]))
-%!assert ("\a\b\f\n\r\t\v", char ([7, 8, 12, 10, 13, 9, 11]))
+%!assert (do_string_escapes ('\0\a\b\f\n\r\t\v'), "\0\a\b\f\n\r\t\v")
+%!assert (do_string_escapes ("\\0\\a\\b\\f\\n\\r\\t\\v"), "\0\a\b\f\n\r\t\v")
+%!assert (do_string_escapes ("\\0\\a\\b\\f\\n\\r\\t\\v"),
+%!        char ([0, 7, 8, 12, 10, 13, 9, 11]))
+%!assert ("\0\a\b\f\n\r\t\v", char ([0, 7, 8, 12, 10, 13, 9, 11]))
+
+%!assert (do_string_escapes ('\\'), "\\")
+%!assert (do_string_escapes ("\\\\"), "\\")
+%!assert (do_string_escapes ("\\\\"), char (92))
+
+%!assert (do_string_escapes ('\''single-quoted\'''), "'single-quoted'")
+%!assert (do_string_escapes ("\\'single-quoted\\'"), "'single-quoted'")
+%!assert (do_string_escapes ('\"double-quoted\"'), "\"double-quoted\"")
+%!assert (do_string_escapes ("\\\"double-quoted\\\""), "\"double-quoted\"")
 
 %!error do_string_escapes ()
 %!error do_string_escapes ("foo", "bar")
+%!error do_string_escapes (3)
 */
 
 const char *
@@ -806,8 +860,16 @@
 %!assert (undo_string_escapes (char ([7, 8, 12, 10, 13, 9, 11])),
 %!        "\\a\\b\\f\\n\\r\\t\\v")
 
+%!assert (undo_string_escapes ("\\"), '\\')
+%!assert (undo_string_escapes ("\\"), "\\\\")
+%!assert (undo_string_escapes (char (92)), "\\\\")
+
+%!assert (undo_string_escapes ("\"double-quoted\""), '\"double-quoted\"')
+%!assert (undo_string_escapes ("\"double-quoted\""), "\\\"double-quoted\\\"")
+
 %!error undo_string_escapes ()
 %!error undo_string_escapes ("foo", "bar")
+%!error undo_string_escapes (3)
 */
 
 DEFUN (is_absolute_filename, args, ,
@@ -892,10 +954,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 +988,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 ();
@@ -935,10 +997,21 @@
 }
 
 /*
-## FIXME: We need system-dependent tests here.
+%!test
+%! f = dir_in_loadpath ("plot");
+%! assert (ischar (f));
+%! assert (! isempty (f));
 
-%!error find_dir_in_path ()
-%!error find_dir_in_path ("foo", "bar", 1)
+%!test
+%! f = dir_in_loadpath ("$$probably_!!_not_&&_a_!!_dir$$");
+%! assert (f, "");
+
+%!test
+%! lst = dir_in_loadpath ("$$probably_!!_not_&&_a_!!_dir$$", "all");
+%! assert (lst, {});
+
+%!error dir_in_loadpath ()
+%!error dir_in_loadpath ("foo", "bar", 1)
 */
 
 DEFUNX ("errno", Ferrno, args, ,
@@ -965,7 +1038,7 @@
           if (! error_state)
             retval = octave_errno::lookup (nm);
           else
-            error ("errno: expecting character string argument");
+            error ("errno: expecting string argument");
         }
       else
         {
@@ -1306,9 +1379,6 @@
     {
       unwind_protect frame;
 
-      frame.protect_var (Vallow_noninteger_range_as_index);
-      Vallow_noninteger_range_as_index = false;
-
       frame.protect_var (error_state);
 
       frame.protect_var (discard_error_messages);
@@ -1316,7 +1386,8 @@
 
       try
         {
-          idx_vector idx = args(0).index_vector ();
+          idx_vector idx = args(0).index_vector (true);
+
           if (! error_state)
             {
               if (nargin == 2)
@@ -1339,9 +1410,11 @@
 /*
 %!assert (isindex ([1, 2, 3]))
 %!assert (isindex (1:3))
+%!assert (isindex (1:3, 2), false)
 %!assert (isindex ([1, 2, -3]), false)
 
 %!error isindex ()
+%!error isindex (1:3, 2, 3)
 */
 
 octave_value_list
@@ -1443,3 +1516,25 @@
   stream.width (owidth);
   stream.fill (ofill);
 }
+
+DEFUN (isstudent, args, ,
+       "-*- texinfo -*-\n\
+@deftypefn {Built-in Function} {} isstudent ()\n\
+Return true if running in the student edition of @sc{matlab}.\n\
+\n\
+@code{isstudent} always returns false in Octave.\n\
+\n\
+@seealso{false}\n\
+@end deftypefn")
+{
+  if (args.length () != 0)
+    print_usage ();
+
+  return octave_value (false);
+}
+
+/*
+%!assert (isstudent (), false)
+
+%!error isstudent (1)
+*/
--- a/libinterp/corefcn/utils.h	Fri Feb 06 08:31:09 2015 -0800
+++ b/libinterp/corefcn/utils.h	Fri Feb 06 08:31:49 2015 -0800
@@ -66,6 +66,11 @@
 extern OCTINTERP_API std::string
 file_in_path (const std::string&, const std::string&);
 
+extern OCTINTERP_API std::string
+find_data_file_in_load_path  (const std::string& fcn,
+                              const std::string& file,
+                              bool require_regular_file = false);
+
 extern OCTINTERP_API std::string contents_file_in_path (const std::string&);
 
 extern OCTINTERP_API std::string fcn_file_in_path (const std::string&);
--- a/libinterp/corefcn/variables.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/libinterp/corefcn/variables.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -150,14 +150,14 @@
 
   if (! retval)
     {
-      std::string s = arg.string_value ();
-
-      std::string cmd = header;
-      cmd.append (s);
-      cmd.append (trailer);
-
-      if (! error_state)
+      if (arg.is_string ())
         {
+          std::string s = arg.string_value ();
+
+          std::string cmd = header;
+          cmd.append (s);
+          cmd.append (trailer);
+
           int parse_status;
 
           eval_string (cmd, true, parse_status, 0);
@@ -283,7 +283,8 @@
 
           frame.run ();
 
-          if (tmp.is_defined () && (tmp.is_map () || tmp.is_java ()))
+          if (tmp.is_defined () &&
+              (tmp.is_map () || tmp.is_java () || tmp.is_classdef_object ()))
             names = tmp.map_keys ();
         }
     }
@@ -340,14 +341,14 @@
       return retval;
     }
 
-  std::string name = args(0).string_value ();
-
-  if (error_state)
+  if (! args(0).is_string ())
     {
       error ("isglobal: NAME must be a string");
       return retval;
     }
 
+  std::string name = args(0).string_value ();
+
   return symbol_table::is_global (name);
 }
 
@@ -388,17 +389,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 +400,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 +463,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 +483,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 +516,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 +559,27 @@
 @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\n\
+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 +588,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 +619,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
@@ -856,17 +936,17 @@
 
   if (nargin == 1)
     {
-      std::string sval = args(0).string_value ();
-
-      if (! error_state)
+      if (args(0).is_string ())
         {
+          std::string sval = args(0).string_value ();
+
           if (empty_ok || ! sval.empty ())
             var = sval;
           else
             error ("%s: value must not be empty", nm);
         }
       else
-        error ("%s: expecting arg to be a character string", nm);
+        error ("%s: first argument must be a string", nm);
     }
   else if (nargin > 1)
     print_usage ();
@@ -897,10 +977,10 @@
 
   if (nargin == 1)
     {
-      std::string sval = args(0).string_value ();
-
-      if (! error_state)
+      if (args(0).is_string ())
         {
+          std::string sval = args(0).string_value ();
+
           int i = 0;
           for (; i < nchoices; i++)
             {
@@ -914,7 +994,7 @@
             error ("%s: value not allowed (\"%s\")", nm, sval.c_str ());
         }
       else
-        error ("%s: expecting arg to be a character string", nm);
+        error ("%s: first argument must be a string", nm);
     }
   else if (nargin > 1)
     print_usage ();
@@ -1405,7 +1485,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;
@@ -1994,10 +2076,11 @@
 
   if (args.length () == 1)
     {
-      std::string name = args(0).string_value ();
-
-      if (! error_state)
-        munlock (name);
+      if (args(0).is_string ())
+        {
+          std::string name = args(0).string_value ();
+          munlock (name);
+        }
       else
         error ("munlock: FCN must be a string");
     }
@@ -2030,10 +2113,11 @@
 
   if (args.length () == 1)
     {
-      std::string name = args(0).string_value ();
-
-      if (! error_state)
-        retval = mislocked (name);
+      if (args(0).is_string ())
+        {
+          std::string name = args(0).string_value ();
+          retval = mislocked (name);
+        }
       else
         error ("mislocked: FCN must be a string");
     }
@@ -2255,6 +2339,7 @@
         {
           symbol_table::clear_objects ();
           octave_class::clear_exemplar_map ();
+          symbol_table::clear_all ();
         }
       else
         {
@@ -2464,6 +2549,7 @@
                     {
                       symbol_table::clear_objects ();
                       octave_class::clear_exemplar_map ();
+                      symbol_table::clear_all ();
                     }
                   else
                     {
--- a/libinterp/corefcn/xdiv.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/libinterp/corefcn/xdiv.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -42,6 +42,7 @@
 #include "fDiagMatrix.h"
 #include "CDiagMatrix.h"
 #include "fCDiagMatrix.h"
+#include "lo-array-gripes.h"
 #include "quit.h"
 
 #include "error.h"
@@ -58,8 +59,7 @@
 static void
 solve_singularity_warning (double rcond)
 {
-  warning_with_id ("Octave:singular-matrix-div",
-                   "matrix singular to machine precision, rcond = %g", rcond);
+  gripe_singular_matrix (rcond);
 }
 
 template <class T1, class T2>
@@ -405,8 +405,7 @@
 static void
 solve_singularity_warning (float rcond)
 {
-  warning ("matrix singular to machine precision, rcond = %g", rcond);
-  warning ("attempting to find minimum norm solution");
+  gripe_singular_matrix (rcond);
 }
 
 INSTANTIATE_MX_LEFTDIV_CONFORM (FloatMatrix, FloatMatrix);
@@ -713,7 +712,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 +795,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 +875,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 +950,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/corefcn/xpow.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/libinterp/corefcn/xpow.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -33,6 +33,7 @@
 #include "CColVector.h"
 #include "CDiagMatrix.h"
 #include "fCDiagMatrix.h"
+#include "fCMatrix.h"
 #include "CMatrix.h"
 #include "EIG.h"
 #include "fEIG.h"
@@ -41,6 +42,7 @@
 #include "dMatrix.h"
 #include "PermMatrix.h"
 #include "mx-cm-cdm.h"
+#include "mx-fcm-fcdm.h"
 #include "oct-cmplx.h"
 #include "Range.h"
 #include "quit.h"
@@ -52,10 +54,6 @@
 
 #include "bsxfun.h"
 
-#ifdef _OPENMP
-#include <omp.h>
-#endif
-
 static inline int
 xisint (double x)
 {
--- a/libinterp/dldfcn/__delaunayn__.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/libinterp/dldfcn/__delaunayn__.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -45,6 +45,8 @@
 #include <iostream>
 #include <string>
 
+#include "oct-locbuf.h"
+
 #include "Cell.h"
 #include "defun-dld.h"
 #include "error.h"
@@ -175,7 +177,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 Feb 06 08:31:09 2015 -0800
+++ b/libinterp/dldfcn/__eigs__.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -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/__fltk_uigetfile__.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/libinterp/dldfcn/__fltk_uigetfile__.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -123,10 +123,10 @@
         }
 
       if (multi_type == Fl_File_Chooser::DIRECTORY)
-        retval(0) = std::string (fc.value ());
+        retval(0) = file_ops::native_separator_path (std::string (fc.value ()));
       else
         {
-          retval(1) = std::string (fc.directory ()) + sep;
+          retval(1) = file_ops::native_separator_path (std::string (fc.directory ()) + sep);
           retval(2) = fc.filter_value () + 1;
         }
     }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libinterp/dldfcn/__ichol__.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,516 @@
+/*
+
+Copyright (C) 2014 Eduardo Ramos Fernández <eduradical951@gmail.com>
+Copyright (C) 2013 Kai T. Ohlhus <k.ohlhus@gmail.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/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "oct-locbuf.h"
+
+#include "defun-dld.h"
+#include "parse.h"
+
+// Secondary functions for complex and real case used in ichol algorithms.
+Complex ichol_mult_complex (Complex a, Complex b)
+{
+#if defined (HAVE_CXX_COMPLEX_SETTERS)
+  b.imag (-std::imag (b));
+#elif defined (HAVE_CXX_COMPLEX_REFERENCE_ACCESSORS)
+  b.imag () = -std::imag (b);
+#else
+  b = std::conj (b);
+#endif
+  return a * b;
+}
+
+double ichol_mult_real (double a, double b)
+{
+  return a * b;
+}
+
+bool ichol_checkpivot_complex (Complex pivot)
+{
+  if (pivot.imag () != 0)
+    {
+      error ("ichol: non-real pivot encountered.  The matrix must be hermitian.");
+      return false;
+    }
+  else if (pivot.real () < 0)
+    {
+      error ("ichol: negative pivot encountered");
+      return false;
+    }
+  return true;
+}
+
+bool ichol_checkpivot_real (double pivot)
+{
+  if (pivot < 0)
+    {
+      error ("ichol: negative pivot encountered");
+      return false;
+    }
+  return true;
+}
+
+template <typename octave_matrix_t, typename T, T (*ichol_mult) (T, T),
+          bool (*ichol_checkpivot) (T)>
+void ichol_0 (octave_matrix_t& sm, const std::string michol = "off")
+{
+
+  const octave_idx_type n = sm.cols ();
+  octave_idx_type j1, jend, j2, jrow, jjrow, j, jw, i, k, jj, r;
+  T tl;
+  char opt;
+  enum {OFF, ON};
+  if (michol == "on")
+    opt = ON;
+  else
+    opt = OFF;
+
+  // Input matrix pointers
+  octave_idx_type* cidx = sm.cidx ();
+  octave_idx_type* ridx = sm.ridx ();
+  T* data = sm.data ();
+
+  // Working arrays
+  OCTAVE_LOCAL_BUFFER (octave_idx_type, Lfirst, n);
+  OCTAVE_LOCAL_BUFFER (octave_idx_type, Llist, n);
+  OCTAVE_LOCAL_BUFFER (octave_idx_type, iw, n);
+  OCTAVE_LOCAL_BUFFER (T, dropsums, n);
+
+  // Initialize working arrays
+  for (i = 0; i < n; i++)
+    {
+      iw[i] = -1;
+      Llist[i] = -1;
+      Lfirst[i] = -1;
+      dropsums[i] = 0;
+    }
+
+  // Main loop
+  for (k = 0; k < n; k++)
+    {
+      j1 = cidx[k];
+      j2 = cidx[k+1];
+      for (j = j1; j < j2; j++)
+        iw[ridx[j]] = j;
+
+      jrow = Llist [k];
+      // Iterate over each non-zero element in the actual row.
+      while (jrow != -1)
+        {
+          jjrow = Lfirst[jrow];
+          jend = cidx[jrow+1];
+          for (jj = jjrow; jj < jend; jj++)
+            {
+              r = ridx[jj];
+              jw = iw[r];
+              tl = ichol_mult (data[jj], data[jjrow]);
+              if (jw != -1)
+                data[jw] -= tl;
+              else
+                // Because of the symmetry of the matrix, we know
+                // the drops in the column r are also in the column k.
+                if (opt == ON)
+                  {
+                    dropsums[r] -= tl;
+                    dropsums[k] -= tl;
+                  }
+            }
+          // Update the linked list and the first entry of the actual column.
+          if ((jjrow + 1) < jend)
+            {
+              Lfirst[jrow]++;
+              j = jrow;
+              jrow = Llist[jrow];
+              Llist[j] = Llist[ridx[Lfirst[j]]];
+              Llist[ridx[Lfirst[j]]] = j;
+            }
+          else
+            jrow = Llist[jrow];
+        }
+
+      if (opt == ON)
+        data[j1] += dropsums[k];
+
+      if (ridx[j1] != k)
+        {
+          error ("ichol: encountered a pivot equal to 0");
+          break;
+        }
+
+      if (! ichol_checkpivot (data[j1]))
+        break;
+
+      data[cidx[k]] = std::sqrt (data[j1]);
+
+      // Update Llist and Lfirst with the k-column information.  Also,
+      // scale the column elements by the pivot and reset the working array iw.
+      if (k < (n - 1))
+        {
+          iw[ridx[j1]] = -1;
+          for (i = j1 + 1; i < j2; i++)
+            {
+              iw[ridx[i]] = -1;
+              data[i] /= data[j1];
+            }
+          Lfirst[k] = j1;
+          if ((Lfirst[k] + 1) < j2)
+            {
+              Lfirst[k]++;
+              jjrow = ridx[Lfirst[k]];
+              Llist[k] = Llist[jjrow];
+              Llist[jjrow] = k;
+            }
+        }
+    }
+}
+
+DEFUN_DLD (__ichol0__, args, nargout, "-*- texinfo -*-\n\
+@deftypefn  {Loadable Function} {@var{L} =} __ichol0__ (@var{A})\n\
+@deftypefnx {Loadable Function} {@var{L} =} __ichol0__ (@var{A}, @var{michol})\n\
+Undocumented internal function.\n\
+@end deftypefn")
+
+{
+  octave_value_list retval;
+
+  int nargin = args.length ();
+  std::string michol = "off";
+
+  if (nargout > 1 || nargin < 1 || nargin > 2)
+    {
+      print_usage ();
+      return retval;
+    }
+
+  if (nargin == 2)
+    michol = args(1).string_value ();
+
+  // In ICHOL0 algorithm the zero-pattern of the input matrix is preserved
+  // so it's structure does not change during the algorithm.  The same input
+  // matrix is used to build the output matrix due to that fact.
+  octave_value_list param_list;
+  if (!args(0).is_complex_type ())
+    {
+      SparseMatrix sm = args(0).sparse_matrix_value ();
+      param_list.append (sm);
+      sm = feval ("tril", param_list)(0).sparse_matrix_value ();
+      ichol_0 <SparseMatrix, double, ichol_mult_real,
+               ichol_checkpivot_real> (sm, michol);
+      if (! error_state)
+        retval(0) = sm;
+    }
+  else
+    {
+      SparseComplexMatrix sm = args(0).sparse_complex_matrix_value ();
+      param_list.append (sm);
+      sm = feval ("tril", param_list)(0).sparse_complex_matrix_value ();
+      ichol_0 <SparseComplexMatrix, Complex, ichol_mult_complex,
+               ichol_checkpivot_complex> (sm, michol);
+      if (! error_state)
+        retval(0) = sm;
+    }
+
+  return retval;
+}
+
+template <typename octave_matrix_t, typename T,  T (*ichol_mult) (T, T),
+          bool (*ichol_checkpivot) (T)>
+void ichol_t (const octave_matrix_t& sm, octave_matrix_t& L, const T* cols_norm,
+              const T droptol, const std::string michol = "off")
+
+{
+
+  const octave_idx_type n = sm.cols ();
+  octave_idx_type j, jrow, jend, jjrow, i, k, jj, total_len,
+                  w_len, max_len, ind;
+  char opt;
+  enum {OFF, ON};
+  if (michol == "on")
+    opt = ON;
+  else
+    opt = OFF;
+
+  // Input matrix pointers
+  octave_idx_type* cidx = sm.cidx ();
+  octave_idx_type* ridx = sm.ridx ();
+  T* data = sm.data ();
+
+  // Output matrix data structures.  Because the final zero pattern pattern of
+  // the output matrix is not known due to fill-in elements, a heuristic
+  // approach has been adopted for memory allocation.  The size of ridx_out_l
+  // and data_out_l is incremented 10% of their actual size (nnz (A) in the
+  // beginning).  If that amount is less than n, their size is just incremented
+  // in n elements.  This way the number of reallocations decreases throughout
+  // the process, obtaining a good performance.
+  max_len = sm.nnz ();
+  max_len += (0.1 * max_len) > n ? 0.1 * max_len : n;
+  Array <octave_idx_type> cidx_out_l (dim_vector (n + 1, 1));
+  octave_idx_type* cidx_l = cidx_out_l.fortran_vec ();
+  Array <octave_idx_type> ridx_out_l (dim_vector (max_len ,1));
+  octave_idx_type* ridx_l = ridx_out_l.fortran_vec ();
+  Array <T> data_out_l (dim_vector (max_len, 1));
+  T* data_l = data_out_l.fortran_vec ();
+
+  // Working arrays
+  OCTAVE_LOCAL_BUFFER (T, w_data, n);
+  OCTAVE_LOCAL_BUFFER (octave_idx_type, Lfirst, n);
+  OCTAVE_LOCAL_BUFFER (octave_idx_type, Llist, n);
+  OCTAVE_LOCAL_BUFFER (T, col_drops, n);
+  std::vector <octave_idx_type> vec;
+  vec.resize (n);
+
+  T zero = T (0);
+  cidx_l[0] = cidx[0];
+  for (i = 0; i < n; i++)
+    {
+      Llist[i] = -1;
+      Lfirst[i] = -1;
+      w_data[i] = 0;
+      col_drops[i] = zero;
+      vec[i] = 0;
+    }
+
+  total_len = 0;
+  for (k = 0; k < n; k++)
+    {
+      ind = 0;
+      for (j = cidx[k]; j < cidx[k+1]; j++)
+        {
+          w_data[ridx[j]] = data[j];
+          if (ridx[j] != k)
+            {
+              vec[ind] = ridx[j];
+              ind++;
+            }
+        }
+      jrow = Llist[k];
+      while (jrow != -1)
+        {
+          jjrow = Lfirst[jrow];
+          jend = cidx_l[jrow+1];
+          for (jj = jjrow; jj < jend; jj++)
+            {
+              j = ridx_l[jj];
+              // If the element in the j position of the row is zero,
+              // then it will become non-zero, so we add it to the
+              // vector that tracks non-zero elements in the working row.
+              if (w_data[j] == zero)
+                {
+                  vec[ind] = j;
+                  ind++;
+                }
+              w_data[j] -=  ichol_mult (data_l[jj], data_l[jjrow]);
+            }
+          // Update the actual column first element and
+          // update the linked list of the jrow row.
+          if ((jjrow + 1) < jend)
+            {
+              Lfirst[jrow]++;
+              j = jrow;
+              jrow = Llist[jrow];
+              Llist[j] = Llist[ridx_l[Lfirst[j]]];
+              Llist[ridx_l[Lfirst[j]]] = j;
+            }
+          else
+            jrow = Llist[jrow];
+        }
+
+      // Resizing output arrays
+      if ((max_len - total_len) < n)
+        {
+          max_len += (0.1 * max_len) > n ? 0.1 * max_len : n;
+          data_out_l.resize (dim_vector (max_len, 1));
+          data_l = data_out_l.fortran_vec ();
+          ridx_out_l.resize (dim_vector (max_len, 1));
+          ridx_l = ridx_out_l.fortran_vec ();
+        }
+
+      // The sorting of the non-zero elements of the working column can be
+      // handled in a couple of ways.  The most efficient two I found, are
+      // keeping the elements in an ordered binary search tree dynamically or
+      // keep them unsorted in a vector and at the end of the outer iteration
+      // order them.  The last approach exhibits lower execution times.
+      std::sort (vec.begin (), vec.begin () + ind);
+
+      data_l[total_len] = w_data[k];
+      ridx_l[total_len] = k;
+      w_len = 1;
+
+      // Extract the non-zero elements of working column and
+      // drop the elements that are lower than droptol * cols_norm[k].
+      for (i = 0; i < ind ; i++)
+        {
+          jrow = vec[i];
+          if (w_data[jrow] != zero)
+            {
+              if (std::abs (w_data[jrow]) < (droptol * cols_norm[k]))
+                {
+                  if (opt == ON)
+                    {
+                      col_drops[k] += w_data[jrow];
+                      col_drops[jrow] += w_data[jrow];
+                    }
+                }
+              else
+                {
+                  data_l[total_len + w_len] = w_data[jrow];
+                  ridx_l[total_len + w_len] = jrow;
+                  w_len++;
+                }
+              vec[i] = 0;
+            }
+          w_data[jrow] = zero;
+        }
+
+      // Compensate column sums --> michol option
+      if (opt == ON)
+        data_l[total_len] += col_drops[k];
+
+      if (data_l[total_len] == zero)
+        {
+          error ("ichol: encountered a pivot equal to 0");
+          break;
+        }
+      else if (! ichol_checkpivot (data_l[total_len]))
+        break;
+
+      // Once elements are dropped and compensation of column sums are done,
+      // scale the elements by the pivot.
+      data_l[total_len] = std::sqrt (data_l[total_len]);
+      for (jj = total_len + 1; jj < (total_len + w_len); jj++)
+        data_l[jj] /=  data_l[total_len];
+      total_len += w_len;
+      // Check if there are too many elements to be indexed with
+      // octave_idx_type type due to fill-in during the process.
+      if (total_len < 0)
+        {
+          error ("ichol: integer overflow.  Too many fill-in elements in L");
+          break;
+        }
+      cidx_l[k+1] = cidx_l[k] - cidx_l[0] + w_len;
+
+      // Update Llist and Lfirst with the k-column information.
+      if (k < (n - 1))
+        {
+          Lfirst[k] = cidx_l[k];
+          if ((Lfirst[k] + 1) < cidx_l[k+1])
+            {
+              Lfirst[k]++;
+              jjrow = ridx_l[Lfirst[k]];
+              Llist[k] = Llist[jjrow];
+              Llist[jjrow] = k;
+            }
+        }
+    }
+
+  if (! error_state)
+    {
+      // Build the output matrices
+      L = octave_matrix_t (n, n, total_len);
+      for (i = 0; i <= n; i++)
+        L.cidx (i) = cidx_l[i];
+      for (i = 0; i < total_len; i++)
+        {
+          L.ridx (i) = ridx_l[i];
+          L.data (i) = data_l[i];
+        }
+    }
+}
+
+DEFUN_DLD (__icholt__, args, nargout, "-*- texinfo -*-\n\
+@deftypefn  {Loadable Function} {@var{L} =} __icholt__ (@var{A})\n\
+@deftypefnx {Loadable Function} {@var{L} =} __icholt__ (@var{A}, @var{droptol})\n\
+@deftypefnx {Loadable Function} {@var{L} =} __icholt__ (@var{A}, @var{droptol}, @var{michol})\n\
+Undocumented internal function.\n\
+@end deftypefn")
+{
+  octave_value_list retval;
+  int nargin = args.length ();
+  // Default values of parameters
+  std::string michol = "off";
+  double droptol = 0;
+
+  if (nargout > 1 || nargin < 1 || nargin > 3)
+    {
+      print_usage ();
+      return retval;
+    }
+
+  // Don't repeat input validation of arguments done in ichol.m
+
+  if (nargin >= 2)
+    droptol = args(1).double_value ();
+
+  if (nargin == 3)
+    michol = args(2).string_value ();
+
+  octave_value_list param_list;
+  if (! args(0).is_complex_type ())
+    {
+      Array <double> cols_norm;
+      SparseMatrix L;
+      param_list.append (args(0).sparse_matrix_value ());
+      SparseMatrix sm_l =
+        feval ("tril", param_list)(0).sparse_matrix_value ();
+      param_list(0) = sm_l;
+      param_list(1) = 1;
+      param_list(2) = "cols";
+      cols_norm = feval ("norm", param_list)(0).vector_value ();
+      param_list.clear ();
+      ichol_t <SparseMatrix,
+               double, ichol_mult_real, ichol_checkpivot_real>
+               (sm_l, L, cols_norm.fortran_vec (), droptol, michol);
+      if (! error_state)
+        retval(0) = L;
+    }
+  else
+    {
+      Array <Complex> cols_norm;
+      SparseComplexMatrix L;
+      param_list.append (args(0).sparse_complex_matrix_value ());
+      SparseComplexMatrix sm_l =
+        feval ("tril", param_list)(0).sparse_complex_matrix_value ();
+      param_list(0) = sm_l;
+      param_list(1) = 1;
+      param_list(2) = "cols";
+      cols_norm = feval ("norm", param_list)(0).complex_vector_value ();
+      param_list.clear ();
+      ichol_t <SparseComplexMatrix,
+               Complex, ichol_mult_complex, ichol_checkpivot_complex>
+               (sm_l, L, cols_norm.fortran_vec (),
+                Complex (droptol), michol);
+      if (! error_state)
+        retval(0) = L;
+    }
+
+  return retval;
+}
+
+/*
+## No test needed for internal helper function.
+%!assert (1)
+*/
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libinterp/dldfcn/__ilu__.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,1103 @@
+/*
+
+Copyright (C) 2014 Eduardo Ramos Fernández <eduradical951@gmail.com>
+Copyright (C) 2013 Kai T. Ohlhus <k.ohlhus@gmail.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/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "oct-locbuf.h"
+
+#include "defun-dld.h"
+#include "parse.h"
+
+// That function implements the IKJ and JKI variants of Gaussian elimination to
+// perform the ILUTP decomposition.  The behaviour is controlled by milu
+// parameter.  If milu = ['off'|'col'] the JKI version is performed taking
+// advantage of CCS format of the input matrix.  If milu = 'row' the input
+// matrix has to be transposed to obtain the equivalent CRS structure so we can
+// work efficiently with rows.  In this case IKJ version is used.
+template <typename octave_matrix_t, typename T>
+void ilu_0 (octave_matrix_t& sm, const std::string milu = "off")
+{
+
+  const octave_idx_type n = sm.cols ();
+  OCTAVE_LOCAL_BUFFER (octave_idx_type, iw, n);
+  OCTAVE_LOCAL_BUFFER (octave_idx_type, uptr, n);
+  octave_idx_type j1, j2, jrow, jw, i, k, jj;
+  T tl, r;
+
+  enum {OFF, ROW, COL};
+  char opt;
+  if (milu == "row")
+    {
+      opt = ROW;
+      sm = sm.transpose ();
+    }
+  else if (milu == "col")
+    opt = COL;
+  else
+    opt = OFF;
+
+  octave_idx_type* cidx = sm.cidx ();
+  octave_idx_type* ridx = sm.ridx ();
+  T* data = sm.data ();
+  for (i = 0; i < n; i++)
+    iw[i] = -1;
+  for (k = 0; k < n; k++)
+    {
+      j1 = cidx[k];
+      j2 = cidx[k+1] - 1;
+      octave_idx_type j;
+      for (j = j1; j <= j2; j++)
+        {
+          iw[ridx[j]] = j;
+        }
+      r = 0;
+      j = j1;
+      jrow = ridx[j];
+      while ((jrow < k) && (j <= j2))
+        {
+          if (opt == ROW)
+            {
+              tl = data[j] / data[uptr[jrow]];
+              data[j] = tl;
+            }
+          for (jj = uptr[jrow] + 1; jj < cidx[jrow+1]; jj++)
+            {
+              jw = iw[ridx[jj]];
+              if (jw != -1)
+                if (opt == ROW)
+                  data[jw] -= tl * data[jj];
+                else
+                  data[jw] -= data[j] * data[jj];
+
+              else
+                // That is for the milu='row'
+                if (opt == ROW)
+                  r += tl * data[jj];
+                else if (opt == COL)
+                  r += data[j] * data[jj];
+            }
+          j++;
+          jrow = ridx[j];
+        }
+      uptr[k] = j;
+      if (opt != OFF)
+        data[uptr[k]] -= r;
+      if (opt != ROW)
+        for (jj = uptr[k] + 1; jj < cidx[k+1]; jj++)
+          data[jj] /=  data[uptr[k]];
+      if (k != jrow)
+        {
+          error ("ilu: A has a zero on the diagonal");
+          break;
+        }
+
+      if (data[j] == T(0))
+        {
+          error ("ilu: encountered a pivot equal to 0");
+          break;
+        }
+      for (i = j1; i <= j2; i++)
+        iw[ridx[i]] = -1;
+    }
+  if (opt == ROW)
+    sm = sm.transpose ();
+}
+
+DEFUN_DLD (__ilu0__, args, nargout, "-*- texinfo -*-\n\
+@deftypefn   {Loadable Function} {[@var{L}, @var{U}] =} __ilu0__ (@var{A})\n\
+@deftypefnx  {Loadable Function} {[@var{L}, @var{U}] =} __ilu0__ (@var{A}, @var{milu})\n\
+@deftypefnx  {Loadable Function} {[@var{L}, @var{U}, @var{P}] =} __ilu0__ (@var{A}, @dots{})\n\
+Undocumented internal function.\n\
+@end deftypefn")
+{
+  octave_value_list retval;
+
+  int nargin = args.length ();
+  std::string milu;
+
+  if (nargout > 2 || nargin < 1 || nargin > 2)
+    {
+      print_usage ();
+      return retval;
+    }
+
+  // In ILU0 algorithm the zero-pattern of the input matrix is preserved so
+  // it's structure does not change during the algorithm.  The same input
+  // matrix is used to build the output matrix due to that fact.
+  octave_value_list param_list;
+  if (! args(0).is_complex_type ())
+    {
+      SparseMatrix sm = args(0).sparse_matrix_value ();
+      ilu_0 <SparseMatrix, double> (sm, milu);
+      if (!error_state)
+        {
+          param_list.append (sm);
+          retval(1) = feval ("triu", param_list)(0).sparse_matrix_value ();
+          SparseMatrix eye =
+            feval ("speye", octave_value_list (
+                     octave_value (sm.cols ())))(0).sparse_matrix_value ();
+          param_list.append (-1);
+          retval(0) = eye +
+                      feval ("tril", param_list)(0).sparse_matrix_value ();
+        }
+    }
+  else
+    {
+      SparseComplexMatrix sm = args(0).sparse_complex_matrix_value ();
+      ilu_0 <SparseComplexMatrix, Complex> (sm, milu);
+      if (! error_state)
+        {
+          param_list.append (sm);
+          retval(1) =
+            feval ("triu", param_list)(0).sparse_complex_matrix_value ();
+          SparseComplexMatrix eye =
+            feval ("speye", octave_value_list (
+                     octave_value (sm.cols ())))(0).sparse_complex_matrix_value ();
+          param_list.append (-1);
+          retval(0) =
+            eye + feval ("tril", param_list)(0).sparse_complex_matrix_value ();
+        }
+    }
+
+  return retval;
+}
+
+template <typename octave_matrix_t, typename T>
+void ilu_crout (octave_matrix_t& sm_l, octave_matrix_t& sm_u,
+                octave_matrix_t& L, octave_matrix_t& U, T* cols_norm,
+                T* rows_norm, const T droptol = 0,
+                const std::string milu = "off")
+{
+
+  // Map the strings into chars for faster comparing inside loops
+  char opt;
+  enum {OFF, ROW, COL};
+  if (milu == "row")
+    opt = ROW;
+  else if (milu == "col")
+    opt = COL;
+  else
+    opt = OFF;
+
+  octave_idx_type jrow, i, j, k, jj, total_len_l, total_len_u, max_len_u,
+                  max_len_l, w_len_u, w_len_l, cols_list_len, rows_list_len;
+
+  const octave_idx_type n = sm_u.cols ();
+  sm_u = sm_u.transpose ();
+
+  max_len_u = sm_u.nnz ();
+  max_len_u += (0.1 * max_len_u) > n ? 0.1 * max_len_u : n;
+  max_len_l = sm_l.nnz ();
+  max_len_l += (0.1 * max_len_l) > n ? 0.1 * max_len_l : n;
+  // Extract pointers to the arrays for faster access inside loops
+  octave_idx_type* cidx_in_u = sm_u.cidx ();
+  octave_idx_type* ridx_in_u = sm_u.ridx ();
+  T* data_in_u = sm_u.data ();
+  octave_idx_type* cidx_in_l = sm_l.cidx ();
+  octave_idx_type* ridx_in_l = sm_l.ridx ();
+  T* data_in_l = sm_l.data ();
+
+  // L output arrays
+  Array <octave_idx_type> ridx_out_l (dim_vector (max_len_l, 1));
+  octave_idx_type* ridx_l = ridx_out_l.fortran_vec ();
+  Array <T> data_out_l (dim_vector (max_len_l, 1));
+  T* data_l = data_out_l.fortran_vec ();
+
+  // U output arrays
+  Array <octave_idx_type> ridx_out_u (dim_vector (max_len_u, 1));
+  octave_idx_type* ridx_u = ridx_out_u.fortran_vec ();
+  Array <T> data_out_u (dim_vector (max_len_u, 1));
+  T* data_u = data_out_u.fortran_vec ();
+
+  // Working arrays
+  OCTAVE_LOCAL_BUFFER (octave_idx_type, cidx_l, n + 1);
+  OCTAVE_LOCAL_BUFFER (octave_idx_type, cidx_u, n + 1);
+  OCTAVE_LOCAL_BUFFER (octave_idx_type, cols_list, n);
+  OCTAVE_LOCAL_BUFFER (octave_idx_type, rows_list, n);
+  OCTAVE_LOCAL_BUFFER (T, w_data_l, n);
+  OCTAVE_LOCAL_BUFFER (T, w_data_u, n);
+  OCTAVE_LOCAL_BUFFER (octave_idx_type, Ufirst, n);
+  OCTAVE_LOCAL_BUFFER (octave_idx_type, Lfirst, n);
+  OCTAVE_LOCAL_BUFFER (T, cr_sum, n);
+
+  T zero = T (0);
+
+  cidx_u[0] = cidx_in_u[0];
+  cidx_l[0] = cidx_in_l[0];
+  for (i = 0; i < n; i++)
+    {
+      w_data_u[i] = zero;
+      w_data_l[i] = zero;
+      cr_sum[i] = zero;
+    }
+
+  total_len_u = 0;
+  total_len_l = 0;
+  cols_list_len = 0;
+  rows_list_len = 0;
+
+  for (k = 0; k < n; k++)
+    {
+      // Load the working column and working row
+      for (i = cidx_in_l[k]; i < cidx_in_l[k+1]; i++)
+        w_data_l[ridx_in_l[i]] = data_in_l[i];
+
+      for (i = cidx_in_u[k]; i < cidx_in_u[k+1]; i++)
+        w_data_u[ridx_in_u[i]] = data_in_u[i];
+
+      // Update U working row
+      for (j = 0; j < rows_list_len; j++)
+        {
+          if ((Ufirst[rows_list[j]] != -1))
+            for (jj = Ufirst[rows_list[j]]; jj < cidx_u[rows_list[j]+1]; jj++)
+              {
+                jrow = ridx_u[jj];
+                w_data_u[jrow] -= data_u[jj] * data_l[Lfirst[rows_list[j]]];
+              }
+        }
+      // Update L working column
+      for (j = 0; j < cols_list_len; j++)
+        {
+          if (Lfirst[cols_list[j]] != -1)
+            for (jj = Lfirst[cols_list[j]]; jj < cidx_l[cols_list[j]+1]; jj++)
+              {
+                jrow = ridx_l[jj];
+                w_data_l[jrow] -= data_l[jj] * data_u[Ufirst[cols_list[j]]];
+              }
+        }
+
+      if ((max_len_u - total_len_u) < n)
+        {
+          max_len_u += (0.1 * max_len_u) > n ? 0.1 * max_len_u : n;
+          data_out_u.resize (dim_vector (max_len_u, 1));
+          data_u = data_out_u.fortran_vec ();
+          ridx_out_u.resize (dim_vector (max_len_u, 1));
+          ridx_u = ridx_out_u.fortran_vec ();
+        }
+
+      if ((max_len_l - total_len_l) < n)
+        {
+          max_len_l += (0.1 * max_len_l) > n ? 0.1 * max_len_l : n;
+          data_out_l.resize (dim_vector (max_len_l, 1));
+          data_l = data_out_l.fortran_vec ();
+          ridx_out_l.resize (dim_vector (max_len_l, 1));
+          ridx_l = ridx_out_l.fortran_vec ();
+        }
+
+      // Expand the working row into the U output data structures
+      w_len_l = 0;
+      data_u[total_len_u] = w_data_u[k];
+      ridx_u[total_len_u] = k;
+      w_len_u = 1;
+      for (i = k + 1; i < n; i++)
+        {
+          if (w_data_u[i] != zero)
+            {
+              if (std::abs (w_data_u[i]) < (droptol * rows_norm[k]))
+                {
+                  if (opt == ROW)
+                    cr_sum[k] += w_data_u[i];
+                  else if (opt == COL)
+                    cr_sum[i] += w_data_u[i];
+                }
+              else
+                {
+                  data_u[total_len_u + w_len_u] = w_data_u[i];
+                  ridx_u[total_len_u + w_len_u] = i;
+                  w_len_u++;
+                }
+            }
+
+          // Expand the working column into the L output data structures
+          if (w_data_l[i] != zero)
+            {
+              if (std::abs (w_data_l[i]) < (droptol * cols_norm[k]))
+                {
+                  if (opt == COL)
+                    cr_sum[k] += w_data_l[i];
+                  else if (opt == ROW)
+                    cr_sum[i] += w_data_l[i];
+                }
+              else
+                {
+                  data_l[total_len_l + w_len_l] = w_data_l[i];
+                  ridx_l[total_len_l + w_len_l] = i;
+                  w_len_l++;
+                }
+            }
+          w_data_u[i] = zero;
+          w_data_l[i] = zero;
+        }
+
+      // Compensate row and column sums --> milu option
+      if (opt == COL || opt == ROW)
+        data_u[total_len_u] += cr_sum[k];
+
+      // Check if the pivot is zero
+      if (data_u[total_len_u] == zero)
+        {
+          error ("ilu: encountered a pivot equal to 0");
+          break;
+        }
+
+      // Scale the elements in L by the pivot
+      for (i = total_len_l ; i < (total_len_l + w_len_l); i++)
+        data_l[i] /= data_u[total_len_u];
+
+
+      total_len_u += w_len_u;
+      total_len_l += w_len_l;
+      // Check if there are too many elements to be indexed with
+      // octave_idx_type type due to fill-in during the process.
+      if (total_len_l < 0 || total_len_u < 0)
+        {
+          error ("ilu: integer overflow.  Too many fill-in elements in L or U");
+          break;
+        }
+      cidx_u[k+1] = cidx_u[k] - cidx_u[0] + w_len_u;
+      cidx_l[k+1] = cidx_l[k] - cidx_l[0] + w_len_l;
+
+      // The tricky part of the algorithm.  The arrays pointing to the first
+      // working element of each column in the next iteration (Lfirst) or
+      // the first working element of each row (Ufirst) are updated.  Also the
+      // arrays working as lists cols_list and rows_list are filled with
+      // indices pointing to Ufirst and Lfirst respectively.
+      // TODO: Maybe the -1 indicating in Ufirst and Lfirst, that no elements
+      // have to be considered in a certain column or row in next iteration,
+      // can be removed.  It feels safer to me using such an indicator.
+      if (k < (n - 1))
+        {
+          if (w_len_u > 0)
+            Ufirst[k] = cidx_u[k];
+          else
+            Ufirst[k] = -1;
+          if (w_len_l > 0)
+            Lfirst[k] = cidx_l[k];
+          else
+            Lfirst[k] = -1;
+          cols_list_len = 0;
+          rows_list_len = 0;
+          for (i = 0; i <= k; i++)
+            {
+              if (Ufirst[i] != -1)
+                {
+                  jj = ridx_u[Ufirst[i]];
+                  if (jj < (k + 1))
+                    {
+                      if (Ufirst[i] < (cidx_u[i+1]))
+                        {
+                          Ufirst[i]++;
+                          if (Ufirst[i] == cidx_u[i+1])
+                            Ufirst[i] = -1;
+                          else
+                            jj = ridx_u[Ufirst[i]];
+                        }
+                    }
+                  if (jj == (k + 1))
+                    {
+                      cols_list[cols_list_len] = i;
+                      cols_list_len++;
+                    }
+                }
+
+              if (Lfirst[i] != -1)
+                {
+                  jj = ridx_l[Lfirst[i]];
+                  if (jj < (k + 1))
+                    if (Lfirst[i] < (cidx_l[i+1]))
+                      {
+                        Lfirst[i]++;
+                        if (Lfirst[i] == cidx_l[i+1])
+                          Lfirst[i] = -1;
+                        else
+                          jj = ridx_l[Lfirst[i]];
+                      }
+                  if (jj == (k + 1))
+                    {
+                      rows_list[rows_list_len] = i;
+                      rows_list_len++;
+                    }
+                }
+            }
+        }
+    }
+
+  if (! error_state)
+    {
+      // Build the output matrices
+      L = octave_matrix_t (n, n, total_len_l);
+      U = octave_matrix_t (n, n, total_len_u);
+      for (i = 0; i <= n; i++)
+        L.cidx (i) = cidx_l[i];
+      for (i = 0; i < total_len_l; i++)
+        {
+          L.ridx (i) = ridx_l[i];
+          L.data (i) = data_l[i];
+        }
+      for (i = 0; i <= n; i++)
+        U.cidx (i) = cidx_u[i];
+      for (i = 0; i < total_len_u; i++)
+        {
+          U.ridx (i) = ridx_u[i];
+          U.data (i) = data_u[i];
+        }
+      U = U.transpose ();
+    }
+}
+
+DEFUN_DLD (__iluc__, args, nargout, "-*- texinfo -*-\n\
+@deftypefn  {Loadable Function} {[@var{L}, @var{U}] =} __iluc__ (@var{A})\n\
+@deftypefnx {Loadable Function} {[@var{L}, @var{U}] =} __iluc__ (@var{A}, @var{droptol}) \n\
+@deftypefnx {Loadable Function} {[@var{L}, @var{U}] =} __iluc__ (@var{A}, @var{droptol}, @var{milu})\n\
+@deftypefnx {Loadable Function} {[@var{L}, @var{U}, @var{P}] =} __iluc__ (@var{A}, @dots{})\n\
+Undocumented internal function.\n\
+@end deftypefn")
+{
+  octave_value_list retval;
+  int nargin = args.length ();
+  std::string milu = "off";
+  double droptol = 0;
+
+  if (nargout != 2 || nargin < 1 || nargin > 3)
+    {
+      print_usage ();
+      return retval;
+    }
+
+  // Don't repeat input validation of arguments done in ilu.m
+  if (nargin >= 2)
+    droptol = args(1).double_value ();
+
+  if (nargin == 3)
+    milu = args(2).string_value ();
+
+  octave_value_list param_list;
+  if (! args(0).is_complex_type ())
+    {
+      Array<double> cols_norm, rows_norm;
+      param_list.append (args(0).sparse_matrix_value ());
+      SparseMatrix sm_u = feval ("triu", param_list)(0).sparse_matrix_value ();
+      param_list.append (-1);
+      SparseMatrix sm_l = feval ("tril", param_list)(0).sparse_matrix_value ();
+      param_list(1) = "rows";
+      rows_norm = feval ("norm", param_list)(0).vector_value ();
+      param_list(1) = "cols";
+      cols_norm = feval ("norm", param_list)(0).vector_value ();
+      param_list.clear ();
+      SparseMatrix U;
+      SparseMatrix L;
+      ilu_crout <SparseMatrix, double> (sm_l, sm_u, L, U,
+                                        cols_norm.fortran_vec (),
+                                        rows_norm.fortran_vec (),
+                                        droptol, milu);
+      if (! error_state)
+        {
+          param_list.append (octave_value (L.cols ()));
+          SparseMatrix eye =
+            feval ("speye", param_list)(0).sparse_matrix_value ();
+          retval(1) = U;
+          retval(0) = L + eye;
+        }
+    }
+  else
+    {
+      Array<Complex> cols_norm, rows_norm;
+      param_list.append (args(0).sparse_complex_matrix_value ());
+      SparseComplexMatrix sm_u =
+        feval("triu", param_list)(0).sparse_complex_matrix_value ();
+      param_list.append (-1);
+      SparseComplexMatrix sm_l =
+        feval("tril", param_list)(0).sparse_complex_matrix_value ();
+      param_list(1) = "rows";
+      rows_norm = feval ("norm", param_list)(0).complex_vector_value ();
+      param_list(1) = "cols";
+      cols_norm = feval ("norm", param_list)(0).complex_vector_value ();
+      param_list.clear ();
+      SparseComplexMatrix U;
+      SparseComplexMatrix L;
+      ilu_crout < SparseComplexMatrix, Complex >
+                (sm_l, sm_u, L, U, cols_norm.fortran_vec () ,
+                 rows_norm.fortran_vec (), Complex (droptol), milu);
+      if (! error_state)
+        {
+          param_list.append (octave_value (L.cols ()));
+          SparseComplexMatrix eye =
+            feval ("speye", param_list)(0).sparse_complex_matrix_value ();
+          retval(1) = U;
+          retval(0) = L + eye;
+        }
+    }
+
+  return retval;
+}
+
+// That function implements the IKJ and JKI variants of gaussian elimination
+// to perform the ILUTP decomposition.  The behaviour is controlled by milu
+// parameter.  If milu = ['off'|'col'] the JKI version is performed taking
+// advantage of CCS format of the input matrix.  Row pivoting is performed.
+// If milu = 'row' the input matrix has to be transposed to obtain the
+// equivalent CRS structure so we can work efficiently with rows.  In that
+// case IKJ version is used and column pivoting is performed.
+
+template <typename octave_matrix_t, typename T>
+void ilu_tp (octave_matrix_t& sm, octave_matrix_t& L, octave_matrix_t& U,
+             octave_idx_type nnz_u, octave_idx_type nnz_l, T* cols_norm,
+             Array <octave_idx_type>& perm_vec, const T droptol = T(0),
+             const T thresh = T(0), const  std::string milu = "off",
+             const double udiag = 0)
+{
+  char opt;
+  enum {OFF, ROW, COL};
+  if (milu == "row")
+    opt = ROW;
+  else if (milu == "col")
+    opt = COL;
+  else
+    opt = OFF;
+
+  const octave_idx_type n = sm.cols ();
+
+  // That is necessary for the JKI (milu = "row") variant.
+  if (opt == ROW)
+    sm = sm.transpose();
+
+  // Extract pointers to the arrays for faster access inside loops
+  octave_idx_type* cidx_in = sm.cidx ();
+  octave_idx_type* ridx_in = sm.ridx ();
+  T* data_in = sm.data ();
+  octave_idx_type jrow, i, j, k, jj, c, total_len_l, total_len_u, p_perm,
+                  max_ind, max_len_l, max_len_u;
+  T tl, aux, maximum;
+
+  max_len_u = nnz_u;
+  max_len_u += (0.1 * max_len_u) > n ? 0.1 * max_len_u : n;
+  max_len_l = nnz_l;
+  max_len_l += (0.1 * max_len_l) > n ? 0.1 * max_len_l : n;
+
+  Array <octave_idx_type> cidx_out_l (dim_vector (n + 1, 1));
+  octave_idx_type* cidx_l = cidx_out_l.fortran_vec ();
+  Array <octave_idx_type> ridx_out_l (dim_vector (max_len_l, 1));
+  octave_idx_type* ridx_l = ridx_out_l.fortran_vec ();
+  Array <T> data_out_l (dim_vector (max_len_l ,1));
+  T* data_l = data_out_l.fortran_vec ();
+  // Data for U
+  Array <octave_idx_type> cidx_out_u (dim_vector (n + 1, 1));
+  octave_idx_type* cidx_u = cidx_out_u.fortran_vec ();
+  Array <octave_idx_type> ridx_out_u (dim_vector (max_len_u, 1));
+  octave_idx_type* ridx_u = ridx_out_u.fortran_vec ();
+  Array <T> data_out_u (dim_vector (max_len_u, 1));
+  T* data_u = data_out_u.fortran_vec();
+
+  // Working arrays and permutation arrays
+  octave_idx_type w_len_u, w_len_l;
+  T total_sum, partial_col_sum, partial_row_sum;
+  std::set <octave_idx_type> iw_l;
+  std::set <octave_idx_type> iw_u;
+  std::set <octave_idx_type>::iterator it, it2;
+  OCTAVE_LOCAL_BUFFER (T, w_data, n);
+  OCTAVE_LOCAL_BUFFER (octave_idx_type, iperm, n);
+  octave_idx_type* perm = perm_vec.fortran_vec ();
+  OCTAVE_LOCAL_BUFFER (octave_idx_type, uptr, n);
+
+
+  T zero = T(0);
+  cidx_l[0] = cidx_in[0];
+  cidx_u[0] = cidx_in[0];
+  for (i = 0; i < n; i++)
+    {
+      w_data[i] = 0;
+      perm[i] = i;
+      iperm[i] = i;
+    }
+  total_len_u = 0;
+  total_len_l = 0;
+
+  for (k = 0; k < n; k++)
+    {
+
+      for (j = cidx_in[k]; j < cidx_in[k+1]; j++)
+        {
+          p_perm = iperm[ridx_in[j]];
+          w_data[iperm[ridx_in[j]]] = data_in[j];
+          if (p_perm > k)
+            iw_l.insert (ridx_in[j]);
+          else
+            iw_u.insert (p_perm);
+        }
+
+      it = iw_u.begin ();
+      jrow = *it;
+      total_sum = zero;
+      while ((jrow < k) && (it != iw_u.end ()))
+        {
+          if (opt == COL)
+            partial_col_sum = w_data[jrow];
+          if (w_data[jrow] != zero)
+            {
+              if (opt == ROW)
+                {
+                  partial_row_sum = w_data[jrow];
+                  tl = w_data[jrow] / data_u[uptr[jrow]];
+                }
+              for (jj = cidx_l[jrow]; jj < cidx_l[jrow+1]; jj++)
+                {
+                  p_perm = iperm[ridx_l[jj]];
+                  aux = w_data[p_perm];
+                  if (opt == ROW)
+                    {
+                      w_data[p_perm] -= tl * data_l[jj];
+                      partial_row_sum += tl * data_l[jj];
+                    }
+                  else
+                    {
+                      tl = data_l[jj] * w_data[jrow];
+                      w_data[p_perm] -= tl;
+                      if (opt == COL)
+                        partial_col_sum += tl;
+                    }
+
+                  if ((aux == zero) && (w_data[p_perm] != zero))
+                    {
+                      if (p_perm > k)
+                        iw_l.insert (ridx_l[jj]);
+                      else
+                        iw_u.insert (p_perm);
+                    }
+                }
+
+              // Drop element from the U part in IKJ and L part in JKI
+              // variant (milu = [col|off])
+              if ((std::abs (w_data[jrow]) < (droptol * cols_norm[k]))
+                  && (w_data[jrow] != zero))
+                {
+                  if (opt == COL)
+                    total_sum += partial_col_sum;
+                  else if (opt == ROW)
+                    total_sum += partial_row_sum;
+                  w_data[jrow] = zero;
+                  it2 = it;
+                  it++;
+                  iw_u.erase (it2);
+                  jrow = *it;
+                  continue;
+                }
+              else
+                // This is the element scaled by the pivot
+                // in the actual iteration
+                if (opt == ROW)
+                  w_data[jrow] = tl;
+            }
+          jrow = *(++it);
+        }
+
+      // Search for the pivot and update iw_l and iw_u if the pivot is not the
+      // diagonal element
+      if ((thresh > zero) && (k < (n - 1)))
+        {
+          maximum = std::abs (w_data[k]) / thresh;
+          max_ind = perm[k];
+          for (it = iw_l.begin (); it != iw_l.end (); ++it)
+            {
+              p_perm = iperm[*it];
+              if (std::abs (w_data[p_perm]) > maximum)
+                {
+                  maximum = std::abs (w_data[p_perm]);
+                  max_ind = *it;
+                  it2 = it;
+                }
+            }
+          // If the pivot is not the diagonal element update all.
+          p_perm = iperm[max_ind];
+          if (max_ind != perm[k])
+            {
+              iw_l.erase (it2);
+              if (w_data[k] != zero)
+                iw_l.insert (perm[k]);
+              else
+                iw_u.insert (k);
+              // Swap data and update permutation vectors
+              aux = w_data[k];
+              iperm[perm[p_perm]] = k;
+              iperm[perm[k]] = p_perm;
+              c = perm[k];
+              perm[k] = perm[p_perm];
+              perm[p_perm] = c;
+              w_data[k] = w_data[p_perm];
+              w_data[p_perm] = aux;
+            }
+
+        }
+
+      // Drop elements in the L part in the IKJ and from the U part in the JKI
+      // version.
+      it = iw_l.begin ();
+      while (it != iw_l.end ())
+        {
+          p_perm = iperm[*it];
+          if (droptol > zero)
+            if (std::abs (w_data[p_perm]) < (droptol * cols_norm[k]))
+              {
+                if (opt != OFF)
+                  total_sum += w_data[p_perm];
+                w_data[p_perm] = zero;
+                it2 = it;
+                it++;
+                iw_l.erase (it2);
+                continue;
+              }
+
+          it++;
+        }
+
+      // If milu == [row|col] summation is preserved.
+      // Compensate diagonal element.
+      if (opt != OFF)
+        {
+          if ((total_sum > zero) && (w_data[k] == zero))
+            iw_u.insert (k);
+          w_data[k] += total_sum;
+        }
+
+
+
+      // Check if the pivot is zero and if udiag is active.
+      // NOTE: If the pivot == 0 and udiag is active, then if milu = [col|row]
+      //       will not preserve the row sum for that column/row.
+      if (w_data[k] == zero)
+        {
+          if (udiag == 1)
+            {
+              w_data[k] = droptol;
+              iw_u.insert (k);
+            }
+          else
+            {
+              error ("ilu: encountered a pivot equal to 0");
+              break;
+            }
+        }
+
+      // Scale the elements on the L part for IKJ version (milu = [col|off])
+      if (opt != ROW)
+        for (it = iw_l.begin (); it != iw_l.end (); ++it)
+          {
+            p_perm = iperm[*it];
+            w_data[p_perm] = w_data[p_perm] / w_data[k];
+          }
+
+
+      if ((max_len_u - total_len_u) < n)
+        {
+          max_len_u += (0.1 * max_len_u) > n ? 0.1 * max_len_u : n;
+          data_out_u.resize (dim_vector (max_len_u, 1));
+          data_u = data_out_u.fortran_vec ();
+          ridx_out_u.resize (dim_vector (max_len_u, 1));
+          ridx_u = ridx_out_u.fortran_vec ();
+        }
+
+      if ((max_len_l - total_len_l) < n)
+        {
+          max_len_l += (0.1 * max_len_l) > n ? 0.1 * max_len_l : n;
+          data_out_l.resize (dim_vector (max_len_l, 1));
+          data_l = data_out_l.fortran_vec ();
+          ridx_out_l.resize (dim_vector (max_len_l, 1));
+          ridx_l = ridx_out_l.fortran_vec ();
+        }
+
+      // Expand working vector into U.
+      w_len_u = 0;
+      for (it = iw_u.begin (); it != iw_u.end (); ++it)
+        {
+          if (w_data[*it] != zero)
+            {
+              data_u[total_len_u + w_len_u] = w_data[*it];
+              ridx_u[total_len_u + w_len_u] = *it;
+              w_len_u++;
+            }
+          w_data[*it] = 0;
+        }
+      // Expand working vector into L.
+      w_len_l = 0;
+      for (it = iw_l.begin (); it != iw_l.end (); ++it)
+        {
+          p_perm = iperm[*it];
+          if (w_data[p_perm] != zero)
+            {
+              data_l[total_len_l + w_len_l] = w_data[p_perm];
+              ridx_l[total_len_l + w_len_l] = *it;
+              w_len_l++;
+            }
+          w_data[p_perm] = 0;
+        }
+      total_len_u += w_len_u;
+      total_len_l += w_len_l;
+      // Check if there are too many elements to be indexed with
+      // octave_idx_type type due to fill-in during the process.
+      if (total_len_l < 0 || total_len_u < 0)
+        {
+          error ("ilu: Integer overflow.  Too many fill-in elements in L or U");
+          break;
+        }
+      if (opt == ROW)
+        uptr[k] = total_len_u - 1;
+      cidx_u[k+1] = cidx_u[k] - cidx_u[0] + w_len_u;
+      cidx_l[k+1] = cidx_l[k] - cidx_l[0] + w_len_l;
+
+      iw_l.clear ();
+      iw_u.clear ();
+    }
+
+  if (! error_state)
+    {
+      octave_matrix_t *L_ptr;
+      octave_matrix_t *U_ptr;
+      octave_matrix_t diag (n, n, n);
+
+      // L and U are interchanged if milu = 'row'.  It is a matter
+      // of nomenclature to re-use code with both IKJ and JKI
+      // versions of the algorithm.
+      if (opt == ROW)
+        {
+          L_ptr = &U;
+          U_ptr = &L;
+          L = octave_matrix_t (n, n, total_len_u - n);
+          U = octave_matrix_t (n, n, total_len_l);
+        }
+      else
+        {
+          L_ptr = &L;
+          U_ptr = &U;
+          L = octave_matrix_t (n, n, total_len_l);
+          U = octave_matrix_t (n, n, total_len_u);
+        }
+
+      for (i = 0; i <= n; i++)
+        {
+          L_ptr->cidx (i) = cidx_l[i];
+          U_ptr->cidx (i) = cidx_u[i];
+          if (opt == ROW)
+            U_ptr->cidx (i) -= i;
+        }
+
+      for (i = 0; i < n; i++)
+        {
+          if (opt == ROW)
+            diag.elem (i,i) = data_u[uptr[i]];
+          j = cidx_l[i];
+
+          while (j < cidx_l[i+1])
+            {
+              L_ptr->ridx (j) = ridx_l[j];
+              L_ptr->data (j) = data_l[j];
+              j++;
+            }
+          j = cidx_u[i];
+
+          while (j < cidx_u[i+1])
+            {
+              c = j;
+              if (opt == ROW)
+                {
+                  // The diagonal is removed from L if milu = 'row'.
+                  // That is because is convenient to have it inside
+                  // the L part to carry out the process.
+                  if (ridx_u[j] == i)
+                    {
+                      j++;
+                      continue;
+                    }
+                  else
+                    c -= i;
+                }
+              U_ptr->data (c) = data_u[j];
+              U_ptr->ridx (c) = ridx_u[j];
+              j++;
+            }
+        }
+
+      if (opt == ROW)
+        {
+          U = U.transpose ();
+          // The diagonal, conveniently permuted is added to U
+          U += diag.index (idx_vector::colon, perm_vec);
+          L = L.transpose ();
+        }
+    }
+}
+
+DEFUN_DLD (__ilutp__, args, nargout, "-*- texinfo -*-\n\
+@deftypefn  {Loadable Function} {[@var{L}, @var{U}] =} __ilutp__ (@var{A})\n\
+@deftypefnx {Loadable Function} {[@var{L}, @var{U}] =} __ilutp__ (@var{A}, @var{droptol})\n\
+@deftypefnx {Loadable Function} {[@var{L}, @var{U}] =} __ilutp__ (@var{A}, @var{droptol}, @var{thresh})\n\
+@deftypefnx {Loadable Function} {[@var{L}, @var{U}] =} __ilutp__ (@var{A}, @var{droptol}, @var{thresh}, @var{milu})\n\
+@deftypefnx {Loadable Function} {[@var{L}, @var{U}] =} __ilutp__ (@var{A}, @var{droptol}, @var{thresh}, @var{milu}, @var{udiag})\n\
+@deftypefnx {Loadable Function} {[@var{L}, @var{U}, @var{P}] =} __ilutp__ (@var{A}, @dots{})\n\
+Undocumented internal function.\n\
+@end deftypefn")
+{
+  octave_value_list retval;
+
+  int nargin = args.length ();
+  std::string milu = "";
+  double droptol = 0, thresh = 1;
+  double udiag = 0;
+
+  if (nargout < 2 || nargout > 3 || nargin < 1 || nargin > 5)
+    {
+      print_usage ();
+      return retval;
+    }
+
+  // Don't repeat input validation of arguments done in ilu.m
+  if (nargin >= 2)
+    droptol = args(1).double_value ();
+
+  if (nargin >= 3)
+    thresh = args(2).double_value ();
+
+  if (nargin >= 4)
+    milu = args(3).string_value ();
+
+  if (nargin == 5)
+    udiag = args(4).double_value ();
+
+  octave_value_list param_list;
+  octave_idx_type nnz_u, nnz_l;
+  if (! args(0).is_complex_type ())
+    {
+      Array <double> rc_norm;
+      SparseMatrix sm = args(0).sparse_matrix_value ();
+      param_list.append (sm);
+      nnz_u =  (feval ("triu", param_list)(0).sparse_matrix_value ()).nnz ();
+      param_list.append (-1);
+      nnz_l =  (feval ("tril", param_list)(0).sparse_matrix_value ()).nnz ();
+      if (milu == "row")
+        param_list (1) = "rows";
+      else
+        param_list (1) = "cols";
+      rc_norm = feval ("norm", param_list)(0).vector_value ();
+      param_list.clear ();
+      Array <octave_idx_type> perm (dim_vector (sm.cols (), 1));
+      SparseMatrix U;
+      SparseMatrix L;
+      ilu_tp <SparseMatrix, double> (sm, L, U, nnz_u, nnz_l,
+                                     rc_norm.fortran_vec (),
+                                     perm, droptol, thresh, milu, udiag);
+      if (! error_state)
+        {
+          param_list.append (octave_value (L.cols ()));
+          SparseMatrix eye =
+            feval ("speye", param_list)(0).sparse_matrix_value ();
+          if (milu == "row")
+            {
+              if (nargout == 3)
+                {
+                  retval(2) = eye.index (idx_vector::colon, perm);
+                  retval(1) = U.index (idx_vector::colon, perm);
+                }
+              else if (nargout == 2)
+                retval(1) = U;
+              retval(0) = L + eye;
+            }
+          else
+            {
+              if (nargout == 3)
+                {
+                  retval(2) = eye.index (perm, idx_vector::colon);
+                  retval(1) = U;
+                  retval(0) = L.index (perm, idx_vector::colon) + eye;
+                }
+              else
+                {
+                  retval(1) = U;
+                  retval(0) = L + eye.index (perm, idx_vector::colon);
+                }
+            }
+        }
+    }
+  else
+    {
+      Array <Complex> rc_norm;
+      SparseComplexMatrix sm = args(0).sparse_complex_matrix_value ();
+      param_list.append (sm);
+      nnz_u =
+        feval ("triu", param_list)(0).sparse_complex_matrix_value ().nnz ();
+      param_list.append (-1);
+      nnz_l =
+        feval ("tril", param_list)(0).sparse_complex_matrix_value ().nnz ();
+      if (milu == "row")
+        param_list(1) = "rows";
+      else
+        param_list(1) = "cols";
+      rc_norm = feval ("norm", param_list)(0).complex_vector_value ();
+      Array <octave_idx_type> perm (dim_vector (sm.cols (), 1));
+      param_list.clear ();
+      SparseComplexMatrix U;
+      SparseComplexMatrix L;
+      ilu_tp < SparseComplexMatrix, Complex>
+              (sm, L, U, nnz_u, nnz_l, rc_norm.fortran_vec (), perm,
+               Complex (droptol), Complex (thresh), milu, udiag);
+
+      if (! error_state)
+        {
+          param_list.append (octave_value (L.cols ()));
+          SparseComplexMatrix eye =
+            feval ("speye", param_list)(0).sparse_complex_matrix_value ();
+          if (milu == "row")
+            {
+              if (nargout == 3)
+                {
+                  retval(2) = eye.index (idx_vector::colon, perm);
+                  retval(1) = U.index (idx_vector::colon, perm);
+                }
+              else if (nargout == 2)
+                retval(1) = U;
+              retval(0) = L + eye;
+            }
+          else
+            {
+              if (nargout == 3)
+                {
+                  retval(2) = eye.index (perm, idx_vector::colon);
+                  retval(1) = U;
+                  retval(0) = L.index (perm, idx_vector::colon) + eye;
+                }
+              else
+                {
+                  retval(1) = U;
+                  retval(0) = L + eye.index (perm, idx_vector::colon);
+                }
+            }
+        }
+    }
+
+  return retval;
+}
+
+/*
+## No test needed for internal helper function.
+%!assert (1)
+*/
+
--- a/libinterp/dldfcn/__init_fltk__.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/libinterp/dldfcn/__init_fltk__.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -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>
@@ -85,15 +87,11 @@
 #include "gl2ps-renderer.h"
 #include "graphics.h"
 #include "parse.h"
-#include "sysdep.h"
 #include "toplev.h"
 #include "variables.h"
 
 #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 +111,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 +131,14 @@
 
   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;
+
+    gl2ps_print (gh_manager::get_object (number), cmd, term);
   }
 
   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 +161,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 +216,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 +241,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 +249,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 +263,13 @@
   void show (void)
   {
     menubar->show ();
+    menubar->redraw ();
   }
 
   void hide (void)
   {
     menubar->hide ();
+    menubar->redraw ();
   }
 
   bool is_visible (void)
@@ -326,7 +286,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 +296,7 @@
               menupath += "/";
             menupath += m->label ();
 
-            if (menupath.compare (findname) == 0 )
+            if (menupath.compare (findname) == 0)
               return (t);
           }
         else
@@ -691,14 +651,20 @@
 {
   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),
+  plot_window (int xx, int yy, int ww, int hh, figure::properties& xfp, bool internal)
+    : Fl_Window (xx, yy, ww, hh + menu_h + status_h + 2, "octave"),
+      window_label (), 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);
+    // See http://fltk.org/articles.php?L415+I0+T+M1000+P1
+    // for 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,115 +674,84 @@
     // 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");
+
+    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");
 
-      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 ();
+    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");
 
-      help = new Fl_Button (4 * status_h, yy, status_h,
-                            status_h, "?");
-      help->callback (button_callback, static_cast<void*> (this));
-      help->tooltip ("Help");
+    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 = new Fl_Output (5 * status_h, yy,
-                              ww > 2*status_h ? ww - status_h : 0,
-                              status_h, "");
+    end ();
 
-      status->textcolor (FL_BLACK);
-      status->color (FL_GRAY);
-      status->textfont (FL_COURIER);
-      status->textsize (10);
-      status->box (FL_ENGRAVED_BOX);
+    set_name ();
+    uimenu->add_to_menu (fp);
+    if (fp.menubar_is ("none") || !uimenu->items_to_show ())
+      hide_menubar ();
+
+    update_boundingbox (internal);
 
-      // 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 ();
-
-    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
-      hide_menubar ();
+        if (fp.get_currentaxes ().ok ())
+          show_canvas ();
+        else
+          hide_canvas ();
+      }
   }
 
   ~plot_window (void)
   {
-    canvas->hide ();
-    status->hide ();
-    uimenu->hide ();
     this->hide ();
+    Fl::check ();
   }
 
   double number (void) { return fp.get___myhandle__ ().value (); }
@@ -835,31 +770,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 +844,6 @@
           show_menubar ();
         else
           hide_menubar ();
-
-        mark_modified ();
       }
   }
 
@@ -943,19 +863,63 @@
     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 ();
+
+    // keep position fix, change outerposition accordingly
+    update_boundingbox (true);
+    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 ();
+  }
+
+  Matrix outerposition2position (const Matrix& outerpos)
+    {
+      Matrix pos = outerpos;
+      pos(1) += menu_dy ();
+      pos(3) -= menu_dy () + status_h + 2;
+      return pos;
+    }
+
+  Matrix position2outerposition (const Matrix& pos)
+    {
+      Matrix outerpos = pos;
+      outerpos(1) -= menu_dy ();
+      outerpos(3) += menu_dy () + status_h + 2;
+      return outerpos;
+    }
+
+  // Called from figure::properties::ID_POSITION if internal = true
+  // or ID_OUTERPOSITION if false.
+  // (someone has requested a position change with set (h, "position", [...])
+  // or set (h, "outerposition", [...])
+
+  void update_boundingbox (bool internal)
+  {
+    Matrix bb = fp.get_boundingbox (internal);
+    if (internal)
+      bb = position2outerposition (bb);
+    resize (bb(0), bb(1), bb(2), bb(3));
+  }
+
   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)
@@ -976,12 +940,6 @@
   // life
   std::string window_label;
 
-  // Mod keys status
-  int shift;
-
-  // Number of dimensions, 2 or 3.
-  int ndim;
-
   // Figure properties.
   figure::properties& fp;
 
@@ -989,7 +947,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)
@@ -1009,40 +967,62 @@
   {
     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)
@@ -1058,7 +1038,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,
@@ -1074,7 +1054,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 ();
@@ -1089,7 +1069,7 @@
 
             if (kid.valid_object () && kid.isa ("axes"))
               {
-                Matrix bb = kid.get_properties ().get_boundingbox (true);
+                Matrix bb = kid.get_properties ().get_boundingbox (false);
 
                 if (bb(0) <= px && px < (bb(0)+bb(2))
                     && bb(1) <= py && py < (bb(1)+bb(3)))
@@ -1125,7 +1105,6 @@
       }
 
     status->value (cbuf.str ().c_str ());
-    status->redraw ();
   }
 
   void view2status (graphics_object ax)
@@ -1142,7 +1121,6 @@
         cbuf << "[azimuth: " << v(0) << ", elevation: " << v(1) << "]";
 
         status->value (cbuf.str ().c_str ());
-        status->redraw ();
       }
   }
 
@@ -1150,9 +1128,7 @@
   {
     if (!fp.is_beingdeleted ())
       {
-        Matrix pos (1,2,0);
-        pos(0) = px;
-        pos(1) = h () - (py + status_h + menu_dy ());
+        Matrix pos = fp.map_from_boundingbox (px, py);
         fp.set_currentpoint (pos);
         graphics_object robj = gh_manager::get_object (fp.get_parent ());
         root_figure::properties& rp =
@@ -1163,19 +1139,25 @@
 
   void set_axes_currentpoint (graphics_object ax, int px, int py)
   {
-    if (ax.valid_object ())
+    if (ax.valid_object () && ax.isa ("axes"))
       {
         axes::properties& ap =
           dynamic_cast<axes::properties&> (ax.get_properties ());
 
-        double xx, yy;
-        pixel2pos (ax, px, py, xx, yy);
+        Matrix x_zlim = ap.get_transform_zlim ();
+        Matrix pos (2, 3, 0.0);
 
-        Matrix pos (2,3,0);
-        pos(0,0) = xx;
-        pos(1,0) = yy;
-        pos(0,1) = xx;
-        pos(1,1) = yy;
+        // front point (nearest to the viewer)
+        ColumnVector tmp = ap.get_transform ().untransform (px, py, x_zlim(0));
+        pos(0,0) = tmp(0);
+        pos(0,1) = tmp(1);
+        pos(0,2) = tmp(2);
+
+        // back point (furthest from the viewer)
+        tmp = ap.get_transform ().untransform (px, py, x_zlim(1));
+        pos(1,0) = tmp(0);
+        pos(1,1) = tmp(1);
+        pos(1,2) = tmp(2);
 
         ap.set_currentpoint (pos);
         fp.set_currentaxes (ap.get___myhandle__ ().value ());
@@ -1190,169 +1172,271 @@
       return 0;
   }
 
-  int key2shift (int key)
+  octave_scalar_map format_key_event (int e_key, const char* e_text, int e_state)
   {
-    if (key == FL_Shift_L || key == FL_Shift_R)
-      return FL_SHIFT;
+    octave_scalar_map evt;
 
-    if (key == FL_Control_L || key == FL_Control_R)
-      return FL_CTRL;
+    evt.assign ("Character", octave_value (e_text));
+    evt.assign ("Modifier", octave_value (modifier2cell (e_state)));
+
+    std::string key_str;
+    std::ostringstream tmp_str;
 
-    if (key == FL_Alt_L || key == FL_Alt_R)
-      return FL_ALT;
+    if (e_key == FL_Escape)
+      key_str = "escape";
+    else if (e_key == FL_Tab)
+      key_str = "tab";
+    else if (e_key == FL_Caps_Lock)
+      key_str = "capslock";
+    else if (e_key == FL_Shift_L || e_key == FL_Shift_R)
+      key_str = "shift";
+    else if (e_key == FL_Control_L || e_key == FL_Control_R)
+      key_str = "control";
+    else if (e_key == FL_Meta_L || e_key == FL_Meta_R)
+      key_str = "windows";
+    else if (e_key == FL_Alt_L || e_key == FL_Alt_R)
+      key_str = "alt";
+    else if (e_key == 32)
+      key_str = "space";
+    else if (e_key == FL_Enter)
+      key_str = "return";
+    else if (e_key == FL_BackSpace)
+      key_str = "backspace";
+    else if (e_key == FL_Print)
+      key_str = "printscreen";
+    else if (e_key == FL_Pause)
+      key_str = "pause";
+    else if (e_key == FL_Home)
+      key_str = "home";
+    else if (e_key == FL_End)
+      key_str = "end";
+    else if (e_key == FL_Insert)
+      key_str = "insert";
+    else if (e_key == FL_Page_Up)
+      key_str = "pageup";
+    else if (e_key == FL_Delete)
+      key_str = "delete";
+    else if (e_key == FL_Page_Down)
+      key_str = "pagedown";
+    else if (e_key == FL_Left)
+      key_str = "leftarrow";
+    else if (e_key == FL_Up)
+      key_str = "uparrow";
+    else if (e_key == FL_Right)
+      key_str = "rightarrow";
+    else if (e_key == FL_Down)
+      key_str = "downarrow";
+    else if (e_key == FL_Num_Lock)
+      key_str = "numlock";
+    else if (e_key == 0xffaf)
+      key_str = "divide";
+    else if (e_key == 0xffaa)
+      key_str = "multiply";
+    else if (e_key == 0xffad)
+      key_str = "subtract";
+    else if (e_key == 0xffab)
+      key_str = "add";
+    else if (e_key == 0xff8d)
+      key_str = "return";
+    else if (e_key == 0xffac)
+      key_str = "separator";
+    else if (e_key >= 0xffb0 && e_key <= 0xffb9)
+      {
+        tmp_str << "numpad" << (e_key - 0xffb0);
+        key_str = tmp_str.str ();
+      }
+    else if (e_key >= (FL_F + 1) && e_key <= (FL_F + 12))
+      {
+        tmp_str << "f" << (e_key - FL_F);
+        key_str = tmp_str.str ();
+      }
+    else if (e_key == ',')
+      key_str = "comma";
+    else if (e_key == '.')
+      key_str = "period";
+    else if (e_key == '-')
+      key_str = "hyphen";
+    else if (e_key == '^' || e_key == '+' || e_key == '#'
+             || e_key == '<' || e_key == 0xfe03 /*AltGr*/)
+      key_str = "0";
+    else if (isalnum (e_key))
+      key_str = std::tolower (e_key);
+    else if (isprint (e_text[0]))
+      key_str = "0";
 
-    if (key == FL_Meta_L || key == FL_Meta_R)
-      return FL_META;
-
-    return 0;
+    evt.assign ("Key", octave_value (key_str));
+    return evt;
   }
 
-  int key2ascii (int key)
-  {
-    if (key < 256) return key;
-    if (key == FL_Tab) return '\t';
-    if (key == FL_Enter) return 0x0a;
-    if (key == FL_BackSpace) return 0x08;
-    if (key == FL_Escape) return 0x1b;
-
-    return 0;
-  }
-
-  Cell modifier2cell ()
+  Cell modifier2cell (int e_state)
   {
     string_vector mod;
 
-    if (shift & FL_SHIFT)
+    if (e_state & FL_SHIFT)
       mod.append (std::string ("shift"));
-    if (shift & FL_CTRL)
+    if (e_state & FL_CTRL)
       mod.append (std::string ("control"));
-    if (shift & FL_ALT || shift & FL_META)
+    if (e_state & FL_ALT)
       mod.append (std::string ("alt"));
-
+    if (e_state & FL_COMMAND)
+      mod.append (std::string ("command"));
     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);
-  }
+    Matrix bb (1, 4);
+    bb(0) = xx;
+    bb(1) = yy;
+    bb(2) = ww;
+    bb(3) = hh;
 
-  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;
+    // update outerposition
+    fp.set_boundingbox (bb, false, false);
 
-    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 ();
+    // update position
+    fp.set_boundingbox (outerposition2position (bb), true, 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;
+
+        // FLTK resends keyboard events with flipped case if all
+        // widgets rejects the event.
+        // See Event Propagation http://www.fltk.org/doc-1.3/events.html
+        static bool key_resent_detected = false;
+
         switch (event)
           {
+          case FL_SHORTCUT:
+            {
+              // check if it a resent event with switched case
+              static int last_event_key = 0;
+              static char last_event_text = 0;
+
+              int e_key = Fl::event_key ();
+              char e_text = Fl::event_text ()[0];
+              key_resent_detected = (e_key == last_event_key
+                  && std::tolower (last_event_text) == std::tolower (e_text)
+                  && ((islower (last_event_text) && isupper (e_text))
+                      || (isupper (last_event_text) && islower (e_text))));
+
+              last_event_key = e_key;
+              last_event_text = e_text;
+            }
+            break;
+
           case FL_KEYDOWN:
             {
-              int key = Fl::event_key ();
+              int e_key = Fl::event_key ();
+              const char *e_text = Fl::event_text ();
+              int e_state = Fl::event_state ();
+              octave_scalar_map evt =
+                format_key_event (e_key, e_text, e_state);
 
-              shift |= key2shift (key);
-              int key_a = key2ascii (key);
-              if (key_a && fp.get_keypressfcn ().is_defined ())
-                {
-                  octave_scalar_map evt;
-                  evt.assign ("Character", octave_value (key_a));
-                  evt.assign ("Key", octave_value (std::tolower (key_a)));
-                  evt.assign ("Modifier", octave_value (modifier2cell ()));
-                  fp.execute_keypressfcn (evt);
-                }
-              switch (key)
+              fp.set_currentcharacter (std::string (e_text));
+              if (fp.get_keypressfcn ().is_defined ()
+                  && (evt.contents ("Key").length () > 0))
+                fp.execute_keypressfcn (evt);
+
+              switch (e_key)
                 {
                 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;
 
           case FL_KEYUP:
             {
-              int key = Fl::event_key ();
-
-              shift &= (~key2shift (key));
-              int key_a = key2ascii (key);
-              if (key_a && fp.get_keyreleasefcn ().is_defined ())
+              int e_key = Fl::event_key ();
+              int e_state = Fl::event_state ();
+              octave_scalar_map evt;
+              if (key_resent_detected && Fl::event_length () == 1)
                 {
-                  octave_scalar_map evt;
-                  evt.assign ("Character", octave_value (key_a));
-                  evt.assign ("Key", octave_value (std::tolower (key_a)));
-                  evt.assign ("Modifier", octave_value (modifier2cell ()));
-                  fp.execute_keyreleasefcn (evt);
+                  // FLTK flipped the case of Fl::event_text because no
+                  // widget wanted the FL_KEYDOWN event.
+                  char tmp_e_text[2];
+                  tmp_e_text[0] = Fl::event_text ()[0];
+                  tmp_e_text[1] = 0;
+                  // Undo the case flip
+                  if (std::islower (tmp_e_text[0]))
+                    tmp_e_text[0] = std::toupper (tmp_e_text[0]);
+                  else
+                    tmp_e_text[0] = std::tolower (tmp_e_text[0]);
+                  evt = format_key_event (e_key, tmp_e_text, e_state);
                 }
+              else
+                {
+                  const char *e_text = Fl::event_text ();
+                  evt = format_key_event (e_key, e_text, e_state);
+                }
+
+              if (fp.get_keyreleasefcn ().is_defined ()
+                  && (evt.contents ("Key").length () > 0))
+                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 (Fl::event_button () == FL_LEFT_MOUSE
+                && Fl::event_shift ())
+              fp.set_selectiontype ("extend");
+            else if ((Fl::event_button () == FL_LEFT_MOUSE
+                      && Fl::event_ctrl ())
+                      || Fl::event_button () == FL_RIGHT_MOUSE)
+              fp.set_selectiontype ("alternate");
+            else if (Fl::event_clicks ())
+              fp.set_selectiontype ("open");
+            else
+              fp.set_selectiontype ("normal");
+
+            if (fp.get_windowbuttondownfcn ().is_defined ())
+              fp.execute_windowbuttondownfcn (Fl::event_button ());
 
             gh = pixel2axes_or_ca (pos_x, pos_y);
 
@@ -1360,12 +1444,24 @@
               {
                 ax_obj = gh_manager::get_object (gh);
                 set_axes_currentpoint (ax_obj, pos_x, pos_y);
-              }
+
+                int ndim = calc_dimensions (ax_obj);
+
+                if (ndim == 3)
+                  rotate->activate ();
+                else // ndim == 2
+                  rotate->deactivate ();
 
-            fp.execute_windowbuttondownfcn (Fl::event_button());
+                fp.set_currentobject (ax_obj.get_handle ().value ());
 
-            if (Fl::event_button () == 1 || Fl::event_button () == 3)
-              return 1;
+                base_properties& props = ax_obj.get_properties ();
+                if (props.get_buttondownfcn ().is_defined ())
+                  props.execute_buttondownfcn (Fl::event_button ());
+
+                return 1;
+              }
+            else if (fp.get_buttondownfcn ().is_defined ())
+              fp.execute_buttondownfcn (Fl::event_button ());
 
             break;
 
@@ -1380,32 +1476,50 @@
               {
                 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 ();
@@ -1425,7 +1539,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;
@@ -1441,6 +1556,9 @@
                   axes::properties& ap =
                     dynamic_cast<axes::properties&> (ax.get_properties ());
 
+                  // Control how fast to zoom when using scroll 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)
@@ -1453,9 +1571,9 @@
 
                   ap.zoom_about_point (x1, y1, factor, false);
                   mark_modified ();
+                  return 1;
                 }
             }
-            return 1;
 
           case FL_RELEASE:
             if (fp.get_windowbuttonupfcn ().is_defined ())
@@ -1464,20 +1582,13 @@
                 fp.execute_windowbuttonupfcn ();
               }
 
-            if (Fl::event_button () == 1)
+            if ((Fl::event_button () == 1) && Fl::event_clicks ())
               {
-                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 ();
-                      }
-                  }
+                // Double click
+                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)
               {
@@ -1524,14 +1635,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);
   }
 };
 
@@ -1655,16 +1767,19 @@
       instance->do_update_canvas (hnd2idx (gh), ca);
   }
 
-  static void toggle_menubar_visibility (int fig_idx, bool menubar_is_figure)
+  static void update_boundingbox (const std::string& fig_idx_str,
+                                  bool internal)
   {
     if (instance_ok ())
-      instance->do_toggle_menubar_visibility (fig_idx, menubar_is_figure);
+      instance->do_update_boundingbox (str2idx (fig_idx_str), internal);
   }
 
   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:
@@ -1700,16 +1815,23 @@
 
     if (idx >= 0 && windows.find (idx) == windows.end ())
       {
-        Matrix pos = fp.get_boundingbox (true);
-
-        int x = pos(0);
-        int y = pos(1);
-        int w = pos(2);
-        int h = pos(3);
+        Matrix pos = fp.get_outerposition ().matrix_value ();
+        bool internal = false;
+        // check if figure::properties::outerposition is default -1.0
+        if (pos(2) != -1.0 && pos(3) != -1.0)
+          {
+            pos = fp.get_boundingbox (internal);
+          }
+        else
+          {
+            // use position
+            internal = true;
+            pos = fp.get_boundingbox (internal);
+          }
 
         idx2figprops (curr_index, fp);
 
-        windows[curr_index++] = new plot_window (x, y, w, h, fp);
+        windows[curr_index++] = new plot_window (pos(0), pos(1), pos(2), pos(3), fp, internal);
       }
   }
 
@@ -1739,11 +1861,13 @@
     if (win != windows.end ())
       {
         if (is_visible)
-          win->second->show ();
+          {
+            win->second->show ();
+            win->second->show_canvas ();
+          }
         else
           win->second->hide ();
 
-        win->second->redraw ();
       }
   }
 
@@ -1767,7 +1891,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)
@@ -1822,6 +1948,14 @@
       }
   }
 
+  void do_update_boundingbox (int idx, bool internal)
+  {
+    wm_iterator win = windows.find (idx);
+
+    if (win != windows.end ())
+      win->second->update_boundingbox (internal);
+  }
+
   static int str2idx (const caseless_str& clstr)
   {
     int ind;
@@ -1882,47 +2016,15 @@
 
 static bool toolkit_loaded = false;
 
-static int
-__fltk_redraw__ (void)
-{
-  if (toolkit_loaded)
-    {
-      // We scan all figures and add those which use FLTK.
-      graphics_object obj = gh_manager::get_object (0);
-      if (obj && obj.isa ("root"))
-        {
-          base_properties& props = obj.get_properties ();
-          Matrix children = props.get_all_children ();
-
-          for (octave_idx_type n = 0; n < children.numel (); n++)
-            {
-              graphics_object fobj = gh_manager::get_object (children (n));
-              if (fobj && fobj.isa ("figure"))
-                {
-                  figure::properties& fp =
-                    dynamic_cast<figure::properties&> (fobj.get_properties ());
-                  if (fp.get___graphics_toolkit__ ()
-                      == FLTK_GRAPHICS_TOOLKIT_NAME)
-                    figure_manager::new_window (fp);
-                }
-            }
-        }
-
-      // it seems that we have to call Fl::check twice to get everything drawn
-      Fl::check ();
-      Fl::check ();
-    }
-
-  return 0;
-}
-
 class fltk_graphics_toolkit : public base_graphics_toolkit
 {
 public:
   fltk_graphics_toolkit (void)
     : base_graphics_toolkit (FLTK_GRAPHICS_TOOLKIT_NAME),
       input_event_hook_fcn_id ()
-  { }
+  {
+    Fl::visual (FL_RGB);
+  }
 
   ~fltk_graphics_toolkit (void) { }
 
@@ -2016,6 +2118,14 @@
                   figure_manager::set_name (tmp);
                 }
                 break;
+
+              case figure::properties::ID_POSITION:
+                figure_manager::update_boundingbox (ov.string_value (), true);
+                break;
+
+              case figure::properties::ID_OUTERPOSITION:
+                figure_manager::update_boundingbox (ov.string_value (), false);
+                break;
               }
           }
       }
@@ -2031,9 +2141,29 @@
 
   void redraw_figure (const graphics_object& go) const
   {
-    figure_manager::mark_modified (go.get_handle ());
+    // We scan all figures and add those which use FLTK.
+    graphics_object obj = gh_manager::get_object (0);
+    if (obj && obj.isa ("root"))
+      {
+        base_properties& props = obj.get_properties ();
+        Matrix children = props.get_all_children ();
 
-    __fltk_redraw__ ();
+        for (octave_idx_type n = 0; n < children.numel (); n++)
+          {
+            graphics_object fobj = gh_manager::get_object (children (n));
+            if (fobj && fobj.isa ("figure"))
+              {
+                figure::properties& fp =
+                  dynamic_cast<figure::properties&> (fobj.get_properties ());
+                if (fp.get___graphics_toolkit__ ()
+                    == FLTK_GRAPHICS_TOOLKIT_NAME)
+                  figure_manager::new_window (fp);
+              }
+          }
+      }
+
+    figure_manager::mark_modified (go.get_handle ());
+    Fl::check ();
   }
 
   void print_figure (const graphics_object& go,
@@ -2042,7 +2172,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
@@ -2050,11 +2179,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
   {
@@ -2070,16 +2204,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 ();
       }
   }
 
@@ -2094,16 +2224,16 @@
 
 #endif
 
-DEFUN_DLD (__fltk_redraw__, , ,
+DEFUN_DLD (__fltk_check__, , ,
            "-*- texinfo -*-\n\
-@deftypefn {Loadable Function} {} __fltk_redraw__ ()\n\
-Undocumented internal function.\n\
+@deftypefn {Loadable Function} {} __fltk_check__ ()\n\
+Undocumented internal function.  Calls Fl::check ()\n\
 @end deftypefn")
 {
 #ifdef HAVE_FLTK
-  __fltk_redraw__ ();
+  Fl::check ();
 #else
-  error ("__fltk_redraw__: not available without OpenGL and FLTK libraries");
+  error ("__fltk_check__: not available without OpenGL and FLTK libraries");
 #endif
 
   return octave_value ();
@@ -2129,8 +2259,8 @@
       gtk_manager::load_toolkit (tk);
       toolkit_loaded = true;
 
-      octave_value fcn (new octave_builtin (F__fltk_redraw__));
-      octave_value fcn_handle (new octave_fcn_handle (fcn, "@__fltk_redraw__"));
+      octave_value fcn (new octave_builtin (F__fltk_check__));
+      octave_value fcn_handle (new octave_fcn_handle (fcn, "@__fltk_check__"));
       octave_value_list id = Fadd_input_event_hook (fcn_handle, 1);
 
       fltk->set_input_event_hook_id (id);
@@ -2142,31 +2272,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\
@@ -2183,101 +2288,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/__init_gnuplot__.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/libinterp/dldfcn/__init_gnuplot__.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -36,11 +36,15 @@
 #include "builtins.h"
 #include "defun-dld.h"
 #include "error.h"
+#include "file-stat.h"
 #include "graphics.h"
+#include "oct-conf.h"
+#include "oct-env.h"
 #include "parse.h"
+#include "utils.h"
 #include "variables.h"
 
-// PKG_ADD: register_graphics_toolkit ("gnuplot");
+// PKG_ADD: if (__have_gnuplot__ ()) register_graphics_toolkit ("gnuplot"); endif
 
 static bool toolkit_loaded = false;
 
@@ -166,13 +170,41 @@
   }
 };
 
-// Initialize the fltk graphics toolkit.
+static bool
+have_gnuplot_binary (void)
+{
+  const std::string exeext = std::string (OCTAVE_CONF_EXEEXT);
+  const std::string path = octave_env::getenv ("PATH");
+
+  octave_value_list tmp = feval ("gnuplot_binary", octave_value_list ());
+  std::string gnuplot_binary = tmp(0).string_value ();
+
+  string_vector args (gnuplot_binary);
+  std::string gnuplot_path = search_path_for_file (path, args);
+
+  file_stat fs (gnuplot_path);
+
+  if (! fs.exists () && ! exeext.empty ())
+    {
+      args[0] += exeext;
+
+      gnuplot_path = search_path_for_file (path, args);
+
+      fs = file_stat (gnuplot_path);
+    }
+
+  return fs.exists ();
+}
+
+// Initialize the gnuplot graphics toolkit.
 
 DEFUN_DLD (__init_gnuplot__, , , "")
 {
   octave_value retval;
 
-  if (! toolkit_loaded)
+  if (! have_gnuplot_binary ())
+    error ("__init_gnuplot__: the gnuplot program is not available, see 'gnuplot_binary'");
+  else if (! toolkit_loaded)
     {
       mlock ();
 
@@ -185,3 +217,16 @@
   return retval;
 }
 
+DEFUN_DLD (__have_gnuplot__, , ,
+           "-*- texinfo -*-\n\
+@deftypefn {Loadable Function} {@var{gnuplot_available} =} __have_gnuplot__ ()\n\
+Undocumented internal function.\n\
+@end deftypefn")
+{
+  octave_value retval;
+
+  retval = have_gnuplot_binary ();
+
+  return retval;
+}
+
--- a/libinterp/dldfcn/__voronoi__.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/libinterp/dldfcn/__voronoi__.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -38,6 +38,7 @@
 
 #include <list>
 
+#include "oct-locbuf.h"
 #include "lo-ieee.h"
 
 #include "Cell.h"
--- a/libinterp/dldfcn/amd.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/libinterp/dldfcn/amd.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -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\
@@ -164,11 +164,11 @@
 
               // FIXME: how can we manage the memory allocation of amd
               //        in a cleaner manner?
-              amd_malloc = malloc;
-              amd_free = free;
-              amd_calloc = calloc;
-              amd_realloc = realloc;
-              amd_printf = printf;
+              SUITESPARSE_ASSIGN_FPTR (malloc_func, amd_malloc, malloc);
+              SUITESPARSE_ASSIGN_FPTR (free_func, amd_free, free);
+              SUITESPARSE_ASSIGN_FPTR (calloc_func, amd_calloc, calloc);
+              SUITESPARSE_ASSIGN_FPTR (realloc_func, amd_realloc, realloc);
+              SUITESPARSE_ASSIGN_FPTR (printf_func, amd_printf, printf);
 
               octave_idx_type result = AMD_NAME (_order) (n_col, cidx, ridx, P,
                                                           Control, Info);
@@ -204,3 +204,19 @@
 
   return retval;
 }
+/*
+%!shared A, A2, opts
+%! A = ones (20, 30);
+%! A2 = ones (30, 30);
+%!
+%!testif HAVE_AMD
+%! assert(amd (A2), [1:30])
+%! opts.dense = 25;
+%! assert(amd (A2, opts), [1:30])
+%! opts.aggressive = 1;
+%! assert(amd (A2, opts), [1:30])
+
+%!error <matrix S must be square|not available in this version> amd (A)
+%!error amd (A2, 2)
+%!error <matrix S is corrupted|not available in this version> amd ([])
+*/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libinterp/dldfcn/audiodevinfo.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,3251 @@
+/*
+
+Copyright (C) 2013 Vytautas Jančauskas
+
+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
+
+// <cstdint> requires c++11
+#include <stdint.h>
+
+#include <string>
+#include <vector>
+
+#include "mach-info.h"
+
+#include "defun-dld.h"
+#include "error.h"
+#include "gripes.h"
+#include "oct-obj.h"
+#include "ov.h"
+#include "ov-int32.h"
+#include "ov-struct.h"
+#include "parse.h"
+
+#if defined (HAVE_PORTAUDIO)
+
+#include <portaudio.h>
+
+PaSampleFormat
+bits_to_format (int bits)
+{
+  if (bits == 8)
+    return paInt8;
+  else if (bits == 16)
+    return paInt16;
+  else if (bits == 24)
+    return paInt24;
+  else if (bits == 32)
+    return paInt32;
+  else if (bits == -1)
+    return paFloat32;
+  else
+    return 0;
+}
+
+#endif
+
+DEFUN_DLD (audiodevinfo, args, ,
+           "-*- texinfo -*-\n\
+@deftypefn {Loadable Function} {@var{devinfo} =} audiodevinfo ()\n\
+\n\
+@deftypefnx {Loadable Function} {@var{devs} =} audiodevinfo (@var{io})\n\
+@deftypefnx {Loadable Function} {@var{name} =} audiodevinfo (@var{io}, @var{id})\n\
+@deftypefnx {Loadable Function} {@var{id} =} audiodevinfo (@var{io}, @var{name})\n\
+@deftypefnx {Loadable Function} {@var{id} =} audiodevinfo (@var{io}, @var{rate}, @var{bits}, @var{chans})\n\
+\n\
+@deftypefnx {Loadable Function} {@var{supports} =} audiodevinfo (@var{io}, @var{id}, @var{rate}, @var{bits}, @var{chans})\n\
+\n\
+Return a structure with fields \"input\" and \"output\".\n\
+The value of each field is a structure array with fields\n\
+\"Name\", @nospell{\"DriverVersion\"} and \"ID\" describing an audio device.\n\
+\n\
+\n\
+If the optional argument @var{io} is 1, return information about input\n\
+devices only.  If it is 0, return information about output devices only.\n\
+\n\
+If the optional argument @var{id} is provided, return information about\n\
+corresponding device.\n\
+\n\
+If the optional argument @var{name} is provided, return the id of the\n\
+named device.\n\
+\n\
+Given a sampling rate, bits per sample, and number of channels for\n\
+an input or output device, return the ID of the first device that\n\
+supports playback or recording using the specified parameters.\n\
+\n\
+If also given a device ID, return true if the device supports playback\n\
+or recording using those parameters.\n\
+@end deftypefn")
+{
+  octave_value retval;
+
+#ifdef HAVE_PORTAUDIO
+
+  int nargin = args.length ();
+
+  octave_scalar_map devinfo;
+  octave_value_list input;
+  octave_value_list output;
+
+  PaError err = Pa_Initialize ();
+
+  if (err != paNoError)
+    {
+      error ("audiodevinfo: PortAudio initialization failed");
+      return retval;
+    }
+
+  int num_devices = Pa_GetDeviceCount ();
+
+  if (num_devices < 0)
+    {
+      error ("audiodevinfo: no audio device found");
+      return retval;
+    }
+
+  octave_idx_type numinput = 0, numoutput = 0;
+  for (int i = 0; i < num_devices; i++)
+    {
+      const PaDeviceInfo *device_info = Pa_GetDeviceInfo (i);
+
+      if (! device_info)
+        {
+          warning ("Octave:invalid-audio-device",
+                   "invalid audio device ID = %d", i);
+          continue;
+        }
+
+      if (device_info->maxInputChannels != 0)
+        numinput++;
+
+      if (device_info->maxOutputChannels != 0)
+        numoutput++;
+    }
+
+  Cell input_name (dim_vector (1, numinput));
+  Cell input_driver_version (dim_vector (1, numinput));
+  Cell input_id (dim_vector (1, numinput));
+  Cell output_name (dim_vector (1, numoutput));
+  Cell output_driver_version (dim_vector (1, numoutput));
+  Cell output_id (dim_vector (1, numoutput));
+
+  octave_idx_type idx_i = 0, idx_o = 0;
+  for (int i = 0; i < num_devices; i++)
+    {
+      const PaDeviceInfo *device_info = Pa_GetDeviceInfo (i);
+
+      if (! device_info)
+        {
+          warning ("Octave:invalid-audio-device",
+                   "invalid audio device ID = %d", i);
+          continue;
+        }
+
+      const PaHostApiInfo *api_info = Pa_GetHostApiInfo (device_info->hostApi);
+
+      const char *driver = api_info ? api_info->name : "";
+
+      char name[128];
+      sprintf (name, "%s (%s)", device_info->name, driver);
+
+      if (device_info->maxInputChannels != 0)
+        {
+          input_name(idx_i) = name;
+          input_driver_version(idx_i) = driver;
+          input_id(idx_i) = i;
+          idx_i++;
+        }
+
+      if (device_info->maxOutputChannels != 0)
+        {
+          output_name(idx_o) = name;
+          output_driver_version(idx_o) = driver;
+          output_id(idx_o) = i;
+          idx_o++;
+        }
+    }
+
+  octave_map inputdev, outputdev;
+  inputdev.setfield ("Name", input_name);
+  inputdev.setfield ("DriverVersion", input_driver_version);
+  inputdev.setfield ("ID", input_id);
+  outputdev.setfield ("Name", output_name);
+  outputdev.setfield ("DriverVersion", output_driver_version);
+  outputdev.setfield ("ID", output_id);
+  devinfo.setfield ("input", inputdev);
+  devinfo.setfield ("output", outputdev);
+
+  // Return information about input and output audio devices and
+  // their properties.
+  if (nargin == 0)
+    retval = devinfo;
+  // Return the number of input or output devices
+  else if (nargin == 1)
+    {
+      if (args(0).int_value () == 0)
+        retval = numoutput;
+      else if (args(0).int_value () == 1)
+        retval = numinput;
+      else
+        {
+          error ("audiodevinfo: please specify 0 for output and 1 for input devices");
+          return retval;
+        }
+    }
+  // Return device name when given id or id when given device name.
+  else if (nargin == 2)
+    {
+      bool found = false;
+      int outin = args(0).int_value ();
+      if (args(1).is_string ())
+        {
+          if (outin == 0)
+            {
+              for (int i = 0; i < numoutput; i++)
+                {
+                  if (output_name(i).string_value () == args(1).string_value ())
+                    {
+                      retval = output_id(i);
+                      found = true;
+                      break;
+                    }
+                }
+            }
+          else if (outin == 1)
+            {
+              for (int i = 0; i < numinput; i++)
+                {
+                  if (input_name(i).string_value () == args(1).string_value ())
+                    {
+                      retval = input_id(i);
+                      found = true;
+                      break;
+                    }
+                }
+            }
+          else
+            {
+              error ("audiodevinfo: please specify 0 for output and 1 for input devices");
+              return retval;
+            }
+        }
+      else
+        {
+          if (outin == 0)
+            {
+              for (int i = 0; i < numoutput; i++)
+                {
+                  if (output_id(i).int_value () == args(1).int_value ())
+                    {
+                      retval = output_name(i);
+                      found = true;
+                      break;
+                    }
+                }
+            }
+          else if (outin == 1)
+            {
+              for (int i = 0; i < numinput; i++)
+                {
+                  if (input_id(i).int_value () == args(1).int_value ())
+                    {
+                      retval = input_name(i);
+                      found = true;
+                      break;
+                    }
+                }
+            }
+          else
+            {
+              error ("audiodevinfo: please specify 0 for output and 1 for input devices");
+              return retval;
+            }
+        }
+      if (not found)
+        error ("audiodevinfo: no device meeting the specified criteria found");
+    }
+  else if (nargin == 3)
+    {
+      // FIXME: what was supposed to happen here?
+    }
+  // Return the id of the first device meeting specified criteria.
+  else if (nargin == 4)
+    {
+      int io = args(0).int_value ();
+      int rate = args(1).int_value ();
+      int bits = args(2).int_value ();
+      int chans = args(3).int_value ();
+
+      for (int i = 0; i < num_devices; i++)
+        {
+          PaStreamParameters stream_parameters;
+          stream_parameters.device = i;
+          stream_parameters.channelCount = chans;
+          PaSampleFormat format = bits_to_format (bits);
+
+          if (format != 0)
+            stream_parameters.sampleFormat = format;
+          else
+            {
+              error ("audiodevinfo: no such bits per sample format");
+              return retval;
+            }
+
+          const PaDeviceInfo *device_info = Pa_GetDeviceInfo (i);
+
+          if (! device_info)
+            {
+              warning ("Octave:invalid-audio-device",
+                       "invalid audio device ID = %d", i);
+              continue;
+            }
+
+          stream_parameters.suggestedLatency
+            = device_info->defaultLowInputLatency;
+
+          stream_parameters.hostApiSpecificStreamInfo = 0;
+
+          if (io == 0)
+            {
+              if (device_info->maxOutputChannels < chans)
+                continue;
+
+              err = Pa_IsFormatSupported (0, &stream_parameters, rate);
+
+              if (err == paFormatIsSupported)
+                {
+                  retval = i;
+                  return retval;
+                }
+            }
+          else if (io == 1)
+            {
+              if (device_info->maxInputChannels < chans)
+                continue;
+
+              err = Pa_IsFormatSupported (&stream_parameters, 0, rate);
+              if (err == paFormatIsSupported)
+                {
+                  retval = i;
+                  return retval;
+                }
+            }
+        }
+      retval = -1;
+    }
+  // Check if given device supports specified playback or recording modes.
+  else if (nargin == 5)
+    {
+      int io = args(0).int_value ();
+      int id = args(1).int_value ();
+      int rate = args(2).int_value ();
+      int bits = args(3).int_value ();
+      int chans = args(4).int_value ();
+      PaStreamParameters stream_parameters;
+      stream_parameters.device = id;
+      stream_parameters.channelCount = chans;
+      PaSampleFormat format = bits_to_format (bits);
+      if (format != 0)
+        stream_parameters.sampleFormat = format;
+      else
+        {
+          error ("audiodevinfo: no such bits per sample format");
+          return retval;
+        }
+
+      const PaDeviceInfo *device_info = Pa_GetDeviceInfo (id);
+
+      if (! device_info)
+        {
+          error ("invalid audio device ID = %d", id);
+          return retval;
+        }
+
+      stream_parameters.suggestedLatency
+        = device_info->defaultLowInputLatency;
+
+      stream_parameters.hostApiSpecificStreamInfo = 0;
+      if (io == 0)
+        {
+          if (device_info->maxOutputChannels < chans)
+            {
+              retval = 0;
+              return retval;
+            }
+          err = Pa_IsFormatSupported (0, &stream_parameters, rate);
+          if (err == paFormatIsSupported)
+            {
+              retval = 1;
+              return retval;
+            }
+        }
+      else if (io == 1)
+        {
+          if (device_info->maxInputChannels < chans)
+            {
+              retval = 0;
+              return retval;
+            }
+          err = Pa_IsFormatSupported (&stream_parameters, 0, rate);
+          if (err == paFormatIsSupported)
+            {
+              retval = 1;
+              return retval;
+            }
+        }
+      else
+        {
+          error ("audiodevinfo: please specify 0 for output and 1 for input devices");
+          return retval;
+        }
+      retval = 0;
+    }
+  else
+    {
+      error ("audiodevinfo: wrong number of arguments");
+      return retval;
+    }
+#else
+
+  error ("portaudio not found on your system and thus audio functionality is not present");
+
+#endif
+
+  return retval;
+}
+
+/*
+%!testif HAVE_PORTAUDIO
+%! devinfo = audiodevinfo;
+%! assert (rows (devinfo.input), 1);
+%! assert (rows (devinfo.output), 1);
+
+%!testif HAVE_PORTAUDIO
+%! devinfo = audiodevinfo;
+%! nout = audiodevinfo (0);
+%! nin = audiodevinfo (1);
+%! assert (columns (devinfo.output), nout);
+%! assert (columns (devinfo.input), nin);
+
+%!testif HAVE_PORTAUDIO
+%! devinfo = audiodevinfo;
+%! nout = audiodevinfo (0);
+%! nin = audiodevinfo (1);
+%! for i = 1:nout,
+%!   assert (devinfo.output(i).Name, audiodevinfo (0, devinfo.output(i).ID))
+%! endfor
+%! for i=1:nin,
+%!   assert (devinfo.input(i).Name, audiodevinfo (1, devinfo.input(i).ID))
+%! endfor
+
+%!testif HAVE_PORTAUDIO
+%! devinfo = audiodevinfo;
+%! nout = audiodevinfo (0);
+%! nin = audiodevinfo (1);
+%! for i = 1:nout,
+%!   assert (devinfo.output(i).ID, audiodevinfo (0, devinfo.output(i).Name))
+%! endfor
+%! for i = 1:nin,
+%!   assert (devinfo.input(i).ID, audiodevinfo (1, devinfo.input(i).Name))
+%! endfor
+*/
+
+#ifdef HAVE_PORTAUDIO
+
+enum audio_type { TYPE_INT8, TYPE_UINT8, TYPE_UINT16, TYPE_DOUBLE };
+
+class audioplayer : public octave_base_value
+{
+public:
+  audioplayer (void);
+  ~audioplayer (void);
+
+  // Overloaded base functions
+  double player_value (void) const { return 0; }
+  virtual double scalar_value (bool = false) const { return 0; }
+  void print (std::ostream& os, bool pr_as_read_syntax = false) const;
+  void print_raw (std::ostream& os, bool pr_as_read_syntax) const;
+
+  // Properties
+  bool is_constant (void) const { return true; }
+  bool is_defined (void) const { return true; }
+  bool print_as_scalar (void) const { return true; }
+
+  void init (void);
+  void init_fn (void);
+  void set_y (const octave_value& y);
+  void set_y (octave_function *fn);
+  void set_y (std::string fn);
+  Matrix& get_y (void);
+  RowVector get_left (void) const;
+  RowVector get_right (void) const;
+  void set_fs (int fs);
+  int get_fs (void);
+  void set_nbits (int nbits);
+  int get_nbits (void);
+  void set_id (int id);
+  int get_id (void);
+  int get_channels (void);
+  audio_type get_type (void);
+
+  void set_sample_number (unsigned int sample);
+  unsigned int get_sample_number (void);
+  unsigned int get_total_samples (void);
+  void set_end_sample (unsigned int sample);
+  unsigned int get_end_sample (void);
+  void reset_end_sample (void);
+  void set_tag (const charMatrix& tag);
+  charMatrix get_tag (void);
+  void set_userdata (const octave_value& userdata);
+  octave_value get_userdata (void);
+  PaStream *get_stream (void);
+
+  void playblocking (void);
+  void play (void);
+  void pause (void);
+  void resume (void);
+  void stop (void);
+  bool isplaying (void);
+
+  octave_function *octave_callback_function;
+
+private:
+  int id;
+  int fs;
+  int nbits;
+  int channels;
+  unsigned int sample_number;
+  unsigned int end_sample;
+  charMatrix tag;
+  Matrix y;
+  octave_value userdata;
+  RowVector left;
+  RowVector right;
+  PaStream *stream;
+  PaStreamParameters output_parameters;
+  audio_type type;
+
+  DECLARE_OV_TYPEID_FUNCTIONS_AND_DATA
+};
+
+static const unsigned int BUFFER_SIZE = 8192;
+
+DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA (audioplayer, "audioplayer", "audioplayer");
+
+static int
+octave_play_callback (const void *, void *output, unsigned long frames,
+                      const PaStreamCallbackTimeInfo *,
+                      PaStreamCallbackFlags, void *data)
+{
+  audioplayer *player = static_cast<audioplayer *> (data);
+
+  if (! player)
+    {
+      error ("audio player callback function called without player");
+      return paAbort;
+    }
+
+  octave_value_list retval = feval (player->octave_callback_function,
+                                    ovl (static_cast<double> (frames)), 1);
+
+  if (error_state || retval.length () < 2)
+    {
+      error ("audio player callback function failed");
+      return paAbort;
+    }
+
+  const Matrix sound = retval(0).matrix_value ();
+  int return_status = retval(1).int_value ();
+
+  if (error_state || frames != sound.rows ()
+      || sound.columns () < 1 || sound.columns () > 2)
+    {
+      error ("audio player callback function failed");
+      return paAbort;
+    }
+
+  // Don't multiply the audio data by scale_factor here.  Although it
+  // does move the operation outside of the loops below, it also causes
+  // a second copy of the data array to be made.
+
+  const ColumnVector sound_l = sound.column (0);
+  const ColumnVector sound_r = (sound.columns () == 1
+                                ? sound_l : sound.column (1));
+
+  const double *p_l = sound_l.data ();
+  const double *p_r = sound_r.data ();
+
+  switch (player->get_nbits ())
+    {
+    case 8:
+      {
+        static double scale_factor = std::pow (2.0, 7) - 1.0;
+
+        int8_t *buffer = static_cast<int8_t *> (output);
+
+        for (unsigned long i = 0; i < frames; i++)
+          {
+            buffer[2*i] = p_l[i] * scale_factor;
+            buffer[2*i+1] = p_r[i] * scale_factor;
+          }
+      }
+      break;
+
+    case 16:
+      {
+        static double scale_factor = std::pow (2.0, 15) - 1.0;
+
+        int16_t *buffer = static_cast<int16_t *> (output);
+
+        for (unsigned long i = 0; i < frames; i++)
+          {
+            buffer[2*i] = p_l[i] * scale_factor;
+            buffer[2*i+1] = p_r[i] * scale_factor;
+          }
+      }
+      break;
+
+    case 24:
+      {
+        static double scale_factor = std::pow (2.0, 23) - 1.0;
+
+        static int big_endian = oct_mach_info::words_big_endian ();
+
+        uint8_t *buffer = static_cast<uint8_t *> (output);
+
+        for (unsigned long i = 0; i < frames; i++)
+          {
+            int32_t sample_l = p_l[i];
+            int32_t sample_r = p_r[i];
+
+            sample_l &= 0x00ffffff;
+            sample_r &= 0x00ffffff;
+
+            // FIXME: Would a mask work better?
+            uint8_t *_sample_l = reinterpret_cast<uint8_t *> (&sample_l);
+            uint8_t *_sample_r = reinterpret_cast<uint8_t *> (&sample_r);
+
+            unsigned long offset = i * 6;
+
+            buffer[offset+0] = _sample_l[0+big_endian] * scale_factor;
+            buffer[offset+1] = _sample_l[1+big_endian] * scale_factor;
+            buffer[offset+2] = _sample_l[2+big_endian] * scale_factor;
+
+            buffer[offset+3] = _sample_r[0+big_endian] * scale_factor;
+            buffer[offset+4] = _sample_r[1+big_endian] * scale_factor;
+            buffer[offset+5] = _sample_r[2+big_endian] * scale_factor;
+          }
+      }
+      break;
+
+    default:
+      error ("invalid player bit depth in callback function");
+      break;
+    }
+
+  return return_status;
+}
+
+static int
+portaudio_play_callback (const void *, void *output, unsigned long frames,
+                         const PaStreamCallbackTimeInfo*,
+                         PaStreamCallbackFlags, void *data)
+{
+  audioplayer *player = static_cast<audioplayer *> (data);
+
+  if (! player)
+    {
+      error ("audio player callback function called without player");
+      return paAbort;
+    }
+
+  // Don't multiply the audio data by scale_factor here.  Although it
+  // would move the operation outside of the loops below, it also causes
+  // a second copy of the *entire* data array to be made when only a
+  // small portion (BUFFER_SIZE elements) is usually needed for this
+  // callback.
+
+  const RowVector sound_l = player->get_left ();
+  const RowVector sound_r = player->get_right ();
+
+  const double *pl = sound_l.data ();
+  const double *pr = sound_r.data ();
+
+  if (player->get_type () == TYPE_DOUBLE)
+    {
+      switch (player->get_nbits ())
+        {
+        case 8:
+          {
+            static double scale_factor = std::pow (2.0, 7) - 1.0;
+
+            int8_t *buffer = static_cast<int8_t *> (output);
+
+            for (unsigned long j = 0; j < frames; j++)
+              {
+                unsigned int sample_number = player->get_sample_number ();
+
+                if (sample_number >= player->get_end_sample ())
+                  return paComplete;
+
+                unsigned long offset = j * 2;
+
+                buffer[offset+0] = pl[sample_number] * scale_factor;
+                buffer[offset+1] = pr[sample_number] * scale_factor;
+
+                player->set_sample_number (sample_number + 1);
+              }
+          }
+          break;
+
+        case 16:
+          {
+            static double scale_factor = std::pow (2.0, 15) - 1.0;
+
+            int16_t *buffer = static_cast<int16_t *> (output);
+
+            for (unsigned long j = 0; j < frames; j++)
+              {
+                unsigned int sample_number = player->get_sample_number ();
+
+                if (sample_number >= player->get_end_sample ())
+                  return paComplete;
+
+                unsigned long offset = j * 2;
+
+                buffer[offset+0] = pl[sample_number] * scale_factor;
+                buffer[offset+1] = pr[sample_number] * scale_factor;
+
+                player->set_sample_number (sample_number + 1);
+              }
+          }
+          break;
+
+        case 24:
+          {
+            static double scale_factor = std::pow (2.0, 23) - 1.0;
+
+            static int big_endian = oct_mach_info::words_big_endian ();
+
+            uint8_t *buffer = static_cast<uint8_t *> (output);
+
+            for (unsigned long j = 0; j < frames; j++)
+              {
+                unsigned int sample_number = player->get_sample_number ();
+
+                if (sample_number >= player->get_end_sample ())
+                  return paComplete;
+
+                int32_t sample_l = pl[sample_number] * scale_factor;
+                int32_t sample_r = pr[sample_number] * scale_factor;
+
+                sample_l &= 0x00ffffff;
+                sample_r &= 0x00ffffff;
+
+                // FIXME: Would a mask work better?
+                uint8_t *_sample_l = reinterpret_cast<uint8_t *> (&sample_l);
+                uint8_t *_sample_r = reinterpret_cast<uint8_t *> (&sample_r);
+
+                unsigned long offset = j * 6;
+
+                buffer[offset+0] = _sample_l[0+big_endian];
+                buffer[offset+1] = _sample_l[1+big_endian];
+                buffer[offset+2] = _sample_l[2+big_endian];
+
+                buffer[offset+3] = _sample_r[0+big_endian];
+                buffer[offset+4] = _sample_r[1+big_endian];
+                buffer[offset+5] = _sample_r[2+big_endian];
+
+                player->set_sample_number (sample_number + 1);
+              }
+          }
+          break;
+
+        default:
+          error ("invalid player bit depth in callback function");
+          break;
+        }
+    }
+  else if (player->get_type () == TYPE_INT8)
+    {
+      int8_t *buffer = static_cast<int8_t *> (output);
+
+      for (unsigned long j = 0; j < frames; j++)
+        {
+          unsigned int sample_number = player->get_sample_number ();
+
+          if (sample_number >= player->get_end_sample ())
+            return paComplete;
+
+          unsigned long offset = j * 2;
+
+          buffer[offset+0] = pl[sample_number];
+          buffer[offset+1] = pr[sample_number];
+
+          player->set_sample_number (sample_number + 1);
+        }
+    }
+  else if (player->get_type () == TYPE_UINT8)
+    {
+      uint8_t *buffer = static_cast<uint8_t *> (output);
+
+      for (unsigned long j = 0; j < frames; j++)
+        {
+          unsigned int sample_number = player->get_sample_number ();
+
+          if (sample_number >= player->get_end_sample ())
+            return paComplete;
+
+          unsigned long offset = j * 2;
+
+          buffer[offset+0] = pl[sample_number];
+          buffer[offset+1] = pr[sample_number];
+
+          player->set_sample_number (sample_number + 1);
+        }
+    }
+  else if (player->get_type () == TYPE_UINT16)
+    {
+      int16_t *buffer = static_cast<int16_t *> (output);
+
+      for (unsigned long j = 0; j < frames; j++)
+        {
+          unsigned int sample_number = player->get_sample_number ();
+
+          if (sample_number >= player->get_end_sample ())
+            return paComplete;
+
+          unsigned long offset = j * 2;
+
+          buffer[offset+0] = pl[sample_number];
+          buffer[offset+1] = pr[sample_number];
+
+          player->set_sample_number (sample_number + 1);
+        }
+    }
+
+  return paContinue;
+}
+
+audioplayer::audioplayer (void)
+  : octave_callback_function (0),
+    id (-1), fs (0), nbits (16), channels (0), sample_number (0),
+    end_sample (-1), tag (""), y (), userdata (Matrix ()),
+    left (), right (), stream (0), output_parameters (), type ()
+{ }
+
+audioplayer::~audioplayer (void)
+{
+  if (isplaying ())
+    {
+      warning ("Octave:audio-interrupt",
+               "interrupting playing audioplayer");
+      stop ();
+    }
+}
+
+void
+audioplayer::print (std::ostream& os, bool pr_as_read_syntax) const
+{
+  print_raw (os, pr_as_read_syntax);
+  newline (os);
+}
+
+void
+audioplayer::print_raw (std::ostream& os, bool) const
+{
+  os << 0;
+}
+
+void
+audioplayer::init_fn (void)
+{
+  if (Pa_Initialize () != paNoError)
+    {
+      error ("audioplayer: initialization error!");
+      return;
+    }
+
+  if (Pa_GetDeviceCount () < 1)
+    {
+      error ("audioplayer: no audio devices found or available!");
+      return;
+    }
+
+  int device = get_id ();
+
+  if (device == -1)
+    device = Pa_GetDefaultOutputDevice ();
+
+  output_parameters.device = device;
+  output_parameters.channelCount = 2;
+  output_parameters.sampleFormat = bits_to_format (get_nbits ());
+
+  const PaDeviceInfo *device_info = Pa_GetDeviceInfo (device);
+
+  if (! device_info)
+    warning ("Octave:invalid-default-audio-device",
+             "invalid default audio device ID = %d", device);
+
+  output_parameters.suggestedLatency
+    = device_info ? device_info->defaultHighOutputLatency : -1;
+
+  output_parameters.hostApiSpecificStreamInfo = 0;
+}
+
+void
+audioplayer::init (void)
+{
+  // Both of these variables are unused.  Should they be
+  // eliminated or is something not yet implemented?
+  //
+  // int channels = y.rows ();
+  // RowVector *sound_l = get_left ();
+
+  if (Pa_Initialize () != paNoError)
+    {
+      error ("audioplayer: initialization error!");
+      return;
+    }
+
+  if (Pa_GetDeviceCount () < 1)
+    {
+      error ("audioplayer: no audio devices found or available!");
+      return;
+    }
+
+  int device = get_id ();
+
+  if (device == -1)
+    device = Pa_GetDefaultOutputDevice ();
+
+  output_parameters.device = device;
+  output_parameters.channelCount = 2;
+
+  if (type == TYPE_DOUBLE)
+    output_parameters.sampleFormat = bits_to_format (get_nbits ());
+  else if (type == TYPE_INT8)
+    output_parameters.sampleFormat = paInt8;
+  else if (type == TYPE_UINT8)
+    output_parameters.sampleFormat = paUInt8;
+  else if (type == TYPE_UINT16)
+    output_parameters.sampleFormat = paInt16;
+
+  const PaDeviceInfo *device_info = Pa_GetDeviceInfo (device);
+
+  if (! device_info)
+    warning ("Octave:invalid-default-audio-device",
+             "invalid default audio device ID = %d", device);
+
+  output_parameters.suggestedLatency
+    = device_info ? device_info->defaultHighOutputLatency : -1;
+
+  output_parameters.hostApiSpecificStreamInfo = 0;
+}
+
+void
+audioplayer::set_y (const octave_value& y_arg)
+{
+  if (y_arg.is_int8_type ())
+    type = TYPE_INT8;
+  else if (y_arg.is_uint8_type ())
+    type = TYPE_UINT8;
+  else if (y_arg.is_int16_type ())
+    type = TYPE_UINT16;
+  else
+    type = TYPE_DOUBLE;
+
+  y = y_arg.matrix_value ();
+
+  if (y.rows () > 2)
+    y = y.transpose ();
+
+  channels = y.rows ();
+  left = y.row (0);
+
+  if (channels == 2)
+    right = y.row (1);
+
+  reset_end_sample ();
+}
+
+void
+audioplayer::set_y (octave_function *fn)
+{
+  octave_callback_function = fn;
+  channels = 2;
+  reset_end_sample ();
+}
+
+Matrix&
+audioplayer::get_y (void)
+{
+  return y;
+}
+
+RowVector
+audioplayer::get_left (void) const
+{
+  return left;
+}
+
+RowVector
+audioplayer::get_right (void) const
+{
+  return channels == 1 ? left : right;
+}
+
+void
+audioplayer::set_fs (int fs_arg)
+{
+  fs = fs_arg;
+}
+
+int
+audioplayer::get_fs (void)
+{
+  return fs;
+}
+
+void
+audioplayer::set_nbits (int nbits_arg)
+{
+  nbits = nbits_arg;
+}
+
+int
+audioplayer::get_nbits (void)
+{
+  return nbits;
+}
+
+void
+audioplayer::set_id (int id_arg)
+{
+  id = id_arg;
+}
+
+int
+audioplayer::get_id (void)
+{
+  return id;
+}
+
+int
+audioplayer::get_channels (void)
+{
+  return channels;
+}
+
+audio_type
+audioplayer::get_type (void)
+{
+  return type;
+}
+
+void
+audioplayer::set_sample_number (unsigned int sample_number_arg)
+{
+  sample_number = sample_number_arg;
+}
+
+unsigned int
+audioplayer::get_sample_number (void)
+{
+  return sample_number;
+}
+
+unsigned int
+audioplayer::get_total_samples (void)
+{
+  return left.length ();
+}
+
+void
+audioplayer::set_end_sample (unsigned int end_sample_arg)
+{
+  end_sample = end_sample_arg;
+}
+
+unsigned int
+audioplayer::get_end_sample (void)
+{
+  return end_sample;
+}
+
+void
+audioplayer::reset_end_sample (void)
+{
+  set_end_sample (left.length ());
+}
+
+void
+audioplayer::set_tag (const charMatrix& tag_arg)
+{
+  tag = tag_arg;
+}
+
+charMatrix
+audioplayer::get_tag (void)
+{
+  return tag;
+}
+
+void
+audioplayer::set_userdata (const octave_value& userdata_arg)
+{
+  userdata = userdata_arg;
+}
+
+octave_value
+audioplayer::get_userdata (void)
+{
+  return userdata;
+}
+
+void
+audioplayer::playblocking (void)
+{
+  if (get_stream ())
+    stop ();
+
+  PaError err;
+  uint32_t buffer[BUFFER_SIZE * 2];
+  err = Pa_OpenStream (&stream, 0, &(output_parameters), get_fs (),
+                       BUFFER_SIZE, paClipOff, 0, 0);
+  if (err != paNoError)
+    {
+      error ("audioplayer: unable to open audio playback stream");
+      return;
+    }
+
+  err = Pa_StartStream (stream);
+  if (err != paNoError)
+    {
+      error ("audioplayer: unable to start start audio playback stream");
+      return;
+    }
+
+  unsigned int start, end;
+  start = get_sample_number ();
+  end = get_end_sample ();
+  for (unsigned int i = start; i < end; i += BUFFER_SIZE)
+    {
+      if (octave_callback_function != 0)
+        octave_play_callback (0, buffer, BUFFER_SIZE, 0, 0, this);
+      else
+        portaudio_play_callback (0, buffer, BUFFER_SIZE, 0, 0, this);
+
+      err = Pa_WriteStream (stream, buffer, BUFFER_SIZE);
+    }
+
+  err = Pa_StopStream (stream);
+  if (err != paNoError)
+    {
+      error ("audioplayer: failed to stop audio playback stream");
+      return;
+    }
+
+  err = Pa_CloseStream (stream);
+  if (err != paNoError)
+    {
+      error ("audioplayer: failed to close audio playback stream");
+      return;
+    }
+
+  stream = 0;
+  set_sample_number (0);
+  reset_end_sample ();
+}
+
+void
+audioplayer::play (void)
+{
+  if (get_stream ())
+    stop ();
+
+  PaError err;
+  if (octave_callback_function != 0)
+    err = Pa_OpenStream (&stream, 0, &(output_parameters),
+                         get_fs (), BUFFER_SIZE, paClipOff,
+                         octave_play_callback, this);
+  else
+    err = Pa_OpenStream (&stream, 0, &(output_parameters),
+                         get_fs (), BUFFER_SIZE, paClipOff,
+                         portaudio_play_callback, this);
+
+  if (err != paNoError)
+    {
+      error ("audioplayer: failed to open audio playback stream");
+      return;
+    }
+
+  err = Pa_StartStream (stream);
+  if (err != paNoError)
+    {
+      error ("audioplayer: failed to start audio playback stream");
+      return;
+    }
+}
+
+void
+audioplayer::pause (void)
+{
+  if (get_stream () == 0)
+    return;
+
+  PaError err;
+  err = Pa_StopStream (stream);
+  if (err != paNoError)
+    {
+      error ("audiorecorder: failed to stop audio recording stream");
+      return;
+    }
+}
+
+void
+audioplayer::resume (void)
+{
+  if (get_stream () == 0)
+    return;
+
+  PaError err;
+  err = Pa_StartStream (stream);
+  if (err != paNoError)
+    {
+      error ("audiorecorder: failed to start audio recording stream");
+      return;
+    }
+}
+
+PaStream *
+audioplayer::get_stream (void)
+{
+  return stream;
+}
+
+void
+audioplayer::stop (void)
+{
+  if (get_stream () == 0)
+    return;
+
+  PaError err;
+  set_sample_number (0);
+  reset_end_sample ();
+  if (not Pa_IsStreamStopped (get_stream ()))
+    {
+      err = Pa_AbortStream (get_stream ());
+      if (err != paNoError)
+        {
+          error ("audioplayer: failed to stop audio playback stream");
+          return;
+        }
+    }
+
+  err = Pa_CloseStream (get_stream ());
+  if (err != paNoError)
+    {
+      error ("audioplayer: failed to close audio playback stream");
+      return;
+    }
+
+  stream = 0;
+}
+
+bool
+audioplayer::isplaying (void)
+{
+  if (get_stream () == 0)
+    return false;
+
+  PaError err;
+  err = Pa_IsStreamActive (stream);
+  if (err != 0 && err != 1)
+    {
+      error ("audiorecorder: checking stream activity status failed");
+      return false;
+    }
+
+  return (err == 1);
+}
+
+class audiorecorder : public octave_base_value
+{
+public:
+  audiorecorder (void);
+  ~audiorecorder (void);
+
+  // Overloaded base functions
+  double player_value (void) const { return 0; }
+  virtual double scalar_value (bool = false) const { return 0; }
+  void print (std::ostream& os, bool pr_as_read_syntax = false) const;
+  void print_raw (std::ostream& os, bool pr_as_read_syntax) const;
+
+  // Properties
+  bool is_constant (void) const { return true; }
+  bool is_defined (void) const { return true; }
+  bool print_as_scalar (void) const { return true; }
+
+  void init (void);
+  void set_fs (int fs);
+  int get_fs (void);
+  void set_nbits (int nbits);
+  int get_nbits (void);
+  void set_id (int id);
+  int get_id (void);
+  void set_channels (int channels);
+  int get_channels (void);
+  audio_type get_type (void);
+
+  void set_sample_number (unsigned int sample);
+  unsigned int get_sample_number (void);
+  unsigned int get_total_samples (void);
+  void set_end_sample (unsigned int sample);
+  unsigned int get_end_sample (void);
+  void reset_end_sample (void);
+  void set_tag (const charMatrix& tag);
+  charMatrix get_tag (void);
+  void set_userdata (const octave_value& userdata);
+  octave_value get_userdata (void);
+  PaStream *get_stream (void);
+
+  octave_value getaudiodata (void);
+  audioplayer *getplayer (void);
+  bool isrecording (void);
+  audioplayer play (void);
+  void record (void);
+  void recordblocking (float seconds);
+  void pause (void);
+  void resume (void);
+  void stop (void);
+  void append (float sample_l, float sample_r);
+
+  octave_function *octave_callback_function;
+
+private:
+  int id;
+  int fs;
+  int nbits;
+  int channels;
+  unsigned int sample_number;
+  unsigned int end_sample;
+  charMatrix tag;
+  Matrix y;
+  octave_value userdata;
+  std::vector<float> left;
+  std::vector<float> right;
+  PaStream *stream;
+  PaStreamParameters input_parameters;
+  audio_type type;
+
+  DECLARE_OV_TYPEID_FUNCTIONS_AND_DATA
+};
+
+DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA (audiorecorder, "audiorecorder", "audiorecorder");
+
+static int
+octave_record_callback (const void *input, void *, unsigned long frames,
+                        const PaStreamCallbackTimeInfo *,
+                        PaStreamCallbackFlags, void *data)
+{
+  audiorecorder *recorder = static_cast<audiorecorder *> (data);
+
+  if (! recorder)
+    {
+      error ("audio recorder callback function called without player");
+      return paAbort;
+    }
+
+  int channels = recorder->get_channels ();
+
+  Matrix sound (frames, 2);
+  sound.resize (frames, 2);
+
+  if (recorder->get_nbits () == 8)
+    {
+      static double scale_factor = std::pow (2.0, 7) - 1.0;
+
+      const int8_t *input8 = static_cast<const int8_t *> (input);
+
+      for (unsigned long i = 0; i < frames; i++)
+        {
+          float sample_l = input8[i*channels] / scale_factor;
+          float sample_r = input8[i*channels + (channels - 1)] / scale_factor;
+
+          sound(i,0) = sample_l;
+          sound(i,1) = sample_r;
+        }
+    }
+  else if (recorder->get_nbits () == 16)
+    {
+      static double scale_factor = std::pow (2.0, 15) - 1.0;
+
+      const int16_t *input16 = static_cast<const int16_t *> (input);
+
+      for (unsigned long i = 0; i < frames; i++)
+        {
+          float sample_l = input16[i*channels] / scale_factor;
+          float sample_r = input16[i*channels + (channels - 1)] / scale_factor;
+
+          sound(i,0) = sample_l;
+          sound(i,1) = sample_r;
+        }
+    }
+  else if (recorder->get_nbits () == 24)
+    {
+      static double scale_factor = std::pow (2.0, 23);
+
+      // FIXME: Is there a better way?
+      const uint8_t *input24 = static_cast<const uint8_t *> (input);
+
+      int32_t sample_l32 = 0, sample_r32 = 0;
+
+      uint8_t *sample_l = reinterpret_cast<uint8_t *> (&sample_l32);
+      uint8_t *sample_r = reinterpret_cast<uint8_t *> (&sample_r32);
+
+      for (unsigned long i = 0; i < frames; i++)
+        {
+          for (int j = 0; j < 3; j++)
+            {
+              sample_l[j] = input24[i*channels*3 + j];
+              sample_r[j] = input24[i*channels*3 + (channels - 1)*3 + j];
+            }
+
+          if (sample_l32 & 0x00800000)
+            sample_l32 |= 0xff000000;
+
+          if (sample_r32 & 0x00800000)
+            sample_r32 |= 0xff000000;
+
+          sound(i,0) = sample_l32 / scale_factor;
+          sound(i,1) = sample_r32 / scale_factor;
+        }
+    }
+
+  octave_value_list retval
+    = feval (recorder->octave_callback_function, ovl (sound), 1);
+
+  return retval(0).int_value ();
+}
+
+static int
+portaudio_record_callback (const void *input, void *, unsigned long frames,
+                           const PaStreamCallbackTimeInfo *,
+                           PaStreamCallbackFlags, void *data)
+{
+  audiorecorder *recorder = static_cast<audiorecorder *> (data);
+
+  if (! recorder)
+    {
+      error ("audio recorder callback function called without player");
+      return paAbort;
+    }
+
+  int channels = recorder->get_channels ();
+
+  if (recorder->get_nbits () == 8)
+    {
+      static float scale_factor = std::pow (2.0f, 7) - 1.0f;
+
+      const int8_t *input8 = static_cast<const int8_t *> (input);
+
+      for (unsigned long i = 0; i < frames; i++)
+        {
+          float sample_l = input8[i*channels] / scale_factor;
+          float sample_r = input8[i*channels + (channels - 1)] / scale_factor;
+
+          recorder->append (sample_l, sample_r);
+        }
+    }
+  else if (recorder->get_nbits () == 16)
+    {
+      static float scale_factor = std::pow (2.0f, 15) - 1.0f;
+
+      const int16_t *input16 = static_cast<const int16_t *> (input);
+
+      for (unsigned long i = 0; i < frames; i++)
+        {
+          float sample_l = input16[i*channels] / scale_factor;
+          float sample_r = input16[i*channels + (channels - 1)] / scale_factor;
+
+          recorder->append (sample_l, sample_r);
+        }
+    }
+  else if (recorder->get_nbits () == 24)
+    {
+      static float scale_factor = std::pow (2.0f, 23);
+
+      // FIXME: Is there a better way?
+      const uint8_t *input24 = static_cast<const uint8_t *> (input);
+
+      int32_t sample_l32 = 0, sample_r32 = 0;
+
+      uint8_t *sample_l = reinterpret_cast<uint8_t *> (&sample_l32);
+      uint8_t *sample_r = reinterpret_cast<uint8_t *> (&sample_r32);
+
+      for (unsigned long i = 0; i < frames; i++)
+        {
+          for (int j = 0; j < 3; j++)
+            {
+              sample_l[j] = input24[i*channels*3 + j];
+              sample_r[j] = input24[i*channels*3 + (channels - 1)*3 + j];
+            }
+
+          if (sample_l32 & 0x00800000)
+            sample_l32 |= 0xff000000;
+
+          if (sample_r32 & 0x00800000)
+            sample_r32 |= 0xff000000;
+
+          recorder->append (sample_l32 / scale_factor,
+                            sample_r32 / scale_factor);
+        }
+    }
+
+  if (recorder->get_sample_number () > recorder->get_end_sample ())
+    return paComplete;
+
+  return paContinue;
+}
+
+audiorecorder::audiorecorder (void)
+  : octave_callback_function (0),
+    id (-1), fs (44100), nbits (16), channels (2), sample_number (0),
+    end_sample (-1), tag (""), y (), userdata (Matrix ()),
+    left (), right (), stream (0), input_parameters (), type ()
+{ }
+
+audiorecorder::~audiorecorder (void)
+{
+  if (isrecording ())
+    {
+      warning ("Octave:audio-interrupt",
+               "interrupting recording audiorecorder");
+      stop ();
+    }
+}
+
+void
+audiorecorder::print (std::ostream& os, bool pr_as_read_syntax) const
+{
+  print_raw (os, pr_as_read_syntax);
+  newline (os);
+}
+
+void
+audiorecorder::print_raw (std::ostream& os, bool) const
+{
+  os << 0;
+}
+
+void
+audiorecorder::init (void)
+{
+  if (Pa_Initialize () != paNoError)
+    {
+      error ("audiorecorder: initialization error!");
+      return;
+    }
+
+  if (Pa_GetDeviceCount () < 1)
+    {
+      error ("audiorecorder: no audio devices found or available!");
+      return;
+    }
+
+  int device = get_id ();
+
+  if (device == -1)
+    device = Pa_GetDefaultInputDevice ();
+
+  input_parameters.device = device;
+  input_parameters.channelCount = get_channels ();
+  input_parameters.sampleFormat = bits_to_format (get_nbits ());
+
+  const PaDeviceInfo *device_info = Pa_GetDeviceInfo (device);
+
+  if (! device_info)
+    warning ("Octave:invalid-default-audio-device",
+             "invalid default audio device ID = %d", device);
+
+  input_parameters.suggestedLatency
+    = device_info ? device_info->defaultHighInputLatency : -1;
+
+  input_parameters.hostApiSpecificStreamInfo = 0;
+}
+
+void
+audiorecorder::set_fs (int fs_arg)
+{
+  fs = fs_arg;
+}
+
+int
+audiorecorder::get_fs (void)
+{
+  return fs;
+}
+
+void
+audiorecorder::set_nbits (int nbits_arg)
+{
+  nbits = nbits_arg;
+}
+
+int
+audiorecorder::get_nbits (void)
+{
+  return nbits;
+}
+
+void
+audiorecorder::set_id (int id_arg)
+{
+  id = id_arg;
+}
+
+int
+audiorecorder::get_id (void)
+{
+  return id;
+}
+
+void
+audiorecorder::set_channels (int channels_arg)
+{
+  assert (channels_arg == 1 || channels_arg == 2);
+  channels = channels_arg;
+}
+
+int
+audiorecorder::get_channels (void)
+{
+  return channels;
+}
+
+audio_type
+audiorecorder::get_type (void)
+{
+  return type;
+}
+
+void
+audiorecorder::set_sample_number (unsigned int sample_number_arg)
+{
+  sample_number = sample_number_arg;
+}
+
+unsigned int
+audiorecorder::get_sample_number (void)
+{
+  return sample_number;
+}
+
+unsigned int
+audiorecorder::get_total_samples (void)
+{
+  return left.size ();
+}
+
+void
+audiorecorder::set_end_sample (unsigned int end_sample_arg)
+{
+  end_sample = end_sample_arg;
+}
+
+unsigned int
+audiorecorder::get_end_sample (void)
+{
+  return end_sample;
+}
+
+void
+audiorecorder::reset_end_sample (void)
+{
+  set_end_sample (left.size ());
+}
+
+void
+audiorecorder::set_tag (const charMatrix& tag_arg)
+{
+  tag = tag_arg;
+}
+
+charMatrix
+audiorecorder::get_tag (void)
+{
+  return tag;
+}
+
+void
+audiorecorder::set_userdata (const octave_value& userdata_arg)
+{
+  userdata = userdata_arg;
+}
+
+octave_value
+audiorecorder::get_userdata (void)
+{
+  return userdata;
+}
+
+octave_value
+audiorecorder::getaudiodata (void)
+{
+  Matrix audio (2, left.size ());
+
+  for (unsigned int i = 0; i < left.size (); i++)
+    {
+      audio(0,i) = left[i];
+      audio(1,i) = right[i];
+    }
+
+  return audio;
+}
+
+audioplayer *
+audiorecorder::getplayer (void)
+{
+  audioplayer *player = new audioplayer ();
+
+  player->set_y (getaudiodata ());
+  player->set_fs (get_fs ());
+  player->set_nbits (get_nbits ());
+  player->init ();
+
+  return player;
+}
+
+bool
+audiorecorder::isrecording (void)
+{
+  if (get_stream () == 0)
+    return false;
+
+  PaError err;
+  err = Pa_IsStreamActive (stream);
+  if (err != 0 && err != 1)
+    {
+      error ("audiorecorder: checking stream activity status failed");
+      return false;
+    }
+
+  return (err == 1);
+}
+
+void
+audiorecorder::record (void)
+{
+  if (get_stream ())
+    stop ();
+
+  left.clear ();
+  right.clear ();
+  PaError err;
+  if (octave_callback_function != 0)
+    {
+      err = Pa_OpenStream (&stream, &(input_parameters), 0,
+                           get_fs (), BUFFER_SIZE, paClipOff,
+                           octave_record_callback, this);
+    }
+  else
+    {
+      err = Pa_OpenStream (&stream, &(input_parameters), 0,
+                           get_fs (), BUFFER_SIZE, paClipOff,
+                           portaudio_record_callback, this);
+    }
+  if (err != paNoError)
+    {
+      error ("audiorecorder: unable to open audio recording stream");
+      return;
+    }
+  err = Pa_StartStream (stream);
+  if (err != paNoError)
+    {
+      error ("audiorecorder: unable to start audio recording stream");
+      return;
+    }
+}
+
+void
+audiorecorder::recordblocking (float seconds)
+{
+  if (get_stream ())
+    stop ();
+
+  left.clear ();
+  right.clear ();
+
+  PaError err;
+  err = Pa_OpenStream (&stream, &(input_parameters), 0,
+                       get_fs (), BUFFER_SIZE, paClipOff, 0, this);
+  if (err != paNoError)
+    {
+      error ("audiorecorder: unable to open audio recording stream");
+      return;
+    }
+
+  err = Pa_StartStream (stream);
+  if (err != paNoError)
+    {
+      error ("audiorecorder: unable to start audio recording stream");
+      return;
+    }
+
+  unsigned int frames = seconds * get_fs ();
+  uint8_t buffer[BUFFER_SIZE * 2 * 3];
+  for (unsigned long i = 0; i < frames / BUFFER_SIZE; i++)
+    {
+      Pa_ReadStream (get_stream (), buffer, BUFFER_SIZE);
+      if (octave_callback_function != 0)
+        octave_record_callback (buffer, 0, BUFFER_SIZE, 0, 0, this);
+      else
+        portaudio_record_callback (buffer, 0, BUFFER_SIZE, 0, 0, this);
+    }
+}
+
+void
+audiorecorder::pause (void)
+{
+  if (get_stream () == 0)
+    return;
+
+  PaError err;
+  err = Pa_StopStream (stream);
+  if (err != paNoError)
+    {
+      error ("audiorecorder: unable to stop audio recording stream");
+      return;
+    }
+}
+
+void
+audiorecorder::resume (void)
+{
+  if (get_stream () == 0)
+    return;
+
+  PaError err;
+  err = Pa_StartStream (stream);
+  if (err != paNoError)
+    {
+      error ("audiorecorder: unable to start audio recording stream");
+      return;
+    }
+}
+
+void
+audiorecorder::stop (void)
+{
+  if (get_stream () == 0)
+    return;
+
+  PaError err;
+  if (not Pa_IsStreamStopped (get_stream ()))
+    {
+      err = Pa_AbortStream (get_stream ());
+      if (err != paNoError)
+        {
+          error ("audioplayer: unable to stop audio playback stream");
+          return;
+        }
+    }
+
+  err = Pa_CloseStream (stream);
+  if (err != paNoError)
+    {
+      error ("audiorecorder: unable to close audio recording stream");
+      return;
+    }
+
+  set_sample_number (0);
+  reset_end_sample ();
+  stream = 0;
+}
+
+void
+audiorecorder::append (float sample_l, float sample_r)
+{
+  left.push_back (sample_l);
+  right.push_back (sample_r);
+  set_sample_number (get_sample_number () + 1);
+}
+
+PaStream *
+audiorecorder::get_stream (void)
+{
+  return stream;
+}
+
+#endif
+
+DEFUN_DLD (__recorder_audiorecorder__, args, ,
+           "-*- texinfo -*-\n\
+@deftypefn  {Loadable Function} {@var{recorder} =} __recorder_audiorecorder__ (@var{fs}, @var{nbits}, @var{channels})\n\
+@deftypefnx {Loadable Function} {@var{recorder} =} __recorder_audiorecorder__ (@var{fs}, @var{nbits}, @var{channels}, @var{id})\n\
+@deftypefnx {Loadable Function} {@var{recorder} =} __recorder_audiorecorder__ (@var{fcn}, @dots{})\n\
+Undocumented internal function.\n\
+@end deftypefn")
+{
+  octave_value retval;
+
+#ifdef HAVE_PORTAUDIO
+
+  int nargin = args.length ();
+
+  audiorecorder* recorder = new audiorecorder ();
+
+  int offset = 0;
+
+  if (nargin > 0)
+    {
+      bool is_function = (args(0).is_string () || args(0).is_function_handle ()
+                          || args(0).is_inline_function ());
+
+      if (is_function)
+        {
+          error ("audioplayer: callbacks not yet implemented");
+          return retval;
+
+          // recorder->octave_callback_function = args(0).function_value ();
+          // offset = 1;
+        }
+    }
+
+  switch (nargin - offset)
+    {
+    case 3:
+      recorder->set_fs (args(0 + offset).int_value ());
+      recorder->set_nbits (args(1 + offset).int_value ());
+      recorder->set_channels (args(2 + offset).int_value ());
+      break;
+
+    case 4:
+      recorder->set_fs (args(0 + offset).int_value ());
+      recorder->set_nbits (args(1 + offset).int_value ());
+      recorder->set_channels (args(2 + offset).int_value ());
+      recorder->set_id (args(3 + offset).int_value ());
+      break;
+    }
+
+  recorder->init ();
+
+  retval = recorder;
+
+#else
+
+  error ("portaudio not found on your system and thus audio functionality is not present");
+
+#endif
+
+  return retval;
+}
+
+#ifdef HAVE_PORTAUDIO
+
+static audiorecorder *
+get_recorder (const octave_value& ov)
+{
+  const octave_base_value& rep = ov.get_rep ();
+
+  octave_base_value *ncrep = const_cast<octave_base_value *> (&rep);
+
+  return dynamic_cast<audiorecorder *> (ncrep);
+}
+
+#endif
+
+DEFUN_DLD (__recorder_getaudiodata__, args, ,
+           "-*- texinfo -*-\n\
+@deftypefn {Loadable Function} {@var{data}} __recorder_getaudiodata__ (@var{recorder})\n\
+Undocumented internal function.\n\
+@end deftypefn")
+{
+  octave_value retval;
+
+#ifdef HAVE_PORTAUDIO
+
+  audiorecorder *recorder = get_recorder (args(0));
+
+  if (! recorder)
+    {
+      print_usage ();
+      return retval;
+    }
+
+  retval = recorder->getaudiodata ();
+
+#else
+
+  error ("portaudio not found on your system and thus audio functionality is not present");
+
+#endif
+
+  return retval;
+}
+
+DEFUN_DLD (__recorder_get_channels__, args, ,
+           "-*- texinfo -*-\n\
+@deftypefn {Loadable Function} {@var{n} =} __recorder_get_channels__ (@var{recorder})\n\
+Undocumented internal function.\n\
+@end deftypefn")
+{
+  octave_value retval;
+
+#ifdef HAVE_PORTAUDIO
+
+  if (args.length () == 1)
+    {
+      audiorecorder *recorder = get_recorder (args(0));
+
+      if (! recorder)
+        {
+          print_usage ();
+          return retval;
+        }
+
+      retval = recorder->get_channels ();
+    }
+
+#else
+
+  error ("portaudio not found on your system and thus audio functionality is not present");
+
+#endif
+
+  return retval;
+}
+
+DEFUN_DLD (__recorder_get_fs__, args, ,
+           "-*- texinfo -*-\n\
+@deftypefn {Loadable Function} {@var{fs} =} __recorder_get_fs__ (@var{recorder})\n\
+Undocumented internal function.\n\
+@end deftypefn")
+{
+  octave_value retval;
+
+#ifdef HAVE_PORTAUDIO
+
+  if (args.length () == 1)
+    {
+      audiorecorder *recorder = get_recorder (args(0));
+
+      if (! recorder)
+        {
+          print_usage ();
+          return retval;
+        }
+
+      retval = recorder->get_fs ();
+    }
+
+#else
+
+  error ("portaudio not found on your system and thus audio functionality is not present");
+
+#endif
+
+  return retval;
+}
+
+DEFUN_DLD (__recorder_get_id__, args, ,
+           "-*- texinfo -*-\n\
+@deftypefn {Loadable Function} {@var{id} =} __recorder_get_id__ (@var{recorder})\n\
+Undocumented internal function.\n\
+@end deftypefn")
+{
+  octave_value retval;
+
+#ifdef HAVE_PORTAUDIO
+
+  if (args.length () == 1)
+    {
+      audiorecorder *recorder = get_recorder (args(0));
+
+      if (! recorder)
+        {
+          print_usage ();
+          return retval;
+        }
+
+      retval = recorder->get_id ();
+    }
+
+#else
+
+  error ("portaudio not found on your system and thus audio functionality is not present");
+
+#endif
+
+  return retval;
+}
+
+DEFUN_DLD (__recorder_get_nbits__, args, ,
+           "-*- texinfo -*-\n\
+@deftypefn {Loadable Function} {@var{nbits} =} __recorder_get_nbits__ (@var{recorder})\n\
+Undocumented internal function.\n\
+@end deftypefn")
+{
+  octave_value retval;
+
+#ifdef HAVE_PORTAUDIO
+
+  if (args.length () == 1)
+    {
+      audiorecorder *recorder = get_recorder (args(0));
+
+      if (! recorder)
+        {
+          print_usage ();
+          return retval;
+        }
+
+      retval = recorder->get_nbits ();
+    }
+
+#else
+
+  error ("portaudio not found on your system and thus audio functionality is not present");
+
+#endif
+
+  return retval;
+}
+
+DEFUN_DLD (__recorder_get_sample_number__, args, ,
+           "-*- texinfo -*-\n\
+@deftypefn {Loadable Function} {@var{n} =} __recorder_get_sample_number__ (@var{recorder})\n\
+Undocumented internal function.\n\
+@end deftypefn")
+{
+  octave_value retval;
+
+#ifdef HAVE_PORTAUDIO
+
+  if (args.length () == 1)
+    {
+      audiorecorder *recorder = get_recorder (args(0));
+
+      if (! recorder)
+        {
+          print_usage ();
+          return retval;
+        }
+
+      retval = recorder->get_sample_number ();
+    }
+
+#else
+
+  error ("portaudio not found on your system and thus audio functionality is not present");
+
+#endif
+
+  return retval;
+}
+
+DEFUN_DLD (__recorder_get_tag__, args, ,
+           "-*- texinfo -*-\n\
+@deftypefn {Loadable Function} {@var{tag} =} __recorder_get_tag__ (@var{recorder})\n\
+Undocumented internal function.\n\
+@end deftypefn")
+{
+  octave_value retval;
+
+#ifdef HAVE_PORTAUDIO
+
+  if (args.length () == 1)
+    {
+      audiorecorder *recorder = get_recorder (args(0));
+
+      if (! recorder)
+        {
+          print_usage ();
+          return retval;
+        }
+
+      retval = recorder->get_tag ();
+    }
+
+#else
+
+  error ("portaudio not found on your system and thus audio functionality is not present");
+
+#endif
+
+  return retval;
+}
+
+DEFUN_DLD (__recorder_get_total_samples__, args, ,
+           "-*- texinfo -*-\n\
+@deftypefn {Loadable Function} {@var{n} =} __recorder_get_total_samples__ (@var{recorder})\n\
+Undocumented internal function.\n\
+@end deftypefn")
+{
+  octave_value retval;
+
+#ifdef HAVE_PORTAUDIO
+
+  if (args.length () == 1)
+    {
+      audiorecorder *recorder = get_recorder (args(0));
+
+      if (! recorder)
+        {
+          print_usage ();
+          return retval;
+        }
+
+      retval = recorder->get_total_samples ();
+    }
+
+#else
+
+  error ("portaudio not found on your system and thus audio functionality is not present");
+
+#endif
+
+  return retval;
+}
+
+DEFUN_DLD (__recorder_get_userdata__, args, ,
+           "-*- texinfo -*-\n\
+@deftypefn {Loadable Function} {@var{data} =} __recorder_get_userdata__ (@var{recorder})\n\
+Undocumented internal function.\n\
+@end deftypefn")
+{
+  octave_value retval;
+
+#ifdef HAVE_PORTAUDIO
+
+  if (args.length () == 1)
+    {
+      audiorecorder *recorder = get_recorder (args(0));
+
+      if (! recorder)
+        {
+          print_usage ();
+          return retval;
+        }
+
+      retval = recorder->get_userdata ();
+    }
+
+#else
+
+  error ("portaudio not found on your system and thus audio functionality is not present");
+
+#endif
+
+  return retval;
+}
+
+DEFUN_DLD (__recorder_isrecording__, args, ,
+           "-*- texinfo -*-\n\
+@deftypefn {Loadable Function} {} __recorder_isrecording__ (@var{recorder})\n\
+Undocumented internal function.\n\
+@end deftypefn")
+{
+  octave_value retval;
+
+#ifdef HAVE_PORTAUDIO
+
+  if (args.length () == 1)
+    {
+      audiorecorder *recorder = get_recorder (args(0));
+
+      if (! recorder)
+        {
+          print_usage ();
+          return retval;
+        }
+
+      retval = recorder->isrecording () ? true : false;
+    }
+
+#else
+
+  error ("portaudio not found on your system and thus audio functionality is not present");
+
+#endif
+
+  return retval;
+}
+
+DEFUN_DLD (__recorder_pause__, args, ,
+           "-*- texinfo -*-\n\
+@deftypefn {Loadable Function} {} __recorder_pause__ (@var{recorder})\n\
+Undocumented internal function.\n\
+@end deftypefn")
+{
+  octave_value retval;
+
+#ifdef HAVE_PORTAUDIO
+
+  if (args.length () == 1)
+    {
+      audiorecorder *recorder = get_recorder (args(0));
+
+      if (! recorder)
+        {
+          print_usage ();
+          return retval;
+        }
+
+      recorder->pause ();
+    }
+
+#else
+
+  error ("portaudio not found on your system and thus audio functionality is not present");
+
+#endif
+
+  return retval;
+}
+
+DEFUN_DLD (__recorder_recordblocking__, args, ,
+           "-*- texinfo -*-\n\
+@deftypefn {Loadable Function} {} __recorder_recordblocking__ (@var{recorder}, @var{seconds})\n\
+Undocumented internal function.\n\
+@end deftypefn")
+{
+  octave_value retval;
+
+#ifdef HAVE_PORTAUDIO
+
+  audiorecorder *recorder = get_recorder (args(0));
+
+  if (! recorder)
+    {
+      print_usage ();
+      return retval;
+    }
+
+  recorder->recordblocking (args(1).float_value ());
+
+#else
+
+  error ("portaudio not found on your system and thus audio functionality is not present");
+
+#endif
+
+  return retval;
+}
+
+DEFUN_DLD (__recorder_record__, args, ,
+           "-*- texinfo -*-\n\
+@deftypefn  {Loadable Function} {} __recorder_record__ (@var{recorder})\n\
+@deftypefnx {Loadable Function} {} __recorder_record__ (@var{recorder}, @var{seconds})\n\
+Undocumented internal function.\n\
+@end deftypefn")
+{
+  octave_value retval;
+
+#ifdef HAVE_PORTAUDIO
+
+  audiorecorder *recorder = get_recorder (args(0));
+
+  if (! recorder)
+    {
+      print_usage ();
+      return retval;
+    }
+
+  if (args.length () == 1)
+    recorder->record ();
+  else if (args.length () == 2)
+    {
+      recorder->set_end_sample (args(1).int_value () * recorder->get_fs ());
+      recorder->record ();
+    }
+  else
+    error ("audiorecorder: wrong number of arguments passed to record");
+
+#else
+
+  error ("portaudio not found on your system and thus audio functionality is not present");
+
+#endif
+
+  return retval;
+}
+
+DEFUN_DLD (__recorder_resume__, args, ,
+           "-*- texinfo -*-\n\
+@deftypefn {Loadable Function} {} __recorder_resume__ (@var{recorder})\n\
+Undocumented internal function.\n\
+@end deftypefn")
+{
+  octave_value retval;
+
+#ifdef HAVE_PORTAUDIO
+
+  if (args.length () == 1)
+    {
+      audiorecorder *recorder = get_recorder (args(0));
+
+      if (! recorder)
+        {
+          print_usage ();
+          return retval;
+        }
+
+      recorder->resume ();
+    }
+
+#else
+
+  error ("portaudio not found on your system and thus audio functionality is not present");
+
+#endif
+
+  return retval;
+}
+
+DEFUN_DLD (__recorder_set_fs__, args, ,
+           "-*- texinfo -*-\n\
+@deftypefn {Loadable Function} {} __recorder_set_fs__ (@var{recorder}, @var{fs})\n\
+Undocumented internal function.\n\
+@end deftypefn")
+{
+  octave_value retval;
+
+#ifdef HAVE_PORTAUDIO
+
+  if (args.length () == 2)
+    {
+      audiorecorder *recorder = get_recorder (args(0));
+
+      if (! recorder)
+        {
+          print_usage ();
+          return retval;
+        }
+
+      recorder->set_fs (args(1).int_value ());
+    }
+
+#else
+
+  error ("portaudio not found on your system and thus audio functionality is not present");
+
+#endif
+
+  return retval;
+}
+
+DEFUN_DLD (__recorder_set_tag__, args, ,
+           "-*- texinfo -*-\n\
+@deftypefn {Loadable Function} {} __recorder_set_tag__ (@var{recorder}, @var{tag})\n\
+Undocumented internal function.\n\
+@end deftypefn")
+{
+  octave_value retval;
+
+#ifdef HAVE_PORTAUDIO
+
+  if (args.length () == 2)
+    {
+      audiorecorder *recorder = get_recorder (args(0));
+
+      if (! recorder)
+        {
+          print_usage ();
+          return retval;
+        }
+
+      recorder->set_tag (args(1).char_matrix_value ());
+    }
+
+#else
+
+  error ("portaudio not found on your system and thus audio functionality is not present");
+
+#endif
+
+  return retval;
+}
+
+DEFUN_DLD (__recorder_set_userdata__, args, ,
+           "-*- texinfo -*-\n\
+@deftypefn {Loadable Function} {} __recorder_set_userdata__ (@var{recorder}, @var{data})\n\
+Undocumented internal function.\n\
+@end deftypefn")
+{
+  octave_value retval;
+
+#ifdef HAVE_PORTAUDIO
+
+  if (args.length () == 2)
+    {
+      audiorecorder *recorder = get_recorder (args(0));
+
+      if (! recorder)
+        {
+          print_usage ();
+          return retval;
+        }
+
+      recorder->set_userdata (args(1));
+    }
+
+#else
+
+  error ("portaudio not found on your system and thus audio functionality is not present");
+
+#endif
+
+  return retval;
+}
+
+DEFUN_DLD (__recorder_stop__, args, ,
+           "-*- texinfo -*-\n\
+@deftypefn {Loadable Function} {} __recorder_stop__ (@var{recorder})\n\
+Undocumented internal function.\n\
+@end deftypefn")
+{
+  octave_value retval;
+
+#ifdef HAVE_PORTAUDIO
+
+  audiorecorder *recorder = get_recorder (args(0));
+
+      if (! recorder)
+        {
+          print_usage ();
+          return retval;
+        }
+
+  recorder->stop ();
+
+#else
+
+  error ("portaudio not found on your system and thus audio functionality is not present");
+
+#endif
+
+  return retval;
+}
+
+DEFUN_DLD (__player_audioplayer__, args, ,
+           "-*- texinfo -*-\n\
+@deftypefn  {Loadable Function} {@var{player} =} __player_audioplayer__ (@var{y}, @var{fs})\n\
+@deftypefnx {Loadable Function} {@var{player} =} __player_audioplayer__ (@var{y}, @var{fs}, @var{nbits})\n\
+@deftypefnx {Loadable Function} {@var{player} =} __player_audioplayer__ (@var{y}, @var{fs}, @var{nbits}, @var{id})\n\
+Undocumented internal function.\n\
+@end deftypefn")
+{
+  octave_value retval;
+
+#ifdef HAVE_PORTAUDIO
+
+  int nargin = args.length ();
+
+  if (nargin < 2 || nargin > 4)
+    {
+      print_usage ();
+      return retval;
+    }
+
+  audioplayer* recorder = new audioplayer ();
+
+  if (! recorder)
+    {
+      print_usage ();
+      return retval;
+    }
+
+  bool is_function = (args(0).is_string () || args(0).is_function_handle ()
+                      || args(0).is_inline_function ());
+
+  if (is_function)
+    {
+      error ("audioplayer: callbacks not yet implemented");
+      return retval;
+
+      // recorder->set_y (args(0).function_value ());
+    }
+  else
+    recorder->set_y (args(0));
+
+  recorder->set_fs (args(1).int_value ());
+
+  switch (nargin)
+    {
+    case 3:
+      recorder->set_nbits (args(2).int_value ());
+      break;
+
+    case 4:
+      recorder->set_nbits (args(2).int_value ());
+      recorder->set_id (args(3).int_value ());
+      break;
+    }
+
+  if (is_function)
+    recorder->init_fn ();
+  else
+    recorder->init ();
+
+  retval = recorder;
+
+#else
+
+  error ("portaudio not found on your system and thus audio functionality is not present");
+
+#endif
+
+  return retval;
+}
+
+#ifdef HAVE_PORTAUDIO
+
+static audioplayer *
+get_player (const octave_value& ov)
+{
+  const octave_base_value& rep = ov.get_rep ();
+
+  octave_base_value *ncrep = const_cast<octave_base_value *> (&rep);
+
+  return dynamic_cast<audioplayer *> (ncrep);
+}
+
+#endif
+
+DEFUN_DLD (__player_get_channels__, args, ,
+           "-*- texinfo -*-\n\
+@deftypefn {Loadable Function} {@var{n} =} __player_get_channels__ (@var{player})\n\
+Undocumented internal function.\n\
+@end deftypefn")
+{
+  octave_value retval;
+
+#ifdef HAVE_PORTAUDIO
+
+  if (args.length () == 1)
+    {
+      audioplayer *player = get_player (args(0));
+
+      if (! player)
+        {
+          print_usage ();
+          return retval;
+        }
+
+      retval = player->get_channels ();
+    }
+
+#else
+
+  error ("portaudio not found on your system and thus audio functionality is not present");
+
+#endif
+
+  return retval;
+}
+
+DEFUN_DLD (__player_get_fs__, args, ,
+           "-*- texinfo -*-\n\
+@deftypefn {Loadable Function} {@var{fs} =} __player_get_fs__ (@var{player})\n\
+Undocumented internal function.\n\
+@end deftypefn")
+{
+  octave_value retval;
+
+#ifdef HAVE_PORTAUDIO
+
+  if (args.length () == 1)
+    {
+      audioplayer *player = get_player (args(0));
+
+      if (! player)
+        {
+          print_usage ();
+          return retval;
+        }
+
+      retval = player->get_fs ();
+    }
+
+#else
+
+  error ("portaudio not found on your system and thus audio functionality is not present");
+
+#endif
+
+  return retval;
+}
+
+DEFUN_DLD (__player_get_id__, args, ,
+           "-*- texinfo -*-\n\
+@deftypefn {Loadable Function} {@var{id} =} __player_get_id__ (@var{player})\n\
+Undocumented internal function.\n\
+@end deftypefn")
+{
+  octave_value retval;
+
+#ifdef HAVE_PORTAUDIO
+
+  if (args.length () == 1)
+    {
+      audioplayer *player = get_player (args(0));
+
+      if (! player)
+        {
+          print_usage ();
+          return retval;
+        }
+
+      retval = player->get_id ();
+    }
+
+#else
+
+  error ("portaudio not found on your system and thus audio functionality is not present");
+
+#endif
+
+  return retval;
+}
+
+DEFUN_DLD (__player_get_nbits__, args, ,
+           "-*- texinfo -*-\n\
+@deftypefn {Loadable Function} {@var{nbits} =} __player_get_nbits__ (@var{player})\n\
+Undocumented internal function.\n\
+@end deftypefn")
+{
+  octave_value retval;
+
+#ifdef HAVE_PORTAUDIO
+
+  if (args.length () == 1)
+    {
+      audioplayer *player = get_player (args(0));
+
+      if (! player)
+        {
+          print_usage ();
+          return retval;
+        }
+
+      retval = player->get_nbits ();
+    }
+
+#else
+
+  error ("portaudio not found on your system and thus audio functionality is not present");
+
+#endif
+
+  return retval;
+}
+
+DEFUN_DLD (__player_get_sample_number__, args, ,
+           "-*- texinfo -*-\n\
+@deftypefn {Loadable Function} {@var{n} =} __player_get_sample_number__ (@var{player})\n\
+Undocumented internal function.\n\
+@end deftypefn")
+{
+  octave_value retval;
+
+#ifdef HAVE_PORTAUDIO
+
+  if (args.length () == 1)
+    {
+      audioplayer *player = get_player (args(0));
+
+      if (! player)
+        {
+          print_usage ();
+          return retval;
+        }
+
+      retval = player->get_sample_number ();
+    }
+
+#else
+
+  error ("portaudio not found on your system and thus audio functionality is not present");
+
+#endif
+
+  return retval;
+}
+
+DEFUN_DLD (__player_get_tag__, args, ,
+           "-*- texinfo -*-\n\
+@deftypefn {Loadable Function} {@var{tag} =} __player_get_tag__ (@var{player})\n\
+Undocumented internal function.\n\
+@end deftypefn")
+{
+  octave_value retval;
+
+#ifdef HAVE_PORTAUDIO
+
+  if (args.length () == 1)
+    {
+      audioplayer *player = get_player (args(0));
+
+      if (! player)
+        {
+          print_usage ();
+          return retval;
+        }
+
+      retval = player->get_tag ();
+    }
+
+#else
+
+  error ("portaudio not found on your system and thus audio functionality is not present");
+
+#endif
+
+  return retval;
+}
+
+DEFUN_DLD (__player_get_total_samples__, args, ,
+           "-*- texinfo -*-\n\
+@deftypefn {Loadable Function} {@var{n} =} __player_get_total_samples__ (@var{player})\n\
+Undocumented internal function.\n\
+@end deftypefn")
+{
+  octave_value retval;
+
+#ifdef HAVE_PORTAUDIO
+
+  if (args.length () == 1)
+    {
+      audioplayer *player = get_player (args(0));
+
+      if (! player)
+        {
+          print_usage ();
+          return retval;
+        }
+
+      retval = player->get_total_samples ();
+    }
+
+#else
+
+  error ("portaudio not found on your system and thus audio functionality is not present");
+
+#endif
+
+  return retval;
+}
+
+DEFUN_DLD (__player_get_userdata__, args, ,
+           "-*- texinfo -*-\n\
+@deftypefn {Loadable Function} {@var{data} =} __player_get_userdata__ (@var{player})\n\
+Undocumented internal function.\n\
+@end deftypefn")
+{
+  octave_value retval;
+
+#ifdef HAVE_PORTAUDIO
+
+  if (args.length () == 1)
+    {
+      audioplayer *player = get_player (args(0));
+
+      if (! player)
+        {
+          print_usage ();
+          return retval;
+        }
+
+      retval = player->get_userdata ();
+    }
+
+#else
+
+  error ("portaudio not found on your system and thus audio functionality is not present");
+
+#endif
+
+  return retval;
+}
+
+DEFUN_DLD (__player_isplaying__, args, ,
+           "-*- texinfo -*-\n\
+@deftypefn {Loadable Function} {} __player_isplaying__ (@var{player})\n\
+Undocumented internal function.\n\
+@end deftypefn")
+{
+  octave_value retval;
+
+#ifdef HAVE_PORTAUDIO
+
+  if (args.length () == 1)
+    {
+      audioplayer *player = get_player (args(0));
+
+      if (! player)
+        {
+          print_usage ();
+          return retval;
+        }
+
+      retval = player->isplaying () ? true : false;
+    }
+
+#else
+
+  error ("portaudio not found on your system and thus audio functionality is not present");
+
+#endif
+
+  return retval;
+}
+
+DEFUN_DLD (__player_pause__, args, ,
+           "-*- texinfo -*-\n\
+@deftypefn {Loadable Function} {} __player_pause__ (@var{player})\n\
+Undocumented internal function.\n\
+@end deftypefn")
+{
+  octave_value retval;
+
+#ifdef HAVE_PORTAUDIO
+
+  if (args.length () == 1)
+    {
+      audioplayer *player = get_player (args(0));
+
+      if (! player)
+        {
+          print_usage ();
+          return retval;
+        }
+
+      player->pause ();
+    }
+
+#else
+
+  error ("portaudio not found on your system and thus audio functionality is not present");
+
+#endif
+
+  return retval;
+}
+
+DEFUN_DLD (__player_playblocking__, args, ,
+           "-*- texinfo -*-\n\
+@deftypefn  {Loadable Function} {} __player_playblocking__ (@var{player})\n\
+@deftypefnx {Loadable Function} {} __player_playblocking__ (@var{player}, @var{start})\n\
+@deftypefnx {Loadable Function} {} __player_playblocking__ (@var{player}, [@var{start}, @var{end}])\n\
+Undocumented internal function.\n\
+@end deftypefn")
+{
+  octave_value retval;
+
+#ifdef HAVE_PORTAUDIO
+
+  audioplayer *player = get_player (args(0));
+
+  if (! player)
+    {
+      print_usage ();
+      return retval;
+    }
+
+  if (args.length () == 1)
+    player->playblocking ();
+  else
+    {
+      if (args(1).is_matrix_type ())
+        {
+          RowVector range = args(1).row_vector_value ();
+
+          unsigned int start = range.elem (0) - 1;
+          unsigned int end = range.elem (1) - 1;
+
+          if (start > player->get_total_samples ()
+              || start > end || end > player->get_total_samples ())
+            {
+              error ("audioplayer: invalid range specified for playback");
+              return retval;
+            }
+
+          player->set_sample_number (start);
+          player->set_end_sample (end);
+        }
+      else
+        {
+          unsigned int start = args(1).int_value () - 1;
+
+          if (start > player->get_total_samples ())
+            {
+              error ("audioplayer: invalid range specified for playback");
+              return retval;
+            }
+
+          player->set_sample_number (start);
+        }
+
+      player->playblocking ();
+    }
+
+#else
+
+  error ("portaudio not found on your system and thus audio functionality is not present");
+
+#endif
+
+  return retval;
+}
+
+DEFUN_DLD (__player_play__, args, ,
+           "-*- texinfo -*-\n\
+@deftypefn  {Loadable Function} {} __player_play__ (@var{player})\n\
+@deftypefnx {Loadable Function} {} __player_play__ (@var{player}, @var{start})\n\
+@deftypefnx {Loadable Function} {} __player_play__ (@var{player}, [@var{start}, @var{end}])\n\
+Undocumented internal function.\n\
+@end deftypefn")
+{
+  octave_value retval;
+
+#ifdef HAVE_PORTAUDIO
+
+  if (args.length () == 1)
+    {
+      audioplayer *player = get_player (args(0));
+
+      if (! player)
+        {
+          print_usage ();
+          return retval;
+        }
+
+      player->play ();
+    }
+  else
+    {
+      audioplayer *player = get_player (args(0));
+
+      if (args(1).is_matrix_type ())
+        {
+          RowVector range = args(1).row_vector_value ();
+
+          unsigned int start = range.elem (0) - 1;
+          unsigned int end = range.elem (1) - 1;
+
+          if (start > player->get_total_samples ()
+              || start > end || end > player->get_total_samples ())
+            {
+              error ("audioplayer: invalid range specified for playback");
+              return retval;
+            }
+
+          player->set_sample_number (start);
+          player->set_end_sample (end);
+        }
+      else
+        {
+          unsigned int start = args(1).int_value () - 1;
+
+          if (start > player->get_total_samples ())
+            {
+              error ("audioplayer: invalid range specified for playback");
+              return retval;
+            }
+
+          player->set_sample_number (start);
+        }
+
+      player->play ();
+    }
+
+#else
+
+  error ("portaudio not found on your system and thus audio functionality is not present");
+
+#endif
+
+  return retval;
+}
+
+DEFUN_DLD (__player_resume__, args, ,
+           "-*- texinfo -*-\n\
+@deftypefn {Loadable Function} {} __player_resume__ (@var{player})\n\
+Undocumented internal function.\n\
+@end deftypefn")
+{
+  octave_value retval;
+
+#ifdef HAVE_PORTAUDIO
+
+  if (args.length () == 1)
+    {
+      audioplayer *player = get_player (args(0));
+
+      if (! player)
+        {
+          print_usage ();
+          return retval;
+        }
+
+      player->resume ();
+    }
+
+#else
+
+  error ("portaudio not found on your system and thus audio functionality is not present");
+
+#endif
+
+  return retval;
+}
+
+DEFUN_DLD (__player_set_fs__, args, ,
+           "-*- texinfo -*-\n\
+@deftypefn {Loadable Function} {} __player_set_fs__ (@var{player}, @var{fs})\n\
+Undocumented internal function.\n\
+@end deftypefn")
+{
+  octave_value retval;
+
+#ifdef HAVE_PORTAUDIO
+
+  if (args.length () == 2)
+    {
+      audioplayer *player = get_player (args(0));
+
+      if (! player)
+        {
+          print_usage ();
+          return retval;
+        }
+
+      player->set_fs (args(1).int_value ());
+    }
+
+#else
+
+  error ("portaudio not found on your system and thus audio functionality is not present");
+
+#endif
+
+  return retval;
+}
+
+DEFUN_DLD (__player_set_tag__, args, ,
+           "-*- texinfo -*-\n\
+@deftypefn {Loadable Function} {} __player_set_tag__ (@var{player}, @var{tag})\n\
+Undocumented internal function.\n\
+@end deftypefn")
+{
+  octave_value retval;
+
+#ifdef HAVE_PORTAUDIO
+
+  if (args.length () == 2)
+    {
+      audioplayer *player = get_player (args(0));
+
+      if (! player)
+        {
+          print_usage ();
+          return retval;
+        }
+
+      player->set_tag (args(1).char_matrix_value ());
+    }
+
+#else
+
+  error ("portaudio not found on your system and thus audio functionality is not present");
+
+#endif
+
+  return retval;
+}
+
+DEFUN_DLD (__player_set_userdata__, args, ,
+           "-*- texinfo -*-\n\
+@deftypefn {Loadable Function} {} __player_set_userdata__ (@var{player}, @var{data})\n\
+Undocumented internal function.\n\
+@end deftypefn")
+{
+  octave_value retval;
+
+#ifdef HAVE_PORTAUDIO
+
+  if (args.length () == 2)
+    {
+      audioplayer *player = get_player (args(0));
+
+      if (! player)
+        {
+          print_usage ();
+          return retval;
+        }
+
+      player->set_userdata (args(1));
+    }
+
+#else
+
+  error ("portaudio not found on your system and thus audio functionality is not present");
+
+#endif
+
+  return retval;
+}
+
+DEFUN_DLD (__player_stop__, args, ,
+           "-*- texinfo -*-\n\
+@deftypefn {Loadable Function} {} __player_stop__ (@var{player})\n\
+Undocumented internal function.\n\
+@end deftypefn")
+{
+  octave_value retval;
+
+#ifdef HAVE_PORTAUDIO
+
+  if (args.length () == 1)
+    {
+      audioplayer *player = get_player (args (0));
+
+      if (! player)
+        {
+          print_usage ();
+          return retval;
+        }
+
+      player->stop ();
+    }
+
+#else
+
+  error ("portaudio not found on your system and thus audio functionality is not present");
+
+#endif
+
+  return retval;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libinterp/dldfcn/audioread.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,522 @@
+/*
+
+Copyright (C) 2013 Vytautas Jančauskas
+
+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 <string>
+#include <map>
+
+#include "oct-locbuf.h"
+#include "unwind-prot.h"
+
+#include "defun-dld.h"
+#include "error.h"
+#include "gripes.h"
+#include "oct-obj.h"
+#include "ov.h"
+#include "ov-struct.h"
+
+#ifdef HAVE_SNDFILE
+#include <sndfile.h>
+#endif
+
+#ifdef HAVE_SNDFILE
+static void
+safe_close (SNDFILE *file)
+{
+  sf_close (file);
+}
+#endif
+
+DEFUN_DLD (audioread, args, ,
+           "-*- texinfo -*-\n\
+@deftypefn  {Loadable Function} {[@var{y}, @var{fs}] =} audioread (@var{filename})\n\
+@deftypefnx {Loadable Function} {[@var{y}, @var{fs}] =} audioread (@var{filename}, @var{samples})\n\
+\n\
+@deftypefnx {Loadable Function} {[@var{y}, @var{fs}] =} audioread (@var{filename}, @var{datatype})\n\
+@deftypefnx {Loadable Function} {[@var{y}, @var{fs}] =} audioread (@var{filename}, @var{samples}, @var{datatype})\n\
+Read the audio file @var{filename} and return the audio data and sampling\n\
+rate.  The audio data is stored as matrix with rows corresponding\n\
+to audio frames and columns corresponding to channels.\n\
+\n\
+The optional two-element vector argument @var{samples} specifies starting\n\
+and ending frames.\n\
+\n\
+The optional argument @var{datatype} specifies the datatype to return.\n\
+If it is @qcode{\"native\"}, then the type of data depends on how the\n\
+data is stored in the audio file.\n\
+\n\
+Read a file and return a specified range of frames in an array of specified\n\
+type.\n\
+\n\
+@end deftypefn")
+{
+  octave_value_list retval;
+
+#ifdef HAVE_SNDFILE
+
+  int nargin = args.length ();
+
+  if (nargin < 1 || nargin > 3)
+    {
+      print_usage ();
+      return retval;
+    }
+
+  std::string filename = args(0).string_value ();
+
+  if (error_state)
+    return retval;
+
+  SF_INFO info;
+  info.format = 0;
+  SNDFILE *file = sf_open (filename.c_str (), SFM_READ, &info);
+
+  if (! file)
+    {
+      error ("audioread: failed to open input file %s", filename.c_str ());
+      return retval;
+    }
+
+  unwind_protect frame;
+
+  frame.add_fcn (safe_close, file);
+
+  OCTAVE_LOCAL_BUFFER (float, data, info.frames * info.channels);
+
+  sf_read_float (file, data, info.frames * info.channels);
+
+  sf_count_t start = 0;
+  sf_count_t end = info.frames;
+
+  if ((nargin == 2 && ! args(1).is_string ()) || nargin == 3)
+    {
+      RowVector range = args(1).row_vector_value ();
+
+      if (error_state)
+        return retval;
+
+      if (range.nelem () != 2)
+        {
+          error ("audioread: invalid specification for range of frames");
+          return retval;
+        }
+
+      double dstart = range(0);
+      double dend = range(1);
+
+      if (dstart < 0 || dstart > dend || D_NINT (dstart) != dstart
+          || D_NINT (dend) != dend)
+        {
+          error ("audioread: invalid specification for range of frames");
+          return retval;
+        }
+
+      start = dstart;
+      end = dend;
+    }
+
+  sf_count_t items = end - start;
+
+  Matrix audio (items, info.channels);
+
+  double *paudio = audio.fortran_vec ();
+
+  data += start * info.channels;
+
+  for (int i = 0; i < items; i++)
+    {
+      for (int channel = 0; channel < info.channels; channel++)
+        paudio[items*channel+i] = *data++;
+    }
+
+  octave_value ret_audio;
+
+  if ((nargin == 2 && args(1).is_string ()) || nargin == 3)
+    {
+      std::string type;
+      if (nargin == 3)
+        type = args(2).string_value ();
+      else
+        type = args(1).string_value ();
+
+      if (error_state)
+        return retval;
+
+      if (type == "native")
+        {
+          if (info.format & SF_FORMAT_PCM_S8)
+            ret_audio = int8NDArray (audio * 127);
+          else if (info.format & SF_FORMAT_PCM_U8)
+            ret_audio = uint8NDArray (audio * 127 + 127);
+          else if (info.format & SF_FORMAT_PCM_16)
+            ret_audio = int16NDArray (audio * 32767);
+          else if (info.format & SF_FORMAT_PCM_24)
+            ret_audio = int32NDArray (audio * 8388608);
+          else if (info.format & SF_FORMAT_PCM_32)
+            ret_audio = int32NDArray (audio * 2147483648);
+          else
+            ret_audio = audio;
+        }
+      else
+        ret_audio = audio;
+    }
+  else
+    ret_audio = audio;
+
+  retval(1) = info.samplerate;
+  retval(0) = ret_audio;
+
+#else
+
+  error ("sndfile not found on your system and thus audioread is not functional");
+
+#endif
+
+  return retval;
+}
+
+#ifdef HAVE_SNDFILE
+
+static int
+extension_to_format (const std::string& ext)
+{
+  static bool initialized = false;
+
+  static std::map<std::string, int> table;
+
+  if (! initialized)
+    {
+      table["wav"] = SF_FORMAT_WAV;
+      table["aiff"] = SF_FORMAT_AIFF;
+      table["au"] = SF_FORMAT_AU;
+      table["raw"] = SF_FORMAT_RAW;
+      table["paf"] = SF_FORMAT_PAF;
+      table["svx"] = SF_FORMAT_SVX;
+      table["nist"] = SF_FORMAT_NIST;
+      table["voc"] = SF_FORMAT_VOC;
+      table["ircam"] = SF_FORMAT_IRCAM;
+      table["w64"] = SF_FORMAT_W64;
+      table["mat4"] = SF_FORMAT_MAT4;
+      table["mat5"] = SF_FORMAT_MAT5;
+      table["pvf"] = SF_FORMAT_PVF;
+      table["xi"] = SF_FORMAT_XI;
+      table["htk"] = SF_FORMAT_HTK;
+      table["sds"] = SF_FORMAT_SDS;
+      table["avr"] = SF_FORMAT_AVR;
+      table["wavex"] = SF_FORMAT_WAVEX;
+      table["sd2"] = SF_FORMAT_SD2;
+      table["flac"] = SF_FORMAT_FLAC;
+      table["caf"] = SF_FORMAT_CAF;
+      table["wve"] = SF_FORMAT_WVE;
+      table["ogg"] = SF_FORMAT_OGG;
+      table["mpc2k"] = SF_FORMAT_MPC2K;
+      table["rf64"] = SF_FORMAT_RF64;
+
+      initialized = true;
+    }
+
+  std::map<std::string, int>::const_iterator it = table.find (ext);
+
+  return (it != table.end ()) ? it->second : 0;
+}
+
+#endif
+
+DEFUN_DLD (audiowrite, args, ,
+           "-*- texinfo -*-\n\
+@deftypefn  {Loadable Function} {} audiowrite (@var{filename}, @var{y}, @var{fs})\n\
+@deftypefnx {Loadable Function} {} audiowrite (@var{filename}, @var{y}, @var{fs}, @var{name}, @var{value}, @dots{})\n\
+\n\
+Write audio data from the matrix @var{y} to @var{filename} with the file\n\
+format determined by the file extension.\n\
+\n\
+Additional name and value argument pairs may be used to specify the\n\
+following options:\n\
+\n\
+@table @samp\n\
+@item BitsPerSample\n\
+Number of bits per sample, valid values are 8, 16, 24 and 32.  Default is 16.\n\
+\n\
+@item BitRate\n\
+Valid argument name, but ignored.  Left for compatibility with @sc{matlab}.\n\
+\n\
+@item Quality\n\
+Quality setting for the Ogg Vorbis compressor.  Values can range between 0\n\
+and 100 with 100 being the highest quality setting.  Default is 75.\n\
+\n\
+@item Title\n\
+Title for the audio file.\n\
+\n\
+@item Artist\n\
+Artist name.\n\
+\n\
+@item Comment\n\
+Comment.\n\
+@end table\n\
+@end deftypefn")
+{
+  // FIXME: shouldn't we return something to indicate whether the file
+  // was written successfully?
+
+  octave_value retval;
+
+#ifdef HAVE_SNDFILE
+
+  int nargin = args.length ();
+
+  if (nargin < 3)
+    {
+      print_usage ();
+      return retval;
+    }
+
+  std::string filename = args(0).string_value ();
+
+  if (error_state)
+    return retval;
+
+  const Matrix audio = args(1).matrix_value ();
+
+  if (error_state)
+    return retval;
+
+  int samplerate = args(2).int_value ();
+
+  if (error_state)
+    return retval;
+
+  std::string ext = filename.substr (filename.find_last_of (".") + 1);
+  std::transform (ext.begin (), ext.end (), ext.begin (), ::tolower);
+
+  sf_count_t items_to_write = audio.rows () * audio.columns ();
+
+  OCTAVE_LOCAL_BUFFER (float, data, items_to_write);
+
+  sf_count_t idx = 0;
+  for (int i = 0; i < audio.rows (); i++)
+    {
+      for (int j = 0; j < audio.columns (); j++)
+        data[idx++] = audio.xelem (i, j);
+    }
+
+  SF_INFO info;
+
+  memset (&info, 0, sizeof (info)) ;
+
+  sf_count_t chunk_size = 0;
+
+  if (ext == "ogg")
+    {
+      info.format = SF_FORMAT_VORBIS;
+
+      // FIXME: there seems to be a bug writing ogg files in one shot
+      // that causes a segfault.  Breaking it up into a series of
+      // smaller chunks seems to avoid the problem and produce valid
+      // files.
+      chunk_size = 0x1FFFFE;
+    }
+  else
+    info.format = SF_FORMAT_PCM_16;
+
+  info.channels = audio.columns ();
+  info.samplerate = samplerate;
+  info.channels = audio.cols ();
+  info.format |= extension_to_format (ext);
+
+  std::string title = "";
+  std::string artist = "";
+  std::string comment = "";
+  // Quality is currently unused?
+  //
+  // float quality = 0.75;
+  for (int i = 3; i < nargin; i += 2)
+    {
+      if (args(i).string_value () == "BitsPerSample")
+        {
+          int bits = args(i + 1).int_value ();
+          if (bits == 8)
+            info.format |= SF_FORMAT_PCM_S8;
+          else if (bits == 16)
+            info.format |= SF_FORMAT_PCM_16;
+          else if (bits == 24)
+            info.format |= SF_FORMAT_PCM_24;
+          else if (bits == 32)
+            info.format |= SF_FORMAT_PCM_32;
+          else
+            {
+              error ("audiowrite: wrong number of bits specified");
+              return retval;
+            }
+        }
+      else if (args(i).string_value () == "BitRate")
+        ;
+      // Quality is currently unused?
+      //
+      // else if (args(i).string_value () == "Quality")
+      //   quality = args(i + 1).int_value () * 0.01;
+      else if (args(i).string_value () == "Title")
+        title = args(i + 1).string_value ();
+      else if (args(i).string_value () == "Artist")
+        artist = args(i + 1).string_value ();
+      else if (args(i).string_value () == "Comment")
+        comment = args(i + 1).string_value ();
+      else
+        {
+          error ("audiowrite: wrong argument name");
+          return retval;
+        }
+    }
+
+  SNDFILE *file = sf_open (filename.c_str (), SFM_WRITE, &info);
+
+  if (! file)
+    {
+      error ("audiowrite: failed to open output file %s", filename.c_str ());
+      return retval;
+    }
+
+  unwind_protect frame;
+
+  frame.add_fcn (safe_close, file);
+
+  if (title != "")
+    sf_set_string (file, SF_STR_TITLE, title.c_str ());
+
+  if (artist != "")
+    sf_set_string (file, SF_STR_ARTIST, artist.c_str ());
+
+  if (comment != "")
+    sf_set_string (file, SF_STR_COMMENT, comment.c_str ());
+
+  sf_count_t total_items_written = 0;
+  sf_count_t offset = 0;
+
+  if (chunk_size == 0)
+    chunk_size = items_to_write;
+
+  while (total_items_written < items_to_write)
+    {
+      if (items_to_write - offset < chunk_size)
+        chunk_size = items_to_write - offset;
+
+      sf_count_t items_written = sf_write_float (file, data+offset, chunk_size);
+
+      if (items_written != chunk_size)
+        {
+          error ("audiowrite: write failed, wrote %ld of %ld items\n",
+                 items_written, chunk_size);
+          return retval;
+        }
+
+      total_items_written += items_written;
+      offset += chunk_size;
+    }
+
+#else
+
+  error ("sndfile not found on your system and thus audiowrite is not functional");
+
+#endif
+
+  return retval;
+}
+
+DEFUN_DLD (audioinfo, args, ,
+           "-*- texinfo -*-\n\
+@deftypefn {Loadable Function} {@var{info} =} audioinfo (@var{filename})\n\
+Return information about an audio file specified by @var{filename}.\n\
+@end deftypefn")
+{
+  octave_value retval;
+
+#ifdef HAVE_SNDFILE
+
+  if (args.length () != 1)
+    {
+      print_usage ();
+      return retval;
+    }
+
+  std::string filename = args(0).string_value ();
+
+  if (error_state)
+    return retval;
+
+  SF_INFO info;
+  info.format = 0;
+  SNDFILE *file = sf_open (filename.c_str (), SFM_READ, &info);
+
+  if (! file)
+    {
+      error ("audioinfo: failed to open file %s", filename.c_str ());
+      return retval;
+    }
+
+  unwind_protect frame;
+
+  frame.add_fcn (safe_close, file);
+
+  octave_scalar_map result;
+
+  result.assign ("Filename", filename);
+  result.assign ("CompressionMethod", "");
+  result.assign ("NumChannels", info.channels);
+  result.assign ("SampleRate", info.samplerate);
+  result.assign ("TotalSamples", info.frames);
+
+  double dframes = info.frames;
+  double drate = info.samplerate;
+  result.assign ("Duration", dframes / drate);
+
+  int bits;
+  if (info.format & SF_FORMAT_PCM_S8)
+    bits = 8;
+  else if (info.format & SF_FORMAT_PCM_U8)
+    bits = 8;
+  else if (info.format & SF_FORMAT_PCM_16)
+    bits = 16;
+  else if (info.format & SF_FORMAT_PCM_24)
+    bits = 24;
+  else if (info.format & SF_FORMAT_PCM_32)
+    bits = 32;
+  else
+    bits = -1;
+
+  result.assign ("BitsPerSample", bits);
+  result.assign ("BitRate", -1);
+  result.assign ("Title", sf_get_string (file, SF_STR_TITLE));
+  result.assign ("Artist", sf_get_string (file, SF_STR_ARTIST));
+  result.assign ("Comment", sf_get_string (file, SF_STR_COMMENT));
+
+  retval = result;
+
+#else
+
+  error ("sndfile not found on your system and thus audioinfo is not functional");
+
+#endif
+
+  return retval;
+}
--- a/libinterp/dldfcn/ccolamd.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/libinterp/dldfcn/ccolamd.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -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\
@@ -133,11 +132,12 @@
 or out-of-order row indices.  @code{@var{stats}(8 : 20)} is always zero in\n\
 the current version of @sc{ccolamd} (reserved for future use).\n\
 \n\
-The authors of the code itself are S. Larimore, T. Davis (Univ. of Florida)\n\
-and S. Rajamanickam in collaboration with J. Bilbert and E. Ng.  Supported\n\
-by the National Science Foundation\n\
-@nospell{(DMS-9504974, DMS-9803599, CCR-0203270)}, and a grant from Sandia\n\
-National Lab.  See @url{http://www.cise.ufl.edu/research/sparse} for\n\
+The authors of the code itself are @nospell{S. Larimore, T. Davis}\n\
+(Univ. of Florida) and @nospell{S. Rajamanickam} in collaboration with\n\
+@nospell{J. Bilbert and E. Ng}.  Supported by the National Science Foundation\n\
+@nospell{(DMS-9504974, DMS-9803599, CCR-0203270)}, and a grant from\n\
+@nospell{Sandia} National Lab.\n\
+See @url{http://www.cise.ufl.edu/research/sparse} for\n\
 ccolamd, csymamd, amd, colamd, symamd, and other related orderings.\n\
 @seealso{colamd, csymamd}\n\
 @end deftypefn")
@@ -390,11 +390,12 @@
 or out-of-order row indices.  @code{@var{stats}(8:20)} is always zero in\n\
 the current version of @sc{ccolamd} (reserved for future use).\n\
 \n\
-The authors of the code itself are S. Larimore, T. Davis (Uni of Florida)\n\
-and S. Rajamanickam in collaboration with J. Bilbert and E. Ng.  Supported\n\
-by the National Science Foundation\n\
-@nospell{(DMS-9504974, DMS-9803599, CCR-0203270)}, and a grant from Sandia\n\
-National Lab.  See @url{http://www.cise.ufl.edu/research/sparse} for\n\
+The authors of the code itself are @nospell{S. Larimore, T. Davis}\n\
+(Univ. of Florida) and @nospell{S. Rajamanickam} in collaboration with\n\
+@nospell{J. Bilbert and E. Ng}.  Supported by the National Science Foundation\n\
+@nospell{(DMS-9504974, DMS-9803599, CCR-0203270)}, and a grant from\n\
+@nospell{Sandia} National Lab.\n\
+See @url{http://www.cise.ufl.edu/research/sparse} for\n\
 ccolamd, csymamd, amd, colamd, symamd, and other related orderings.\n\
 @seealso{symamd, ccolamd}\n\
 @end deftypefn")
--- a/libinterp/dldfcn/chol.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/libinterp/dldfcn/chol.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -135,7 +135,7 @@
 \n\
 In general the lower triangular factorization is significantly faster for\n\
 sparse matrices.\n\
-@seealso{hess, lu, qr, qz, schur, svd, cholinv, chol2inv, cholupdate, cholinsert, choldelete, cholshift}\n\
+@seealso{hess, lu, qr, qz, schur, svd, ichol, cholinv, chol2inv, cholupdate, cholinsert, choldelete, cholshift}\n\
 @end deftypefn")
 {
   octave_value_list retval;
@@ -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/colamd.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/libinterp/dldfcn/colamd.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -270,10 +270,9 @@
 \n\
 The ordering is followed by a column elimination tree post-ordering.\n\
 \n\
-The authors of the code itself are Stefan I. Larimore and Timothy A.\n\
-Davis @email{davis@@cise.ufl.edu}, University of Florida.  The algorithm was\n\
-developed in collaboration with John Gilbert, Xerox PARC, and Esmond\n\
-Ng, Oak Ridge National Laboratory.  (see\n\
+The authors of the code itself are @nospell{Stefan I. Larimore} and\n\
+@nospell{Timothy A. Davis @email{davis@@cise.ufl.edu}}, University of Florida.  The algorithm was developed in collaboration with @nospell{John Gilbert},\n\
+Xerox PARC, and @nospell{Esmond Ng}, Oak Ridge National Laboratory.  (see\n\
 @url{http://www.cise.ufl.edu/research/sparse/colamd})\n\
 @seealso{colperm, symamd, ccolamd}\n\
 @end deftypefn")
@@ -506,10 +505,9 @@
 \n\
 The ordering is followed by a column elimination tree post-ordering.\n\
 \n\
-The authors of the code itself are Stefan I. Larimore and Timothy A.\n\
-Davis @email{davis@@cise.ufl.edu}, University of Florida.  The algorithm was\n\
-developed in collaboration with John Gilbert, Xerox PARC, and Esmond\n\
-Ng, Oak Ridge National Laboratory.  (see\n\
+The authors of the code itself are @nospell{Stefan I. Larimore} and\n\
+@nospell{Timothy A. Davis @email{davis@@cise.ufl.edu}}, University of Florida.  The algorithm was developed in collaboration with @nospell{John Gilbert},\n\
+Xerox PARC, and @nospell{Esmond Ng}, Oak Ridge National Laboratory.  (see\n\
 @url{http://www.cise.ufl.edu/research/sparse/colamd})\n\
 @seealso{colperm, colamd}\n\
 @end deftypefn")
--- a/libinterp/dldfcn/config-module.awk	Fri Feb 06 08:31:09 2015 -0800
+++ b/libinterp/dldfcn/config-module.awk	Fri Feb 06 08:31:49 2015 -0800
@@ -66,7 +66,7 @@
       {
         printf ("dldfcn/%s.df: CPPFLAGS += %s\n",
                 basename, cppflags[i]);
-        printf ("dldfcn_%s_la_CPPFLAGS = %s $(AM_CPPFLAGS)\n",
+        printf ("dldfcn_%s_la_CPPFLAGS = $(AM_CPPFLAGS) %s\n",
                 basename, cppflags[i]);
       }
     printf ("dldfcn_%s_la_LDFLAGS = -avoid-version -module $(NO_UNDEFINED_LDFLAG) %s $(OCT_LINK_OPTS)\n",
--- a/libinterp/dldfcn/convhulln.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/libinterp/dldfcn/convhulln.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -33,7 +33,7 @@
 #include <config.h>
 #endif
 
-#include <sstream>
+#include "oct-locbuf.h"
 
 #include "Cell.h"
 #include "defun-dld.h"
--- a/libinterp/dldfcn/dmperm.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/libinterp/dldfcn/dmperm.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -136,8 +136,10 @@
 @deftypefn  {Loadable Function} {@var{p} =} dmperm (@var{S})\n\
 @deftypefnx {Loadable Function} {[@var{p}, @var{q}, @var{r}, @var{S}] =} dmperm (@var{S})\n\
 \n\
-@cindex Dulmage-Mendelsohn decomposition\n\
-Perform a Dulmage-Mendelsohn permutation of the sparse matrix @var{S}.\n\
+@cindex @nospell{Dulmage-Mendelsohn} decomposition\n\
+Perform a @nospell{Dulmage-Mendelsohn} permutation of the sparse matrix\n\
+@var{S}.\n\
+\n\
 With a single output argument @code{dmperm} performs the row permutations\n\
 @var{p} such that @code{@var{S}(@var{p},:)} has no zero elements on the\n\
 diagonal.\n\
@@ -147,9 +149,9 @@
 triangular form.  The values of @var{r} and @var{S} define the boundaries\n\
 of the blocks.  If @var{S} is square then @code{@var{r} == @var{S}}.\n\
 \n\
-The method used is described in: A. Pothen & C.-J. Fan. @cite{Computing the\n\
-Block Triangular Form of a Sparse Matrix}. ACM Trans. Math. Software,\n\
-16(4):303-324, 1990.\n\
+The method used is described in: @nospell{A. Pothen & C.-J. Fan.}\n\
+@cite{Computing the Block Triangular Form of a Sparse Matrix}.\n\
+ACM Trans. Math. Software, 16(4):303-324, 1990.\n\
 @seealso{colamd, ccolamd}\n\
 @end deftypefn")
 {
@@ -194,8 +196,8 @@
 \n\
 Calculate the structural rank of the sparse matrix @var{S}.  Note that\n\
 only the structure of the matrix is used in this calculation based on\n\
-a Dulmage-Mendelsohn permutation to block triangular form.  As such the\n\
-numerical rank of the matrix @var{S} is bounded by\n\
+a @nospell{Dulmage-Mendelsohn} permutation to block triangular form.  As\n\
+such the numerical rank of the matrix @var{S} is bounded by\n\
 @code{sprank (@var{S}) >= rank (@var{S})}.  Ignoring floating point errors\n\
 @code{sprank (@var{S}) == rank (@var{S})}.\n\
 @seealso{dmperm}\n\
--- a/libinterp/dldfcn/fftw.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/libinterp/dldfcn/fftw.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -32,6 +32,8 @@
 #include "error.h"
 #include "ov.h"
 
+#include "gripes.h"
+
 DEFUN_DLD (fftw, args, ,
            "-*- texinfo -*-\n\
 @deftypefn  {Loadable Function} {@var{method} =} fftw (\"planner\")\n\
@@ -189,7 +191,7 @@
                               methf = octave_float_fftw_planner::HYBRID;
                             }
                           else
-                            error ("unrecognized planner METHOD");
+                            error ("fftw: unrecognized planner METHOD");
 
                           if (!error_state)
                             {
@@ -210,7 +212,7 @@
                         }
                     }
                   else
-                    error ("fftw planner expects a string value as METHOD");
+                    error ("fftw: planner expects a string value as METHOD");
                 }
               else //planner getter
                 {
@@ -246,7 +248,7 @@
                           if (arg1.length () < 1)
                             fftw_forget_wisdom ();
                           else if (! fftw_import_wisdom_from_string (arg1.c_str ()))
-                            error ("could not import supplied WISDOM");
+                            error ("fftw: could not import supplied WISDOM");
 
                           if (!error_state)
                             retval = octave_value (std::string (str));
@@ -280,7 +282,7 @@
                           if (arg1.length () < 1)
                             fftwf_forget_wisdom ();
                           else if (! fftwf_import_wisdom_from_string (arg1.c_str ()))
-                            error ("could not import supplied WISDOM");
+                            error ("fftw: could not import supplied WISDOM");
 
                           if (!error_state)
                             retval = octave_value (std::string (str));
@@ -303,24 +305,24 @@
                   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);
 #else
-                          warning ("this copy of Octave was not configured to use the multithreaded fftw libraries.");
+                          gripe_disabled_feature ("fftw", "multithreaded FFTW");
 #endif
 #if defined (HAVE_FFTW3F_THREADS)
                           octave_float_fftw_planner::threads (nthreads);
 #else
-                          warning ("this copy of Octave was not configured to use the multithreaded fftwf libraries.");
+                          gripe_disabled_feature ("fftw", "multithreaded FFTW");
 #endif
                         }
                       else
-                        error ("number of threads must be >=1");
+                        error ("fftw: number of threads must be >=1");
                     }
                   else
-                    error ("setting threads needs one integer argument.");
+                    error ("fftw: setting threads needs one integer argument");
                 }
               else //threads getter
 #if defined (HAVE_FFTW3_THREADS)
@@ -330,14 +332,14 @@
 #endif
             }
           else
-            error ("unrecognized argument");
+            error ("fftw: unrecognized argument");
         }
     }
   else
-    error ("unrecognized argument");
+    error ("fftw: unrecognized argument");
 #else
 
-  warning ("fftw: this copy of Octave was not configured to use the FFTW3 planner");
+  gripe_disabled_feature ("fftw", "the FFTW3 planner");
 
 #endif
 
@@ -367,8 +369,22 @@
 %!   fftw ("planner", def_method);
 %! end_unwind_protect
 
-%!error <Invalid call to fftw> fftw ();
-%!error <Invalid call to fftw> fftw ("planner", "estimate", "measure");
+%!testif HAVE_FFTW
+%! def_dwisdom = fftw ("dwisdom");
+%! def_swisdom = fftw ("swisdom");
+%! unwind_protect
+%!   wisdom = fftw ("dwisdom");
+%!   assert (ischar (wisdom));
+%!   fftw ("dwisdom", wisdom);
+%!   assert (fftw ("dwisdom"), wisdom);
+%!   wisdom = fftw ("swisdom");
+%!   assert (ischar (wisdom));
+%!   fftw ("swisdom", wisdom);
+%!   assert (fftw ("swisdom"), wisdom);
+%! unwind_protect_cleanup
+%!   fftw ("dwisdom", def_dwisdom);
+%!   fftw ("swisdom", def_swisdom);
+%! end_unwind_protect
 
 %!testif HAVE_FFTW3_THREADS
 %! n = fftw ("threads");
@@ -378,4 +394,15 @@
 %! unwind_protect_cleanup
 %!   fftw ("threads", n);
 %! end_unwind_protect
+
+%!error <Invalid call to fftw> fftw ();
+%!error <Invalid call to fftw> fftw ("planner", "estimate", "measure");
+%!error fftw (3);
+%!error fftw ("invalid");
+%!error fftw ("planner", "invalid");
+%!error fftw ("planner", 2);
+%!error fftw ("dwisdom", "invalid");
+%!error fftw ("swisdom", "invalid");
+%!error fftw ("threads", "invalid");
+%!error fftw ("threads", -3);
  */
--- a/libinterp/dldfcn/module-files	Fri Feb 06 08:31:09 2015 -0800
+++ b/libinterp/dldfcn/module-files	Fri Feb 06 08:31:49 2015 -0800
@@ -4,6 +4,8 @@
 __eigs__.cc|$(ARPACK_CPPFLAGS) $(SPARSE_XCPPFLAGS)|$(ARPACK_LDFLAGS) $(SPARSE_XLDFLAGS)|$(ARPACK_LIBS) $(SPARSE_XLIBS) $(LAPACK_LIBS) $(BLAS_LIBS)
 __fltk_uigetfile__.cc|$(GRAPHICS_CFLAGS) $(FT2_CPPFLAGS)|$(GRAPHICS_LDFLAGS) $(FT2_LDFLAGS)|$(GRAPHICS_LIBS) $(FT2_LIBS)
 __glpk__.cc|$(GLPK_CPPFLAGS)|$(GLPK_LDFLAGS)|$(GLPK_LIBS)
+__ichol__.cc
+__ilu__.cc
 __init_fltk__.cc|$(GRAPHICS_CFLAGS) $(FT2_CPPFLAGS) $(FONTCONFIG_CPPFLAGS)|$(GRAPHICS_LDFLAGS) $(FT2_LDFLAGS)|$(GRAPHICS_LIBS) $(FT2_LIBS) $(OPENGL_LIBS)
 __init_gnuplot__.cc|$(FT2_CPPFLAGS) $(FONTCONFIG_CPPFLAGS)||
 __magick_read__.cc|$(MAGICK_CPPFLAGS)|$(MAGICK_LDFLAGS)|$(MAGICK_LIBS)
@@ -19,3 +21,5 @@
 symbfact.cc|$(SPARSE_XCPPFLAGS)|$(SPARSE_XLDFLAGS)|$(SPARSE_XLIBS)
 symrcm.cc|$(SPARSE_XCPPFLAGS)|$(SPARSE_XLDFLAGS)|$(SPARSE_XLIBS)
 tsearch.cc
+audioread.cc|$(SNDFILE_CPPFLAGS)|$(SNDFILE_LDFLAGS)|$(SNDFILE_LIBS)
+audiodevinfo.cc|$(PORTAUDIO_CPPFLAGS)|$(PORTAUDIO_LDFLAGS)|$(PORTAUDIO_LIBS)
--- a/libinterp/dldfcn/qr.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/libinterp/dldfcn/qr.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -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/symbfact.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/libinterp/dldfcn/symbfact.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -114,17 +114,17 @@
   if (spu == 0.)
     {
       cm->print = -1;
-      cm->print_function = 0;
+      SUITESPARSE_ASSIGN_FPTR (printf_func, cm->print_function, 0);
     }
   else
     {
       cm->print = static_cast<int> (spu) + 2;
-      cm->print_function =&SparseCholPrint;
+      SUITESPARSE_ASSIGN_FPTR (printf_func, cm->print_function, &SparseCholPrint);
     }
 
   cm->error_handler = &SparseCholError;
-  cm->complex_divide = CHOLMOD_NAME(divcomplex);
-  cm->hypotenuse = CHOLMOD_NAME(hypot);
+  SUITESPARSE_ASSIGN_FPTR2 (divcomplex_func, cm->complex_divide, divcomplex);
+  SUITESPARSE_ASSIGN_FPTR2 (hypot_func, cm->hypotenuse, hypot);
 
   double dummy;
   cholmod_sparse Astore;
--- a/libinterp/dldfcn/symrcm.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/libinterp/dldfcn/symrcm.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -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];
@@ -414,7 +414,7 @@
 DEFUN_DLD (symrcm, args, ,
            "-*- texinfo -*-\n\
 @deftypefn {Loadable Function} {@var{p} =} symrcm (@var{S})\n\
-Return the symmetric reverse Cuthill-McKee permutation of @var{S}.\n\
+Return the symmetric reverse @nospell{Cuthill-McKee} permutation of @var{S}.\n\
 @var{p} is a permutation vector such that\n\
 @code{@var{S}(@var{p}, @var{p})} tends to have its diagonal elements\n\
 closer to the diagonal than @var{S}.  This is a good preordering for LU\n\
@@ -425,11 +425,11 @@
 bandwidth minimization problem.  The implementation is based in the\n\
 descriptions found in\n\
 \n\
-E. Cuthill, J. McKee. @cite{Reducing the Bandwidth of Sparse Symmetric\n\
-Matrices}. Proceedings of the 24th ACM National Conference, 157--172\n\
-1969, Brandon Press, New Jersey.\n\
+@nospell{E. Cuthill, J. McKee}. @cite{Reducing the Bandwidth of Sparse\n\
+Symmetric Matrices}. Proceedings of the 24th ACM National Conference,\n\
+157--172 1969, Brandon Press, New Jersey.\n\
 \n\
-A. George, J.W.H. Liu. @cite{Computer Solution of Large Sparse\n\
+@nospell{A. George, J.W.H. Liu}. @cite{Computer Solution of Large Sparse\n\
 Positive Definite Systems}, Prentice Hall Series in Computational\n\
 Mathematics, ISBN 0-13-165274-5, 1981.\n\
 \n\
@@ -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 Feb 06 08:31:09 2015 -0800
+++ b/libinterp/dldfcn/tsearch.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -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 Feb 06 08:31:09 2015 -0800
+++ b/libinterp/genprops.awk	Fri Feb 06 08:31:49 2015 -0800
@@ -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 (\"set\", 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 Feb 06 08:31:09 2015 -0800
+++ b/libinterp/octave-value/module.mk	Fri Feb 06 08:31:49 2015 -0800
@@ -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 Feb 06 08:31:09 2015 -0800
+++ b/libinterp/octave-value/ov-base-diag.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -100,7 +100,6 @@
                                         bool resize_ok)
 {
   octave_value retval;
-  typedef typename DMT::element_type el_type;
 
   if (idx.length () == 2 && ! resize_ok)
     {
@@ -412,9 +411,9 @@
 
 template <class DMT, class MT>
 idx_vector
-octave_base_diag<DMT, MT>::index_vector (void) const
+octave_base_diag<DMT, MT>::index_vector (bool require_integers) const
 {
-  return to_dense ().index_vector ();
+  return to_dense ().index_vector (require_integers);
 }
 
 template <class DMT, class MT>
@@ -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 Feb 06 08:31:09 2015 -0800
+++ b/libinterp/octave-value/ov-base-diag.h	Fri Feb 06 08:31:49 2015 -0800
@@ -133,7 +133,7 @@
   double scalar_value (bool frc_str_conv = false) const
   { return double_value (frc_str_conv); }
 
-  idx_vector index_vector (void) const;
+  idx_vector index_vector (bool /* require_integers */ = false) const;
 
   Matrix matrix_value (bool = false) const;
 
@@ -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 Feb 06 08:31:09 2015 -0800
+++ b/libinterp/octave-value/ov-base-int.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -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 Feb 06 08:31:09 2015 -0800
+++ b/libinterp/octave-value/ov-base-int.h	Fri Feb 06 08:31:49 2015 -0800
@@ -29,7 +29,6 @@
 #include <string>
 
 #include "mx-base.h"
-#include "oct-alloc.h"
 #include "str-vec.h"
 
 #include "error.h"
@@ -74,10 +73,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 +118,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 Feb 06 08:31:09 2015 -0800
+++ b/libinterp/octave-value/ov-base-mat.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -27,6 +27,8 @@
 
 #include <iostream>
 
+#include "Array-util.h"
+
 #include "Cell.h"
 #include "oct-obj.h"
 #include "oct-map.h"
@@ -351,7 +353,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 +438,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);
@@ -476,7 +479,10 @@
               octave_print_internal (buf, matrix(j*nr+i));
               std::string tmp = buf.str ();
               size_t pos = tmp.find_first_not_of (" ");
-              os << tmp.substr (pos);
+              if (pos != std::string::npos)
+                os << tmp.substr (pos);
+              else if (! tmp.empty ())
+                os << tmp[0];
 
               if (++elts >= max_elts)
                 goto done;
--- a/libinterp/octave-value/ov-base-mat.h	Fri Feb 06 08:31:09 2015 -0800
+++ b/libinterp/octave-value/ov-base-mat.h	Fri Feb 06 08:31:49 2015 -0800
@@ -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 Feb 06 08:31:09 2015 -0800
+++ b/libinterp/octave-value/ov-base-scalar.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -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);
@@ -176,7 +176,17 @@
   octave_print_internal (buf, scalar);
   std::string tmp = buf.str ();
   size_t pos = tmp.find_first_not_of (" ");
-  os << tmp.substr (pos);
+  if (pos != std::string::npos)
+    os << tmp.substr (pos);
+  else if (! tmp.empty ())
+    os << tmp[0];
+}
+
+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>
--- a/libinterp/octave-value/ov-base-scalar.h	Fri Feb 06 08:31:09 2015 -0800
+++ b/libinterp/octave-value/ov-base-scalar.h	Fri Feb 06 08:31:49 2015 -0800
@@ -30,7 +30,6 @@
 
 #include "lo-mappers.h"
 #include "lo-utils.h"
-#include "oct-alloc.h"
 #include "str-vec.h"
 #include "MatrixType.h"
 
@@ -132,7 +131,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 +147,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 Feb 06 08:31:09 2015 -0800
+++ b/libinterp/octave-value/ov-base-sparse.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -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 Feb 06 08:31:09 2015 -0800
+++ b/libinterp/octave-value/ov-base-sparse.h	Fri Feb 06 08:31:49 2015 -0800
@@ -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 Feb 06 08:31:09 2015 -0800
+++ b/libinterp/octave-value/ov-base.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -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)
@@ -214,7 +215,7 @@
 }
 
 idx_vector
-octave_base_value::index_vector (void) const
+octave_base_value::index_vector (bool /* require_integers */) const
 {
   std::string nm = type_name ();
   error ("%s type invalid as index value", nm.c_str ());
@@ -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 ("string argument required for '.' index");
+                        return retval;
+                      }
+                  }
+                else
+                  {
+                    error ("only single argument permitted 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 Feb 06 08:31:09 2015 -0800
+++ b/libinterp/octave-value/ov-base.h	Fri Feb 06 08:31:49 2015 -0800
@@ -287,7 +287,7 @@
                   const std::list<octave_value_list>& idx,
                   const octave_value& rhs);
 
-  virtual idx_vector index_vector (void) const;
+  virtual idx_vector index_vector (bool require_integers = false) const;
 
   virtual dim_vector dims (void) const { return dim_vector (); }
 
@@ -366,6 +366,8 @@
 
   virtual bool is_object (void) const { return false; }
 
+  virtual bool is_classdef_object (void) const { return false; }
+
   virtual bool is_java (void) const { return false; }
 
   virtual bool is_cs_list (void) const { return false; }
@@ -583,6 +585,9 @@
   virtual octave_base_value *unique_parent_class (const std::string&)
   { return 0; }
 
+  virtual bool is_instance_of (const std::string&) const
+  { return false; }
+
   virtual octave_function *function_value (bool silent = false);
 
   virtual octave_user_function *user_function_value (bool silent = false);
@@ -606,7 +611,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 +833,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 Feb 06 08:31:09 2015 -0800
+++ b/libinterp/octave-value/ov-bool-mat.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -52,7 +52,6 @@
 
 template class octave_base_matrix<boolNDArray>;
 
-DEFINE_OCTAVE_ALLOCATOR (octave_bool_matrix);
 
 DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA (octave_bool_matrix,
                                      "bool matrix", "logical");
@@ -79,7 +78,7 @@
 
   if (matrix.ndims () == 2)
     {
-      boolMatrix bm = matrix.matrix_value ();
+      boolMatrix bm (matrix);
 
       octave_idx_type nr = bm.rows ();
       octave_idx_type nc = bm.cols ();
@@ -421,7 +420,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 +551,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 Feb 06 08:31:09 2015 -0800
+++ b/libinterp/octave-value/ov-bool-mat.h	Fri Feb 06 08:31:49 2015 -0800
@@ -30,7 +30,6 @@
 #include <string>
 
 #include "mx-base.h"
-#include "oct-alloc.h"
 
 #include "error.h"
 #include "oct-stream.h"
@@ -88,8 +87,10 @@
 
   octave_base_value *try_narrowing_conversion (void);
 
-  idx_vector index_vector (void) const
-  { return idx_cache ? *idx_cache : set_idx_cache (idx_vector (matrix)); }
+  idx_vector index_vector (bool /* require_integers */ = false) const
+  {
+    return idx_cache ? *idx_cache : set_idx_cache (idx_vector (matrix));
+  }
 
   builtin_type_t builtin_type (void) const { return btyp_bool; }
 
@@ -133,10 +134,10 @@
   { return double_value (frc_str_conv); }
 
   Matrix matrix_value (bool = false) const
-  { return Matrix (matrix.matrix_value ()); }
+  { return Matrix (boolMatrix (matrix)); }
 
   FloatMatrix float_matrix_value (bool = false) const
-  { return FloatMatrix (matrix.matrix_value ()); }
+  { return FloatMatrix (boolMatrix (matrix)); }
 
   NDArray array_value (bool = false) const
   { return NDArray (matrix); }
@@ -149,10 +150,10 @@
   FloatComplex float_complex_value (bool = false) const;
 
   ComplexMatrix complex_matrix_value (bool = false) const
-  { return ComplexMatrix (matrix.matrix_value ( )); }
+  { return ComplexMatrix (boolMatrix (matrix)); }
 
   FloatComplexMatrix float_complex_matrix_value (bool = false) const
-  { return FloatComplexMatrix (matrix.matrix_value ( )); }
+  { return FloatComplexMatrix (boolMatrix (matrix)); }
 
   ComplexNDArray complex_array_value (bool = false) const
   { return ComplexNDArray (matrix); }
@@ -174,19 +175,19 @@
   }
 
   boolMatrix bool_matrix_value (bool = false) const
-  { return matrix.matrix_value (); }
+  { return boolMatrix (matrix); }
 
   boolNDArray bool_array_value (bool = false) const
   { return matrix; }
 
   SparseMatrix sparse_matrix_value (bool = false) const
-  { return SparseMatrix (Matrix (matrix.matrix_value ())); }
+  { return SparseMatrix (Matrix (boolMatrix (matrix))); }
 
   SparseComplexMatrix sparse_complex_matrix_value (bool = false) const
-  { return SparseComplexMatrix (ComplexMatrix (matrix.matrix_value ())); }
+  { return SparseComplexMatrix (ComplexMatrix (boolMatrix (matrix))); }
 
   SparseBoolMatrix sparse_bool_matrix_value (bool = false) const
-  { return SparseBoolMatrix (matrix.matrix_value ()); }
+  { return SparseBoolMatrix (boolMatrix (matrix)); }
 
   octave_value convert_to_str_internal (bool pad, bool force, char type) const;
 
@@ -230,7 +231,6 @@
 
 protected:
 
-  DECLARE_OCTAVE_ALLOCATOR
 
   DECLARE_OV_TYPEID_FUNCTIONS_AND_DATA
 };
--- a/libinterp/octave-value/ov-bool-sparse.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/libinterp/octave-value/ov-bool-sparse.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -49,7 +49,6 @@
 
 template class OCTINTERP_API octave_base_sparse<SparseBoolMatrix>;
 
-DEFINE_OCTAVE_ALLOCATOR (octave_sparse_bool_matrix);
 
 DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA (octave_sparse_bool_matrix,
                                      "sparse bool matrix", "logical");
@@ -225,16 +224,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 +357,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 +567,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-sparse.h	Fri Feb 06 08:31:09 2015 -0800
+++ b/libinterp/octave-value/ov-bool-sparse.h	Fri Feb 06 08:31:49 2015 -0800
@@ -30,7 +30,6 @@
 #include <string>
 
 #include "mx-base.h"
-#include "oct-alloc.h"
 #include "str-vec.h"
 
 #include "error.h"
@@ -86,8 +85,10 @@
   octave_base_value *try_narrowing_conversion (void);
 
   // FIXME Adapt idx_vector to allow sparse logical indexing without overflow!!
-  idx_vector index_vector (void) const
-  { return idx_vector (matrix); }
+  idx_vector index_vector (bool /* require_integers */ = false) const
+  {
+    return idx_vector (matrix);
+  }
 
   builtin_type_t builtin_type (void) const { return btyp_bool; }
 
@@ -151,7 +152,6 @@
 
 protected:
 
-  DECLARE_OCTAVE_ALLOCATOR
 
   DECLARE_OV_TYPEID_FUNCTIONS_AND_DATA
 };
--- a/libinterp/octave-value/ov-bool.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/libinterp/octave-value/ov-bool.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -46,7 +46,6 @@
 
 template class octave_base_scalar<bool>;
 
-DEFINE_OCTAVE_ALLOCATOR (octave_bool);
 
 DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA (octave_bool, "bool", "logical");
 
@@ -165,7 +164,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-bool.h	Fri Feb 06 08:31:09 2015 -0800
+++ b/libinterp/octave-value/ov-bool.h	Fri Feb 06 08:31:49 2015 -0800
@@ -30,7 +30,6 @@
 
 #include "lo-utils.h"
 #include "mx-base.h"
-#include "oct-alloc.h"
 #include "str-vec.h"
 
 #include "oct-stream.h"
@@ -72,7 +71,7 @@
   octave_value do_index_op (const octave_value_list& idx,
                             bool resize_ok = false);
 
-  idx_vector index_vector (void) const { return idx_vector (scalar); }
+  idx_vector index_vector (bool /* require_integers */ = false) const { return idx_vector (scalar); }
 
   builtin_type_t builtin_type (void) const { return btyp_bool; }
 
@@ -244,7 +243,6 @@
 
 private:
 
-  DECLARE_OCTAVE_ALLOCATOR
 
   DECLARE_OV_TYPEID_FUNCTIONS_AND_DATA
 };
--- a/libinterp/octave-value/ov-builtin.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/libinterp/octave-value/ov-builtin.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -33,7 +33,6 @@
 #include "toplev.h"
 #include "unwind-prot.h"
 
-DEFINE_OCTAVE_ALLOCATOR (octave_builtin);
 
 DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA (octave_builtin,
                                      "built-in function",
@@ -127,7 +126,7 @@
 
       try
         {
-          BEGIN_PROFILER_BLOCK (profiler_name ())
+          BEGIN_PROFILER_BLOCK (octave_builtin)
 
           retval = (*f) (args, nargout);
           // Do not allow null values to be returned from functions.
--- a/libinterp/octave-value/ov-builtin.h	Fri Feb 06 08:31:09 2015 -0800
+++ b/libinterp/octave-value/ov-builtin.h	Fri Feb 06 08:31:49 2015 -0800
@@ -110,7 +110,6 @@
 
   octave_builtin& operator = (const octave_builtin& ob);
 
-  DECLARE_OCTAVE_ALLOCATOR
 
   DECLARE_OV_TYPEID_FUNCTIONS_AND_DATA
 };
--- a/libinterp/octave-value/ov-cell.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/libinterp/octave-value/ov-cell.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -124,7 +124,6 @@
 
 template class octave_base_matrix<Cell>;
 
-DEFINE_OCTAVE_ALLOCATOR (octave_cell);
 
 DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA (octave_cell, "cell", "cell");
 
@@ -687,7 +686,7 @@
 }
 
 void
-octave_cell::print (std::ostream& os, bool) const
+octave_cell::print (std::ostream& os, bool)
 {
   print_raw (os);
 }
@@ -1077,7 +1076,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 Feb 06 08:31:09 2015 -0800
+++ b/libinterp/octave-value/ov-cell.h	Fri Feb 06 08:31:49 2015 -0800
@@ -31,7 +31,6 @@
 #include <memory>
 
 #include "mx-base.h"
-#include "oct-alloc.h"
 #include "str-vec.h"
 
 #include "Cell.h"
@@ -147,7 +146,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;
 
@@ -183,7 +182,6 @@
 
   mutable std::auto_ptr<Array<std::string> > cellstr_cache;
 
-  DECLARE_OCTAVE_ALLOCATOR
 
   DECLARE_OV_TYPEID_FUNCTIONS_AND_DATA
 };
--- a/libinterp/octave-value/ov-ch-mat.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/libinterp/octave-value/ov-ch-mat.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -42,7 +42,7 @@
 template class octave_base_matrix<charNDArray>;
 
 idx_vector
-octave_char_matrix::index_vector (void) const
+octave_char_matrix::index_vector (bool /* require_integers */) const
 {
   const char *p = matrix.data ();
   if (numel () == 1 && *p == ':')
--- a/libinterp/octave-value/ov-ch-mat.h	Fri Feb 06 08:31:09 2015 -0800
+++ b/libinterp/octave-value/ov-ch-mat.h	Fri Feb 06 08:31:49 2015 -0800
@@ -30,7 +30,6 @@
 #include <string>
 
 #include "mx-base.h"
-#include "oct-alloc.h"
 #include "str-vec.h"
 
 #include "error.h"
@@ -87,7 +86,7 @@
   octave_base_value *empty_clone (void) const
   { return new octave_char_matrix (); }
 
-  idx_vector index_vector (void) const;
+  idx_vector index_vector (bool require_integers = false) const;
 
   builtin_type_t builtin_type (void) const { return btyp_char; }
 
@@ -107,10 +106,10 @@
   { return float_value (frc_str_conv); }
 
   Matrix matrix_value (bool = false) const
-  { return Matrix (matrix.matrix_value ()); }
+  { return Matrix (charMatrix (matrix)); }
 
   FloatMatrix float_matrix_value (bool = false) const
-  { return FloatMatrix (matrix.matrix_value ()); }
+  { return FloatMatrix (charMatrix (matrix)); }
 
   NDArray array_value (bool = false) const
   { return NDArray (matrix); }
@@ -123,10 +122,10 @@
   FloatComplex float_complex_value (bool = false) const;
 
   ComplexMatrix complex_matrix_value (bool = false) const
-  { return ComplexMatrix (matrix.matrix_value ()); }
+  { return ComplexMatrix (charMatrix (matrix)); }
 
   FloatComplexMatrix float_complex_matrix_value (bool = false) const
-  { return FloatComplexMatrix (matrix.matrix_value ()); }
+  { return FloatComplexMatrix (charMatrix (matrix)); }
 
   ComplexNDArray complex_array_value (bool = false) const
   { return ComplexNDArray (matrix); }
@@ -135,7 +134,7 @@
   { return FloatComplexNDArray (matrix); }
 
   charMatrix char_matrix_value (bool = false) const
-  { return matrix.matrix_value (); }
+  { return charMatrix (matrix); }
 
   charNDArray char_array_value (bool = false) const
   { return matrix; }
--- a/libinterp/octave-value/ov-class.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/libinterp/octave-value/ov-class.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -57,7 +57,6 @@
 #include "unwind-prot.h"
 #include "variables.h"
 
-DEFINE_OCTAVE_ALLOCATOR(octave_class);
 
 int octave_class::t_id (-1);
 
@@ -268,97 +267,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 +306,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)
 {
@@ -991,7 +885,7 @@
 }
 
 idx_vector
-octave_class::index_vector (void) const
+octave_class::index_vector (bool require_integers) const
 {
   idx_vector retval;
 
@@ -1014,7 +908,7 @@
             // add one to the value returned as the index_vector method
             // expects it to be one based.
             retval = do_binary_op (octave_value::op_add, tmp (0),
-                                   octave_value (1.0)).index_vector ();
+                                   octave_value (1.0)).index_vector (require_integers);
         }
     }
   else
@@ -1120,6 +1014,35 @@
   return retval;
 }
 
+bool
+octave_class::is_instance_of (const std::string& cls_name) const
+{
+  bool retval = false;
+
+  if (cls_name == class_name ())
+    retval = true;
+  else
+    {
+      for (std::list<std::string>::const_iterator pit = parent_list.begin ();
+           pit != parent_list.end ();
+           pit++)
+        {
+          octave_map::const_iterator smap = map.seek (*pit);
+
+          const Cell& tmp = map.contents (smap);
+
+          const octave_value& vtmp = tmp(0);
+
+          retval = vtmp.is_instance_of (cls_name);
+
+          if (retval)
+            break;
+        }
+    }
+
+  return retval;
+}
+
 string_vector
 octave_class::all_strings (bool pad) const
 {
@@ -1139,7 +1062,7 @@
           if (tmp(0).is_string ())
             retval = tmp(0).all_strings (pad);
           else
-            error ("cname/char method did not return a character string");
+            error ("cname/char method did not return a string");
         }
     }
   else
@@ -1150,7 +1073,7 @@
 
 
 void
-octave_class::print (std::ostream& os, bool) const
+octave_class::print (std::ostream& os, bool)
 {
   print_raw (os);
 }
@@ -1279,7 +1202,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 +1211,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 +1353,7 @@
                   success = false;
                 }
             }
-          else if (len == 0 )
+          else if (len == 0)
             {
               map = octave_map (dim_vector (1, 1));
               c_name = classname;
@@ -1573,7 +1497,7 @@
           success = false;
         }
     }
-  else if (len == 0 )
+  else if (len == 0)
     map = octave_map (dim_vector (1, 1));
   else
     panic_impossible ();
@@ -1950,10 +1874,10 @@
       // Called as class constructor
       octave_function *fcn = octave_call_stack::caller ();
 
-      std::string id = args(1).string_value ();
+      if (args(1).is_string ())
+        {
+          std::string id = args(1).string_value ();
 
-      if (! error_state)
-        {
           if (fcn)
             {
               if (fcn->is_class_constructor (id) || fcn->is_class_method (id))
@@ -1998,7 +1922,7 @@
             error ("class: invalid call from outside class constructor or method");
         }
       else
-        error ("class: ID (class name) must be a character string");
+        error ("class: ID (class name) must be a string");
     }
 
   return retval;
@@ -2016,32 +1940,112 @@
 %!error class ()
 */
 
-DEFUN (__isa_parent__, args, ,
+DEFUN (isa, args, ,
        "-*- texinfo -*-\n\
-@deftypefn {Built-in Function} {} __isa_parent__ (@var{class}, @var{name})\n\
-Undocumented internal function.\n\
+@deftypefn {Function File} {} isa (@var{obj}, @var{classname})\n\
+Return true if @var{obj} is an object from the class @var{classname}.\n\
+\n\
+@var{classname} may also be one of the following class categories:\n\
+\n\
+@table @asis\n\
+@item @qcode{\"float\"}\n\
+Floating point value comprising classes @qcode{\"double\"} and\n\
+@qcode{\"single\"}.\n\
+\n\
+@item @qcode{\"integer\"}\n\
+Integer value comprising classes (u)int8, (u)int16, (u)int32, (u)int64.\n\
+\n\
+@item @qcode{\"numeric\"}\n\
+Numeric value comprising either a floating point or integer value.\n\
+@end table\n\
+\n\
+If @var{classname} is a cell array of string, a logical array of the same\n\
+size is returned, containing true for each class to which @var{obj}\n\
+belongs to.\n\
+\n\
+@seealso{class, typeinfo}\n\
 @end deftypefn")
 {
-  octave_value retval = false;
+  octave_value retval;
+
+  if (args.length () != 2)
+    {
+      print_usage ();
+      return retval;
+    }
 
-  if (args.length () == 2)
+  octave_value obj = args(0); // not const because of find_parent_class ()
+  const Array<std::string> cls = args(1).cellstr_value ();
+  if (error_state)
     {
-      octave_value cls = args(0);
-      octave_value nm = args(1);
+      error ("isa: CLASSNAME must be a string or cell array of strings");
+      return retval;
+    }
+
+  boolNDArray matches (cls.dims (), false);
+  const octave_idx_type n = cls.numel ();
+  for (octave_idx_type idx = 0; idx < n; idx++)
+    {
+      const std::string cl = cls(idx);
+      if ((cl == "float"   && obj.is_float_type   ()) ||
+          (cl == "integer" && obj.is_integer_type ()) ||
+          (cl == "numeric" && obj.is_numeric_type ()) ||
+          obj.class_name () == cl || obj.is_instance_of (cl))
+        matches(idx) = true;
+    }
+  return octave_value (matches);
+}
 
-      if (! error_state)
-        {
-          if (cls.find_parent_class (nm.string_value ()))
-            retval = true;
-        }
-      else
-        error ("__isa_parent__: expecting arguments to be character strings");
-    }
-  else
-    print_usage ();
+/*
+%!assert (isa ("char", "float"), false)
+%!assert (isa (logical (1), "float"), false)
+%!assert (isa (double (13), "float"), true)
+%!assert (isa (single (13), "float"), true)
+%!assert (isa (int8 (13), "float"), false)
+%!assert (isa (int16 (13), "float"), false)
+%!assert (isa (int32 (13), "float"), false)
+%!assert (isa (int64 (13), "float"), false)
+%!assert (isa (uint8 (13), "float"), false)
+%!assert (isa (uint16 (13), "float"), false)
+%!assert (isa (uint32 (13), "float"), false)
+%!assert (isa (uint64 (13), "float"), false)
+%!assert (isa ("char", "numeric"), false)
+%!assert (isa (logical (1), "numeric"), false)
+%!assert (isa (double (13), "numeric"), true)
+%!assert (isa (single (13), "numeric"), true)
+%!assert (isa (int8 (13), "numeric"), true)
+%!assert (isa (int16 (13), "numeric"), true)
+%!assert (isa (int32 (13), "numeric"), true)
+%!assert (isa (int64 (13), "numeric"), true)
+%!assert (isa (uint8 (13), "numeric"), true)
+%!assert (isa (uint16 (13), "numeric"), true)
+%!assert (isa (uint32 (13), "numeric"), true)
+%!assert (isa (uint64 (13), "numeric"), true)
+%!assert (isa (uint8 (13), "integer"), true)
+%!assert (isa (double (13), "integer"), false)
+%!assert (isa (single (13), "integer"), false)
+%!assert (isa (single (13), {"integer", "float", "single"}), [false true true])
 
-  return retval;
-}
+%!assert (isa (double (13), "double"))
+%!assert (isa (single (13), "single"))
+%!assert (isa (int8 (13), "int8"))
+%!assert (isa (int16 (13), "int16"))
+%!assert (isa (int32 (13), "int32"))
+%!assert (isa (int64 (13), "int64"))
+%!assert (isa (uint8 (13), "uint8"))
+%!assert (isa (uint16 (13), "uint16"))
+%!assert (isa (uint32 (13), "uint32"))
+%!assert (isa (uint64 (13), "uint64"))
+%!assert (isa ("string", "char"))
+%!assert (isa (true, "logical"))
+%!assert (isa (false, "logical"))
+%!assert (isa ({1, 2}, "cell"))
+%!assert (isa ({1, 2}, {"numeric", "integer", "cell"}), [false false true])
+
+%!test
+%! a.b = 1;
+%! assert (isa (a, "struct"));
+*/
 
 DEFUN (__parent_classes__, args, ,
        "-*- texinfo -*-\n\
@@ -2068,7 +2072,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;
@@ -2083,8 +2087,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 Feb 06 08:31:09 2015 -0800
+++ b/libinterp/octave-value/ov-class.h	Fri Feb 06 08:31:49 2015 -0800
@@ -33,7 +33,6 @@
 #include "str-vec.h"
 
 #include "error.h"
-#include "oct-alloc.h"
 #include "oct-map.h"
 #include "ov-base.h"
 #include "ov-typeinfo.h"
@@ -115,7 +114,7 @@
                                const std::list<octave_value_list>& idx,
                                const octave_value& rhs);
 
-  idx_vector index_vector (void) const;
+  idx_vector index_vector (bool require_integers = false) const;
 
   dim_vector dims (void) const { return map.dims (); }
 
@@ -167,9 +166,11 @@
 
   octave_base_value *unique_parent_class (const std::string&);
 
+  bool is_instance_of (const std::string&) const;
+
   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;
 
@@ -205,7 +206,6 @@
 
   octave_map map;
 
-  DECLARE_OCTAVE_ALLOCATOR
 
 public:
   int type_id (void) const { return t_id; }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libinterp/octave-value/ov-classdef.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,4051 @@
+/*
+
+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"
+
+// Define to 1 to enable debugging statements.
+#define DEBUG_TRACE 0
+
+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;
+}
+
+//----------------------------------------------------------------------------
+
+
+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);
+}
+
+bool
+octave_classdef::is_instance_of (const std::string& cls_name) const
+{
+  cdef_class cls = lookup_class (cls_name, false, false);
+
+  if (cls.ok ())
+    return is_superclass (cls, object.get_class ());
+
+  return false;
+}
+
+//----------------------------------------------------------------------------
+
+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;
+};
+
+//----------------------------------------------------------------------------
+
+octave_map
+cdef_object::map_value (void) const
+{
+  octave_map retval;
+
+  warning_with_id ("Octave:classdef-to-struct",
+                   "struct: converting a classdef object into a struct "
+                   "overrides the access restrictions defined for properties. "
+                   "All properties are returned, including private and "
+                   "protected ones.");
+
+  cdef_class cls = get_class ();
+
+  if (cls.ok ())
+    {
+      std::map<std::string, cdef_property> props;
+
+      props = cls.get_property_map (cdef_class::property_all);
+
+      for (std::map<std::string, cdef_property>::iterator it = props.begin ();
+           it != props.end (); ++it)
+        {
+          octave_value pvalue;
+
+          if (is_array ())
+            {
+              Array<cdef_object> a_obj = array_value ();
+
+              Cell cvalue (a_obj.dims ());
+
+              for (octave_idx_type i = 0; i < a_obj.numel (); i++)
+                {
+                  cvalue (i) = it->second.get_value (a_obj(i), false);
+
+                  if (error_state)
+                    break;
+                }
+
+              if (! error_state)
+                retval.setfield (it->first, cvalue);
+            }
+          else
+            {
+              Cell cvalue (dim_vector (1, 1), it->second.get_value (*this, false));
+
+              if (! error_state)
+                retval.setfield (it->first, cvalue);
+            }
+
+          if (error_state)
+            break;
+        }
+    }
+
+  return retval;
+}
+
+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)
+{
+#if DEBUG_TRACE
+  std::cerr << "deleting " << get_class ().get_name ()
+            << " object (handle)" << std::endl;
+#endif
+}
+
+value_cdef_object::~value_cdef_object (void)
+{
+#if DEBUG_TRACE
+  std::cerr << "deleting " << get_class ().get_name ()
+            << " object (value)" << std::endl;
+#endif
+}
+
+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)
+                        {
+#if DEBUG_TRACE
+                          std::cerr << "explicit superclass constructor: "
+                                    << it->get_name () << std::endl;
+#endif
+
+                          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 (int mode)
+{
+  std::map<std::string,cdef_property> props;
+
+  props = get_property_map (mode);
+
+  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 ();
+}
+
+std::map<std::string, cdef_property>
+cdef_class::cdef_class_rep::get_property_map (int mode)
+{
+  std::map<std::string,cdef_property> props;
+
+  find_properties (props, mode);
+
+  return props;
+}
+
+void
+cdef_class::cdef_class_rep::find_properties (std::map<std::string,cdef_property>& props,
+                                             int mode)
+{
+  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 (mode == property_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,
+                                         (mode == property_all ?
+                                          property_all :
+                                          property_inherited));
+      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
+
+#if DEBUG_TRACE
+      std::cerr << "constructor" << std::endl;
+#endif
+
+      retval(0) = construct (idx.front ());
+      break;
+
+    case '.':
+      // Static method, constant (or property?)
+
+#if DEBUG_TRACE
+      std::cerr << "static method/property" << std::endl;
+#endif
+
+      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;
+
+#if DEBUG_TRACE
+  std::cerr << "class: " << full_class_name << std::endl;
+#endif
+
+  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 ();
+
+#if DEBUG_TRACE
+          std::cerr << "superclass: " << sclass_name << std::endl;
+#endif
+
+          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);
+
+#if DEBUG_TRACE
+          std::cerr << "class attribute: " << aname << " = "
+                    << attribute_value_to_string (*it, avalue) << std::endl;
+#endif
+
+          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;
+
+#if DEBUG_TRACE
+          std::cerr << "method block" << std::endl;
+#endif
+
+          // 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);
+
+#if DEBUG_TRACE
+                  std::cerr << "method attribute: " << aname << " = "
+                            << attribute_value_to_string (*ait, avalue)
+                            << std::endl;
+#endif
+
+                  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);
+
+#if DEBUG_TRACE
+                      std::cerr << (mname == class_name ? "constructor" : "method")
+                                << ": " << mname << std::endl;
+#endif
+
+                      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;
+
+#if DEBUG_TRACE
+          std::cerr << "property block" << std::endl;
+#endif
+
+          // 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);
+
+#if DEBUG_TRACE
+                  std::cerr << "property attribute: " << aname << " = "
+                            << attribute_value_to_string (*ait, avalue)
+                            << std::endl;
+#endif
+
+                  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);
+
+#if DEBUG_TRACE
+                  std::cerr << "property: " << (*pit)->ident ()->name ()
+                            << std::endl;
+#endif
+
+                  if ((*pit)->expression ())
+                    {
+                      octave_value pvalue = (*pit)->expression ()->rvalue1 ();
+
+#if DEBUG_TRACE
+                      std::cerr << "property default: "
+                                << attribute_value_to_string (*pit, pvalue)
+                                << std::endl;
+#endif
+
+                      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 && args(0).is_defined ())
+            {
+              if (args (0).is_classdef_object ())
+                {
+                  cdef_object new_obj = to_cdef (args(0));
+
+                  if (! error_state)
+                    obj = new_obj;
+                }
+              else
+                ::warning ("set-method of property `%s' returned a non-classdef object",
+                           get_name ().c_str ());
+            }
+        }
+    }
+}
+
+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)
+            {
+#if DEBUG_TRACE
+              std::cerr << "meta.package query: " << nm << std::endl;
+#endif
+
+              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, 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;
+
+#if DEBUG_TRACE
+  std::cerr << "__meta_class_query__ ("
+            << args(0).string_value () << ")"
+            << std::endl;
+#endif
+
+  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 Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,1688 @@
+/*
+
+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 (); }
+
+  octave_map map_value (void) const;
+
+  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 (int mode);
+
+    std::map<std::string, cdef_property> get_property_map (int mode);
+
+    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,
+                          int mode = 0);
+
+    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 (int mode = property_normal)
+    { return get_rep ()->get_properties (mode); }
+
+  std::map<std::string, cdef_property>
+  get_property_map (int mode = property_normal)
+    { return get_rep ()->get_property_map (mode); }
+
+  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 (); }
+
+public:
+  enum
+    {
+      property_normal,
+      property_inherited,
+      property_all
+    };
+
+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 false; }
+
+  bool is_object (void) const { return true; }
+
+  bool is_classdef_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);
+
+  bool is_instance_of (const std::string& cls_name) const;
+
+  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 (); }
+
+  octave_map map_value (void) const { return object.map_value (); }
+
+  dim_vector dims (void) const { return object.dims (); }
+
+private:
+  cdef_object object;
+
+private:
+
+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 Feb 06 08:31:09 2015 -0800
+++ b/libinterp/octave-value/ov-colon.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -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 Feb 06 08:31:09 2015 -0800
+++ b/libinterp/octave-value/ov-colon.h	Fri Feb 06 08:31:49 2015 -0800
@@ -59,7 +59,7 @@
   octave_base_value *empty_clone (void) const
   { return new octave_magic_colon (); }
 
-  idx_vector index_vector (void) const { return idx_vector (':'); }
+  idx_vector index_vector (bool /* require_integers */ = false) const { return idx_vector (':'); }
 
   bool is_defined (void) const { return true; }
 
@@ -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 Feb 06 08:31:09 2015 -0800
+++ b/libinterp/octave-value/ov-complex.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -50,7 +50,6 @@
 
 template class octave_base_scalar<Complex>;
 
-DEFINE_OCTAVE_ALLOCATOR (octave_complex);
 
 DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA (octave_complex,
                                      "complex scalar", "double");
@@ -105,7 +104,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 +118,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 +314,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-complex.h	Fri Feb 06 08:31:09 2015 -0800
+++ b/libinterp/octave-value/ov-complex.h	Fri Feb 06 08:31:49 2015 -0800
@@ -30,7 +30,6 @@
 
 #include "lo-ieee.h"
 #include "mx-base.h"
-#include "oct-alloc.h"
 #include "str-vec.h"
 
 #include "gripes.h"
@@ -80,7 +79,7 @@
                             bool resize_ok = false);
 
   // Use this to give a more specific error message
-  idx_vector index_vector (void) const
+  idx_vector index_vector (bool /* require_integers */ = false) const
   {
     error ("attempted to use a complex scalar as an index\n"
            "       (forgot to initialize i or j?)");
@@ -198,7 +197,6 @@
 
 private:
 
-  DECLARE_OCTAVE_ALLOCATOR
 
   DECLARE_OV_TYPEID_FUNCTIONS_AND_DATA
 };
--- a/libinterp/octave-value/ov-cs-list.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/libinterp/octave-value/ov-cs-list.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -35,7 +35,6 @@
 #include "ov-cs-list.h"
 #include "unwind-prot.h"
 
-DEFINE_OCTAVE_ALLOCATOR (octave_cs_list);
 
 DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA (octave_cs_list, "cs-list", "cs-list");
 
--- a/libinterp/octave-value/ov-cs-list.h	Fri Feb 06 08:31:09 2015 -0800
+++ b/libinterp/octave-value/ov-cs-list.h	Fri Feb 06 08:31:49 2015 -0800
@@ -33,7 +33,6 @@
 
 #include "Cell.h"
 #include "error.h"
-#include "oct-alloc.h"
 #include "oct-obj.h"
 #include "ov-typeinfo.h"
 
@@ -83,7 +82,6 @@
   // The list of Octave values.
   octave_value_list lst;
 
-  DECLARE_OCTAVE_ALLOCATOR
 
   DECLARE_OV_TYPEID_FUNCTIONS_AND_DATA
 };
--- a/libinterp/octave-value/ov-cx-diag.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/libinterp/octave-value/ov-cx-diag.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -36,7 +36,6 @@
 
 template class octave_base_diag<ComplexDiagMatrix, ComplexMatrix>;
 
-DEFINE_OCTAVE_ALLOCATOR (octave_complex_diag_matrix);
 
 DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA (octave_complex_diag_matrix,
                                      "complex diagonal matrix", "double");
@@ -167,7 +166,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-diag.h	Fri Feb 06 08:31:09 2015 -0800
+++ b/libinterp/octave-value/ov-cx-diag.h	Fri Feb 06 08:31:49 2015 -0800
@@ -89,7 +89,6 @@
   bool chk_valid_scalar (const octave_value&,
                          Complex&) const;
 
-  DECLARE_OCTAVE_ALLOCATOR
 
   DECLARE_OV_TYPEID_FUNCTIONS_AND_DATA
 };
--- a/libinterp/octave-value/ov-cx-mat.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/libinterp/octave-value/ov-cx-mat.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -58,7 +58,6 @@
 
 template class octave_base_matrix<ComplexNDArray>;
 
-DEFINE_OCTAVE_ALLOCATOR (octave_complex_matrix);
 
 DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA (octave_complex_matrix,
                                      "complex matrix", "double");
@@ -152,7 +151,7 @@
     gripe_implicit_conversion ("Octave:imag-to-real",
                                "complex matrix", "real matrix");
 
-  retval = ::real (matrix.matrix_value ());
+  retval = ::real (ComplexMatrix (matrix));
 
   return retval;
 }
@@ -166,7 +165,7 @@
     gripe_implicit_conversion ("Octave:imag-to-real",
                                "complex matrix", "real matrix");
 
-  retval = ::real (matrix.matrix_value ());
+  retval = ::real (ComplexMatrix (matrix));
 
   return retval;
 }
@@ -214,13 +213,13 @@
 ComplexMatrix
 octave_complex_matrix::complex_matrix_value (bool) const
 {
-  return matrix.matrix_value ();
+  return ComplexMatrix (matrix);
 }
 
 FloatComplexMatrix
 octave_complex_matrix::float_complex_matrix_value (bool) const
 {
-  return FloatComplexMatrix (matrix.matrix_value ());
+  return FloatComplexMatrix (ComplexMatrix (matrix));
 }
 
 boolNDArray
@@ -270,7 +269,7 @@
     gripe_implicit_conversion ("Octave:imag-to-real",
                                "complex matrix", "real matrix");
 
-  retval = SparseMatrix (::real (matrix.matrix_value ()));
+  retval = SparseMatrix (::real (ComplexMatrix (matrix)));
 
   return retval;
 }
@@ -278,7 +277,7 @@
 SparseComplexMatrix
 octave_complex_matrix::sparse_complex_matrix_value (bool) const
 {
-  return SparseComplexMatrix (matrix.matrix_value ());
+  return SparseComplexMatrix (ComplexMatrix (matrix));
 }
 
 octave_value
@@ -302,7 +301,7 @@
   if (matrix.ndims () == 2
       && (matrix.rows () == 1 || matrix.columns () == 1))
     {
-      ComplexMatrix mat = matrix.matrix_value ();
+      ComplexMatrix mat (matrix);
 
       retval = mat.diag (m, n);
     }
@@ -561,7 +560,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-mat.h	Fri Feb 06 08:31:09 2015 -0800
+++ b/libinterp/octave-value/ov-cx-mat.h	Fri Feb 06 08:31:49 2015 -0800
@@ -30,7 +30,6 @@
 #include <string>
 
 #include "mx-base.h"
-#include "oct-alloc.h"
 #include "str-vec.h"
 
 #include "error.h"
@@ -177,7 +176,6 @@
 
 private:
 
-  DECLARE_OCTAVE_ALLOCATOR
 
   DECLARE_OV_TYPEID_FUNCTIONS_AND_DATA
 };
--- a/libinterp/octave-value/ov-cx-sparse.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/libinterp/octave-value/ov-cx-sparse.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -49,7 +49,6 @@
 
 template class OCTINTERP_API octave_base_sparse<SparseComplexMatrix>;
 
-DEFINE_OCTAVE_ALLOCATOR (octave_sparse_complex_matrix);
 
 DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA (octave_sparse_complex_matrix,
                                      "sparse complex matrix", "double");
@@ -241,16 +240,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 +389,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 +636,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-cx-sparse.h	Fri Feb 06 08:31:09 2015 -0800
+++ b/libinterp/octave-value/ov-cx-sparse.h	Fri Feb 06 08:31:49 2015 -0800
@@ -30,7 +30,6 @@
 #include <string>
 
 #include "mx-base.h"
-#include "oct-alloc.h"
 #include "str-vec.h"
 
 #include "error.h"
@@ -154,7 +153,6 @@
 
 private:
 
-  DECLARE_OCTAVE_ALLOCATOR
 
   DECLARE_OV_TYPEID_FUNCTIONS_AND_DATA
 };
--- a/libinterp/octave-value/ov-dld-fcn.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/libinterp/octave-value/ov-dld-fcn.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -33,7 +33,6 @@
 #include "ov-dld-fcn.h"
 #include "ov.h"
 
-DEFINE_OCTAVE_ALLOCATOR (octave_dld_function);
 
 DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA (octave_dld_function,
                                      "dynamically-linked function",
--- a/libinterp/octave-value/ov-dld-fcn.h	Fri Feb 06 08:31:09 2015 -0800
+++ b/libinterp/octave-value/ov-dld-fcn.h	Fri Feb 06 08:31:49 2015 -0800
@@ -95,7 +95,6 @@
 
   octave_dld_function& operator = (const octave_dld_function& fn);
 
-  DECLARE_OCTAVE_ALLOCATOR
 
   DECLARE_OV_TYPEID_FUNCTIONS_AND_DATA
 };
--- a/libinterp/octave-value/ov-fcn-handle.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/libinterp/octave-value/ov-fcn-handle.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -64,7 +64,6 @@
 #include "ls-oct-binary.h"
 #include "ls-utils.h"
 
-DEFINE_OCTAVE_ALLOCATOR (octave_fcn_handle);
 
 DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA (octave_fcn_handle,
                                      "function handle",
@@ -270,7 +269,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 +299,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 +322,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 +720,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);
@@ -1315,7 +1315,7 @@
 %! endif
 %! for i = 1:numel (modes)
 %!   mode = modes{i};
-%!   nm = tmpnam ();
+%!   nm = tempname ();
 %!   unwind_protect
 %!     f2 (1); # bug #33857
 %!     save (mode, nm, "f2", "g2", "hm2", "hdld2", "hbi2");
@@ -1368,7 +1368,7 @@
 %! endif
 %! for i = 1:numel (modes)
 %!   mode = modes{i};
-%!   nm = tmpnam ();
+%!   nm = tempname ();
 %!   unwind_protect
 %!     fcn_handle_save_recurse (2, mode, nm, f2, g2, hm2, hdld2, hbi2);
 %!     clear f2 g2 hm2 hdld2 hbi2
@@ -1386,7 +1386,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 +1572,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));
@@ -1848,10 +1849,11 @@
 
   if (nargin == 1 || nargin == 2)
     {
-      std::string nm = args(0).string_value ();
-
-      if (! error_state)
-        retval = make_fcn_handle (nm, nargin != 2);
+      if (args(0).is_string ())
+        {
+          std::string nm = args(0).string_value ();
+          retval = make_fcn_handle (nm, nargin != 2);
+        }
       else
         error ("str2func: FCN_NAME must be a string");
     }
--- a/libinterp/octave-value/ov-fcn-handle.h	Fri Feb 06 08:31:09 2015 -0800
+++ b/libinterp/octave-value/ov-fcn-handle.h	Fri Feb 06 08:31:49 2015 -0800
@@ -28,7 +28,6 @@
 #include <string>
 #include <memory>
 
-#include "oct-alloc.h"
 
 #include "ov-base.h"
 #include "ov-base-mat.h"
@@ -153,7 +152,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;
 
@@ -164,7 +163,6 @@
 
   bool set_fcn (const std::string &octaveroot, const std::string& fpath);
 
-  DECLARE_OCTAVE_ALLOCATOR
 
   DECLARE_OV_TYPEID_FUNCTIONS_AND_DATA
 
--- a/libinterp/octave-value/ov-fcn-inline.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/libinterp/octave-value/ov-fcn-inline.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -53,7 +53,6 @@
 #include "ls-hdf5.h"
 #include "ls-utils.h"
 
-DEFINE_OCTAVE_ALLOCATOR (octave_fcn_inline);
 
 DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA (octave_fcn_inline,
                                      "inline function",
@@ -284,14 +283,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 +423,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 +597,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);
@@ -852,9 +852,10 @@
        "-*- texinfo -*-\n\
 @deftypefn {Built-in Function} {} formula (@var{fun})\n\
 Return a character string representing the inline function @var{fun}.\n\
+\n\
 Note that @code{char (@var{fun})} is equivalent to\n\
 @code{formula (@var{fun})}.\n\
-@seealso{argnames, inline, vectorize}\n\
+@seealso{char, argnames, inline, vectorize}\n\
 @end deftypefn")
 {
   octave_value retval;
--- a/libinterp/octave-value/ov-fcn-inline.h	Fri Feb 06 08:31:09 2015 -0800
+++ b/libinterp/octave-value/ov-fcn-inline.h	Fri Feb 06 08:31:49 2015 -0800
@@ -26,7 +26,6 @@
 #include <iosfwd>
 #include <string>
 
-#include "oct-alloc.h"
 
 #include "ov-base.h"
 #include "ov-base-mat.h"
@@ -86,13 +85,12 @@
   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;
 
 private:
 
-  DECLARE_OCTAVE_ALLOCATOR
 
   DECLARE_OV_TYPEID_FUNCTIONS_AND_DATA
 
--- a/libinterp/octave-value/ov-fcn.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/libinterp/octave-value/ov-fcn.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -28,7 +28,6 @@
 #include "oct-obj.h"
 #include "ov-fcn.h"
 
-DEFINE_OCTAVE_ALLOCATOR (octave_function);
 
 octave_base_value *
 octave_function::clone (void) const
--- a/libinterp/octave-value/ov-fcn.h	Fri Feb 06 08:31:09 2015 -0800
+++ b/libinterp/octave-value/ov-fcn.h	Fri Feb 06 08:31:49 2015 -0800
@@ -28,7 +28,6 @@
 #include "oct-time.h"
 #include "str-vec.h"
 
-#include "oct-alloc.h"
 #include "oct-obj.h"
 #include "ov-base.h"
 #include "ov-typeinfo.h"
@@ -46,7 +45,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 +85,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 +100,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 +160,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 +176,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 +200,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;
 
@@ -199,7 +222,6 @@
 
   octave_function& operator = (const octave_function& f);
 
-  DECLARE_OCTAVE_ALLOCATOR
 };
 
 #endif
--- a/libinterp/octave-value/ov-float.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/libinterp/octave-value/ov-float.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -53,7 +53,6 @@
 
 template class octave_base_scalar<float>;
 
-DEFINE_OCTAVE_ALLOCATOR (octave_float_scalar);
 
 DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA (octave_float_scalar, "float scalar",
                                      "single");
@@ -191,7 +190,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 +326,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-float.h	Fri Feb 06 08:31:09 2015 -0800
+++ b/libinterp/octave-value/ov-float.h	Fri Feb 06 08:31:49 2015 -0800
@@ -32,7 +32,6 @@
 #include "lo-mappers.h"
 #include "lo-utils.h"
 #include "mx-base.h"
-#include "oct-alloc.h"
 #include "str-vec.h"
 
 #include "gripes.h"
@@ -77,7 +76,7 @@
   octave_value do_index_op (const octave_value_list& idx,
                             bool resize_ok = false);
 
-  idx_vector index_vector (void) const { return idx_vector (scalar); }
+  idx_vector index_vector (bool /* require_integers */ = false) const { return idx_vector (scalar); }
 
   octave_value any (int = 0) const
   { return (scalar != 0 && ! lo_ieee_isnan (scalar)); }
@@ -254,7 +253,6 @@
 
 private:
 
-  DECLARE_OCTAVE_ALLOCATOR
 
   DECLARE_OV_TYPEID_FUNCTIONS_AND_DATA
 };
--- a/libinterp/octave-value/ov-flt-complex.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/libinterp/octave-value/ov-flt-complex.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -50,7 +50,6 @@
 
 template class octave_base_scalar<FloatComplex>;
 
-DEFINE_OCTAVE_ALLOCATOR (octave_float_complex);
 
 DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA (octave_float_complex,
                                      "float complex scalar", "single");
@@ -89,7 +88,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 +102,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 +299,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-complex.h	Fri Feb 06 08:31:09 2015 -0800
+++ b/libinterp/octave-value/ov-flt-complex.h	Fri Feb 06 08:31:49 2015 -0800
@@ -30,7 +30,6 @@
 
 #include "lo-ieee.h"
 #include "mx-base.h"
-#include "oct-alloc.h"
 #include "str-vec.h"
 
 #include "gripes.h"
@@ -189,7 +188,6 @@
 
 private:
 
-  DECLARE_OCTAVE_ALLOCATOR
 
   DECLARE_OV_TYPEID_FUNCTIONS_AND_DATA
 };
--- a/libinterp/octave-value/ov-flt-cx-diag.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/libinterp/octave-value/ov-flt-cx-diag.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -35,7 +35,6 @@
 
 template class octave_base_diag<FloatComplexDiagMatrix, FloatComplexMatrix>;
 
-DEFINE_OCTAVE_ALLOCATOR (octave_float_complex_diag_matrix);
 
 DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA (octave_float_complex_diag_matrix,
                                      "float complex diagonal matrix", "single");
@@ -150,7 +149,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-diag.h	Fri Feb 06 08:31:09 2015 -0800
+++ b/libinterp/octave-value/ov-flt-cx-diag.h	Fri Feb 06 08:31:49 2015 -0800
@@ -87,7 +87,6 @@
   bool chk_valid_scalar (const octave_value&,
                          FloatComplex&) const;
 
-  DECLARE_OCTAVE_ALLOCATOR
 
   DECLARE_OV_TYPEID_FUNCTIONS_AND_DATA
 };
--- a/libinterp/octave-value/ov-flt-cx-mat.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/libinterp/octave-value/ov-flt-cx-mat.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -62,7 +62,6 @@
 
 template class octave_base_matrix<FloatComplexNDArray>;
 
-DEFINE_OCTAVE_ALLOCATOR (octave_float_complex_matrix);
 
 DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA (octave_float_complex_matrix,
                                      "float complex matrix", "single");
@@ -140,7 +139,7 @@
     gripe_implicit_conversion ("Octave:imag-to-real",
                                "complex matrix", "real matrix");
 
-  retval = ::real (matrix.matrix_value ());
+  retval = ::real (FloatComplexMatrix (matrix));
 
   return retval;
 }
@@ -154,7 +153,7 @@
     gripe_implicit_conversion ("Octave:imag-to-real",
                                "complex matrix", "real matrix");
 
-  retval = ::real (matrix.matrix_value ());
+  retval = ::real (FloatComplexMatrix (matrix));
 
   return retval;
 }
@@ -202,13 +201,13 @@
 ComplexMatrix
 octave_float_complex_matrix::complex_matrix_value (bool) const
 {
-  return matrix.matrix_value ();
+  return FloatComplexMatrix (matrix);
 }
 
 FloatComplexMatrix
 octave_float_complex_matrix::float_complex_matrix_value (bool) const
 {
-  return FloatComplexMatrix (matrix.matrix_value ());
+  return FloatComplexMatrix (matrix);
 }
 
 boolNDArray
@@ -290,7 +289,7 @@
   if (matrix.ndims () == 2
       && (matrix.rows () == 1 || matrix.columns () == 1))
     {
-      FloatComplexMatrix mat = matrix.matrix_value ();
+      FloatComplexMatrix mat (matrix);
 
       retval = mat.diag (m, n);
     }
@@ -536,7 +535,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-cx-mat.h	Fri Feb 06 08:31:09 2015 -0800
+++ b/libinterp/octave-value/ov-flt-cx-mat.h	Fri Feb 06 08:31:49 2015 -0800
@@ -30,7 +30,6 @@
 #include <string>
 
 #include "mx-base.h"
-#include "oct-alloc.h"
 #include "str-vec.h"
 
 #include "error.h"
@@ -175,7 +174,6 @@
 
 private:
 
-  DECLARE_OCTAVE_ALLOCATOR
 
   DECLARE_OV_TYPEID_FUNCTIONS_AND_DATA
 };
--- a/libinterp/octave-value/ov-flt-re-diag.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/libinterp/octave-value/ov-flt-re-diag.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -34,7 +34,6 @@
 
 template class octave_base_diag<FloatDiagMatrix, FloatMatrix>;
 
-DEFINE_OCTAVE_ALLOCATOR (octave_float_diag_matrix);
 
 DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA (octave_float_diag_matrix,
                                      "float diagonal matrix", "single");
@@ -119,7 +118,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-diag.h	Fri Feb 06 08:31:09 2015 -0800
+++ b/libinterp/octave-value/ov-flt-re-diag.h	Fri Feb 06 08:31:49 2015 -0800
@@ -87,7 +87,6 @@
   bool chk_valid_scalar (const octave_value&,
                          float&) const;
 
-  DECLARE_OCTAVE_ALLOCATOR
 
   DECLARE_OV_TYPEID_FUNCTIONS_AND_DATA
 };
--- a/libinterp/octave-value/ov-flt-re-mat.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/libinterp/octave-value/ov-flt-re-mat.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -70,7 +70,6 @@
 
 template class octave_base_matrix<FloatNDArray>;
 
-DEFINE_OCTAVE_ALLOCATOR (octave_float_matrix);
 
 DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA (octave_float_matrix, "float matrix",
                                      "single");
@@ -127,13 +126,13 @@
 Matrix
 octave_float_matrix::matrix_value (bool) const
 {
-  return Matrix (matrix.matrix_value ());
+  return Matrix (FloatMatrix (matrix));
 }
 
 FloatMatrix
 octave_float_matrix::float_matrix_value (bool) const
 {
-  return matrix.matrix_value ();
+  return FloatMatrix (matrix);
 }
 
 Complex
@@ -181,13 +180,13 @@
 ComplexMatrix
 octave_float_matrix::complex_matrix_value (bool) const
 {
-  return ComplexMatrix (matrix.matrix_value ());
+  return ComplexMatrix (FloatMatrix (matrix));
 }
 
 FloatComplexMatrix
 octave_float_matrix::float_complex_matrix_value (bool) const
 {
-  return FloatComplexMatrix (matrix.matrix_value ());
+  return FloatComplexMatrix (FloatMatrix (matrix));
 }
 
 ComplexNDArray
@@ -268,7 +267,7 @@
   if (matrix.ndims () == 2
       && (matrix.rows () == 1 || matrix.columns () == 1))
     {
-      FloatMatrix mat = matrix.matrix_value ();
+      FloatMatrix mat (matrix);
 
       retval = mat.diag (m, n);
     }
@@ -563,7 +562,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 +811,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-flt-re-mat.h	Fri Feb 06 08:31:09 2015 -0800
+++ b/libinterp/octave-value/ov-flt-re-mat.h	Fri Feb 06 08:31:49 2015 -0800
@@ -30,7 +30,6 @@
 #include <string>
 
 #include "mx-base.h"
-#include "oct-alloc.h"
 #include "str-vec.h"
 
 #include "error.h"
@@ -89,8 +88,10 @@
 
   octave_base_value *try_narrowing_conversion (void);
 
-  idx_vector index_vector (void) const
-  { return idx_cache ? *idx_cache : set_idx_cache (idx_vector (matrix)); }
+  idx_vector index_vector (bool /* require_integers */ = false) const
+  {
+    return idx_cache ? *idx_cache : set_idx_cache (idx_vector (matrix));
+  }
 
   builtin_type_t builtin_type (void) const { return btyp_float; }
 
@@ -208,7 +209,6 @@
   octave_value map (unary_mapper_t umap) const;
 
 private:
-  DECLARE_OCTAVE_ALLOCATOR
 
   DECLARE_OV_TYPEID_FUNCTIONS_AND_DATA
 };
--- a/libinterp/octave-value/ov-int16.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/libinterp/octave-value/ov-int16.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -59,7 +59,6 @@
 
 template class octave_base_int_matrix<int16NDArray>;
 
-DEFINE_OCTAVE_ALLOCATOR (octave_int16_matrix);
 
 DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA (octave_int16_matrix,
                                      "int16 matrix", "int16");
@@ -68,7 +67,6 @@
 
 template class octave_base_int_scalar<octave_int16>;
 
-DEFINE_OCTAVE_ALLOCATOR (octave_int16_scalar);
 
 DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA (octave_int16_scalar,
                                      "int16 scalar", "int16");
--- a/libinterp/octave-value/ov-int32.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/libinterp/octave-value/ov-int32.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -59,7 +59,6 @@
 
 template class octave_base_int_matrix<int32NDArray>;
 
-DEFINE_OCTAVE_ALLOCATOR (octave_int32_matrix);
 
 DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA (octave_int32_matrix,
                                      "int32 matrix", "int32");
@@ -68,7 +67,6 @@
 
 template class octave_base_int_scalar<octave_int32>;
 
-DEFINE_OCTAVE_ALLOCATOR (octave_int32_scalar);
 
 DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA (octave_int32_scalar,
                                      "int32 scalar", "int32");
--- a/libinterp/octave-value/ov-int64.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/libinterp/octave-value/ov-int64.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -59,7 +59,6 @@
 
 template class octave_base_int_matrix<int64NDArray>;
 
-DEFINE_OCTAVE_ALLOCATOR (octave_int64_matrix);
 
 DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA (octave_int64_matrix,
                                      "int64 matrix", "int64");
@@ -68,7 +67,6 @@
 
 template class octave_base_int_scalar<octave_int64>;
 
-DEFINE_OCTAVE_ALLOCATOR (octave_int64_scalar);
 
 DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA (octave_int64_scalar,
                                      "int64 scalar", "int64");
--- a/libinterp/octave-value/ov-int8.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/libinterp/octave-value/ov-int8.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -59,7 +59,6 @@
 
 template class octave_base_int_matrix<int8NDArray>;
 
-DEFINE_OCTAVE_ALLOCATOR (octave_int8_matrix);
 
 DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA (octave_int8_matrix,
                                      "int8 matrix", "int8");
@@ -68,7 +67,6 @@
 
 template class octave_base_int_scalar<octave_int8>;
 
-DEFINE_OCTAVE_ALLOCATOR (octave_int8_scalar);
 
 DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA (octave_int8_scalar,
                                      "int8 scalar", "int8");
--- a/libinterp/octave-value/ov-intx.h	Fri Feb 06 08:31:09 2015 -0800
+++ b/libinterp/octave-value/ov-intx.h	Fri Feb 06 08:31:49 2015 -0800
@@ -27,7 +27,6 @@
 #include <string>
 
 #include "mx-base.h"
-#include "oct-alloc.h"
 #include "str-vec.h"
 
 #include "error.h"
@@ -303,8 +302,10 @@
     matrix_ref ().changesign ();
   }
 
-  idx_vector index_vector (void) const
-  { return idx_cache ? *idx_cache : set_idx_cache (idx_vector (matrix)); }
+  idx_vector index_vector (bool /* require_integers */ = false) const
+  {
+    return idx_cache ? *idx_cache : set_idx_cache (idx_vector (matrix));
+  }
 
   int write (octave_stream& os, int block_size,
              oct_data_conv::data_type output_type, int skip,
@@ -356,8 +357,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);
         }
@@ -366,7 +374,6 @@
 
 private:
 
-  DECLARE_OCTAVE_ALLOCATOR
 
   DECLARE_OV_TYPEID_FUNCTIONS_AND_DATA
 };
@@ -606,7 +613,7 @@
     scalar -= OCTAVE_INT_T (1);
   }
 
-  idx_vector index_vector (void) const { return idx_vector (scalar); }
+  idx_vector index_vector (bool /* require_integers */ = false) const { return idx_vector (scalar); }
 
   int write (octave_stream& os, int block_size,
              oct_data_conv::data_type output_type, octave_idx_type skip,
@@ -656,6 +663,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 ());
@@ -666,7 +678,6 @@
 
 private:
 
-  DECLARE_OCTAVE_ALLOCATOR
 
   DECLARE_OV_TYPEID_FUNCTIONS_AND_DATA
 };
--- a/libinterp/octave-value/ov-java.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/libinterp/octave-value/ov-java.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -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)
                 {
@@ -1568,7 +1569,6 @@
 
 // octave_java class definition
 
-DEFINE_OCTAVE_ALLOCATOR (octave_java);
 
 int octave_java::t_id (-1);
 
@@ -1761,7 +1761,7 @@
 }
 
 void
-octave_java::print (std::ostream& os, bool) const
+octave_java::print (std::ostream& os, bool)
 {
   print_raw (os);
   newline (os);
@@ -2049,9 +2049,10 @@
 
       if (args.length () > 0)
         {
-          std::string classname = args(0).string_value ();
-          if (! error_state)
+          if (args(0).is_string ())
             {
+              std::string classname = args(0).string_value ();
+
               octave_value_list tmp;
               for (int i=1; i<args.length (); i++)
                 tmp(i-1) = args(i);
@@ -2113,9 +2114,10 @@
 
       if (args.length () > 1)
         {
-          std::string methodname = args(0).string_value ();
-          if (! error_state)
+          if (args(0).is_string ())
             {
+              std::string methodname = args(0).string_value ();
+
               octave_value_list tmp;
               for (int i=2; i<args.length (); i++)
                 tmp(i-2) = args(i);
@@ -2186,9 +2188,10 @@
 
       if (args.length () == 2)
         {
-          std::string name = args(1).string_value ();
-          if (! error_state)
+          if (args(1).is_string ())
             {
+              std::string name = args(1).string_value ();
+
               if (args(0).is_java ())
                 {
                   octave_java *jobj = TO_JAVA (args(0));
@@ -2248,9 +2251,10 @@
 
       if (args.length () == 3)
         {
-          std::string name = args(1).string_value ();
-          if (! error_state)
+          if (args(1).is_string ())
             {
+              std::string name = args(1).string_value ();
+
               if (args(0).is_java ())
                 {
                   octave_java *jobj = TO_JAVA (args(0));
--- a/libinterp/octave-value/ov-java.h	Fri Feb 06 08:31:09 2015 -0800
+++ b/libinterp/octave-value/ov-java.h	Fri Feb 06 08:31:49 2015 -0800
@@ -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;
 
@@ -294,7 +294,6 @@
 
   std::string java_classname;
 
-  DECLARE_OCTAVE_ALLOCATOR
 
 public:
   int type_id (void) const { return t_id; }
--- a/libinterp/octave-value/ov-lazy-idx.h	Fri Feb 06 08:31:09 2015 -0800
+++ b/libinterp/octave-value/ov-lazy-idx.h	Fri Feb 06 08:31:49 2015 -0800
@@ -59,8 +59,7 @@
 
   octave_value full_value (void) const { return make_value (); }
 
-  idx_vector index_vector (void) const
-  { return index; }
+  idx_vector index_vector (bool /* require_integers */ = false) const { return index; }
 
   builtin_type_t builtin_type (void) const { return btyp_double; }
 
@@ -129,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-mex-fcn.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/libinterp/octave-value/ov-mex-fcn.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -37,7 +37,6 @@
 #include "toplev.h"
 #include "unwind-prot.h"
 
-DEFINE_OCTAVE_ALLOCATOR (octave_mex_function);
 
 DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA (octave_mex_function,
                                      "mex function", "mex function");
@@ -148,8 +147,10 @@
 
       try
         {
-          BEGIN_PROFILER_BLOCK (profiler_name ())
+          BEGIN_PROFILER_BLOCK (octave_mex_function)
+
           retval = call_mex (have_fmex, mex_fcn_ptr, args, nargout, this);
+
           END_PROFILER_BLOCK
         }
       catch (octave_execution_exception)
--- a/libinterp/octave-value/ov-mex-fcn.h	Fri Feb 06 08:31:09 2015 -0800
+++ b/libinterp/octave-value/ov-mex-fcn.h	Fri Feb 06 08:31:49 2015 -0800
@@ -114,7 +114,6 @@
 
   octave_mex_function& operator = (const octave_mex_function& fn);
 
-  DECLARE_OCTAVE_ALLOCATOR
 
   DECLARE_OV_TYPEID_FUNCTIONS_AND_DATA
 };
--- a/libinterp/octave-value/ov-oncleanup.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/libinterp/octave-value/ov-oncleanup.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -98,14 +98,9 @@
       error ("onCleanup: internal error: unhandled exception in cleanup action");
     }
 
-  // We don't want to ignore errors that occur in the cleanup code, so
-  // if an error is encountered there, leave error_state alone.
-  // Otherwise, set it back to what it was before.
+  // FIXME: can this happen now?
   if (error_state)
-    {
-      frame.discard_first ();
-      octave_call_stack::backtrace_error_message ();
-    }
+    frame.discard_first ();
 }
 
 octave_scalar_map
@@ -170,7 +165,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 Feb 06 08:31:09 2015 -0800
+++ b/libinterp/octave-value/ov-oncleanup.h	Fri Feb 06 08:31:49 2015 -0800
@@ -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 Feb 06 08:31:09 2015 -0800
+++ b/libinterp/octave-value/ov-perm.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -245,9 +245,9 @@
 FORWARD_MATRIX_VALUE (charNDArray, char_array)
 
 idx_vector
-octave_perm_matrix::index_vector (void) const
+octave_perm_matrix::index_vector (bool require_integers) const
 {
-  return to_dense ().index_vector ();
+  return to_dense ().index_vector (require_integers);
 }
 
 octave_value
@@ -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);
@@ -420,7 +418,6 @@
   return dense_cache;
 }
 
-DEFINE_OCTAVE_ALLOCATOR (octave_perm_matrix);
 
 DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA (octave_perm_matrix,
                                      "permutation matrix", "double");
@@ -451,3 +448,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 Feb 06 08:31:09 2015 -0800
+++ b/libinterp/octave-value/ov-perm.h	Fri Feb 06 08:31:49 2015 -0800
@@ -131,7 +131,7 @@
   double scalar_value (bool frc_str_conv = false) const
   { return double_value (frc_str_conv); }
 
-  idx_vector index_vector (void) const;
+  idx_vector index_vector (bool require_integers = false) const;
 
   PermMatrix perm_matrix_value (void) const
   { return matrix; }
@@ -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;
@@ -228,7 +230,6 @@
 
 private:
 
-  DECLARE_OCTAVE_ALLOCATOR
 
   DECLARE_OV_TYPEID_FUNCTIONS_AND_DATA
 };
--- a/libinterp/octave-value/ov-range.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/libinterp/octave-value/ov-range.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -46,9 +46,8 @@
 #include "ls-utils.h"
 
 // If TRUE, allow ranges with non-integer elements as array indices.
-bool Vallow_noninteger_range_as_index = false;
+static bool Vallow_noninteger_range_as_index = true;
 
-DEFINE_OCTAVE_ALLOCATOR (octave_range);
 
 DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA (octave_range, "range", "double");
 
@@ -148,13 +147,14 @@
 }
 
 idx_vector
-octave_range::index_vector (void) const
+octave_range::index_vector (bool require_integers) const
 {
   if (idx_cache)
     return *idx_cache;
   else
     {
-      if (! Vallow_noninteger_range_as_index
+      if (require_integers
+          || ! Vallow_noninteger_range_as_index
           || range.all_elements_are_ints ())
         return set_idx_cache (idx_vector (range));
       else
@@ -351,7 +351,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);
@@ -548,7 +548,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);
@@ -675,6 +676,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\
@@ -690,6 +698,14 @@
 The original variable value is restored when exiting the function.\n\
 @end deftypefn")
 {
+  static bool warned = false;
+  if (! warned)
+    {
+      warned = true;
+      warning_with_id ("Octave:deprecated-function",
+                       "allow_noninteger_range_as_index is obsolete and will be removed from a future version of Octave");
+    }
+
   return SET_INTERNAL_VARIABLE (allow_noninteger_range_as_index);
 }
 
--- a/libinterp/octave-value/ov-range.h	Fri Feb 06 08:31:09 2015 -0800
+++ b/libinterp/octave-value/ov-range.h	Fri Feb 06 08:31:49 2015 -0800
@@ -33,7 +33,6 @@
 #include "lo-mappers.h"
 #include "lo-utils.h"
 #include "mx-base.h"
-#include "oct-alloc.h"
 #include "str-vec.h"
 
 #include "error.h"
@@ -104,7 +103,7 @@
   octave_value do_index_op (const octave_value_list& idx,
                             bool resize_ok = false);
 
-  idx_vector index_vector (void) const;
+  idx_vector index_vector (bool require_integers = false) const;
 
   dim_vector dims (void) const
   {
@@ -249,7 +248,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 +289,8 @@
     return m.map (umap);
   }
 
+  octave_value fast_elem_extract (octave_idx_type n) const;
+
 private:
 
   Range range;
@@ -312,12 +313,8 @@
 
   octave_range& operator = (const octave_range&);
 
-  DECLARE_OCTAVE_ALLOCATOR
 
   DECLARE_OV_TYPEID_FUNCTIONS_AND_DATA
 };
 
-// If TRUE, allow ranges with non-integer elements as array indices.
-extern bool Vallow_noninteger_range_as_index;
-
 #endif
--- a/libinterp/octave-value/ov-re-diag.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/libinterp/octave-value/ov-re-diag.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -35,7 +35,6 @@
 
 template class octave_base_diag<DiagMatrix, Matrix>;
 
-DEFINE_OCTAVE_ALLOCATOR (octave_diag_matrix);
 
 DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA (octave_diag_matrix, "diagonal matrix",
                                      "double");
@@ -179,7 +178,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-diag.h	Fri Feb 06 08:31:09 2015 -0800
+++ b/libinterp/octave-value/ov-re-diag.h	Fri Feb 06 08:31:49 2015 -0800
@@ -92,7 +92,6 @@
   bool chk_valid_scalar (const octave_value&,
                          double&) const;
 
-  DECLARE_OCTAVE_ALLOCATOR
 
   DECLARE_OV_TYPEID_FUNCTIONS_AND_DATA
 };
--- a/libinterp/octave-value/ov-re-mat.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/libinterp/octave-value/ov-re-mat.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -70,7 +70,6 @@
 
 template class octave_base_matrix<NDArray>;
 
-DEFINE_OCTAVE_ALLOCATOR (octave_matrix);
 
 DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA (octave_matrix, "matrix", "double");
 
@@ -142,13 +141,13 @@
 Matrix
 octave_matrix::matrix_value (bool) const
 {
-  return matrix.matrix_value ();
+  return Matrix (matrix);
 }
 
 FloatMatrix
 octave_matrix::float_matrix_value (bool) const
 {
-  return FloatMatrix (matrix.matrix_value ());
+  return FloatMatrix (Matrix (matrix));
 }
 
 Complex
@@ -196,13 +195,13 @@
 ComplexMatrix
 octave_matrix::complex_matrix_value (bool) const
 {
-  return ComplexMatrix (matrix.matrix_value ());
+  return ComplexMatrix (Matrix (matrix));
 }
 
 FloatComplexMatrix
 octave_matrix::float_complex_matrix_value (bool) const
 {
-  return FloatComplexMatrix (matrix.matrix_value ());
+  return FloatComplexMatrix (Matrix (matrix));
 }
 
 ComplexNDArray
@@ -244,7 +243,7 @@
 SparseMatrix
 octave_matrix::sparse_matrix_value (bool) const
 {
-  return SparseMatrix (matrix.matrix_value ());
+  return SparseMatrix (Matrix (matrix));
 }
 
 SparseComplexMatrix
@@ -277,7 +276,7 @@
   if (matrix.ndims () == 2
       && (matrix.rows () == 1 || matrix.columns () == 1))
     {
-      Matrix mat = matrix.matrix_value ();
+      Matrix mat (matrix);
 
       retval = mat.diag (m, n);
     }
@@ -675,7 +674,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 +934,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-mat.h	Fri Feb 06 08:31:09 2015 -0800
+++ b/libinterp/octave-value/ov-re-mat.h	Fri Feb 06 08:31:49 2015 -0800
@@ -30,7 +30,6 @@
 #include <string>
 
 #include "mx-base.h"
-#include "oct-alloc.h"
 #include "str-vec.h"
 
 #include "error.h"
@@ -104,7 +103,7 @@
 
   octave_base_value *try_narrowing_conversion (void);
 
-  idx_vector index_vector (void) const
+  idx_vector index_vector (bool /* require_integers */ = false) const
   { return idx_cache ? *idx_cache : set_idx_cache (idx_vector (matrix)); }
 
   builtin_type_t builtin_type (void) const { return btyp_double; }
@@ -234,7 +233,6 @@
   octave_value map (unary_mapper_t umap) const;
 
 private:
-  DECLARE_OCTAVE_ALLOCATOR
 
   DECLARE_OV_TYPEID_FUNCTIONS_AND_DATA
 };
--- a/libinterp/octave-value/ov-re-sparse.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/libinterp/octave-value/ov-re-sparse.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -49,13 +49,12 @@
 
 template class OCTINTERP_API octave_base_sparse<SparseMatrix>;
 
-DEFINE_OCTAVE_ALLOCATOR (octave_sparse_matrix);
 
 DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA (octave_sparse_matrix, "sparse matrix",
                                      "double");
 
 idx_vector
-octave_sparse_matrix::index_vector (void) const
+octave_sparse_matrix::index_vector (bool /* require_integers */) const
 {
   if (matrix.numel () == matrix.nnz ())
     return idx_vector (array_value ());
@@ -274,16 +273,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 +420,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-re-sparse.h	Fri Feb 06 08:31:09 2015 -0800
+++ b/libinterp/octave-value/ov-re-sparse.h	Fri Feb 06 08:31:49 2015 -0800
@@ -30,7 +30,6 @@
 #include <string>
 
 #include "mx-base.h"
-#include "oct-alloc.h"
 #include "str-vec.h"
 
 #include "error.h"
@@ -92,7 +91,7 @@
 
   octave_base_value *try_narrowing_conversion (void);
 
-  idx_vector index_vector (void) const;
+  idx_vector index_vector (bool require_integers = false) const;
 
   builtin_type_t builtin_type (void) const { return btyp_double; }
 
@@ -158,7 +157,6 @@
 private:
   octave_value map (double (*fcn) (double)) const;
 
-  DECLARE_OCTAVE_ALLOCATOR
 
   DECLARE_OV_TYPEID_FUNCTIONS_AND_DATA
 };
--- a/libinterp/octave-value/ov-scalar.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/libinterp/octave-value/ov-scalar.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -53,7 +53,6 @@
 
 template class octave_base_scalar<double>;
 
-DEFINE_OCTAVE_ALLOCATOR (octave_scalar);
 
 DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA (octave_scalar, "scalar", "double");
 
@@ -206,7 +205,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 +342,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-scalar.h	Fri Feb 06 08:31:09 2015 -0800
+++ b/libinterp/octave-value/ov-scalar.h	Fri Feb 06 08:31:49 2015 -0800
@@ -32,7 +32,6 @@
 #include "lo-mappers.h"
 #include "lo-utils.h"
 #include "mx-base.h"
-#include "oct-alloc.h"
 #include "str-vec.h"
 
 #include "gripes.h"
@@ -76,7 +75,7 @@
 
   type_conv_info numeric_demotion_function (void) const;
 
-  idx_vector index_vector (void) const { return idx_vector (scalar); }
+  idx_vector index_vector (bool /* require_integers */ = false) const { return idx_vector (scalar); }
 
   octave_value any (int = 0) const
   { return (scalar != 0 && ! lo_ieee_isnan (scalar)); }
@@ -253,7 +252,6 @@
 
 private:
 
-  DECLARE_OCTAVE_ALLOCATOR
 
   DECLARE_OV_TYPEID_FUNCTIONS_AND_DATA
 };
--- a/libinterp/octave-value/ov-str-mat.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/libinterp/octave-value/ov-str-mat.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -53,8 +53,6 @@
 #include "pt-mat.h"
 #include "utils.h"
 
-DEFINE_OCTAVE_ALLOCATOR (octave_char_matrix_str);
-DEFINE_OCTAVE_ALLOCATOR (octave_char_matrix_sq_str);
 
 DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA (octave_char_matrix_str, "string", "char");
 DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA (octave_char_matrix_sq_str, "sq_string",
@@ -211,7 +209,7 @@
 
   if (matrix.ndims () == 2)
     {
-      charMatrix chm = matrix.matrix_value ();
+      charMatrix chm (matrix);
 
       octave_idx_type n = chm.rows ();
 
@@ -233,7 +231,7 @@
 
   if (matrix.ndims () == 2)
     {
-      charMatrix chm = matrix.matrix_value ();
+      charMatrix chm (matrix);
 
       retval = chm.row_as_string (0);  // FIXME?
     }
@@ -250,7 +248,7 @@
 
   if (matrix.ndims () == 2)
     {
-      const charMatrix chm = matrix.matrix_value ();
+      const charMatrix chm (matrix);
       octave_idx_type nr = chm.rows ();
       retval.clear (nr, 1);
       for (octave_idx_type i = 0; i < nr; i++)
@@ -583,7 +581,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-str-mat.h	Fri Feb 06 08:31:09 2015 -0800
+++ b/libinterp/octave-value/ov-str-mat.h	Fri Feb 06 08:31:49 2015 -0800
@@ -171,7 +171,6 @@
 
 private:
 
-  DECLARE_OCTAVE_ALLOCATOR
 
   DECLARE_OV_TYPEID_FUNCTIONS_AND_DATA
 };
@@ -255,7 +254,6 @@
 
 private:
 
-  DECLARE_OCTAVE_ALLOCATOR
 
   DECLARE_OV_TYPEID_FUNCTIONS_AND_DATA
 };
--- a/libinterp/octave-value/ov-struct.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/libinterp/octave-value/ov-struct.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -47,7 +47,6 @@
 #include "ls-utils.h"
 #include "pr-output.h"
 
-DEFINE_OCTAVE_ALLOCATOR(octave_struct);
 
 DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA(octave_struct, "struct", "struct");
 
@@ -648,7 +647,7 @@
 }
 
 void
-octave_struct::print (std::ostream& os, bool) const
+octave_struct::print (std::ostream& os, bool)
 {
   print_raw (os);
 }
@@ -844,7 +843,7 @@
               success = false;
             }
         }
-      else if (len == 0 )
+      else if (len == 0)
         map = octave_map (dv);
       else
         panic_impossible ();
@@ -1132,7 +1131,6 @@
 
   return retval;
 }
-DEFINE_OCTAVE_ALLOCATOR(octave_scalar_struct);
 
 DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA(octave_scalar_struct, "scalar struct",
                                     "struct");
@@ -1359,7 +1357,7 @@
 }
 
 void
-octave_scalar_struct::print (std::ostream& os, bool) const
+octave_scalar_struct::print (std::ostream& os, bool)
 {
   print_raw (os);
 }
@@ -1814,7 +1812,7 @@
 \n\
 Finally, if the value is a non-scalar cell array, then @code{struct}\n\
 produces a struct @strong{array}.\n\
-@seealso{cell2struct, fieldnames, orderfields, getfield, setfield, rmfield, structfun}\n\
+@seealso{cell2struct, fieldnames, getfield, setfield, rmfield, isfield, orderfields, isstruct, structfun}\n\
 @end deftypefn")
 {
   octave_value retval;
@@ -2012,8 +2010,10 @@
 @deftypefn  {Built-in Function} {} isfield (@var{x}, \"@var{name}\")\n\
 @deftypefnx {Built-in Function} {} isfield (@var{x}, @var{name})\n\
 Return true if the @var{x} is a structure and it includes an element named\n\
-@var{name}.  If @var{name} is a cell array of strings then a logical array of\n\
-equal dimension is returned.\n\
+@var{name}.\n\
+\n\
+If @var{name} is a cell array of strings then a logical array of equal\n\
+dimension is returned.\n\
 @seealso{fieldnames}\n\
 @end deftypefn")
 {
@@ -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")
@@ -2237,12 +2237,14 @@
 
 DEFUN (rmfield, args, ,
        "-*- texinfo -*-\n\
-@deftypefn  {Built-in Function} {@var{s} =} rmfield (@var{s}, \"@var{f}\")\n\
-@deftypefnx {Built-in Function} {@var{s} =} rmfield (@var{s}, @var{f})\n\
+@deftypefn  {Built-in Function} {@var{sout} =} rmfield (@var{s}, \"@var{f}\")\n\
+@deftypefnx {Built-in Function} {@var{sout} =} rmfield (@var{s}, @var{f})\n\
 Return a @emph{copy} of the structure (array) @var{s} with the field @var{f}\n\
-removed.  If @var{f} is a cell array of strings or a character array, remove\n\
-each of the named fields.\n\
-@seealso{orderfields, fieldnames}\n\
+removed.\n\
+\n\
+If @var{f} is a cell array of strings or a character array, remove each of\n\
+the named fields.\n\
+@seealso{orderfields, fieldnames, isfield}\n\
 @end deftypefn")
 {
   octave_value retval;
--- a/libinterp/octave-value/ov-struct.h	Fri Feb 06 08:31:09 2015 -0800
+++ b/libinterp/octave-value/ov-struct.h	Fri Feb 06 08:31:49 2015 -0800
@@ -32,7 +32,6 @@
 #include "str-vec.h"
 
 #include "error.h"
-#include "oct-alloc.h"
 #include "oct-map.h"
 #include "ov-base.h"
 #include "ov-typeinfo.h"
@@ -126,7 +125,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;
 
@@ -162,7 +161,6 @@
 
 private:
 
-  DECLARE_OCTAVE_ALLOCATOR
 
   DECLARE_OV_TYPEID_FUNCTIONS_AND_DATA
 };
@@ -249,7 +247,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;
 
@@ -283,7 +281,6 @@
 
   octave_value to_array (void);
 
-  DECLARE_OCTAVE_ALLOCATOR
 
   DECLARE_OV_TYPEID_FUNCTIONS_AND_DATA
 };
--- a/libinterp/octave-value/ov-uint16.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/libinterp/octave-value/ov-uint16.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -59,7 +59,6 @@
 
 template class octave_base_int_matrix<uint16NDArray>;
 
-DEFINE_OCTAVE_ALLOCATOR (octave_uint16_matrix);
 
 DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA (octave_uint16_matrix,
                                      "uint16 matrix", "uint16");
@@ -68,7 +67,6 @@
 
 template class octave_base_int_scalar<octave_uint16>;
 
-DEFINE_OCTAVE_ALLOCATOR (octave_uint16_scalar);
 
 DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA (octave_uint16_scalar,
                                      "uint16 scalar", "uint16");
--- a/libinterp/octave-value/ov-uint32.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/libinterp/octave-value/ov-uint32.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -59,7 +59,6 @@
 
 template class octave_base_int_matrix<uint32NDArray>;
 
-DEFINE_OCTAVE_ALLOCATOR (octave_uint32_matrix);
 
 DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA (octave_uint32_matrix,
                                      "uint32 matrix", "uint32");
@@ -68,7 +67,6 @@
 
 template class octave_base_int_scalar<octave_uint32>;
 
-DEFINE_OCTAVE_ALLOCATOR (octave_uint32_scalar);
 
 DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA (octave_uint32_scalar,
                                      "uint32 scalar", "uint32");
--- a/libinterp/octave-value/ov-uint64.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/libinterp/octave-value/ov-uint64.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -59,7 +59,6 @@
 
 template class octave_base_int_matrix<uint64NDArray>;
 
-DEFINE_OCTAVE_ALLOCATOR (octave_uint64_matrix);
 
 DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA (octave_uint64_matrix,
                                      "uint64 matrix", "uint64");
@@ -68,7 +67,6 @@
 
 template class octave_base_int_scalar<octave_uint64>;
 
-DEFINE_OCTAVE_ALLOCATOR (octave_uint64_scalar);
 
 DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA (octave_uint64_scalar,
                                      "uint64 scalar", "uint64");
--- a/libinterp/octave-value/ov-uint8.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/libinterp/octave-value/ov-uint8.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -59,7 +59,6 @@
 
 template class octave_base_int_matrix<uint8NDArray>;
 
-DEFINE_OCTAVE_ALLOCATOR (octave_uint8_matrix);
 
 DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA (octave_uint8_matrix,
                                      "uint8 matrix", "uint8");
@@ -68,7 +67,6 @@
 
 template class octave_base_int_scalar<octave_uint8>;
 
-DEFINE_OCTAVE_ALLOCATOR (octave_uint8_scalar);
 
 DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA (octave_uint8_scalar,
                                      "uint8 scalar", "uint8");
--- a/libinterp/octave-value/ov-usr-fcn.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/libinterp/octave-value/ov-usr-fcn.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -69,7 +69,6 @@
 
 // User defined scripts.
 
-DEFINE_OCTAVE_ALLOCATOR (octave_user_script);
 
 DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA (octave_user_script,
                                      "user-defined script",
@@ -149,8 +148,10 @@
                   frame.protect_var (tree_evaluator::statement_context);
                   tree_evaluator::statement_context = tree_evaluator::script;
 
-                  BEGIN_PROFILER_BLOCK (profiler_name ())
+                  BEGIN_PROFILER_BLOCK (octave_user_script)
+
                   cmd_list->accept (*current_evaluator);
+
                   END_PROFILER_BLOCK
 
                   if (tree_return_command::returning)
@@ -158,9 +159,6 @@
 
                   if (tree_break_command::breaking)
                     tree_break_command::breaking--;
-
-                  if (error_state)
-                    octave_call_stack::backtrace_error_message ();
                 }
               else
                 ::error ("max_recursion_depth exceeded");
@@ -181,7 +179,6 @@
 
 // User defined functions.
 
-DEFINE_OCTAVE_ALLOCATOR (octave_user_function);
 
 DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA (octave_user_function,
                                      "user-defined function",
@@ -203,7 +200,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 +316,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 +471,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 +482,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 +542,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.
@@ -574,7 +611,7 @@
   frame.protect_var (tree_evaluator::statement_context);
   tree_evaluator::statement_context = tree_evaluator::function;
 
-  BEGIN_PROFILER_BLOCK (profiler_name ())
+  BEGIN_PROFILER_BLOCK (octave_user_function)
 
   if (is_special_expr ())
     {
@@ -600,10 +637,7 @@
     tree_break_command::breaking--;
 
   if (error_state)
-    {
-      octave_call_stack::backtrace_error_message ();
-      return retval;
-    }
+    return retval;
 
   // Copy return values out.
 
@@ -744,7 +778,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++)
             {
@@ -791,9 +826,11 @@
        "-*- texinfo -*-\n\
 @deftypefn  {Built-in Function} {} nargin ()\n\
 @deftypefnx {Built-in Function} {} nargin (@var{fcn})\n\
-Within a function, return the number of arguments passed to the function.\n\
-At the top level, return the number of command line arguments passed to\n\
-Octave.\n\
+Report the number of input arguments to a function.\n\
+\n\
+Called from within a function, return the number of arguments passed to the\n\
+function.  At the top level, return the number of command line arguments\n\
+passed to Octave.\n\
 \n\
 If called with the optional argument @var{fcn}---a function name or handle---\n\
 return the declared number of arguments that the function can accept.\n\
@@ -813,7 +850,7 @@
 @end example\n\
 \n\
 Programming Note: @code{nargin} does not work on built-in functions.\n\
-@seealso{nargout, varargin, isargout, varargout, nthargout}\n\
+@seealso{nargout, narginchk, varargin, inputname}\n\
 @end deftypefn")
 {
   octave_value retval;
@@ -849,7 +886,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
@@ -872,11 +909,18 @@
        "-*- texinfo -*-\n\
 @deftypefn  {Built-in Function} {} nargout ()\n\
 @deftypefnx {Built-in Function} {} nargout (@var{fcn})\n\
-Within a function, return the number of values the caller expects to\n\
-receive.  If called with the optional argument @var{fcn}---a function\n\
-name or handle---return the number of declared output values that the\n\
-function can produce.  If the final output argument is @var{varargout}\n\
-the returned value is negative.\n\
+Report the number of output arguments from a function.\n\
+\n\
+Called from within a function, return the number of values the caller expects\n\
+to receive.  At the top level, @code{nargout} with no argument is undefined\n\
+and will produce an error.\n\
+\n\
+If called with the optional argument @var{fcn}---a function name or\n\
+handle---return the number of declared output values that the function can\n\
+produce.\n\
+\n\
+If the final output argument is @var{varargout} the returned value is\n\
+negative.\n\
 \n\
 For example,\n\
 \n\
@@ -911,10 +955,9 @@
 will return -2, because @code{imread} has two outputs and the second is\n\
 @var{varargout}.\n\
 \n\
-At the top level, @code{nargout} with no argument is undefined and will\n\
-produce an error.  @code{nargout} does not work for built-in functions and\n\
+Programming Note.  @code{nargout} does not work for built-in functions and\n\
 returns -1 for all anonymous functions.\n\
-@seealso{nargin, varargin, isargout, varargout, nthargout}\n\
+@seealso{nargin, varargout, isargout, nthargout}\n\
 @end deftypefn")
 {
   octave_value retval;
@@ -971,7 +1014,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
@@ -1037,16 +1080,18 @@
        "-*- texinfo -*-\n\
 @deftypefn {Built-in Function} {} isargout (@var{k})\n\
 Within a function, return a logical value indicating whether the argument\n\
-@var{k} will be assigned to a variable on output.  If the result is false,\n\
-the argument has been ignored during the function call through the use of\n\
-the tilde (~) special output argument.  Functions can use @code{isargout} to\n\
-avoid performing unnecessary calculations for outputs which are unwanted.\n\
+@var{k} will be assigned to a variable on output.\n\
+\n\
+If the result is false, the argument has been ignored during the function\n\
+call through the use of the tilde (~) special output argument.  Functions\n\
+can use @code{isargout} to avoid performing unnecessary calculations for\n\
+outputs which are unwanted.\n\
 \n\
 If @var{k} is outside the range @code{1:max (nargout)}, the function returns\n\
 false.  @var{k} can also be an array, in which case the function works\n\
 element-by-element and a logical array is returned.  At the top level,\n\
 @code{isargout} returns an error.\n\
-@seealso{nargout, nargin, varargin, varargout, nthargout}\n\
+@seealso{nargout, varargout, nthargout}\n\
 @end deftypefn")
 {
   octave_value retval;
--- a/libinterp/octave-value/ov-usr-fcn.h	Fri Feb 06 08:31:09 2015 -0800
+++ b/libinterp/octave-value/ov-usr-fcn.h	Fri Feb 06 08:31:49 2015 -0800
@@ -165,7 +165,6 @@
 
   octave_user_script& operator = (const octave_user_script& f);
 
-  DECLARE_OCTAVE_ALLOCATOR
 
   DECLARE_OV_TYPEID_FUNCTIONS_AND_DATA
 };
@@ -327,12 +326,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 +415,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 +484,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;
@@ -506,7 +520,6 @@
 
   octave_user_function& operator = (const octave_user_function& fn);
 
-  DECLARE_OCTAVE_ALLOCATOR
 
   DECLARE_OV_TYPEID_FUNCTIONS_AND_DATA
 };
--- a/libinterp/octave-value/ov.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/libinterp/octave-value/ov.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -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"
@@ -92,7 +93,18 @@
 
 // We are likely to have a lot of octave_value objects to allocate, so
 // make the grow_size large.
-DEFINE_OCTAVE_ALLOCATOR2(octave_value, 1024);
+
+// If TRUE, don't create special diagonal matrix objects.
+
+static bool Vdisable_diagonal_matrix = false;
+
+// If TRUE, don't create special permutation matrix objects.
+
+static bool Vdisable_permutation_matrix = false;
+
+// If TRUE, don't create special range objects.
+
+static bool Vdisable_range = false;
 
 // FIXME
 
@@ -673,37 +685,49 @@
 }
 
 octave_value::octave_value (const DiagArray2<double>& d)
-  : rep (new octave_diag_matrix (d))
+  : rep (Vdisable_diagonal_matrix
+         ? dynamic_cast<octave_base_value *> (new octave_matrix (Matrix (d)))
+         : dynamic_cast<octave_base_value *> (new octave_diag_matrix (d)))
 {
   maybe_mutate ();
 }
 
 octave_value::octave_value (const DiagArray2<float>& d)
-  : rep (new octave_float_diag_matrix (d))
+  : rep (Vdisable_diagonal_matrix
+         ? dynamic_cast<octave_base_value *> (new octave_float_matrix (FloatMatrix (d)))
+         : dynamic_cast<octave_base_value *> (new octave_float_diag_matrix (d)))
 {
   maybe_mutate ();
 }
 
 octave_value::octave_value (const DiagArray2<Complex>& d)
-  : rep (new octave_complex_diag_matrix (d))
+  : rep (Vdisable_diagonal_matrix
+         ? dynamic_cast<octave_base_value *> (new octave_complex_matrix (ComplexMatrix (d)))
+         : dynamic_cast<octave_base_value *> (new octave_complex_diag_matrix (d)))
 {
   maybe_mutate ();
 }
 
 octave_value::octave_value (const DiagArray2<FloatComplex>& d)
-  : rep (new octave_float_complex_diag_matrix (d))
+  : rep (Vdisable_diagonal_matrix
+         ? dynamic_cast<octave_base_value *> (new octave_float_complex_matrix (FloatComplexMatrix (d)))
+         : dynamic_cast<octave_base_value *> (new octave_float_complex_diag_matrix (d)))
 {
   maybe_mutate ();
 }
 
 octave_value::octave_value (const DiagMatrix& d)
-  : rep (new octave_diag_matrix (d))
+  : rep (Vdisable_diagonal_matrix
+         ? dynamic_cast<octave_base_value *> (new octave_matrix (Matrix (d)))
+         : dynamic_cast<octave_base_value *> (new octave_diag_matrix (d)))
 {
   maybe_mutate ();
 }
 
 octave_value::octave_value (const FloatDiagMatrix& d)
-  : rep (new octave_float_diag_matrix (d))
+  : rep (Vdisable_diagonal_matrix
+         ? dynamic_cast<octave_base_value *> (new octave_float_matrix (FloatMatrix (d)))
+         : dynamic_cast<octave_base_value *> (new octave_float_diag_matrix (d)))
 {
   maybe_mutate ();
 }
@@ -781,13 +805,17 @@
 }
 
 octave_value::octave_value (const ComplexDiagMatrix& d)
-  : rep (new octave_complex_diag_matrix (d))
+  : rep (Vdisable_diagonal_matrix
+         ? dynamic_cast<octave_base_value *> (new octave_complex_matrix (ComplexMatrix (d)))
+         : dynamic_cast<octave_base_value *> (new octave_complex_diag_matrix (d)))
 {
   maybe_mutate ();
 }
 
 octave_value::octave_value (const FloatComplexDiagMatrix& d)
-  : rep (new octave_float_complex_diag_matrix (d))
+  : rep (Vdisable_diagonal_matrix
+         ? dynamic_cast<octave_base_value *> (new octave_float_complex_matrix (FloatComplexMatrix (d)))
+         : dynamic_cast<octave_base_value *> (new octave_float_complex_diag_matrix (d)))
 {
   maybe_mutate ();
 }
@@ -817,7 +845,9 @@
 }
 
 octave_value::octave_value (const PermMatrix& p)
-  : rep (new octave_perm_matrix (p))
+  : rep (Vdisable_permutation_matrix
+         ? dynamic_cast<octave_base_value *> (new octave_matrix (Matrix (p)))
+         : dynamic_cast<octave_base_value *> (new octave_perm_matrix (p)))
 {
   maybe_mutate ();
 }
@@ -1176,8 +1206,10 @@
   maybe_mutate ();
 }
 
-octave_value::octave_value (const Range& r)
-  : rep (new octave_range (r))
+octave_value::octave_value (const Range& r, bool force_range)
+  : rep (force_range || ! Vdisable_range
+         ? dynamic_cast<octave_base_value *> (new octave_range (r))
+         : dynamic_cast<octave_base_value *> (new octave_matrix (r.matrix_value ())))
 {
   maybe_mutate ();
 }
@@ -1193,13 +1225,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 +1984,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 +2242,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 +2418,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);
@@ -2835,10 +2873,9 @@
 
       for (int k = 0; k < nel; k++)
         {
-          std::string item = type(k).string_value ();
-
-          if (! error_state)
+          if (type(k).is_string ())
             {
+              std::string item = type(k).string_value ();
               if (item == "{}")
                 type_string[k] = '{';
               else if (item == "()")
@@ -2853,8 +2890,7 @@
             }
           else
             {
-              error ("%s: expecting type(%d) to be a character string",
-                     name, k+1);
+              error ("%s: type(%d) must be a string", name, k+1);
               return;
             }
 
@@ -2877,8 +2913,7 @@
             }
           else
             {
-              error ("%s: expecting subs(%d) to be a character string or cell array",
-                     name, k+1);
+              error ("%s: subs(%d) must be a string or cell array", name, k+1);
               return;
             }
 
@@ -3141,3 +3176,107 @@
 %!error is_dq_string ()
 %!error is_dq_string ("foo", 2)
 */
+
+DEFUN (disable_permutation_matrix, args, nargout,
+       "-*- texinfo -*-\n\
+@deftypefn  {Built-in Function} {@var{val} =} disable_permutation_matrix ()\n\
+@deftypefnx {Built-in Function} {@var{old_val} =} disable_permutation_matrix (@var{new_val})\n\
+@deftypefnx {Built-in Function} {} disable_permutation_matrix (@var{new_val}, \"local\")\n\
+Query or set the internal variable that controls whether permutation\n\
+matrices are stored in a special space-efficient format.  The default\n\
+value is true.  If this option is disabled Octave will store permutation\n\
+matrices as full matrices.\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{disable_range, disable_diagonal_matrix}\n\
+@end deftypefn")
+{
+  return SET_INTERNAL_VARIABLE (disable_permutation_matrix);
+}
+
+/*
+%!function p = __test_dpm__ (dpm)
+%!  disable_permutation_matrix (dpm, "local");
+%!  [~, ~, p] = lu ([1,2;3,4]);
+%!endfunction
+
+%!assert (typeinfo (__test_dpm__ (false)), "permutation matrix");
+%!assert (typeinfo (__test_dpm__ (true)), "matrix");
+*/
+
+DEFUN (disable_diagonal_matrix, args, nargout,
+       "-*- texinfo -*-\n\
+@deftypefn  {Built-in Function} {@var{val} =} disable_diagonal_matrix ()\n\
+@deftypefnx {Built-in Function} {@var{old_val} =} disable_diagonal_matrix (@var{new_val})\n\
+@deftypefnx {Built-in Function} {} disable_diagonal_matrix (@var{new_val}, \"local\")\n\
+Query or set the internal variable that controls whether diagonal\n\
+matrices are stored in a special space-efficient format.  The default\n\
+value is true.  If this option is disabled Octave will store diagonal\n\
+matrices as full matrices.\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{disable_range, disable_permutation_matrix}\n\
+@end deftypefn")
+{
+  return SET_INTERNAL_VARIABLE (disable_diagonal_matrix);
+}
+
+/*
+%!function [x, xi, fx, fxi] = __test_ddm__ (ddm)
+%!  disable_diagonal_matrix (ddm, "local");
+%!  x = eye (2);
+%!  xi = x*i;
+%!  fx = single (x);
+%!  fxi = single (xi);
+%!endfunction
+
+%!shared x, xi, fx, fxi
+%!  [x, xi, fx, fxi] = __test_ddm__ (false);
+%!assert (typeinfo (x), "diagonal matrix");
+%!assert (typeinfo (xi), "complex diagonal matrix");
+%!assert (typeinfo (fx), "float diagonal matrix");
+%!assert (typeinfo (fxi), "float complex diagonal matrix");
+
+%!shared x, xi, fx, fxi
+%!  [x, xi, fx, fxi] = __test_ddm__ (true);
+%!assert (typeinfo (x), "matrix");
+%!assert (typeinfo (xi), "complex matrix");
+%!assert (typeinfo (fx), "float matrix");
+%!assert (typeinfo (fxi), "float complex matrix");
+*/
+
+DEFUN (disable_range, args, nargout,
+       "-*- texinfo -*-\n\
+@deftypefn  {Built-in Function} {@var{val} =} disable_range ()\n\
+@deftypefnx {Built-in Function} {@var{old_val} =} disable_range (@var{new_val})\n\
+@deftypefnx {Built-in Function} {} disable_range (@var{new_val}, \"local\")\n\
+Query or set the internal variable that controls whether ranges are stored\n\
+in a special space-efficient format.  The default value is true.  If this\n\
+option is disabled Octave will store ranges as full matrices.\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{disable_diagonal_matrix, disable_permutation_matrix}\n\
+@end deftypefn")
+{
+  return SET_INTERNAL_VARIABLE (disable_range);
+}
+
+/*
+%!function r = __test_dr__ (dr)
+%!  disable_range (dr, "local");
+%!  ## Constant folding will produce range for 1:13.
+%!  base = 1;
+%!  limit = 13;
+%!  r = base:limit;
+%!endfunction
+
+%!assert (typeinfo (__test_dr__ (false)), "range");
+%!assert (typeinfo (__test_dr__ (true)), "matrix");
+*/
+
--- a/libinterp/octave-value/ov.h	Fri Feb 06 08:31:09 2015 -0800
+++ b/libinterp/octave-value/ov.h	Fri Feb 06 08:31:49 2015 -0800
@@ -35,7 +35,6 @@
 #include "idx-vector.h"
 #include "mach-info.h"
 #include "mx-base.h"
-#include "oct-alloc.h"
 #include "oct-time.h"
 #include "str-vec.h"
 
@@ -46,7 +45,6 @@
 class mxArray;
 class octave_map;
 class octave_scalar_map;
-class Octave_map;
 class octave_stream;
 class octave_function;
 class octave_user_function;
@@ -282,11 +280,12 @@
   octave_value (const Array<std::string>& cellstr);
   octave_value (const idx_vector& idx, bool lazy = true);
   octave_value (double base, double limit, double inc);
-  octave_value (const Range& r);
+  octave_value (const Range& r, bool force_range = false);
   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);
@@ -455,8 +454,10 @@
 
   octave_value& assign (assign_op, const octave_value& rhs);
 
-  idx_vector index_vector (void) const
-  { return rep->index_vector (); }
+  idx_vector index_vector (bool require_integers = false) const
+  {
+    return rep->index_vector (require_integers);
+  }
 
   // Size.
 
@@ -570,6 +571,9 @@
   bool is_object (void) const
   { return rep->is_object (); }
 
+  bool is_classdef_object (void) const
+  { return rep->is_classdef_object (); }
+
   bool is_java (void) const
   { return rep->is_java (); }
 
@@ -913,6 +917,9 @@
   find_parent_class (const std::string& parent_class_name)
   { return rep->find_parent_class (parent_class_name); }
 
+  bool is_instance_of (const std::string& cls_name) const
+  { return rep->is_instance_of (cls_name); }
+
   octave_function *function_value (bool silent = false) const;
 
   octave_user_function *user_function_value (bool silent = false) const;
@@ -1015,7 +1022,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
@@ -1233,7 +1240,6 @@
   // const octave_base_value* which actually silently calls octave_value (bool).
   octave_value (const octave_base_value *);
 
-  DECLARE_OCTAVE_ALLOCATOR
 };
 
 // Publish externally used friend functions.
--- a/libinterp/octave.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/libinterp/octave.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -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"
@@ -95,8 +96,7 @@
 static string_vector octave_argv;
 
 // The name used to invoke Octave.
-static std::string
-octave_program_invocation_name;
+static std::string octave_program_invocation_name;
 
 // The last component of octave_program_invocation_name.
 static std::string octave_program_name;
@@ -157,16 +157,19 @@
 // (--no-window-system, -W)
 static bool no_window_system = false;
 
-// The code to evaluate at startup (--eval CODE)
+// The code to evaluate at startup
+// (--eval CODE)
 static std::string code_to_eval;
 
 // If TRUE, don't exit after evaluating code given by --eval option.
+// (--persist)
 static bool persist = false;
 
 // If TRUE, the GUI should be started.
 static bool start_gui = false;
 
-// If TRUE use traditional settings (--traditional)
+// If TRUE use traditional (maximally MATLAB compatible) settings
+// (--traditional)
 static bool traditional = false;
 
 // Store the command-line options for later use.
@@ -256,10 +259,10 @@
             << std::endl;
 }
 
-// Execute commands from a file and catch potential exceptions in a
-// consistent way.  This function should be called anywhere we might
-// parse and execute commands from a file before before we have entered
-// the main loop in toplev.cc.
+// Execute commands from a file and catch potential exceptions in a consistent
+// way.  This function should be called anywhere we might parse and execute
+// commands from a file before before we have entered the main loop in
+// toplev.cc.
 
 static void
 safe_source_file (const std::string& file_name,
@@ -314,8 +317,8 @@
   if (read_init_files)
     {
       // Try to execute commands from $HOME/$OCTAVE_INITFILE and
-      // $OCTAVE_INITFILE.  If $OCTAVE_INITFILE is not set, .octaverc
-      // is assumed.
+      // $OCTAVE_INITFILE.  If $OCTAVE_INITFILE is not set,
+      // .octaverc is assumed.
 
       bool home_rc_already_executed = false;
 
@@ -472,7 +475,7 @@
   set_liboctave_warning_with_id_handler (warning_with_id);
 }
 
-// What happens on --traditional.
+// What internal options get configured by --traditional.
 
 static void
 maximum_braindamage (void)
@@ -482,25 +485,23 @@
   FPS1 (octave_value (">> "));
   FPS2 (octave_value (""));
   FPS4 (octave_value (""));
-  Fallow_noninteger_range_as_index (octave_value (true));
   Fbeep_on_error (octave_value (true));
   Fconfirm_recursive_rmdir (octave_value (false));
   Fcrash_dumps_octave_core (octave_value (false));
-  Fsave_default_options (octave_value ("-mat-binary"));
-  Fdo_braindead_shortcircuit_evaluation (octave_value (true));
+  Fdisable_diagonal_matrix (octave_value (true));
+  Fdisable_permutation_matrix (octave_value (true));
+  Fdisable_range (octave_value (true));
   Ffixed_point_format (octave_value (true));
   Fhistory_timestamp_format_string (octave_value ("%%-- %D %I:%M %p --%%"));
   Fpage_screen_output (octave_value (false));
   Fprint_empty_dimensions (octave_value (false));
+  Fsave_default_options (octave_value ("-mat-binary"));
+  Fstruct_levels_to_print (octave_value (0));
 
   disable_warning ("Octave:abbreviated-property-match");
-  disable_warning ("Octave:fopen-file-in-path");
+  disable_warning ("Octave:data-file-in-path");
   disable_warning ("Octave:function-name-clash");
-  disable_warning ("Octave:load-file-in-path");
   disable_warning ("Octave:possible-matlab-short-circuit-operator");
-
-  // Initialized to "error" by default.
-  set_warning_state ("Octave:noninteger-range-as-index", "on");
 }
 
 // EMBEDDED is declared int instead of bool because this function is
@@ -538,9 +539,8 @@
       switch (optc)
         {
         case '?':
-          // Unrecognized option.  getopt_long already printed a
-          // message about that, so we will just print the usage string
-          // and exit.
+          // Unrecognized option.  getopt_long already printed a message about
+          // it, so we will just print the usage string and exit.
           octave_print_terse_usage_and_exit ();
           break;
 
@@ -685,18 +685,28 @@
           break;
 
         default:
-          // getopt_long should print a message about unrecognized
-          // options and return '?', which is handled above.  So if we
-          // end up here, it is because there was an option but we
-          // forgot to handle it.  That should be fatal.
+          // getopt_long should print a message about unrecognized options and
+          // return '?', which is handled above.  If we end up here, it is
+          // because there was an option but we forgot to handle it.
+          // That should be fatal.
           panic_impossible ();
           break;
         }
     }
 
+  // Check for various incompatible argument pairs
   if (force_gui_option && no_gui_option)
     {
-      error ("error: only one of --force-gui and --no-gui may be used");
+      error ("only one of --force-gui and --no-gui may be used");
+
+      octave_print_terse_usage_and_exit ();
+    }
+
+  bool script_file = (argc - optind) > 0;
+
+  if (! code_to_eval.empty () && script_file)
+    {
+      error ("--eval \"CODE\" and script file are mutually exclusive options");
 
       octave_print_terse_usage_and_exit ();
     }
@@ -723,8 +733,8 @@
 
   set_default_prompts ();
 
-  // Initialize default warning state before --traditional option may
-  // reset them.
+  // Initialize default warning state before --traditional option
+  // that may reset them.
 
   initialize_default_warning_state ();
 
@@ -735,10 +745,9 @@
 
   octave_ieee_init ();
 
-  // The idea here is to force xerbla to be referenced so that we will
-  // link to our own version instead of the one provided by the BLAS
-  // library.  But octave_NaN should never be -1, so we should never
-  // actually call xerbla.
+  // The idea here is to force xerbla to be referenced so that we will link to
+  // our own version instead of the one provided by the BLAS library.  But
+  // octave_NaN should never be -1, so we should never actually call xerbla.
 
   if (octave_NaN == -1)
     F77_FUNC (xerbla, XERBLA) ("octave", 13 F77_CHAR_ARG_LEN (6));
@@ -758,6 +767,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);
@@ -771,8 +782,7 @@
   if (no_window_system)
     display_info::no_window_system ();
 
-  // Is input coming from a terminal?  If so, we are probably
-  // interactive.
+  // Is input coming from a terminal?  If so, we are probably interactive.
 
   // If stdin is not a tty, then we are reading commands from a pipe or
   // a redirected file.
@@ -784,6 +794,10 @@
   if (! interactive && ! forced_line_editing)
     line_editing = false;
 
+  // Also skip start-up message unless session is interactive.
+  if (! (interactive || forced_interactive))
+    inhibit_startup_message = true;
+
   // Force default line editor if we don't want readline editing.
   if (! line_editing)
     command_editor::force_default_editor ();
@@ -821,19 +835,12 @@
   if (! inhibit_startup_message && reading_startup_message_printed)
     std::cout << std::endl;
 
-  // If there is an extra argument, see if it names a file to read.
-  // Additional arguments are taken as command line options for the
-  // script.
-
-  int last_arg_idx = optind;
-
-  int remaining_args = octave_cmdline_argc - last_arg_idx;
-
+  // Execute any code specified with --eval 'CODE'
   if (! code_to_eval.empty ())
     {
       int parse_status = execute_eval_option_code (code_to_eval);
 
-      if (! (persist || remaining_args > 0))
+      if (! persist)
         {
           quitting_gracefully = true;
 
@@ -841,6 +848,12 @@
         }
     }
 
+  // If there is an extra argument, see if it names a file to read.
+  // Additional arguments are taken as command line options for the script.
+
+  int last_arg_idx = optind;
+  int remaining_args = octave_cmdline_argc - last_arg_idx;
+
   if (remaining_args > 0)
     {
       // If we are running an executable script (#! /bin/octave) then
@@ -865,23 +878,22 @@
   // Now argv should have the full set of args.
   intern_argv (octave_cmdline_argc, octave_cmdline_argv);
 
-  // Force input to be echoed if not really interactive, but the user
-  // has forced interactive behavior.
+  // Force input to be echoed if not really interactive,
+  // but the user has forced interactive behavior.
 
   if (! interactive && forced_interactive)
     {
       command_editor::blink_matching_paren (false);
 
       // FIXME: is this the right thing to do?
-
       Fecho_executing_commands (octave_value (ECHO_CMD_LINE));
     }
 
   if (octave_embedded)
     {
-      // FIXME: do we need to do any cleanup here before
-      // returning?  If we don't, what will happen to Octave functions
-      // that have been registered to execute with atexit, for example?
+      // FIXME: Do we need to do any cleanup here before returning?
+      // If we don't, what will happen to Octave functions that have been
+      // registered to execute with atexit, for example?
 
       return 1;
     }
@@ -919,17 +931,16 @@
   if (persist)
     return true;
 
-  // If stdin is not a tty, then assume we are reading commands from a
-  // pipe or a redirected file and the GUI should not start.  If this is
-  // not the case (for example, starting from a desktop "launcher" with
-  // no terminal) and you want to start the GUI, you may use the
-  // --force-gui option to start the GUI.
+  // If stdin is not a tty, then assume we are reading commands from a pipe or
+  // a redirected file and the GUI should not start.  If this is not the case
+  // (for example, starting from a desktop "launcher" with no terminal) and you
+  // want to start the GUI, you may use the --force-gui option to start the GUI.
 
   if (! gnulib::isatty (fileno (stdin)))
     return false;
 
-  // If we have code to eval or execute from a file, and we are going to
-  // exit immediately after executing it, don't start the gui.
+  // If we have code to eval or execute from a file, and we are going to exit
+  // immediately after executing it, don't start the gui.
 
   int last_arg_idx = optind;
   int remaining_args = octave_cmdline_argc - last_arg_idx;
@@ -940,8 +951,7 @@
   return true;
 }
 
-// Return int instead of bool because this function is declared
-// extern "C".
+// Return int instead of bool because this function is declared extern "C".
 
 int
 octave_starting_gui (void)
@@ -974,8 +984,9 @@
 DEFUN (argv, args, ,
        "-*- texinfo -*-\n\
 @deftypefn {Built-in Function} {} argv ()\n\
-Return the command line arguments passed to Octave.  For example,\n\
-if you invoked Octave using the command\n\
+Return the command line arguments passed to Octave.\n\
+\n\
+For example, if you invoked Octave using the command\n\
 \n\
 @example\n\
 octave --no-line-editing --silent\n\
@@ -985,9 +996,9 @@
 @code{argv} would return a cell array of strings with the elements\n\
 @option{--no-line-editing} and @option{--silent}.\n\
 \n\
-If you write an executable Octave script, @code{argv} will return the\n\
-list of arguments passed to the script.  @xref{Executable Octave Programs},\n\
-for an example of how to create an executable Octave script.\n\
+If you write an executable Octave script, @code{argv} will return the list\n\
+of arguments passed to the script.  @xref{Executable Octave Programs}, for\n\
+an example of how to create an executable Octave script.\n\
 @end deftypefn")
 {
   octave_value retval;
--- a/libinterp/operators/op-b-b.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/libinterp/operators/op-b-b.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -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 Feb 06 08:31:09 2015 -0800
+++ b/libinterp/operators/op-cm-sm.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -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-dm-scm.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/libinterp/operators/op-dm-scm.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -24,6 +24,15 @@
 #include <config.h>
 #endif
 
+#include "mx-cm-s.h"
+#include "mx-s-cm.h"
+
+#include "mx-dm-cs.h"
+#include "mx-cs-dm.h"
+
+#include "mx-m-cs.h"
+#include "mx-cs-m.h"
+
 #include "gripes.h"
 #include "oct-obj.h"
 #include "ov.h"
--- a/libinterp/operators/op-dm-template.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/libinterp/operators/op-dm-template.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -24,6 +24,10 @@
 #include <config.h>
 #endif
 
+// FIXME: it might be nice to only include the declarations of the
+// operators that are actually needed instead of including all of them.
+#include "mx-ops.h"
+
 #include "ops.h"
 #include "xdiv.h"
 #include LINCLUDE
--- a/libinterp/operators/op-fcm-fs.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/libinterp/operators/op-fcm-fs.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -24,8 +24,7 @@
 #include <config.h>
 #endif
 
-#include "mx-cm-s.h"
-#include "mx-cnda-s.h"
+#include "mx-fcnda-fs.h"
 
 #include "gripes.h"
 #include "oct-obj.h"
--- a/libinterp/operators/op-fcs-fm.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/libinterp/operators/op-fcs-fm.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -24,10 +24,8 @@
 #include <config.h>
 #endif
 
-#include "mx-cs-nda.h"
-#include "mx-nda-cs.h"
-#include "mx-cs-nda.h"
-#include "mx-nda-cs.h"
+#include "mx-fcs-fnda.h"
+#include "mx-fnda-fcs.h"
 
 #include "gripes.h"
 #include "oct-obj.h"
--- a/libinterp/operators/op-i16-i16.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/libinterp/operators/op-i16-i16.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -57,6 +57,15 @@
 #include "mx-i16-nda.h"
 #include "mx-nda-i16.h"
 
+#include "mx-i16nda-fs.h"
+#include "mx-fs-i16nda.h"
+
+#include "mx-i16nda-fnda.h"
+#include "mx-fnda-i16nda.h"
+
+#include "mx-i16-fnda.h"
+#include "mx-fnda-i16.h"
+
 #include "gripes.h"
 #include "oct-obj.h"
 #include "ov.h"
--- a/libinterp/operators/op-i32-i32.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/libinterp/operators/op-i32-i32.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -57,6 +57,15 @@
 #include "mx-i32-nda.h"
 #include "mx-nda-i32.h"
 
+#include "mx-i32nda-fs.h"
+#include "mx-fs-i32nda.h"
+
+#include "mx-i32nda-fnda.h"
+#include "mx-fnda-i32nda.h"
+
+#include "mx-i32-fnda.h"
+#include "mx-fnda-i32.h"
+
 #include "gripes.h"
 #include "oct-obj.h"
 #include "ov.h"
--- a/libinterp/operators/op-i64-i64.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/libinterp/operators/op-i64-i64.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -57,6 +57,15 @@
 #include "mx-i64-nda.h"
 #include "mx-nda-i64.h"
 
+#include "mx-i64nda-fs.h"
+#include "mx-fs-i64nda.h"
+
+#include "mx-i64nda-fnda.h"
+#include "mx-fnda-i64nda.h"
+
+#include "mx-i64-fnda.h"
+#include "mx-fnda-i64.h"
+
 #include "gripes.h"
 #include "oct-obj.h"
 #include "ov.h"
--- a/libinterp/operators/op-i8-i8.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/libinterp/operators/op-i8-i8.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -57,6 +57,15 @@
 #include "mx-i8-nda.h"
 #include "mx-nda-i8.h"
 
+#include "mx-i8nda-fs.h"
+#include "mx-fs-i8nda.h"
+
+#include "mx-i8nda-fnda.h"
+#include "mx-fnda-i8nda.h"
+
+#include "mx-i8-fnda.h"
+#include "mx-fnda-i8.h"
+
 #include "gripes.h"
 #include "oct-obj.h"
 #include "ov.h"
--- a/libinterp/operators/op-int.h	Fri Feb 06 08:31:09 2015 -0800
+++ b/libinterp/operators/op-int.h	Fri Feb 06 08:31:49 2015 -0800
@@ -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 Feb 06 08:31:09 2015 -0800
+++ b/libinterp/operators/op-pm-sm.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -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-pm-template.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/libinterp/operators/op-pm-template.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -24,6 +24,10 @@
 #include <config.h>
 #endif
 
+// FIXME: it might be nice to only include the declarations of the
+// operators that are actually needed instead of including all of them.
+#include "mx-ops.h"
+
 #include "ov-perm.h"
 #include MINCLUDE
 #include "ops.h"
--- a/libinterp/operators/op-sbm-sbm.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/libinterp/operators/op-sbm-sbm.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -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/operators/op-ui16-ui16.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/libinterp/operators/op-ui16-ui16.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -57,6 +57,15 @@
 #include "mx-ui16-nda.h"
 #include "mx-nda-ui16.h"
 
+#include "mx-ui16nda-fs.h"
+#include "mx-fs-ui16nda.h"
+
+#include "mx-ui16nda-fnda.h"
+#include "mx-fnda-ui16nda.h"
+
+#include "mx-ui16-fnda.h"
+#include "mx-fnda-ui16.h"
+
 #include "gripes.h"
 #include "oct-obj.h"
 #include "ov.h"
--- a/libinterp/operators/op-ui32-ui32.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/libinterp/operators/op-ui32-ui32.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -57,6 +57,15 @@
 #include "mx-ui32-nda.h"
 #include "mx-nda-ui32.h"
 
+#include "mx-ui32nda-fs.h"
+#include "mx-fs-ui32nda.h"
+
+#include "mx-ui32nda-fnda.h"
+#include "mx-fnda-ui32nda.h"
+
+#include "mx-ui32-fnda.h"
+#include "mx-fnda-ui32.h"
+
 #include "gripes.h"
 #include "oct-obj.h"
 #include "ov.h"
--- a/libinterp/operators/op-ui64-ui64.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/libinterp/operators/op-ui64-ui64.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -57,6 +57,15 @@
 #include "mx-ui64-nda.h"
 #include "mx-nda-ui64.h"
 
+#include "mx-ui64nda-fs.h"
+#include "mx-fs-ui64nda.h"
+
+#include "mx-ui64nda-fnda.h"
+#include "mx-fnda-ui64nda.h"
+
+#include "mx-ui64-fnda.h"
+#include "mx-fnda-ui64.h"
+
 #include "gripes.h"
 #include "oct-obj.h"
 #include "ov.h"
--- a/libinterp/operators/op-ui8-ui8.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/libinterp/operators/op-ui8-ui8.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -57,6 +57,15 @@
 #include "mx-ui8-nda.h"
 #include "mx-nda-ui8.h"
 
+#include "mx-ui8nda-fs.h"
+#include "mx-fs-ui8nda.h"
+
+#include "mx-ui8nda-fnda.h"
+#include "mx-fnda-ui8nda.h"
+
+#include "mx-ui8-fnda.h"
+#include "mx-fnda-ui8.h"
+
 #include "gripes.h"
 #include "oct-obj.h"
 #include "ov.h"
--- a/libinterp/parse-tree/lex.h	Fri Feb 06 08:31:09 2015 -0800
+++ b/libinterp/parse-tree/lex.h	Fri Feb 06 08:31:49 2015 -0800
@@ -261,16 +261,18 @@
       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),
       input_line_number (1), current_input_column (1),
       bracketflag (0), braceflag (0),
       looping (0), defining_func (0), looking_at_function_handle (0),
-      block_comment_nesting_level (0), token_count (0),
-      current_input_line (), comment_text (), help_text (),
-      string_text (), string_line (0), string_column (0),
+      block_comment_nesting_level (0), command_arg_paren_count (0),
+      token_count (0), current_input_line (), comment_text (),
+      help_text (), string_text (), string_line (0), string_column (0),
       fcn_file_name (), fcn_file_full_name (), looking_at_object_index (),
       parsed_function_name (), pending_local_variables (),
       symtab_context (), nesting_level (), tokens ()
@@ -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;
@@ -389,6 +397,9 @@
   // nestng level for blcok comments.
   int block_comment_nesting_level;
 
+  // Parenthesis count for command argument parsing.
+  int command_arg_paren_count;
+
   // Count of tokens recognized by this lexer since initialized or
   // since the last reset.
   size_t token_count;
@@ -569,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);
@@ -587,6 +600,8 @@
 
   int handle_meta_identifier (void);
 
+  int handle_fq_identifier (void);
+
   int handle_identifier (void);
 
   void maybe_warn_separator_insert (char sep);
@@ -672,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 Feb 06 08:31:09 2015 -0800
+++ b/libinterp/parse-tree/lex.ll	Fri Feb 06 08:31:49 2015 -0800
@@ -43,7 +43,7 @@
 
 }
 
-%s COMMAND_START
+%x COMMAND_START
 %s MATRIX_START
 
 %x INPUT_FILE_START
@@ -54,6 +54,8 @@
 %x DQ_STRING_START
 %x SQ_STRING_START
 
+%x FQ_IDENT_START
+
 %{
 
 #include <cctype>
@@ -167,7 +169,8 @@
     { \
       curr_lexer->lexer_debug (PATTERN); \
  \
-      if (curr_lexer->previous_token_may_be_command ()) \
+      if (curr_lexer->previous_token_may_be_command () \
+          && curr_lexer->space_follows_previous_token ()) \
         { \
           yyless (0); \
           curr_lexer->push_start_state (COMMAND_START); \
@@ -243,6 +246,64 @@
     } \
   while (0)
 
+// When a command argument boundary is detected, push out the
+// current argument being built.  This one seems like a good
+// candidate for a function call.
+
+#define COMMAND_ARG_FINISH \
+  do \
+    { \
+      if (curr_lexer->string_text.empty ()) \
+        break; \
+ \
+      int retval = curr_lexer->handle_token (curr_lexer->string_text, \
+                                             SQ_STRING); \
+ \
+      curr_lexer->string_text = ""; \
+      curr_lexer->command_arg_paren_count = 0; \
+ \
+      yyless (0); \
+ \
+      return retval; \
+    } \
+  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;
 
@@ -251,11 +312,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]
@@ -264,6 +320,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]+))
 
@@ -307,54 +364,129 @@
 // Help and other command-style functions.
 %}
 
-<COMMAND_START>{NL} {
-    curr_lexer->lexer_debug ("<COMMAND_START>{NL}");
+%{
+// Commands can be continued on a second line using the ellipsis.
+// If an argument is in construction, it is completed.
+%}
+
+<COMMAND_START>(\.\.\.){ANY_EXCEPT_NL}*{NL} {
+    curr_lexer->lexer_debug ("<COMMAND_START>(\\.\\.\\.){ANY_EXCEPT_NL}*{NL}");
+
+    COMMAND_ARG_FINISH;
+
+    curr_lexer->input_line_number++;
+    curr_lexer->current_input_column = 1;
+
+    HANDLE_STRING_CONTINUATION;
+  }
+
+%{
+// Commands normally end at the end of a line or a semicolon.
+%}
+
+<COMMAND_START>({CCHAR}{ANY_EXCEPT_NL}*)?{NL} {
+    curr_lexer->lexer_debug ("<COMMAND_START>({CCHAR}{ANY_EXCEPT_NL}*)?{NL}");
+
+    COMMAND_ARG_FINISH;
 
     curr_lexer->input_line_number++;
     curr_lexer->current_input_column = 1;
-
     curr_lexer->looking_for_object_index = false;
     curr_lexer->at_beginning_of_statement = true;
-
     curr_lexer->pop_start_state ();
 
-    return curr_lexer->count_token ('\n');
+    return curr_lexer->handle_token ('\n');
+  }
+
+<COMMAND_START>[\,\;] {
+    curr_lexer->lexer_debug ("<COMMAND_START>[\\,\\;]");
+
+    if (yytext[0] != ',' || curr_lexer->command_arg_paren_count == 0)
+      {
+        COMMAND_ARG_FINISH;
+        curr_lexer->looking_for_object_index = false;
+        curr_lexer->at_beginning_of_statement = true;
+        curr_lexer->pop_start_state ();
+        return curr_lexer->handle_token (yytext[0]);
+      }
+    else
+      curr_lexer->string_text += yytext;
+
+    curr_lexer->current_input_column += yyleng;
   }
 
-<COMMAND_START>[\;\,] {
-    curr_lexer->lexer_debug ("<COMMAND_START>[\\;\\,]");
-
-    curr_lexer->looking_for_object_index = false;
-    curr_lexer->at_beginning_of_statement = true;
-
-    curr_lexer->pop_start_state ();
-
-    if (strcmp (yytext, ",") == 0)
-      return curr_lexer->handle_token (',');
-    else
-      return curr_lexer->handle_token (';');
+%{
+// Unbalanced parentheses serve as pseudo-quotes: they are included in
+// the final argument string, but they cause parentheses and quotes to
+// be slurped into that argument as well.
+%}
+
+<COMMAND_START>[\(\[\{]* {
+    curr_lexer->lexer_debug ("<COMMAND_START>[\\(\\[\\{]+");
+
+    curr_lexer->command_arg_paren_count += yyleng;
+    curr_lexer->string_text += yytext;
+    curr_lexer->current_input_column += yyleng;
   }
 
+<COMMAND_START>[\)\]\}]* {
+   curr_lexer->lexer_debug ("<COMMAND_START>[\\)\\]\\}]+");
+
+   curr_lexer->command_arg_paren_count -= yyleng;
+   curr_lexer->string_text += yytext;
+   curr_lexer->current_input_column += yyleng;
+}
+
+%{
+// Handle quoted strings.  Quoted strings that are not separated by
+// whitespace from other argument text are combined with that previous
+// text.  For instance,
+//
+//   command 'text1'"text2"
+//
+// has a single argument text1text2, not two separate arguments.
+// That's why we must test to see if we are in command argument mode
+// when processing the end of a string.
+%}
+
 <COMMAND_START>[\"\'] {
     curr_lexer->lexer_debug ("<COMMAND_START>[\\\"\\']");
 
-    curr_lexer->at_beginning_of_statement = false;
-
-    curr_lexer->current_input_column++;
-
-    curr_lexer->begin_string (yytext[0] == '"'
-                              ? DQ_STRING_START : SQ_STRING_START);
+    if (curr_lexer->command_arg_paren_count == 0)
+      curr_lexer->begin_string (yytext[0] == '"'
+                                ? DQ_STRING_START : SQ_STRING_START);
+    else
+      curr_lexer->string_text += yytext;
+
+    curr_lexer->current_input_column += yyleng;
   }
 
-<COMMAND_START>[^#% \t\r\n\;\,\"\'][^ \t\r\n\;\,]*{S}* {
-    curr_lexer->lexer_debug ("<COMMAND_START>[^#% \\t\\r\\n\\;\\,\\\"\\'][^ \\t\\r\\n\\;\\,]*{S}*");
-
-    std::string tok = strip_trailing_whitespace (yytext);
-
-    curr_lexer->looking_for_object_index = false;
-    curr_lexer->at_beginning_of_statement = false;
-
-    return curr_lexer->handle_token (tok, SQ_STRING);
+%{
+// In standard command argument processing, whitespace separates
+// arguments.  In the presence of unbalanced parentheses, it is
+// incorporated into the argument.
+%}
+
+<COMMAND_START>{S}* {
+    curr_lexer->lexer_debug ("<COMMAND_START>{S}*");
+
+    if (curr_lexer->command_arg_paren_count == 0)
+      COMMAND_ARG_FINISH;
+    else
+      curr_lexer->string_text += yytext;
+
+    curr_lexer->current_input_column += yyleng;
+  }
+
+%{
+// Everything else is slurped into the command arguments.
+%}
+
+<COMMAND_START>([\.]|[^#% \t\r\n\.\,\;\"\'\(\[\{\}\]\)]*) {
+    curr_lexer->lexer_debug ("<COMMAND_START>([\\.]|[^#% \\t\\r\\n\\.\\,\\;\\\"\\'\\(\\[\\{\\}\\]\\)]*");
+
+    curr_lexer->string_text += yytext;
+    curr_lexer->current_input_column += yyleng;
   }
 
 <MATRIX_START>{S}* {
@@ -702,17 +834,20 @@
 
     curr_lexer->pop_start_state ();
 
-    curr_lexer->looking_for_object_index = true;
-    curr_lexer->at_beginning_of_statement = false;
-
-    curr_lexer->push_token (new token (DQ_STRING,
-                                       curr_lexer->string_text,
-                                       curr_lexer->string_line,
-                                       curr_lexer->string_column));
-
-    curr_lexer->string_text = "";
-
-    return curr_lexer->count_token_internal (DQ_STRING);
+    if (curr_lexer->start_state() != COMMAND_START)
+      {
+        curr_lexer->looking_for_object_index = true;
+        curr_lexer->at_beginning_of_statement = false;
+
+        curr_lexer->push_token (new token (DQ_STRING,
+                                           curr_lexer->string_text,
+                                           curr_lexer->string_line,
+                                           curr_lexer->string_column));
+
+        curr_lexer->string_text = "";
+
+        return curr_lexer->count_token_internal (DQ_STRING);
+      }
   }
 
 <DQ_STRING_START>\\[0-7]{1,3} {
@@ -883,17 +1018,20 @@
 
     curr_lexer->pop_start_state ();
 
-    curr_lexer->looking_for_object_index = true;
-    curr_lexer->at_beginning_of_statement = false;
-
-    curr_lexer->push_token (new token (SQ_STRING,
-                                       curr_lexer->string_text,
-                                       curr_lexer->string_line,
-                                       curr_lexer->string_column));
-
-    curr_lexer->string_text = "";
-
-    return curr_lexer->count_token_internal (SQ_STRING);
+    if (curr_lexer->start_state() != COMMAND_START)
+      {
+        curr_lexer->looking_for_object_index = true;
+        curr_lexer->at_beginning_of_statement = false;
+
+        curr_lexer->push_token (new token (SQ_STRING,
+                                           curr_lexer->string_text,
+                                           curr_lexer->string_line,
+                                           curr_lexer->string_column));
+
+        curr_lexer->string_text = "";
+
+        return curr_lexer->count_token_internal (SQ_STRING);
+      }
   }
 
 <SQ_STRING_START>[^\'\n\r]+ {
@@ -915,6 +1053,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.
 %}
 
@@ -1035,46 +1202,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 ())
       {
@@ -1089,7 +1235,7 @@
           {
             curr_lexer->looking_for_object_index = true;
 
-            return curr_lexer->count_token_internal (SUPERCLASSREF);
+            return curr_lexer->count_token_internal (id_tok);
           }
       }
   }
@@ -1098,9 +1244,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 ())
@@ -1116,7 +1261,7 @@
           {
             curr_lexer->looking_for_object_index = true;
 
-            return curr_lexer->count_token_internal (METAQUERY);
+            return curr_lexer->count_token_internal (id_tok);
           }
       }
   }
@@ -1784,21 +1929,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\
@@ -1864,8 +1994,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;
@@ -1889,6 +2021,7 @@
   fcn_file_full_name = "";
   looking_at_object_index.clear ();
   looking_at_object_index.push_front (false);
+  command_arg_paren_count = 0;
 
   while (! parsed_function_name.empty ())
     parsed_function_name.pop ();
@@ -2266,20 +2399,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;
@@ -2292,10 +2411,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;
@@ -2481,6 +2599,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 ()
@@ -2652,36 +2798,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 ();
 
@@ -2691,37 +2824,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.
@@ -3279,6 +3416,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)
 {
@@ -3294,12 +3437,7 @@
   if (! input_buf.empty ())
     status = input_buf.copy_chunk (buf, max_size);
   else
-    {
-      status = YY_NULL;
-
-      if (! input_buf.at_eof ())
-        fatal_error ("octave_base_lexer::fill_flex_buffer failed");
-    }
+    status = YY_NULL;
 
   return status;
 }
@@ -3315,12 +3453,8 @@
   if (! input_buf.empty ())
     status = input_buf.copy_chunk (buf, max_size);
   else
-    {
-      status = YY_NULL;
-
-      if (! input_buf.at_eof ())
-        fatal_error ("octave_base_lexer::fill_flex_buffer failed");
-    }
+    status = YY_NULL;
 
   return status;
 }
+
--- a/libinterp/parse-tree/module.mk	Fri Feb 06 08:31:09 2015 -0800
+++ b/libinterp/parse-tree/module.mk	Fri Feb 06 08:31:49 2015 -0800
@@ -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 Feb 06 08:31:09 2015 -0800
+++ b/libinterp/parse-tree/oct-parse.in.yy	Fri Feb 06 08:31:49 2015 -0800
@@ -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; }
                 ;
 
 // =====================
@@ -940,7 +992,7 @@
 
 if_cmd_list1    : expression stmt_begin opt_sep opt_list
                   {
-                    $1->mark_braindead_shortcircuit (lexer.fcn_file_full_name);
+                    $1->mark_braindead_shortcircuit ();
 
                     $$ = parser.start_if_command ($1, $4);
                   }
@@ -953,7 +1005,7 @@
 
 elseif_clause   : ELSEIF stash_comment opt_sep expression stmt_begin opt_sep opt_list
                   {
-                    $4->mark_braindead_shortcircuit (lexer.fcn_file_full_name);
+                    $4->mark_braindead_shortcircuit ();
 
                     $$ = parser.make_elseif_clause ($1, $4, $7, $2);
                   }
@@ -1015,7 +1067,7 @@
 
 loop_command    : WHILE stash_comment expression stmt_begin opt_sep opt_list END
                   {
-                    $3->mark_braindead_shortcircuit (lexer.fcn_file_full_name);
+                    $3->mark_braindead_shortcircuit ();
 
                     if (! ($$ = parser.make_while_command ($1, $3, $6, $7, $2)))
                       {
@@ -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.
@@ -2463,6 +2571,8 @@
 
   if (end_token_ok (end_tok, parfor ? token::parfor_end : token::for_end))
     {
+      expr->mark_as_for_cmd_expr ();
+
       octave_comment_list *tc = lexer.comment_buf.get_comment ();
 
       lexer.looping--;
@@ -2999,6 +3109,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 +3397,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 +3425,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 +3447,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 +3845,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 +3879,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 +3894,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 +3965,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 +4030,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 +4078,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 +4091,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 +4308,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 +5039,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 Feb 06 08:31:09 2015 -0800
+++ b/libinterp/parse-tree/octave.gperf	Fri Feb 06 08:31:49 2015 -0800
@@ -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 Feb 06 08:31:09 2015 -0800
+++ b/libinterp/parse-tree/parse.h	Fri Feb 06 08:31:49 2015 -0800
@@ -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 Feb 06 08:31:09 2015 -0800
+++ b/libinterp/parse-tree/pt-all.h	Fri Feb 06 08:31:49 2015 -0800
@@ -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-binop.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/libinterp/parse-tree/pt-binop.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -36,7 +36,7 @@
 
 // TRUE means we mark | and & expressions for braindead short-circuit
 // behavior.
-static bool Vdo_braindead_shortcircuit_evaluation;
+static bool Vdo_braindead_shortcircuit_evaluation = true;
 
 // Binary expressions.
 
@@ -54,6 +54,16 @@
   return retval;
 }
 
+void
+tree_binary_expression::matlab_style_short_circuit_warning (const char *op)
+{
+  warning_with_id ("Octave:possible-matlab-short-circuit-operator",
+                   "Matlab-style short-circuit operation performed for operator %s",
+                   op);
+
+  braindead_shortcircuit_warning_issued = true;
+}
+
 octave_value
 tree_binary_expression::rvalue1 (int)
 {
@@ -83,6 +93,7 @@
                         {
                           if (etype == octave_value::op_el_or)
                             {
+                              matlab_style_short_circuit_warning ("|");
                               result = true;
                               goto done;
                             }
@@ -90,7 +101,10 @@
                       else
                         {
                           if (etype == octave_value::op_el_and)
-                            goto done;
+                            {
+                              matlab_style_short_circuit_warning ("&");
+                              goto done;
+                            }
                         }
 
                       if (op_rhs)
@@ -121,7 +135,7 @@
 
           if (! error_state && b.is_defined ())
             {
-              BEGIN_PROFILER_BLOCK ("binary " + oper ())
+              BEGIN_PROFILER_BLOCK (tree_binary_expression)
 
               // Note: The profiler does not catch the braindead
               // short-circuit evaluation code above, but that should be
@@ -298,6 +312,14 @@
 The original variable value is restored when exiting the function.\n\
 @end deftypefn")
 {
+  static bool warned = false;
+  if (! warned)
+    {
+      warned = true;
+      warning_with_id ("Octave:deprecated-function",
+                       "do_braindead_shortcircuit_evaluation is obsolete and will be removed from a future version of Octave");
+    }
+
   return SET_INTERNAL_VARIABLE (do_braindead_shortcircuit_evaluation);
 }
 
--- a/libinterp/parse-tree/pt-binop.h	Fri Feb 06 08:31:09 2015 -0800
+++ b/libinterp/parse-tree/pt-binop.h	Fri Feb 06 08:31:49 2015 -0800
@@ -46,14 +46,16 @@
                           octave_value::binary_op t
                             = octave_value::unknown_binary_op)
     : tree_expression (l, c), op_lhs (0), op_rhs (0), etype (t),
-      eligible_for_braindead_shortcircuit (false) { }
+      eligible_for_braindead_shortcircuit (false),
+      braindead_shortcircuit_warning_issued (false) { }
 
   tree_binary_expression (tree_expression *a, tree_expression *b,
                           int l = -1, int c = -1,
                           octave_value::binary_op t
                             = octave_value::unknown_binary_op)
     : tree_expression (l, c), op_lhs (a), op_rhs (b), etype (t),
-      eligible_for_braindead_shortcircuit (false) { }
+      eligible_for_braindead_shortcircuit (false),
+      braindead_shortcircuit_warning_issued (false) { }
 
   ~tree_binary_expression (void)
   {
@@ -61,23 +63,14 @@
     delete op_rhs;
   }
 
-  void mark_braindead_shortcircuit (const std::string& file)
+  void mark_braindead_shortcircuit (void)
   {
     if (etype == octave_value::op_el_and || etype == octave_value::op_el_or)
       {
-        if (file.empty ())
-          warning_with_id ("Octave:possible-matlab-short-circuit-operator",
-                           "possible Matlab-style short-circuit operator at line %d, column %d",
-                           line (), column ());
-        else
-          warning_with_id ("Octave:possible-matlab-short-circuit-operator",
-                           "%s: possible Matlab-style short-circuit operator at line %d, column %d",
-                           file.c_str (), line (), column ());
-
         eligible_for_braindead_shortcircuit = true;
 
-        op_lhs->mark_braindead_shortcircuit (file);
-        op_rhs->mark_braindead_shortcircuit (file);
+        op_lhs->mark_braindead_shortcircuit ();
+        op_rhs->mark_braindead_shortcircuit ();
       }
   }
 
@@ -107,6 +100,9 @@
 
   void accept (tree_walker& tw);
 
+  std::string profiler_name (void) const { return "binary " + oper (); }
+
+
 protected:
 
   // The operands for the expression.
@@ -122,6 +118,12 @@
   // or WHILE statement.
   bool eligible_for_braindead_shortcircuit;
 
+  // TRUE if we have already issued a warning about short circuiting
+  // for this operator.
+  bool braindead_shortcircuit_warning_issued;
+
+  void matlab_style_short_circuit_warning (const char *op);
+
   // No copying!
 
   tree_binary_expression (const tree_binary_expression&);
--- a/libinterp/parse-tree/pt-bp.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/libinterp/parse-tree/pt-bp.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -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 Feb 06 08:31:09 2015 -0800
+++ b/libinterp/parse-tree/pt-bp.h	Fri Feb 06 08:31:49 2015 -0800
@@ -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 Feb 06 08:31:09 2015 -0800
+++ b/libinterp/parse-tree/pt-cbinop.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -32,6 +32,49 @@
 #include "pt-unop.h"
 #include "pt-walk.h"
 
+octave_value_list
+tree_compound_binary_expression::rvalue (int nargout)
+{
+  octave_value_list retval;
+
+  if (nargout > 1)
+    error ("binary operator '%s': invalid number of output arguments",
+           oper () . c_str ());
+  else
+    retval = rvalue1 (nargout);
+
+  return retval;
+}
+
+octave_value
+tree_compound_binary_expression::rvalue1 (int)
+{
+  octave_value retval;
+
+  if (error_state)
+    return retval;
+
+  if (op_lhs)
+    {
+      octave_value a = op_lhs->rvalue1 ();
+
+      if (! error_state && a.is_defined () && op_rhs)
+        {
+          octave_value b = op_rhs->rvalue1 ();
+
+          if (! error_state && b.is_defined ())
+            {
+              retval = ::do_binary_op (etype, a, b);
+
+              if (error_state)
+                retval = octave_value ();
+            }
+        }
+    }
+
+  return retval;
+}
+
 // If a tree expression is a transpose or hermitian transpose, return
 // the argument and corresponding operator.
 
@@ -162,7 +205,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-cbinop.h	Fri Feb 06 08:31:09 2015 -0800
+++ b/libinterp/parse-tree/pt-cbinop.h	Fri Feb 06 08:31:49 2015 -0800
@@ -52,6 +52,12 @@
 
   octave_value::compound_binary_op cop_type (void) const { return etype; }
 
+  bool rvalue_ok (void) const { return true; }
+
+  octave_value rvalue1 (int nargout = 1);
+
+  octave_value_list rvalue (int nargout);
+
 private:
 
   tree_expression *op_lhs;
--- a/libinterp/parse-tree/pt-cell.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/libinterp/parse-tree/pt-cell.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -44,7 +44,7 @@
 
   Cell val;
 
-  int i = 0;
+  octave_idx_type i = 0;
 
   for (iterator p = begin (); p != end (); p++)
     {
@@ -65,10 +65,15 @@
         {
           octave_idx_type this_nc = row.length ();
 
-          if (nc != this_nc)
+          if (this_nc != nc)
             {
-              ::error ("number of columns must match");
-              return retval;
+              if (this_nc == 0)
+                continue;  // blank line
+              else
+                {
+                  ::error ("number of columns must match");
+                  return retval;
+                }
             }
         }
 
@@ -78,6 +83,8 @@
       i++;
     }
 
+  if (i < nr)
+    val.resize (dim_vector (i, nc));  // there were blank rows
   retval = val;
 
   return retval;
--- a/libinterp/parse-tree/pt-check.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/libinterp/parse-tree/pt-check.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -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 Feb 06 08:31:09 2015 -0800
+++ b/libinterp/parse-tree/pt-check.h	Fri Feb 06 08:31:49 2015 -0800
@@ -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 Feb 06 08:31:49 2015 -0800
@@ -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 Feb 06 08:31:49 2015 -0800
@@ -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-colon.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/libinterp/parse-tree/pt-colon.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -96,7 +96,12 @@
     retval = Range ();
   else
     {
-      retval = Range (m_base(0), m_limit(0), m_increment(0));
+      Range r (m_base(0), m_limit(0), m_increment(0));
+
+      // For compatibility with Matlab, don't allow the range used in
+      // a FOR loop expression to be converted to a Matrix.
+
+      retval = octave_value (r, is_for_cmd_expr ());
 
       if (result_is_str)
         retval = retval.convert_to_str (false, true, dq_str ? '"' : '\'');
--- a/libinterp/parse-tree/pt-const.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/libinterp/parse-tree/pt-const.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -34,7 +34,6 @@
 
 // We are likely to have a lot of tree_constant objects to allocate,
 // so make the grow_size large.
-DEFINE_OCTAVE_ALLOCATOR2 (tree_constant, 1024);
 
 void
 tree_constant::print (std::ostream& os, bool pr_as_read_syntax,
--- a/libinterp/parse-tree/pt-const.h	Fri Feb 06 08:31:09 2015 -0800
+++ b/libinterp/parse-tree/pt-const.h	Fri Feb 06 08:31:49 2015 -0800
@@ -26,7 +26,6 @@
 #include <iosfwd>
 #include <string>
 
-#include "oct-alloc.h"
 
 class octave_value_list;
 class tree_walker;
@@ -99,7 +98,6 @@
 
   tree_constant& operator = (const tree_constant&);
 
-  DECLARE_OCTAVE_ALLOCATOR
 };
 
 #endif
--- a/libinterp/parse-tree/pt-eval.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/libinterp/parse-tree/pt-eval.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -57,6 +57,8 @@
 
 bool tree_evaluator::debug_mode = false;
 
+bool tree_evaluator::quiet_breakpoint_flag = false;
+
 tree_evaluator::stmt_list_type tree_evaluator::statement_context
   = tree_evaluator::other;
 
@@ -368,7 +370,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)
           {
@@ -626,6 +629,12 @@
 }
 
 void
+tree_evaluator::visit_funcall (tree_funcall&)
+{
+  panic_impossible ();
+}
+
+void
 tree_evaluator::visit_parameter_list (tree_parameter_list&)
 {
   panic_impossible ();
@@ -694,13 +703,12 @@
           if (! Vdebugging)
             octave_call_stack::set_location (stmt.line (), stmt.column ());
 
-          // FIXME: we need to distinguish functions from scripts
-          //        to get this right.
           if ((statement_context == script
-               && ((Vecho_executing_commands & ECHO_SCRIPTS)
-                   || (Vecho_executing_commands & ECHO_FUNCTIONS)))
+               && ((Vecho_executing_commands & ECHO_SCRIPTS
+                   && octave_call_stack::all_scripts ())
+                   || Vecho_executing_commands & ECHO_FUNCTIONS))
               || (statement_context == function
-                  && (Vecho_executing_commands & ECHO_FUNCTIONS)))
+                  && Vecho_executing_commands & ECHO_FUNCTIONS))
             stmt.echo_code ();
         }
 
@@ -925,6 +933,7 @@
 
               err.assign ("message", last_error_message ());
               err.assign ("identifier", last_error_id ());
+              err.assign ("stack", last_error_stack ());
 
               if (! error_state)
                 ult.assign (octave_value::op_asn_eq, err);
@@ -1103,6 +1112,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 Feb 06 08:31:09 2015 -0800
+++ b/libinterp/parse-tree/pt-eval.h	Fri Feb 06 08:31:49 2015 -0800
@@ -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&);
@@ -149,6 +151,8 @@
 
   static bool debug_mode;
 
+  static bool quiet_breakpoint_flag;
+
   // Possible types of evaluation contexts.
   enum stmt_list_type
   {
--- a/libinterp/parse-tree/pt-exp.h	Fri Feb 06 08:31:09 2015 -0800
+++ b/libinterp/parse-tree/pt-exp.h	Fri Feb 06 08:31:49 2015 -0800
@@ -40,8 +40,8 @@
 public:
 
   tree_expression (int l = -1, int c = -1)
-    : tree (l, c), num_parens (0), postfix_indexed (false),
-      print_flag (false) { }
+    : tree (l, c), num_parens (0), postfix_index_type ('\0'),
+      for_cmd_expr (false), 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
@@ -100,7 +102,11 @@
 
   virtual std::string original_text (void) const;
 
-  virtual void mark_braindead_shortcircuit (const std::string&) { }
+  virtual void mark_braindead_shortcircuit (void) { }
+
+  void mark_as_for_cmd_expr (void) { for_cmd_expr = true; }
+
+  bool is_for_cmd_expr (void) const { return for_cmd_expr; }
 
   tree_expression *mark_in_parens (void)
   {
@@ -108,9 +114,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 +129,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 +143,14 @@
   //                  ==> 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;
+
+  // TRUE if this expression is the EXPR in for loop:
+  // FOR i = EXPR ... END
+  bool for_cmd_expr;
 
   // 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 Feb 06 08:31:49 2015 -0800
@@ -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 Feb 06 08:31:49 2015 -0800
@@ -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 Feb 06 08:31:09 2015 -0800
+++ b/libinterp/parse-tree/pt-id.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -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 Feb 06 08:31:09 2015 -0800
+++ b/libinterp/parse-tree/pt-id.h	Fri Feb 06 08:31:49 2015 -0800
@@ -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 Feb 06 08:31:09 2015 -0800
+++ b/libinterp/parse-tree/pt-idx.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -220,7 +220,7 @@
               if (t.is_string () && t.rows () == 1)
                 fn = t.string_value ();
               else
-                error ("dynamic structure field names must be character strings");
+                error ("dynamic structure field names must be strings");
             }
         }
       else
@@ -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 Feb 06 08:31:09 2015 -0800
+++ b/libinterp/parse-tree/pt-mat.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -26,6 +26,7 @@
 
 #include <iostream>
 
+#include "oct-locbuf.h"
 #include "quit.h"
 
 #include "data.h"
@@ -387,27 +388,30 @@
 
   first_elem = true;
 
-  for (iterator p = begin (); p != end (); p++)
+  if (! error_state)
     {
-      octave_quit ();
-
-      octave_value val = *p;
-
-      dim_vector this_elt_dv = val.dims ();
-
-      if (! this_elt_dv.zero_by_zero ())
+      for (iterator p = begin (); p != end (); p++)
         {
-          all_mt = false;
+          octave_quit ();
+
+          octave_value val = *p;
 
-          if (first_elem)
+          dim_vector this_elt_dv = val.dims ();
+
+          if (! this_elt_dv.zero_by_zero ())
             {
-              first_elem = false;
-              dv = this_elt_dv;
-            }
-          else if ((! any_class) && (! dv.hvcat (this_elt_dv, 1)))
-            {
-              eval_error ("horizontal dimensions mismatch", dv, this_elt_dv);
-              break;
+              all_mt = false;
+
+              if (first_elem)
+                {
+                  first_elem = false;
+                  dv = this_elt_dv;
+                }
+              else if ((! any_class) && (! dv.hvcat (this_elt_dv, 1)))
+                {
+                  eval_error ("horizontal dimensions mismatch", dv, this_elt_dv);
+                  break;
+                }
             }
         }
     }
@@ -684,7 +688,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++)
     {
@@ -754,7 +759,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 ();
@@ -792,12 +798,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 ();
@@ -830,12 +838,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 Feb 06 08:31:09 2015 -0800
+++ b/libinterp/parse-tree/pt-pr-code.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -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;
     }
@@ -1218,6 +1226,9 @@
     os << alt_txt;
   else
     {
+      // Print prefix for blank lines.
+      indent ();
+
       os << "\n";
 
       beginning_of_line = true;
@@ -1268,7 +1279,13 @@
       if (c == '\n')
         {
           if (prev_char_was_newline)
-            os << "##";
+            {
+              printed_something = true;
+
+              indent ();
+
+              os << "##";
+            }
 
           newline ();
 
--- a/libinterp/parse-tree/pt-pr-code.h	Fri Feb 06 08:31:09 2015 -0800
+++ b/libinterp/parse-tree/pt-pr-code.h	Fri Feb 06 08:31:49 2015 -0800
@@ -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 Feb 06 08:31:09 2015 -0800
+++ b/libinterp/parse-tree/pt-select.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -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-unop.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/libinterp/parse-tree/pt-unop.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -73,7 +73,7 @@
 
           if (! error_state)
             {
-              BEGIN_PROFILER_BLOCK ("prefix " + oper ())
+              BEGIN_PROFILER_BLOCK (tree_prefix_expression)
 
               ref.do_unary_op (etype);
 
@@ -89,7 +89,7 @@
 
           if (! error_state && val.is_defined ())
             {
-              BEGIN_PROFILER_BLOCK ("prefix " + oper ())
+              BEGIN_PROFILER_BLOCK (tree_prefix_expression)
 
               // Attempt to do the operation in-place if it is unshared
               // (a temporary expression).
@@ -162,8 +162,10 @@
             {
               retval = ref.value ();
 
-              BEGIN_PROFILER_BLOCK ("postfix " + oper ())
+              BEGIN_PROFILER_BLOCK (tree_postfix_expression)
+
               ref.do_unary_op (etype);
+
               END_PROFILER_BLOCK
             }
         }
@@ -173,7 +175,7 @@
 
           if (! error_state && val.is_defined ())
             {
-              BEGIN_PROFILER_BLOCK ("postfix " + oper ())
+              BEGIN_PROFILER_BLOCK (tree_postfix_expression)
 
               retval = ::do_unary_op (etype, val);
 
--- a/libinterp/parse-tree/pt-unop.h	Fri Feb 06 08:31:09 2015 -0800
+++ b/libinterp/parse-tree/pt-unop.h	Fri Feb 06 08:31:49 2015 -0800
@@ -108,6 +108,9 @@
 
   void accept (tree_walker& tw);
 
+  std::string profiler_name (void) const { return "prefix " + oper (); }
+
+
 private:
 
   // No copying!
@@ -145,6 +148,8 @@
 
   void accept (tree_walker& tw);
 
+  std::string profiler_name (void) const { return "postfix " + oper (); }
+
 private:
 
   // No copying!
--- a/libinterp/parse-tree/pt-walk.h	Fri Feb 06 08:31:09 2015 -0800
+++ b/libinterp/parse-tree/pt-walk.h	Fri Feb 06 08:31:49 2015 -0800
@@ -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 Feb 06 08:31:09 2015 -0800
+++ b/libinterp/parse-tree/token.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -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 Feb 06 08:31:09 2015 -0800
+++ b/libinterp/parse-tree/token.h	Fri Feb 06 08:31:49 2015 -0800
@@ -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/Makefile.am	Fri Feb 06 08:31:09 2015 -0800
+++ b/liboctave/Makefile.am	Fri Feb 06 08:31:49 2015 -0800
@@ -20,10 +20,6 @@
 
 include $(top_srcdir)/build-aux/common.mk
 
-## Run cruft dir with stand-alone Makefile.
-## Eventually this will use module.mk syntax.
-SUBDIRS = cruft
-
 ## Search local directories before those specified by the user.
 AM_CPPFLAGS = \
   -I$(srcdir)/array \
@@ -55,6 +51,7 @@
 
 octinclude_HEADERS = \
   $(ARRAY_INC) \
+  $(CRUFT_INC) \
   $(NUMERIC_INC) \
   $(OPERATORS_INC) \
   $(SYSTEM_INC) \
@@ -75,7 +72,10 @@
 
 ## A list of all files that could include tests
 
+liboctave_la_LIBADD =
+
 include array/module.mk
+include cruft/module.mk
 include numeric/module.mk
 include operators/module.mk
 include system/module.mk
@@ -92,14 +92,7 @@
 # Dummy C++ source to force C++ linking.
 nodist_EXTRA_liboctave_la_SOURCES = dummy.cc
 
-liboctave_la_LIBADD = \
-  array/libarray.la \
-  cruft/libcruft.la \
-  cruft/ranlib/libranlib.la \
-  numeric/libnumeric.la \
-  operators/liboperators.la \
-  system/libsystem.la \
-  util/libutil.la \
+liboctave_la_LIBADD += \
   $(top_builddir)/libgnu/libgnu.la \
   $(LIBOCTAVE_LINK_DEPS)
 
--- a/liboctave/array/Array-C.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/liboctave/array/Array-C.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -41,22 +41,54 @@
   return xisnan (x);
 }
 
+// Sort Criteria: 1) isnan, 2) magnitude of z, 3) phase of z in range (-pi, pi]
+
 static bool
 nan_ascending_compare (const Complex& x, const Complex& y)
 {
-  return (xisnan (y)
-          ? ! xisnan (x)
-          : ((std::abs (x) < std::abs (x))
-             || ((std::abs (x) == std::abs (x)) && (arg (x) < arg (x)))));
+  if (xisnan (y))
+    return (! xisnan (x));
+
+  double xabs = std::abs (x);
+  double yabs = std::abs (y);
+
+  if (xabs < yabs)
+    return true;
+  else if (xabs == yabs)
+    {
+      double xarg = arg (x);
+      double yarg = arg (y);
+      xarg = (xarg == -M_PI) ? M_PI : xarg; 
+      yarg = (yarg == -M_PI) ? M_PI : yarg; 
+
+      return xarg < yarg;
+    }
+  else
+    return false;
 }
 
 static bool
 nan_descending_compare (const Complex& x, const Complex& y)
 {
-  return (xisnan (x)
-          ? ! xisnan (y)
-          : ((std::abs (x) > std::abs (x))
-             || ((std::abs (x) == std::abs (x)) && (arg (x) > arg (x)))));
+  if (xisnan (x))
+    return (! xisnan (y));
+
+  double xabs = std::abs (x);
+  double yabs = std::abs (y);
+
+  if (xabs > yabs)
+    return true;
+  else if (xabs == yabs)
+    {
+      double xarg = arg (x);
+      double yarg = arg (y);
+      xarg = (xarg == -M_PI) ? M_PI : xarg; 
+      yarg = (yarg == -M_PI) ? M_PI : yarg; 
+
+      return xarg > yarg;
+    }
+  else
+    return false;
 }
 
 Array<Complex>::compare_fcn_type
@@ -88,7 +120,7 @@
   return result;
 }
 
-INSTANTIATE_ARRAY_SORT (Complex);
+template class OCTAVE_API octave_sort<Complex>;
 
 INSTANTIATE_ARRAY (Complex, OCTAVE_API);
 
--- a/liboctave/array/Array-b.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/liboctave/array/Array-b.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -52,7 +52,8 @@
   // FIXME: This is essentially a simple bucket sort.
   // Can it be efficiently done by std::partition?
   OCTAVE_LOCAL_BUFFER (octave_idx_type, jdx, nel);
-  octave_idx_type k = 0, l = 0;
+  octave_idx_type k = 0;
+  octave_idx_type l = 0;
   for (octave_idx_type i = 0; i < nel; i++)
     {
       if (data[i] == desc)
@@ -103,7 +104,7 @@
   do_bool_partition<true> (data, idx, nel);
 }
 
-INSTANTIATE_ARRAY_SORT (bool);
+template class OCTAVE_API octave_sort<bool>;
 
 INSTANTIATE_ARRAY (bool, OCTAVE_API);
 
--- a/liboctave/array/Array-ch.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/liboctave/array/Array-ch.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -32,7 +32,7 @@
 #define INLINE_DESCENDING_SORT
 #include "oct-sort.cc"
 
-INSTANTIATE_ARRAY_SORT (char);
+template class OCTAVE_API octave_sort<char>;
 
 INSTANTIATE_ARRAY (char, OCTAVE_API);
 
--- a/liboctave/array/Array-d.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/liboctave/array/Array-d.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -155,7 +155,7 @@
   return mode;
 }
 
-INSTANTIATE_ARRAY_SORT (double);
+template class OCTAVE_API octave_sort<double>;
 
 INSTANTIATE_ARRAY (double, OCTAVE_API);
 
--- a/liboctave/array/Array-f.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/liboctave/array/Array-f.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -155,7 +155,7 @@
   return mode;
 }
 
-INSTANTIATE_ARRAY_SORT (float);
+template class OCTAVE_API octave_sort<float>;
 
 INSTANTIATE_ARRAY (float, OCTAVE_API);
 
--- a/liboctave/array/Array-fC.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/liboctave/array/Array-fC.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -41,22 +41,54 @@
   return xisnan (x);
 }
 
+// Sort Criteria: 1) isnan, 2) magnitude of z, 3) phase of z in range (-pi, pi]
+
 static bool
 nan_ascending_compare (const FloatComplex& x, const FloatComplex& y)
 {
-  return (xisnan (y)
-          ? ! xisnan (x)
-          : ((std::abs (x) < std::abs (x))
-             || ((std::abs (x) == std::abs (x)) && (arg (x) < arg (x)))));
+  if (xisnan (y))
+    return (! xisnan (x));
+
+  float xabs = std::abs (x);
+  float yabs = std::abs (y);
+
+  if (xabs < yabs)
+    return true;
+  else if (xabs == yabs)
+    {
+      float xarg = arg (x);
+      float yarg = arg (y);
+      xarg = (xarg == -M_PI) ? M_PI : xarg; 
+      yarg = (yarg == -M_PI) ? M_PI : yarg; 
+
+      return xarg < yarg;
+    }
+  else
+    return false;
 }
 
 static bool
 nan_descending_compare (const FloatComplex& x, const FloatComplex& y)
 {
-  return (xisnan (x)
-          ? ! xisnan (y)
-          : ((std::abs (x) > std::abs (x))
-             || ((std::abs (x) == std::abs (x)) && (arg (x) > arg (x)))));
+  if (xisnan (x))
+    return (! xisnan (y));
+
+  float xabs = std::abs (x);
+  float yabs = std::abs (y);
+
+  if (xabs > yabs)
+    return true;
+  else if (xabs == yabs)
+    {
+      float xarg = arg (x);
+      float yarg = arg (y);
+      xarg = (xarg == -M_PI) ? M_PI : xarg; 
+      yarg = (yarg == -M_PI) ? M_PI : yarg; 
+
+      return xarg > yarg;
+    }
+  else
+    return false;
 }
 
 Array<FloatComplex>::compare_fcn_type
@@ -88,7 +120,7 @@
   return result;
 }
 
-INSTANTIATE_ARRAY_SORT (FloatComplex);
+template class OCTAVE_API octave_sort<FloatComplex>;
 
 INSTANTIATE_ARRAY (FloatComplex, OCTAVE_API);
 
--- a/liboctave/array/Array-i.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/liboctave/array/Array-i.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -35,10 +35,10 @@
 #define INLINE_DESCENDING_SORT
 #include "oct-sort.cc"
 
-INSTANTIATE_ARRAY_SORT (int);
-INSTANTIATE_ARRAY_SORT (long);
+template class OCTAVE_API octave_sort<int>;
+template class OCTAVE_API octave_sort<long>;
 #if defined (HAVE_LONG_LONG_INT)
-INSTANTIATE_ARRAY_SORT (long long);
+template class OCTAVE_API octave_sort<long long>;
 #endif
 
 INSTANTIATE_ARRAY (int, OCTAVE_API);
@@ -47,20 +47,20 @@
 INSTANTIATE_ARRAY (long long, OCTAVE_API);
 #endif
 
-INSTANTIATE_ARRAY_SORT (octave_int8);
-INSTANTIATE_ARRAY_SORT (octave_int16);
-INSTANTIATE_ARRAY_SORT (octave_int32);
-INSTANTIATE_ARRAY_SORT (octave_int64);
+template class OCTAVE_API octave_sort<octave_int8>;
+template class OCTAVE_API octave_sort<octave_int16>;
+template class OCTAVE_API octave_sort<octave_int32>;
+template class OCTAVE_API octave_sort<octave_int64>;
 
 INSTANTIATE_ARRAY (octave_int8, OCTAVE_API);
 INSTANTIATE_ARRAY (octave_int16, OCTAVE_API);
 INSTANTIATE_ARRAY (octave_int32, OCTAVE_API);
 INSTANTIATE_ARRAY (octave_int64, OCTAVE_API);
 
-INSTANTIATE_ARRAY_SORT (octave_uint8);
-INSTANTIATE_ARRAY_SORT (octave_uint16);
-INSTANTIATE_ARRAY_SORT (octave_uint32);
-INSTANTIATE_ARRAY_SORT (octave_uint64);
+template class OCTAVE_API octave_sort<octave_uint8>;
+template class OCTAVE_API octave_sort<octave_uint16>;
+template class OCTAVE_API octave_sort<octave_uint32>;
+template class OCTAVE_API octave_sort<octave_uint64>;
 
 INSTANTIATE_ARRAY (octave_uint8, OCTAVE_API);
 INSTANTIATE_ARRAY (octave_uint16, OCTAVE_API);
--- a/liboctave/array/Array-s.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/liboctave/array/Array-s.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -33,7 +33,7 @@
 #define INLINE_DESCENDING_SORT
 #include "oct-sort.cc"
 
-INSTANTIATE_ARRAY_SORT (short);
+template class OCTAVE_API octave_sort<short>;
 
 INSTANTIATE_ARRAY (short, OCTAVE_API);
 
--- a/liboctave/array/Array-str.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/liboctave/array/Array-str.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -32,6 +32,6 @@
 #include "Array.cc"
 #include "oct-sort.cc"
 
-INSTANTIATE_ARRAY_SORT (std::string);
+template class OCTAVE_API octave_sort<std::string>;
 
 INSTANTIATE_ARRAY (std::string, OCTAVE_API);
--- a/liboctave/array/Array-util.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/liboctave/array/Array-util.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -423,9 +423,11 @@
 dim_vector
 zero_dims_inquire (const Array<idx_vector>& ia, const dim_vector& rhdv)
 {
-  int ial = ia.length (), rhdvl = rhdv.length ();
+  int ial = ia.length ();
+  int rhdvl = rhdv.length ();
   dim_vector rdv = dim_vector::alloc (ial);
-  bool *scalar = new bool [ial], *colon = new bool [ial];
+  bool *scalar = new bool [ial];
+  bool *colon = new bool [ial];
   // Mark scalars and colons, count non-scalar indices.
   int nonsc = 0;
   bool all_colons = true;
@@ -479,7 +481,8 @@
 zero_dims_inquire (const idx_vector& i, const idx_vector& j,
                    const dim_vector& rhdv)
 {
-  bool icol = i.is_colon (), jcol = j.is_colon ();
+  bool icol = i.is_colon ();
+  bool jcol = j.is_colon ();
   dim_vector rdv;
   if (icol && jcol && rhdv.length () == 2)
     {
@@ -563,10 +566,12 @@
       else if (all_ranges && clen != 0)
         {
           // All ranges case - the result is a range.
-          octave_idx_type start = 0, step = 0;
+          octave_idx_type start = 0;
+          octave_idx_type step = 0;
           for (octave_idx_type i = len - 1; i >= 0; i--)
             {
-              octave_idx_type xstart = idxa(i)(0), xstep = idxa(i)(1) - xstart;
+              octave_idx_type xstart = idxa(i)(0);
+              octave_idx_type xstep = idxa(i)(1) - xstart;
               start = start * dvx(i) + xstart;
               step = step * dvx(i) + xstep;
             }
@@ -597,7 +602,8 @@
 Array<idx_vector>
 ind2sub (const dim_vector& dv, const idx_vector& idx)
 {
-  octave_idx_type len = idx.length (0), n = dv.length ();
+  octave_idx_type len = idx.length (0);
+  octave_idx_type n = dv.length ();
   Array<idx_vector> retval (dim_vector (n, 1));
   octave_idx_type numel = dv.numel ();
 
--- a/liboctave/array/Array.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/liboctave/array/Array.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -76,7 +76,7 @@
       slice_data = rep->data;
     }
   else
-    fill_or_memset (slice_len, val, slice_data);
+    std::fill_n (slice_data, slice_len, val);
 }
 
 template <class T>
@@ -270,7 +270,9 @@
 Array<T>
 Array<T>::page (octave_idx_type k) const
 {
-  octave_idx_type r = dimensions(0), c = dimensions (1), p = r*c;
+  octave_idx_type r = dimensions(0);
+  octave_idx_type c = dimensions(1);
+  octave_idx_type p = r*c;
 #ifdef BOUNDS_CHECKING
   if (k < 0 || k > dimensions.numel (2))
     gripe_index_out_of_range (3, 3, k+1, dimensions.numel (2));
@@ -393,10 +395,11 @@
   {
     if (lev == 0)
       {
-        octave_idx_type step = stride[0], len = dim[0];
+        octave_idx_type step = stride[0];
+        octave_idx_type len = dim[0];
         if (step == 1)
           {
-            copy_or_memcpy (len, src, dest);
+            std::copy (src, src + len, dest);
             dest += len;
           }
         else
@@ -411,7 +414,8 @@
       dest = blk_trans (src, dest, dim[1], dim[0]);
     else
       {
-        octave_idx_type step = stride[lev], len = dim[lev];
+        octave_idx_type step = stride[lev];
+        octave_idx_type len = dim[lev];
         for (octave_idx_type i = 0, j = 0; i < len; i++, j+= step)
           dest = do_permute (src + i * step, dest, lev-1);
       }
@@ -568,7 +572,8 @@
       dest += idx[0].index (src, dim[0], dest);
     else
       {
-        octave_idx_type nn = idx[lev].length (dim[lev]), d = cdim[lev];
+        octave_idx_type nn = idx[lev].length (dim[lev]);
+        octave_idx_type d = cdim[lev];
         for (octave_idx_type i = 0; i < nn; i++)
           dest = do_index (src + d*idx[lev].xelem (i), dest, lev-1);
       }
@@ -584,7 +589,8 @@
       src += idx[0].assign (src, dim[0], dest);
     else
       {
-        octave_idx_type nn = idx[lev].length (dim[lev]), d = cdim[lev];
+        octave_idx_type nn = idx[lev].length (dim[lev]);
+        octave_idx_type d = cdim[lev];
         for (octave_idx_type i = 0; i < nn; i++)
           src = do_assign (src, dest + d*idx[lev].xelem (i), lev-1);
       }
@@ -600,7 +606,8 @@
       idx[0].fill (val, dim[0], dest);
     else
       {
-        octave_idx_type nn = idx[lev].length (dim[lev]), d = cdim[lev];
+        octave_idx_type nn = idx[lev].length (dim[lev]);
+        octave_idx_type d = cdim[lev];
         for (octave_idx_type i = 0; i < nn; i++)
           do_fill (val, dest + d*idx[lev].xelem (i), lev-1);
       }
@@ -655,7 +662,8 @@
     sext = cext + n;
     dext = sext + n;
 
-    octave_idx_type sld = ld, dld = ld;
+    octave_idx_type sld = ld;
+    octave_idx_type dld = ld;
     for (int j = 0; j < n; j++)
       {
         cext[j] = std::min (ndv(i+j), odv(i+j));
@@ -675,16 +683,18 @@
   {
     if (lev == 0)
       {
-        copy_or_memcpy (cext[0], src, dest);
-        fill_or_memset (dext[0] - cext[0], rfv, dest + cext[0]);
+        std::copy (src, src+cext[0], dest);
+        std::fill_n (dest + cext[0], dext[0] - cext[0], rfv);
       }
     else
       {
-        octave_idx_type sd = sext[lev-1], dd = dext[lev-1], 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);
 
-        fill_or_memset (dext[lev] - k * dd, rfv, dest + k * dd);
+        std::fill_n (dest + k * dd, dext[lev] - k * dd, rfv);
       }
   }
 
@@ -771,7 +781,8 @@
 {
   // Get dimensions, allowing Fortran indexing in the 2nd dim.
   dim_vector dv = dimensions.redim (2);
-  octave_idx_type r = dv(0), c = dv(1);
+  octave_idx_type r = dv(0);
+  octave_idx_type c = dv(1);
   Array<T> retval;
 
   if (i.is_colon () && j.is_colon ())
@@ -786,7 +797,9 @@
       if (j.extent (c) != c)
         gripe_index_out_of_range (2, 2, j.extent (c), c); // throws
 
-      octave_idx_type n = numel (), il = i.length (r), jl = j.length (c);
+      octave_idx_type n = numel ();
+      octave_idx_type il = i.length (r);
+      octave_idx_type jl = j.length (c);
 
       idx_vector ii (i);
 
@@ -946,7 +959,7 @@
                   Array<T> tmp (Array<T> (dim_vector (nn, 1)), dv, 0, n);
                   T *dest = tmp.fortran_vec ();
 
-                  copy_or_memcpy (nx, data (), dest);
+                  std::copy (data (), data () + nx, dest);
                   dest[nx] = rfv;
 
                   *this = tmp;
@@ -957,9 +970,10 @@
               Array<T> tmp = Array<T> (dv);
               T *dest = tmp.fortran_vec ();
 
-              octave_idx_type n0 = std::min (n, nx), n1 = n - n0;
-              copy_or_memcpy (n0, data (), dest);
-              fill_or_memset (n1, rfv, dest + n0);
+              octave_idx_type n0 = std::min (n, nx);
+              octave_idx_type n1 = n - n0;
+              std::copy (data (), data () + n0, dest);
+              std::fill_n (dest + n0, n1, rfv);
 
               *this = tmp;
             }
@@ -975,33 +989,36 @@
 {
   if (r >= 0 && c >= 0 && ndims () == 2)
     {
-      octave_idx_type rx = rows (), cx = columns ();
+      octave_idx_type rx = rows ();
+      octave_idx_type cx = columns ();
       if (r != rx || c != cx)
         {
           Array<T> tmp = Array<T> (dim_vector (r, c));
           T *dest = tmp.fortran_vec ();
 
-          octave_idx_type r0 = std::min (r, rx), r1 = r - r0;
-          octave_idx_type c0 = std::min (c, cx), c1 = c - c0;
+          octave_idx_type r0 = std::min (r, rx);
+          octave_idx_type r1 = r - r0;
+          octave_idx_type c0 = std::min (c, cx);
+          octave_idx_type c1 = c - c0;
           const T *src = data ();
           if (r == rx)
             {
-              copy_or_memcpy (r * c0, src, dest);
+              std::copy (src, src + r * c0, dest);
               dest += r * c0;
             }
           else
             {
               for (octave_idx_type k = 0; k < c0; k++)
                 {
-                  copy_or_memcpy (r0, src, dest);
+                  std::copy (src, src + r0, dest);
                   src += rx;
                   dest += r0;
-                  fill_or_memset (r1, rfv, dest);
+                  std::fill_n (dest, r1, rfv);
                   dest += r1;
                 }
             }
 
-          fill_or_memset (r * c1, rfv, dest);
+          std::fill_n (dest, r * c1, rfv);
 
           *this = tmp;
         }
@@ -1042,7 +1059,8 @@
   Array<T> tmp = *this;
   if (resize_ok)
     {
-      octave_idx_type n = numel (), nx = i.extent (n);
+      octave_idx_type n = numel ();
+      octave_idx_type nx = i.extent (n);
       if (n != nx)
         {
           if (i.is_scalar ())
@@ -1067,8 +1085,10 @@
   if (resize_ok)
     {
       dim_vector dv = dimensions.redim (2);
-      octave_idx_type r = dv(0), c = dv(1);
-      octave_idx_type rx = i.extent (r), cx = j.extent (c);
+      octave_idx_type r = dv(0);
+      octave_idx_type c = dv(1);
+      octave_idx_type rx = i.extent (r);
+      octave_idx_type cx = j.extent (c);
       if (r != rx || c != cx)
         {
           if (i.is_scalar () && j.is_scalar ())
@@ -1119,7 +1139,8 @@
 void
 Array<T>::assign (const idx_vector& i, const Array<T>& rhs, const T& rfv)
 {
-  octave_idx_type n = numel (), rhl = rhs.numel ();
+  octave_idx_type n = numel ();
+  octave_idx_type rhl = rhs.numel ();
 
   if (rhl == 1 || i.length (n) == rhl)
     {
@@ -1190,7 +1211,8 @@
     }
 
   bool isfill = rhs.numel () == 1;
-  octave_idx_type il = i.length (rdv(0)), jl = j.length (rdv(1));
+  octave_idx_type il = i.length (rdv(0));
+  octave_idx_type jl = j.length (rdv(1));
   rhdv.chop_all_singletons ();
   bool match = (isfill
                 || (rhdv.length () == 2 && il == rhdv(0) && jl == rhdv(1)));
@@ -1228,7 +1250,9 @@
       else
         {
           // The actual work.
-          octave_idx_type n = numel (), r = dv (0), c = dv (1);
+          octave_idx_type n = numel ();
+          octave_idx_type r = dv(0);
+          octave_idx_type c = dv(1);
           idx_vector ii (i);
 
           const T* src = rhs.data ();
@@ -1299,10 +1323,13 @@
         }
 
       // Check whether LHS and RHS match, up to singleton dims.
-      bool match = true, all_colons = true, isfill = rhs.numel () == 1;
+      bool match = true;
+      bool all_colons = true;
+      bool isfill = rhs.numel () == 1;
 
       rhdv.chop_all_singletons ();
-      int j = 0, rhdvl = rhdv.length ();
+      int j = 0;
+      int rhdvl = rhdv.length ();
       for (int i = 0; i < ial; i++)
         {
           all_colons = all_colons && ia(i).is_colon_equiv (rdv(i));
@@ -1389,8 +1416,8 @@
           Array<T> tmp (dim_vector (col_vec ? m : 1, !col_vec ? m : 1));
           const T *src = data ();
           T *dest = tmp.fortran_vec ();
-          copy_or_memcpy (l, src, dest);
-          copy_or_memcpy (n - u, src + u, dest + l);
+          std::copy (src, src + l, dest);
+          std::copy (src + u, src + n, dest + l);
           *this = tmp;
         }
       else
@@ -1427,7 +1454,9 @@
       if (i.is_cont_range (n, l, u))
         {
           // Special case deleting a contiguous range.
-          octave_idx_type nd = n + l - u, dl = 1, du = 1;
+          octave_idx_type nd = n + l - u;
+          octave_idx_type dl = 1;
+          octave_idx_type du = 1;
           dim_vector rdv = dimensions;
           rdv(dim) = nd;
           for (int k = 0; k < dim; k++) dl *= dimensions(k);
@@ -1440,9 +1469,9 @@
           l *= dl; u *= dl; n *= dl;
           for (octave_idx_type k = 0; k < du; k++)
             {
-              copy_or_memcpy (l, src, dest);
+              std::copy (src, src + l, dest);
               dest += l;
-              copy_or_memcpy (n - u, src + u, dest);
+              std::copy (src + u, src + n, dest);
               dest += n - u;
               src += n;
             }
@@ -1776,7 +1805,8 @@
         {
           // copy and partition out NaNs.
           // FIXME: impact on integer types noticeable?
-          octave_idx_type kl = 0, ku = ns;
+          octave_idx_type kl = 0;
+          octave_idx_type ku = ns;
           for (octave_idx_type i = 0; i < ns; i++)
             {
               T tmp = ov[i];
@@ -1820,7 +1850,8 @@
 
           // gather and partition out NaNs.
           // FIXME: impact on integer types noticeable?
-          octave_idx_type kl = 0, ku = ns;
+          octave_idx_type kl = 0;
+          octave_idx_type ku = ns;
           for (octave_idx_type i = 0; i < ns; i++)
             {
               T tmp = ov[i*stride + offset];
@@ -1898,7 +1929,8 @@
         {
           // copy and partition out NaNs.
           // FIXME: impact on integer types noticeable?
-          octave_idx_type kl = 0, ku = ns;
+          octave_idx_type kl = 0;
+          octave_idx_type ku = ns;
           for (octave_idx_type i = 0; i < ns; i++)
             {
               T tmp = ov[i];
@@ -1956,7 +1988,8 @@
 
           // gather and partition out NaNs.
           // FIXME: impact on integer types noticeable?
-          octave_idx_type kl = 0, ku = ns;
+          octave_idx_type kl = 0;
+          octave_idx_type ku = ns;
           for (octave_idx_type i = 0; i < ns; i++)
             {
               T tmp = ov[i*stride + offset];
@@ -2056,7 +2089,8 @@
 
   octave_sort<T> lsort (safe_comparator (mode, *this, true));
 
-  octave_idx_type r = rows (), c = cols ();
+  octave_idx_type r = rows ();
+  octave_idx_type c = cols ();
 
   idx = Array<octave_idx_type> (dim_vector (r, 1));
 
@@ -2072,7 +2106,8 @@
 {
   octave_sort<T> lsort;
 
-  octave_idx_type r = rows (), c = cols ();
+  octave_idx_type r = rows ();
+  octave_idx_type c = cols ();
 
   if (r <= 1 || c == 0)
     return mode ? mode : ASCENDING;
@@ -2086,7 +2121,8 @@
       octave_idx_type i;
       for (i = 0; i < cols (); i++)
         {
-          T l = elem (0, i), u = elem (rows () - 1, i);
+          T l = elem (0, i);
+          T u = elem (rows () - 1, i);
           if (compare (l, u))
             {
               if (mode == DESCENDING)
@@ -2150,7 +2186,8 @@
 Array<octave_idx_type>
 Array<T>::lookup (const Array<T>& values, sortmode mode) const
 {
-  octave_idx_type n = numel (), nval = values.numel ();
+  octave_idx_type n = numel ();
+  octave_idx_type nval = values.numel ();
   octave_sort<T> lsort;
   Array<octave_idx_type> idx (values.dims ());
 
@@ -2194,7 +2231,8 @@
 Array<T>::nnz (void) const
 {
   const T *src = data ();
-  octave_idx_type nel = nelem (), retval = 0;
+  octave_idx_type nel = nelem ();
+  octave_idx_type retval = 0;
   const T zero = T ();
   for (octave_idx_type i = 0; i < nel; i++)
     if (src[i] != zero)
@@ -2233,7 +2271,8 @@
       if (backward)
         {
           // Do the search as a series of successive single-element searches.
-          octave_idx_type k = 0, l = nel - 1;
+          octave_idx_type k = 0;
+          octave_idx_type l = nel - 1;
           for (; k < n; k++)
             {
               for (; l >= 0 && src[l] == zero; l--) ;
@@ -2250,7 +2289,8 @@
       else
         {
           // Do the search as a series of successive single-element searches.
-          octave_idx_type k = 0, l = 0;
+          octave_idx_type k = 0;
+          octave_idx_type l = 0;
           for (; k < n; k++)
             {
               for (; l != nel && src[l] == zero; l++) ;
@@ -2369,7 +2409,8 @@
 
   for (octave_idx_type j = 0; j < iter; j++)
     {
-      octave_idx_type kl = 0, ku = ns;
+      octave_idx_type kl = 0;
+      octave_idx_type ku = ns;
 
       if (stride == 1)
         {
@@ -2437,9 +2478,6 @@
   return m;
 }
 
-
-#define INSTANTIATE_ARRAY_SORT(T) template class OCTAVE_API octave_sort<T>;
-
 #define NO_INSTANTIATE_ARRAY_SORT(T) \
  \
 template <> Array<T>  \
@@ -2530,9 +2568,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/Array.h	Fri Feb 06 08:31:09 2015 -0800
+++ b/liboctave/array/Array.h	Fri Feb 06 08:31:49 2015 -0800
@@ -38,22 +38,16 @@
 #include "lo-utils.h"
 #include "oct-sort.h"
 #include "quit.h"
-#include "oct-mem.h"
 #include "oct-refcount.h"
 
-// One dimensional array class.  Handles the reference counting for
-// all the derived classes.
-
+//!Handles the reference counting for all the derived classes.
 template <class T>
 class
 Array
 {
 protected:
 
-  //--------------------------------------------------------------------
-  // The real representation of all arrays.
-  //--------------------------------------------------------------------
-
+  //! The real representation of all arrays.
   class ArrayRep
   {
   public:
@@ -63,14 +57,14 @@
     octave_refcount<int> count;
 
     ArrayRep (T *d, octave_idx_type l)
-      : data (no_ctor_new<T> (l)), len (l), count (1)
+      : data (new T [l]), len (l), count (1)
     {
-      copy_or_memcpy (l, d, data);
+      std::copy (d, d+l, data);
     }
 
     template <class U>
     ArrayRep (U *d, octave_idx_type l)
-      : data (no_ctor_new<T> (l)), len (l), count (1)
+      : data (new T [l]), len (l), count (1)
     {
       std::copy (d, d+l, data);
     }
@@ -78,21 +72,21 @@
     ArrayRep (void) : data (0), len (0), count (1) { }
 
     explicit ArrayRep (octave_idx_type n)
-      : data (no_ctor_new<T> (n)), len (n), count (1) { }
+      : data (new T [n]), len (n), count (1) { }
 
     explicit ArrayRep (octave_idx_type n, const T& val)
-      : data (no_ctor_new<T> (n)), len (n), count (1)
+      : data (new T [n]), len (n), count (1)
     {
-      fill_or_memset (n, val, data);
+      std::fill_n (data, n, val);
     }
 
     ArrayRep (const ArrayRep& a)
-      : data (no_ctor_new<T> (a.len)), len (a.len), count (1)
+      : data (new T [a.len]), len (a.len), count (1)
     {
-      copy_or_memcpy (a.len, a.data, data);
+      std::copy (a.data, a.data + a.len, data);
     }
 
-    ~ArrayRep (void) { no_ctor_delete<T> (data); }
+    ~ArrayRep (void) { delete [] data; }
 
     octave_idx_type length (void) const { return len; }
 
@@ -144,7 +138,7 @@
   T* slice_data;
   octave_idx_type slice_len;
 
-  // slice constructor
+  //! slice constructor
   Array (const Array<T>& a, const dim_vector& dv,
          octave_idx_type l, octave_idx_type u)
     : dimensions (dv), rep(a.rep), slice_data (a.slice_data+l), slice_len (u-l)
@@ -167,7 +161,7 @@
 
 protected:
 
-  // For jit support
+  //! For jit support
   Array (T *sdata, octave_idx_type slen, octave_idx_type *adims, void *arep)
     : dimensions (adims),
       rep (reinterpret_cast<typename Array<T>::ArrayRep *> (arep)),
@@ -175,8 +169,7 @@
 
 public:
 
-  // Empty ctor (0x0).
-
+  //! Empty ctor (0 by 0).
   Array (void)
     : dimensions (), rep (nil_rep ()), slice_data (rep->data),
       slice_len (rep->len)
@@ -184,21 +177,7 @@
     rep->count++;
   }
 
-  // Obsolete 1D ctor (there are no 1D arrays).
-  explicit Array (octave_idx_type n) GCC_ATTR_DEPRECATED
-    : dimensions (n, 1), rep (new typename Array<T>::ArrayRep (n)),
-      slice_data (rep->data), slice_len (rep->len)
-  { }
-
-  // Obsolete initialized 1D ctor (there are no 1D arrays).
-  explicit Array (octave_idx_type n, const T& val) GCC_ATTR_DEPRECATED
-    : dimensions (n, 1), rep (new typename Array<T>::ArrayRep (n)),
-      slice_data (rep->data), slice_len (rep->len)
-  {
-    fill (val);
-  }
-
-  // nD uninitialized ctor.
+  //! nD uninitialized ctor.
   explicit Array (const dim_vector& dv)
     : dimensions (dv),
       rep (new typename Array<T>::ArrayRep (dv.safe_numel ())),
@@ -207,7 +186,7 @@
     dimensions.chop_trailing_singletons ();
   }
 
-  // nD initialized ctor.
+  //! nD initialized ctor.
   explicit Array (const dim_vector& dv, const T& val)
     : dimensions (dv),
       rep (new typename Array<T>::ArrayRep (dv.safe_numel ())),
@@ -217,10 +196,10 @@
     dimensions.chop_trailing_singletons ();
   }
 
-  // Reshape constructor.
+  //! Reshape constructor.
   Array (const Array<T>& a, const dim_vector& dv);
 
-  // Type conversion case.
+  //! Type conversion case.
   template <class U>
   Array (const Array<U>& a)
     : dimensions (a.dims ()),
@@ -228,7 +207,7 @@
       slice_data (rep->data), slice_len (rep->len)
   { }
 
-  // No type conversion case.
+  //! No type conversion case.
   Array (const Array<T>& a)
     : dimensions (a.dimensions), rep (a.rep), slice_data (a.slice_data),
       slice_len (a.slice_len)
@@ -270,16 +249,15 @@
   void clear (octave_idx_type r, octave_idx_type c)
   { clear (dim_vector (r, c)); }
 
+  //@{
+  //! Number of elements in the array. These are all synonyms.
   octave_idx_type capacity (void) const { return slice_len; }
   octave_idx_type length (void) const { return capacity (); }
   octave_idx_type nelem (void) const { return capacity (); }
   octave_idx_type numel (void) const { return nelem (); }
+  //@}
 
-  octave_idx_type dim1 (void) const { return dimensions(0); }
-  octave_idx_type dim2 (void) const { return dimensions(1); }
-  octave_idx_type dim3 (void) const { return dimensions(2); }
-
-  // Return the array as a column vector.
+  //! Return the array as a column vector.
   Array<T> as_column (void) const
   {
     Array<T> retval (*this);
@@ -289,7 +267,7 @@
     return retval;
   }
 
-  // Return the array as a row vector.
+  //! Return the array as a row vector.
   Array<T> as_row (void) const
   {
     Array<T> retval (*this);
@@ -299,7 +277,7 @@
     return retval;
   }
 
-  // Return the array as a matrix.
+  //! Return the array as a matrix.
   Array<T> as_matrix (void) const
   {
     Array<T> retval (*this);
@@ -309,22 +287,40 @@
     return retval;
   }
 
+  //! @name First dimension
+  //!
+  //! Get the first dimension of the array (number of rows)
+  //@{
+  octave_idx_type dim1 (void) const { return dimensions(0); }
   octave_idx_type rows (void) const { return dim1 (); }
+  //@}
+
+  //! @name Second dimension
+  //!
+  //! Get the second dimension of the array (number of columns)
+  //@{
+  octave_idx_type dim2 (void) const { return dimensions(1); }
   octave_idx_type cols (void) const { return dim2 (); }
   octave_idx_type columns (void) const { return dim2 (); }
+  //@}
+
+  //! @name Third dimension
+  //!
+  //! Get the third dimension of the array (number of pages)
+  //@{
+  octave_idx_type dim3 (void) const { return dimensions(2); }
   octave_idx_type pages (void) const { return dim3 (); }
+  //@}
 
   size_t byte_size (void) const
   { return static_cast<size_t> (numel ()) * sizeof (T); }
 
-  // Return a const-reference so that dims ()(i) works efficiently.
+  //! Return a const-reference so that dims ()(i) works efficiently.
   const dim_vector& dims (void) const { return dimensions; }
 
+  //! Chop off leading singleton dimensions
   Array<T> squeeze (void) const;
 
-  void chop_trailing_singletons (void) GCC_ATTR_DEPRECATED
-  { dimensions.chop_trailing_singletons (); }
-
   octave_idx_type compute_index (octave_idx_type i, octave_idx_type j) const;
   octave_idx_type compute_index (octave_idx_type i, octave_idx_type j,
                                  octave_idx_type k) const;
@@ -434,13 +430,13 @@
   // Fast extractors. All of these produce shallow copies.
   // Warning: none of these do check bounds, unless BOUNDS_CHECKING is on!
 
-  // Extract column: A(:,k+1).
+  //! Extract column: A(:,k+1).
   Array<T> column (octave_idx_type k) const;
-  // Extract page: A(:,:,k+1).
+  //! Extract page: A(:,:,k+1).
   Array<T> page (octave_idx_type k) const;
 
-  // Extract a slice from this array as a column vector: A(:)(lo+1:up).
-  // Must be 0 <= lo && up <= numel. May be up < lo.
+  //! Extract a slice from this array as a column vector: A(:)(lo+1:up).
+  //! Must be 0 <= lo && up <= numel. May be up < lo.
   Array<T> linear_slice (octave_idx_type lo, octave_idx_type up) const;
 
   Array<T> reshape (octave_idx_type nr, octave_idx_type nc) const
@@ -472,41 +468,39 @@
 
   int ndims (void) const { return dimensions.length (); }
 
-  // Indexing without resizing.
-
+  //@{
+  //! Indexing without resizing.
   Array<T> index (const idx_vector& i) const;
 
   Array<T> index (const idx_vector& i, const idx_vector& j) const;
 
   Array<T> index (const Array<idx_vector>& ia) const;
+  //@}
 
   virtual T resize_fill_value (void) const;
 
-  // Resizing (with fill).
+  //@{
+  //! Resizing (with fill).
+  void resize2 (octave_idx_type nr, octave_idx_type nc, const T& rfv);
+  void resize2 (octave_idx_type nr, octave_idx_type nc)
+  {
+    resize2 (nr, nc, resize_fill_value ());
+  }
 
   void resize1 (octave_idx_type n, const T& rfv);
   void resize1 (octave_idx_type n) { resize1 (n, resize_fill_value ()); }
 
-  void resize (octave_idx_type n) GCC_ATTR_DEPRECATED { resize1 (n); }
-
-  void resize (octave_idx_type nr, octave_idx_type nc,
-               const T& rfv) GCC_ATTR_DEPRECATED
-  {
-    resize2 (nr, nc, rfv);
-  }
-
-  void resize (octave_idx_type nr, octave_idx_type nc) GCC_ATTR_DEPRECATED
-  {
-    resize2 (nr, nc, resize_fill_value ());
-  }
-
   void resize (const dim_vector& dv, const T& rfv);
   void resize (const dim_vector& dv) { resize (dv, resize_fill_value ()); }
+  //@}
 
-  // Indexing with possible resizing and fill
-  // FIXME: this is really a corner case, that should better be
+  //@{
+  //! Indexing with possible resizing and fill
+
+  // FIXME -- this is really a corner case, that should better be
   // handled directly in liboctinterp.
 
+
   Array<T> index (const idx_vector& i, bool resize_ok, const T& rfv) const;
   Array<T> index (const idx_vector& i, bool resize_ok) const
   {
@@ -527,9 +521,11 @@
   {
     return index (ia, resize_ok, resize_fill_value ());
   }
+  //@}
 
-  // Indexed assignment (always with resize & fill).
 
+  //@{
+  //! Indexed assignment (always with resize & fill).
   void assign (const idx_vector& i, const Array<T>& rhs, const T& rfv);
   void assign (const idx_vector& i, const Array<T>& rhs)
   {
@@ -548,25 +544,28 @@
   {
     assign (ia, rhs, resize_fill_value ());
   }
+  //@}
 
-  // Deleting elements.
+  //@{
+  //! Deleting elements.
 
-  // A(I) = [] (with a single subscript)
+  //! A(I) = [] (with a single subscript)
   void delete_elements (const idx_vector& i);
 
-  // A(:,...,I,...,:) = [] (>= 2 subscripts, one of them is non-colon)
+  //! A(:,...,I,...,:) = [] (>= 2 subscripts, one of them is non-colon)
   void delete_elements (int dim, const idx_vector& i);
 
-  // Dispatcher to the above two.
+  //! Dispatcher to the above two.
   void delete_elements (const Array<idx_vector>& ia);
+  //@}
 
-  // Insert an array into another at a specified position.
-  // If size (a) is [d1 d2 ... dN] and idx is [i1 i2 ... iN],
-  // this method is equivalent to
-  // x(i1:i1+d1-1, i2:i2+d2-1, ... , iN:iN+dN-1) = a.
+  //! Insert an array into another at a specified position. If
+  //! size (a) is [d1 d2 ... dN] and idx is [i1 i2 ... iN], this
+  //! method is equivalent to x(i1:i1+d1-1, i2:i2+d2-1, ... ,
+  //! iN:iN+dN-1) = a.
   Array<T>& insert (const Array<T>& a, const Array<octave_idx_type>& idx);
 
-  // This is just a special case for idx = [r c 0 ...]
+  //! This is just a special case for idx = [r c 0 ...]
   Array<T>& insert (const Array<T>& a, octave_idx_type r, octave_idx_type c);
 
   void maybe_economize (void)
@@ -582,54 +581,60 @@
 
   void print_info (std::ostream& os, const std::string& prefix) const;
 
-  // Unsafe.  This function exists to support the MEX interface.
-  // You should not use it anywhere else.
+  //! Give a pointer to the data in mex format. Unsafe. This function
+  //! exists to support the MEX interface. You should not use it
+  //! anywhere else.
   void *mex_get_data (void) const { return const_cast<T *> (data ()); }
 
   Array<T> sort (int dim = 0, sortmode mode = ASCENDING) const;
   Array<T> sort (Array<octave_idx_type> &sidx, int dim = 0,
                  sortmode mode = ASCENDING) const;
 
-  // Ordering is auto-detected or can be specified.
+  //! Ordering is auto-detected or can be specified.
   sortmode is_sorted (sortmode mode = UNSORTED) const;
 
-  // Sort by rows returns only indices.
+  //! Sort by rows returns only indices.
   Array<octave_idx_type> sort_rows_idx (sortmode mode = ASCENDING) const;
 
-  // Ordering is auto-detected or can be specified.
+  //! Ordering is auto-detected or can be specified.
   sortmode is_sorted_rows (sortmode mode = UNSORTED) const;
 
-  // Do a binary lookup in a sorted array. Must not contain NaNs.
-  // Mode can be specified or is auto-detected by comparing 1st and last element.
+  //! @brief Do a binary lookup in a sorted array. Must not contain NaNs.
+  //! Mode can be specified or is auto-detected by comparing 1st and last element.
   octave_idx_type lookup (const T& value, sortmode mode = UNSORTED) const;
 
-  // Ditto, but for an array of values, specializing on the case when values
-  // are sorted. NaNs get the value N.
+  //! Ditto, but for an array of values, specializing on the case when values
+  //! are sorted. NaNs get the value N.
   Array<octave_idx_type> lookup (const Array<T>& values,
                                  sortmode mode = UNSORTED) const;
 
-  // Count nonzero elements.
+  //! Count nonzero elements.
   octave_idx_type nnz (void) const;
 
-  // Find indices of (at most n) nonzero elements. If n is specified, backward
-  // specifies search from backward.
-  Array<octave_idx_type> find (octave_idx_type n = -1,
-                               bool backward = false) const;
+  //! Find indices of (at most n) nonzero elements. If n is specified,
+  //! backward specifies search from backward.
+  Array<octave_idx_type> find (octave_idx_type n = -1, bool backward = false) const;
 
-  // Returns the n-th element in increasing order, using the same ordering as
-  // used for sort. n can either be a scalar index or a contiguous range.
+  //! Returns the n-th element in increasing order, using the same
+  //! ordering as used for sort. n can either be a scalar index or a
+  //! contiguous range.
   Array<T> nth_element (const idx_vector& n, int dim = 0) const;
 
+  //! Get the kth super or subdiagonal. The zeroth diagonal is the
+  //! ordinary diagonal.
   Array<T> diag (octave_idx_type k = 0) const;
 
   Array<T> diag (octave_idx_type m, octave_idx_type n) const;
 
-  // Concatenation along a specified (0-based) dimension, equivalent to cat().
-  // dim = -1 corresponds to dim = 0 and dim = -2 corresponds to dim = 1,
-  // but apply the looser matching rules of vertcat/horzcat.
+  //! Concatenation along a specified (0-based) dimension, equivalent
+  //! to cat(). dim = -1 corresponds to dim = 0 and dim = -2
+  //! corresponds to dim = 1, but apply the looser matching rules of
+  //! vertcat/horzcat.
   static Array<T>
   cat (int dim, octave_idx_type n, const Array<T> *array_list);
 
+  //! Apply function fcn to each element of the Array<T>. This function
+  //! is optimised with a manually unrolled loop.
   template <class U, class F>
   Array<U>
   map (F fcn) const
@@ -660,7 +665,8 @@
     return result;
   }
 
-  // Overloads for function references.
+  //@{
+  //! Overloads for function references.
   template <class U>
   Array<U>
   map (U (&fcn) (T)) const
@@ -670,15 +676,17 @@
   Array<U>
   map (U (&fcn) (const T&)) const
   { return map<U, U (&) (const T&)> (fcn); }
+  //@}
 
-  // Generic any/all test functionality with arbitrary predicate.
+  //! Generic any/all test functionality with arbitrary predicate.
   template <class F, bool zero>
   bool test (F fcn) const
   {
     return any_all_test<F, T, zero> (fcn, data (), length ());
   }
 
-  // Simpler calls.
+  //@{
+  //! Simpler calls.
   template <class F>
   bool test_any (F fcn) const
   { return test<F, false> (fcn); }
@@ -686,8 +694,10 @@
   template <class F>
   bool test_all (F fcn) const
   { return test<F, true> (fcn); }
+  //@}
 
-  // Overloads for function references.
+  //@{
+  //! Overloads for function references.
   bool test_any (bool (&fcn) (T)) const
   { return test<bool (&) (T), false> (fcn); }
 
@@ -699,15 +709,17 @@
 
   bool test_all (bool (&fcn) (const T&)) const
   { return test<bool (&) (const T&), true> (fcn); }
+  //@}
 
   template <class U> friend class Array;
 
-  // Returns true if this->dims () == dv, and if so, replaces this->dimensions
-  // by a shallow copy of dv. This is useful for maintaining several arrays with
-  // supposedly equal dimensions (e.g. structs in the interpreter).
+  //! Returns true if this->dims () == dv, and if so, replaces this->dimensions
+  //! by a shallow copy of dv. This is useful for maintaining several arrays with
+  //! supposedly equal dimensions (e.g. structs in the interpreter).
   bool optimize_dimensions (const dim_vector& dv);
 
-  // WARNING: Only call these functions from jit
+  //@{
+  //! WARNING: Only call these functions from jit
 
   int *jit_ref_count (void) { return rep->count.get (); }
 
@@ -716,24 +728,17 @@
   octave_idx_type *jit_dimensions (void) const { return dimensions.to_jit (); }
 
   void *jit_array_rep (void) const { return rep; }
+  //@}
 
 private:
-
-  void resize2 (octave_idx_type nr, octave_idx_type nc, const T& rfv);
-  void resize2 (octave_idx_type nr, octave_idx_type nc)
-  {
-    resize2 (nr, nc, resize_fill_value ());
-  }
-
   static void instantiation_guard ();
 };
 
-// This is a simple wrapper template that will subclass an Array<T> type or any
-// later type derived from it and override the default non-const operator() to
-// not check for the array's uniqueness. It is, however, the user's
-// responsibility to ensure the array is actually unaliased whenever elements
-// are accessed.
-
+//! This is a simple wrapper template that will subclass an Array<T>
+//! type or any later type derived from it and override the default
+//! non-const operator() to not check for the array's uniqueness. It
+//! is, however, the user's responsibility to ensure the array is
+//! actually unaliased whenever elements are accessed.
 template<class ArrayClass>
 class NoAlias : public ArrayClass
 {
--- a/liboctave/array/Array2.h	Fri Feb 06 08:31:09 2015 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,35 +0,0 @@
-// Template array classes
-/*
-
-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/>.
-
-*/
-
-#if !defined (octave_Array2_h)
-#define octave_Array2_h 1
-
-#include "Array.h"
-#define Array2 Array
-
-// If we're with GNU C++, issue a warning.
-#ifdef __GNUC__
-#warning Using Array2<T> is deprecated. Use Array<T> directly.
-#endif
-
-#endif
--- a/liboctave/array/Array3.h	Fri Feb 06 08:31:09 2015 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,94 +0,0 @@
-// Template array classes
-/*
-
-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/>.
-
-*/
-
-#if !defined (octave_Array3_h)
-#define octave_Array3_h 1
-
-#include <cassert>
-#include <cstdlib>
-
-#include "Array.h"
-#include "lo-error.h"
-
-class idx_vector;
-
-// Three dimensional array class.
-
-template <class T>
-class
-Array3 : public Array<T>
-{
-public:
-
-  Array3 (void) : Array<T> (dim_vector (0, 0, 0)) { }
-
-  Array3 (octave_idx_type r, octave_idx_type c,
-          octave_idx_type p) : Array<T> (dim_vector (r, c, p)) { }
-
-  Array3 (octave_idx_type r, octave_idx_type c, octave_idx_type p, const T& val)
-    : Array<T> (dim_vector (r, c, p), val) { }
-
-  Array3 (const Array3<T>& a)
-    : Array<T> (a, a.dims ()) { }
-
-  Array3 (const Array<T>& a, octave_idx_type r, octave_idx_type c,
-          octave_idx_type p)
-    : Array<T> (a, dim_vector (r, c, p)) { }
-
-  ~Array3 (void) { }
-
-  Array3<T>& operator = (const Array3<T>& a)
-  {
-    if (this != &a)
-      Array<T>::operator = (a);
-
-    return *this;
-  }
-
-  void resize (octave_idx_type r, octave_idx_type c, octave_idx_type p)
-  { Array<T>::resize (dim_vector (r, c, p)); }
-
-  void resize (octave_idx_type r, octave_idx_type c, octave_idx_type p,
-               const T& val)
-  { Array<T>::resize (dim_vector (r, c, p), val); }
-
-  Array3<T> sort (octave_idx_type dim = 0, sortmode mode = ASCENDING) const
-  {
-    Array<T> tmp = Array<T>::sort (dim, mode);
-    return Array3<T> (tmp, tmp.rows (), tmp.columns (), tmp.pages ());
-  }
-
-  Array3<T> sort (Array<octave_idx_type> &sidx, octave_idx_type dim = 0,
-                  sortmode mode = ASCENDING) const
-  {
-    Array<T> tmp = Array<T>::sort (sidx, dim, mode);
-    return Array3<T> (tmp, tmp.rows (), tmp.columns (), tmp.pages ());
-  }
-};
-
-// If we're with GNU C++, issue a warning.
-#ifdef __GNUC__
-#warning Using Array3<T> is deprecated. Use Array<T> directly.
-#endif
-
-#endif
--- a/liboctave/array/ArrayN.h	Fri Feb 06 08:31:09 2015 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,35 +0,0 @@
-// Template array classes
-/*
-
-Copyright (C) 2000-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_ArrayN_h)
-#define octave_ArrayN_h 1
-
-#include "Array.h"
-#define ArrayN Array
-
-// If we're with GNU C++, issue a warning.
-#ifdef __GNUC__
-#warning Using ArrayN<T> is deprecated. Use Array<T> directly.
-#endif
-
-#endif
--- a/liboctave/array/CDiagMatrix.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/liboctave/array/CDiagMatrix.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -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;
@@ -448,7 +449,8 @@
 
   ComplexDiagMatrix c (a_nr, b_nc);
 
-  octave_idx_type len = c.length (), lenm = len < a_nc ? len : a_nc;
+  octave_idx_type len = c.length ();
+  octave_idx_type lenm = len < a_nc ? len : a_nc;
 
   for (octave_idx_type i = 0; i < lenm; i++)
     c.dgxelem (i) = a.dgelem (i) * b.dgelem (i);
@@ -549,7 +551,8 @@
 ComplexDiagMatrix::rcond (void) const
 {
   ColumnVector av = extract_diag (0).map<double> (std::abs);
-  double amx = av.max (), amn = av.min ();
+  double amx = av.max ();
+  double amn = av.min ();
   return amx == 0 ? 0.0 : amn / amx;
 }
 
--- a/liboctave/array/CDiagMatrix.h	Fri Feb 06 08:31:09 2015 -0800
+++ b/liboctave/array/CDiagMatrix.h	Fri Feb 06 08:31:49 2015 -0800
@@ -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 Feb 06 08:31:09 2015 -0800
+++ b/liboctave/array/CMatrix.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -36,8 +36,15 @@
 #include <sys/types.h>
 
 #include "Array-util.h"
+#include "boolMatrix.h"
+#include "chMatrix.h"
+#include "dMatrix.h"
 #include "CMatrix.h"
-#include "CmplxAEPBAL.h"
+#include "CNDArray.h"
+#include "CRowVector.h"
+#include "dRowVector.h"
+#include "CDiagMatrix.h"
+#include "dDiagMatrix.h"
 #include "CmplxCHOL.h"
 #include "CmplxSCHUR.h"
 #include "CmplxSVD.h"
@@ -48,7 +55,6 @@
 #include "lo-ieee.h"
 #include "lo-mappers.h"
 #include "lo-utils.h"
-#include "mx-base.h"
 #include "mx-cm-dm.h"
 #include "mx-cm-s.h"
 #include "mx-dm-cm.h"
@@ -262,39 +268,67 @@
 // Complex Matrix class
 
 ComplexMatrix::ComplexMatrix (const Matrix& a)
-  : MArray<Complex> (a)
+  : ComplexNDArray (a)
 {
 }
 
 ComplexMatrix::ComplexMatrix (const RowVector& rv)
-  : MArray<Complex> (rv)
+  : ComplexNDArray (rv)
 {
 }
 
 ComplexMatrix::ComplexMatrix (const ColumnVector& cv)
-  : MArray<Complex> (cv)
+  : ComplexNDArray (cv)
 {
 }
 
 ComplexMatrix::ComplexMatrix (const DiagMatrix& a)
-  : MArray<Complex> (a.dims (), 0.0)
+  : ComplexNDArray (a.dims (), 0.0)
+{
+  for (octave_idx_type i = 0; i < a.length (); i++)
+    elem (i, i) = a.elem (i, i);
+}
+
+ComplexMatrix::ComplexMatrix (const MDiagArray2<double>& a)
+  : ComplexNDArray (a.dims (), 0.0)
+{
+  for (octave_idx_type i = 0; i < a.length (); i++)
+    elem (i, i) = a.elem (i, i);
+}
+
+ComplexMatrix::ComplexMatrix (const DiagArray2<double>& a)
+  : ComplexNDArray (a.dims (), 0.0)
 {
   for (octave_idx_type i = 0; i < a.length (); i++)
     elem (i, i) = a.elem (i, i);
 }
 
 ComplexMatrix::ComplexMatrix (const ComplexRowVector& rv)
-  : MArray<Complex> (rv)
+  : ComplexNDArray (rv)
 {
 }
 
 ComplexMatrix::ComplexMatrix (const ComplexColumnVector& cv)
-  : MArray<Complex> (cv)
+  : ComplexNDArray (cv)
 {
 }
 
 ComplexMatrix::ComplexMatrix (const ComplexDiagMatrix& a)
-  : MArray<Complex> (a.dims (), 0.0)
+  : ComplexNDArray (a.dims (), 0.0)
+{
+  for (octave_idx_type i = 0; i < a.length (); i++)
+    elem (i, i) = a.elem (i, i);
+}
+
+ComplexMatrix::ComplexMatrix (const MDiagArray2<Complex>& a)
+  : ComplexNDArray (a.dims (), 0.0)
+{
+  for (octave_idx_type i = 0; i < a.length (); i++)
+    elem (i, i) = a.elem (i, i);
+}
+
+ComplexMatrix::ComplexMatrix (const DiagArray2<Complex>& a)
+  : ComplexNDArray (a.dims (), 0.0)
 {
   for (octave_idx_type i = 0; i < a.length (); i++)
     elem (i, i) = a.elem (i, i);
@@ -303,12 +337,12 @@
 // FIXME: could we use a templated mixed-type copy function here?
 
 ComplexMatrix::ComplexMatrix (const boolMatrix& a)
-  : MArray<Complex> (a)
+  : ComplexNDArray (a)
 {
 }
 
 ComplexMatrix::ComplexMatrix (const charMatrix& a)
-  : MArray<Complex> (a.dims (), 0.0)
+  : ComplexNDArray (a.dims (), 0.0)
 {
   for (octave_idx_type i = 0; i < a.rows (); i++)
     for (octave_idx_type j = 0; j < a.cols (); j++)
@@ -316,7 +350,7 @@
 }
 
 ComplexMatrix::ComplexMatrix (const Matrix& re, const Matrix& im)
-  : MArray<Complex> (re.dims ())
+  : ComplexNDArray (re.dims ())
 {
   if (im.rows () != rows () || im.cols () != cols ())
     (*current_liboctave_error_handler) ("complex: internal error");
@@ -463,7 +497,7 @@
 ComplexMatrix::insert (const ComplexMatrix& a,
                        octave_idx_type r, octave_idx_type c)
 {
-  Array<Complex>::insert (a, r, c);
+  ComplexNDArray::insert (a, r, c);
   return *this;
 }
 
@@ -1353,7 +1387,7 @@
 
   octave_idx_type nn = 4*npts+15;
 
-  Array<Complex> wsave (nn, 1);
+  Array<Complex> wsave (dim_vector (nn, 1));
   Complex *pwsave = wsave.fortran_vec ();
 
   retval = *this;
@@ -1394,7 +1428,7 @@
 
   octave_idx_type nn = 4*npts+15;
 
-  Array<Complex> wsave (nn, 1);
+  Array<Complex> wsave (dim_vector (nn, 1));
   Complex *pwsave = wsave.fortran_vec ();
 
   retval = *this;
@@ -1438,7 +1472,7 @@
 
   octave_idx_type nn = 4*npts+15;
 
-  Array<Complex> wsave (nn, 1);
+  Array<Complex> wsave (dim_vector (nn, 1));
   Complex *pwsave = wsave.fortran_vec ();
 
   retval = *this;
@@ -1460,7 +1494,7 @@
   wsave.resize (dim_vector (nn, 1));
   pwsave = wsave.fortran_vec ();
 
-  Array<Complex> tmp (npts, 1);
+  Array<Complex> tmp (dim_vector (npts, 1));
   Complex *prow = tmp.fortran_vec ();
 
   F77_FUNC (zffti, ZFFTI) (npts, pwsave);
@@ -1504,7 +1538,7 @@
 
   octave_idx_type nn = 4*npts+15;
 
-  Array<Complex> wsave (nn, 1);
+  Array<Complex> wsave (dim_vector (nn, 1));
   Complex *pwsave = wsave.fortran_vec ();
 
   retval = *this;
@@ -1529,7 +1563,7 @@
   wsave.resize (dim_vector (nn, 1));
   pwsave = wsave.fortran_vec ();
 
-  Array<Complex> tmp (npts, 1);
+  Array<Complex> tmp (dim_vector (npts, 1));
   Complex *prow = tmp.fortran_vec ();
 
   F77_FUNC (zffti, ZFFTI) (npts, pwsave);
@@ -1722,7 +1756,7 @@
 double
 ComplexMatrix::rcond (MatrixType &mattype) const
 {
-  double rcon;
+  double rcon = octave_NaN;
   octave_idx_type nr = rows ();
   octave_idx_type nc = cols ();
 
@@ -1920,11 +1954,27 @@
             {
               const Complex *tmp_data = fortran_vec ();
 
+              retval = b;
+              Complex *result = retval.fortran_vec ();
+
+              char uplo = 'U';
+              char trans = get_blas_char (transt);
+              char dia = 'N';
+
+              F77_XFCN (ztrtrs, ZTRTRS, (F77_CONST_CHAR_ARG2 (&uplo, 1),
+                                         F77_CONST_CHAR_ARG2 (&trans, 1),
+                                         F77_CONST_CHAR_ARG2 (&dia, 1),
+                                         nr, b_nc, tmp_data, nr,
+                                         result, nr, info
+                                         F77_CHAR_ARG_LEN (1)
+                                         F77_CHAR_ARG_LEN (1)
+                                         F77_CHAR_ARG_LEN (1)));
+
               if (calc_cond)
                 {
                   char norm = '1';
-                  char uplo = 'U';
-                  char dia = 'N';
+                  uplo = 'U';
+                  dia = 'N';
 
                   Array<Complex> z (dim_vector (2 * nc, 1));
                   Complex *pz = z.fortran_vec ();
@@ -1952,30 +2002,9 @@
                       if (sing_handler)
                         sing_handler (rcon);
                       else
-                        (*current_liboctave_error_handler)
-                          ("matrix singular to machine precision, rcond = %g",
-                           rcon);
+                        gripe_singular_matrix (rcon);
                     }
                 }
-
-              if (info == 0)
-                {
-                  retval = b;
-                  Complex *result = retval.fortran_vec ();
-
-                  char uplo = 'U';
-                  char trans = get_blas_char (transt);
-                  char dia = 'N';
-
-                  F77_XFCN (ztrtrs, ZTRTRS, (F77_CONST_CHAR_ARG2 (&uplo, 1),
-                                             F77_CONST_CHAR_ARG2 (&trans, 1),
-                                             F77_CONST_CHAR_ARG2 (&dia, 1),
-                                             nr, b_nc, tmp_data, nr,
-                                             result, nr, info
-                                             F77_CHAR_ARG_LEN (1)
-                                             F77_CHAR_ARG_LEN (1)
-                                             F77_CHAR_ARG_LEN (1)));
-                }
             }
         }
       else
@@ -2021,11 +2050,27 @@
             {
               const Complex *tmp_data = fortran_vec ();
 
+              retval = b;
+              Complex *result = retval.fortran_vec ();
+
+              char uplo = 'L';
+              char trans = get_blas_char (transt);
+              char dia = 'N';
+
+              F77_XFCN (ztrtrs, ZTRTRS, (F77_CONST_CHAR_ARG2 (&uplo, 1),
+                                         F77_CONST_CHAR_ARG2 (&trans, 1),
+                                         F77_CONST_CHAR_ARG2 (&dia, 1),
+                                         nr, b_nc, tmp_data, nr,
+                                         result, nr, info
+                                         F77_CHAR_ARG_LEN (1)
+                                         F77_CHAR_ARG_LEN (1)
+                                         F77_CHAR_ARG_LEN (1)));
+
               if (calc_cond)
                 {
                   char norm = '1';
-                  char uplo = 'L';
-                  char dia = 'N';
+                  uplo = 'L';
+                  dia = 'N';
 
                   Array<Complex> z (dim_vector (2 * nc, 1));
                   Complex *pz = z.fortran_vec ();
@@ -2053,30 +2098,9 @@
                       if (sing_handler)
                         sing_handler (rcon);
                       else
-                        (*current_liboctave_error_handler)
-                          ("matrix singular to machine precision, rcond = %g",
-                           rcon);
+                        gripe_singular_matrix (rcon);
                     }
                 }
-
-              if (info == 0)
-                {
-                  retval = b;
-                  Complex *result = retval.fortran_vec ();
-
-                  char uplo = 'L';
-                  char trans = get_blas_char (transt);
-                  char dia = 'N';
-
-                  F77_XFCN (ztrtrs, ZTRTRS, (F77_CONST_CHAR_ARG2 (&uplo, 1),
-                                             F77_CONST_CHAR_ARG2 (&trans, 1),
-                                             F77_CONST_CHAR_ARG2 (&dia, 1),
-                                             nr, b_nc, tmp_data, nr,
-                                             result, nr, info
-                                             F77_CHAR_ARG_LEN (1)
-                                             F77_CHAR_ARG_LEN (1)
-                                             F77_CHAR_ARG_LEN (1)));
-                }
             }
         }
       else
@@ -2159,9 +2183,7 @@
                       if (sing_handler)
                         sing_handler (rcon);
                       else
-                        (*current_liboctave_error_handler)
-                          ("matrix singular to machine precision, rcond = %g",
-                           rcon);
+                        gripe_singular_matrix (rcon);
                     }
                 }
 
@@ -2216,8 +2238,7 @@
               if (sing_handler)
                 sing_handler (rcon);
               else
-                (*current_liboctave_error_handler)
-                  ("matrix singular to machine precision");
+                gripe_singular_matrix ();
 
               mattype.mark_as_rectangular ();
             }
@@ -2245,9 +2266,7 @@
                       if (sing_handler)
                         sing_handler (rcon);
                       else
-                        (*current_liboctave_error_handler)
-                          ("matrix singular to machine precision, rcond = %g",
-                           rcon);
+                        gripe_singular_matrix (rcon);
                     }
                 }
 
@@ -2342,9 +2361,9 @@
 
   // Only calculate the condition number for LU/Cholesky
   if (typ == MatrixType::Upper || typ == MatrixType::Permuted_Upper)
-    retval = utsolve (mattype, b, info, rcon, sing_handler, false, transt);
+    retval = utsolve (mattype, b, info, rcon, sing_handler, true, transt);
   else if (typ == MatrixType::Lower || typ == MatrixType::Permuted_Lower)
-    retval = ltsolve (mattype, b, info, rcon, sing_handler, false, transt);
+    retval = ltsolve (mattype, b, info, rcon, sing_handler, true, transt);
   else if (transt == blas_trans)
     return transpose ().solve (mattype, b, info, rcon, sing_handler,
                                singular_fallback);
@@ -3096,154 +3115,60 @@
   return *this;
 }
 
-// unary operations
-
-boolMatrix
-ComplexMatrix::operator ! (void) const
-{
-  if (any_element_is_nan ())
-    gripe_nan_to_logical_conversion ();
-
-  return do_mx_unary_op<bool, Complex> (*this, mx_inline_not);
-}
-
 // other operations
 
-bool
-ComplexMatrix::any_element_is_nan (void) const
-{
-  return do_mx_check<Complex> (*this, mx_inline_any_nan);
-}
-
-bool
-ComplexMatrix::any_element_is_inf_or_nan (void) const
-{
-  return ! do_mx_check<Complex> (*this, mx_inline_all_finite);
-}
-
-// Return true if no elements have imaginary components.
-
-bool
-ComplexMatrix::all_elements_are_real (void) const
-{
-  return do_mx_check<Complex> (*this, mx_inline_all_real);
-}
-
-// Return nonzero if any element of CM has a non-integer real or
-// imaginary part.  Also extract the largest and smallest (real or
-// imaginary) values and return them in MAX_VAL and MIN_VAL.
-
-bool
-ComplexMatrix::all_integers (double& max_val, double& min_val) const
-{
-  octave_idx_type nr = rows ();
-  octave_idx_type nc = cols ();
-
-  if (nr > 0 && nc > 0)
-    {
-      Complex val = elem (0, 0);
-
-      double r_val = std::real (val);
-      double i_val = std::imag (val);
-
-      max_val = r_val;
-      min_val = r_val;
-
-      if (i_val > max_val)
-        max_val = i_val;
-
-      if (i_val < max_val)
-        min_val = i_val;
-    }
-  else
-    return false;
-
-  for (octave_idx_type j = 0; j < nc; j++)
-    for (octave_idx_type i = 0; i < nr; i++)
-      {
-        Complex val = elem (i, j);
-
-        double r_val = std::real (val);
-        double i_val = std::imag (val);
-
-        if (r_val > max_val)
-          max_val = r_val;
-
-        if (i_val > max_val)
-          max_val = i_val;
-
-        if (r_val < min_val)
-          min_val = r_val;
-
-        if (i_val < min_val)
-          min_val = i_val;
-
-        if (D_NINT (r_val) != r_val || D_NINT (i_val) != i_val)
-          return false;
-      }
-
-  return true;
-}
-
-bool
-ComplexMatrix::too_large_for_float (void) const
-{
-  return test_any (xtoo_large_for_float);
-}
-
-// FIXME: Do these really belong here?  Maybe they should be in a base class?
-
 boolMatrix
 ComplexMatrix::all (int dim) const
 {
-  return do_mx_red_op<bool, Complex> (*this, dim, mx_inline_all);
+  return ComplexNDArray::all (dim);
 }
 
 boolMatrix
 ComplexMatrix::any (int dim) const
 {
-  return do_mx_red_op<bool, Complex> (*this, dim, mx_inline_any);
+  return ComplexNDArray::any (dim);
 }
 
 ComplexMatrix
 ComplexMatrix::cumprod (int dim) const
 {
-  return do_mx_cum_op<Complex, Complex> (*this, dim, mx_inline_cumprod);
+  return ComplexNDArray::cumprod (dim);
 }
 
 ComplexMatrix
 ComplexMatrix::cumsum (int dim) const
 {
-  return do_mx_cum_op<Complex, Complex> (*this, dim, mx_inline_cumsum);
+  return ComplexNDArray::cumsum (dim);
 }
 
 ComplexMatrix
 ComplexMatrix::prod (int dim) const
 {
-  return do_mx_red_op<Complex, Complex> (*this, dim, mx_inline_prod);
+  return ComplexNDArray::prod (dim);
 }
 
 ComplexMatrix
 ComplexMatrix::sum (int dim) const
 {
-  return do_mx_red_op<Complex, Complex> (*this, dim, mx_inline_sum);
+  return ComplexNDArray::sum (dim);
 }
 
 ComplexMatrix
 ComplexMatrix::sumsq (int dim) const
 {
-  return do_mx_red_op<double, Complex> (*this, dim, mx_inline_sumsq);
+  return ComplexNDArray::sumsq (dim);
 }
 
-Matrix ComplexMatrix::abs (void) const
+Matrix
+ComplexMatrix::abs (void) const
 {
-  return do_mx_unary_map<double, Complex, std::abs> (*this);
+  return ComplexNDArray::abs ();
 }
 
 ComplexMatrix
 ComplexMatrix::diag (octave_idx_type k) const
 {
-  return MArray<Complex>::diag (k);
+  return ComplexNDArray::diag (k);
 }
 
 ComplexDiagMatrix
@@ -3705,7 +3630,7 @@
 
   // FIXME: check info?
 
-  retval = -ua * cx * ub.hermitian ();
+  retval = ua * cx * ub.hermitian ();
 
   return retval;
 }
@@ -3765,8 +3690,10 @@
 {
   ComplexMatrix retval;
 
-  bool tra = transa != blas_no_trans, trb = transb != blas_no_trans;
-  bool cja = transa == blas_conj_trans, cjb = transb == blas_conj_trans;
+  bool tra = transa != blas_no_trans;
+  bool trb = transb != blas_no_trans;
+  bool cja = transa == blas_conj_trans;
+  bool cjb = transb == blas_conj_trans;
 
   octave_idx_type a_nr = tra ? a.cols () : a.rows ();
   octave_idx_type a_nc = tra ? a.rows () : a.cols ();
@@ -3822,8 +3749,10 @@
         }
       else
         {
-          octave_idx_type lda = a.rows (), tda = a.cols ();
-          octave_idx_type ldb = b.rows (), tdb = b.cols ();
+          octave_idx_type lda = a.rows ();
+          octave_idx_type tda = a.cols ();
+          octave_idx_type ldb = b.rows ();
+          octave_idx_type tdb = b.cols ();
 
           retval = ComplexMatrix (a_nr, b_nc, 0.0);
           Complex *c = retval.fortran_vec ();
@@ -3902,7 +3831,7 @@
     for (octave_idx_type i = 0; i < nr; i++)
       {
         octave_quit ();
-        result (i, j) = xmin (c, m (i, j));
+        result(i, j) = xmin (c, m(i, j));
       }
 
   return result;
@@ -3922,7 +3851,7 @@
     for (octave_idx_type i = 0; i < nr; i++)
       {
         octave_quit ();
-        result (i, j) = xmin (m (i, j), c);
+        result(i, j) = xmin (m(i, j), c);
       }
 
   return result;
@@ -3951,7 +3880,7 @@
       for (octave_idx_type i = 0; i < nr; i++)
         {
           octave_quit ();
-          if (std::imag (a (i, j)) != 0.0 || std::imag (b (i, j)) != 0.0)
+          if (std::imag (a(i, j)) != 0.0 || std::imag (b(i, j)) != 0.0)
             {
               columns_are_real_only = 0;
               break;
@@ -3961,14 +3890,14 @@
       if (columns_are_real_only)
         {
           for (octave_idx_type i = 0; i < nr; i++)
-            result (i, j) = xmin (std::real (a (i, j)), std::real (b (i, j)));
+            result(i, j) = xmin (std::real (a(i, j)), std::real (b(i, j)));
         }
       else
         {
           for (octave_idx_type i = 0; i < nr; i++)
             {
               octave_quit ();
-              result (i, j) = xmin (a (i, j), b (i, j));
+              result(i, j) = xmin (a(i, j), b(i, j));
             }
         }
     }
@@ -3990,7 +3919,7 @@
     for (octave_idx_type i = 0; i < nr; i++)
       {
         octave_quit ();
-        result (i, j) = xmax (c, m (i, j));
+        result(i, j) = xmax (c, m(i, j));
       }
 
   return result;
@@ -4010,7 +3939,7 @@
     for (octave_idx_type i = 0; i < nr; i++)
       {
         octave_quit ();
-        result (i, j) = xmax (m (i, j), c);
+        result(i, j) = xmax (m(i, j), c);
       }
 
   return result;
@@ -4039,7 +3968,7 @@
       for (octave_idx_type i = 0; i < nr; i++)
         {
           octave_quit ();
-          if (std::imag (a (i, j)) != 0.0 || std::imag (b (i, j)) != 0.0)
+          if (std::imag (a(i, j)) != 0.0 || std::imag (b(i, j)) != 0.0)
             {
               columns_are_real_only = 0;
               break;
@@ -4051,7 +3980,7 @@
           for (octave_idx_type i = 0; i < nr; i++)
             {
               octave_quit ();
-              result (i, j) = xmax (std::real (a (i, j)), std::real (b (i, j)));
+              result(i, j) = xmax (std::real (a(i, j)), std::real (b(i, j)));
             }
         }
       else
@@ -4059,7 +3988,7 @@
           for (octave_idx_type i = 0; i < nr; i++)
             {
               octave_quit ();
-              result (i, j) = xmax (a (i, j), b (i, j));
+              result(i, j) = xmax (a(i, j), b(i, j));
             }
         }
     }
--- a/liboctave/array/CMatrix.h	Fri Feb 06 08:31:09 2015 -0800
+++ b/liboctave/array/CMatrix.h	Fri Feb 06 08:31:49 2015 -0800
@@ -26,6 +26,7 @@
 #include "MArray.h"
 #include "MDiagArray2.h"
 #include "MatrixType.h"
+#include "CNDArray.h"
 
 #include "mx-defs.h"
 #include "mx-op-decl.h"
@@ -34,7 +35,7 @@
 
 class
 OCTAVE_API
-ComplexMatrix : public MArray<Complex>
+ComplexMatrix : public ComplexNDArray
 {
 public:
 
@@ -43,26 +44,26 @@
 
   typedef void (*solve_singularity_handler) (double rcon);
 
-  ComplexMatrix (void) : MArray<Complex> () { }
+  ComplexMatrix (void) : ComplexNDArray () { }
 
   ComplexMatrix (octave_idx_type r, octave_idx_type c)
-    : MArray<Complex> (dim_vector (r, c)) { }
+    : ComplexNDArray (dim_vector (r, c)) { }
 
   ComplexMatrix (octave_idx_type r, octave_idx_type c, const Complex& val)
-    : MArray<Complex> (dim_vector (r, c), val) { }
+    : ComplexNDArray (dim_vector (r, c), val) { }
 
-  ComplexMatrix (const dim_vector& dv) : MArray<Complex> (dv.redim (2)) { }
+  ComplexMatrix (const dim_vector& dv) : ComplexNDArray (dv.redim (2)) { }
 
   ComplexMatrix (const dim_vector& dv, const Complex& val)
-    : MArray<Complex> (dv.redim (2), val) { }
+    : ComplexNDArray (dv.redim (2), val) { }
 
-  ComplexMatrix (const ComplexMatrix& a) : MArray<Complex> (a) { }
+  ComplexMatrix (const ComplexMatrix& a) : ComplexNDArray (a) { }
 
   template <class U>
-  ComplexMatrix (const MArray<U>& a) : MArray<Complex> (a.as_matrix ()) { }
+  ComplexMatrix (const MArray<U>& a) : ComplexNDArray (a.as_matrix ()) { }
 
   template <class U>
-  ComplexMatrix (const Array<U>& a) : MArray<Complex> (a.as_matrix ()) { }
+  ComplexMatrix (const Array<U>& a) : ComplexNDArray (a.as_matrix ()) { }
 
   ComplexMatrix (const Matrix& re, const Matrix& im);
 
@@ -74,22 +75,24 @@
 
   explicit ComplexMatrix (const DiagMatrix& a);
 
+  explicit ComplexMatrix (const MDiagArray2<double>& a);
+
+  explicit ComplexMatrix (const DiagArray2<double>& a);
+
   explicit ComplexMatrix (const ComplexRowVector& rv);
 
   explicit ComplexMatrix (const ComplexColumnVector& cv);
 
   explicit ComplexMatrix (const ComplexDiagMatrix& a);
 
+  explicit ComplexMatrix (const MDiagArray2<Complex>& a);
+
+  explicit ComplexMatrix (const DiagArray2<Complex>& a);
+
   explicit ComplexMatrix (const boolMatrix& a);
 
   explicit ComplexMatrix (const charMatrix& a);
 
-  ComplexMatrix& operator = (const ComplexMatrix& a)
-  {
-    MArray<Complex>::operator = (a);
-    return *this;
-  }
-
   bool operator == (const ComplexMatrix& a) const;
   bool operator != (const ComplexMatrix& a) const;
 
@@ -356,18 +359,8 @@
   ComplexMatrix& operator += (const Matrix& a);
   ComplexMatrix& operator -= (const Matrix& a);
 
-  // unary operations
-
-  boolMatrix operator ! (void) const;
-
   // other operations
 
-  bool any_element_is_nan (void) const;
-  bool any_element_is_inf_or_nan (void) const;
-  bool all_elements_are_real (void) const;
-  bool all_integers (double& max_val, double& min_val) const;
-  bool too_large_for_float (void) const;
-
   boolMatrix all (int dim = -1) const;
   boolMatrix any (int dim = -1) const;
 
--- a/liboctave/array/CNDArray.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/liboctave/array/CNDArray.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -39,6 +39,7 @@
 #include "MArray-defs.h"
 #include "mx-base.h"
 #include "mx-op-defs.h"
+#include "mx-cnda-s.h"
 #include "oct-fftw.h"
 #include "oct-locbuf.h"
 
@@ -814,20 +815,6 @@
   return *this;
 }
 
-ComplexMatrix
-ComplexNDArray::matrix_value (void) const
-{
-  ComplexMatrix retval;
-
-  if (ndims () == 2)
-    retval = ComplexMatrix (Array<Complex> (*this));
-  else
-    (*current_liboctave_error_handler)
-      ("invalid conversion of ComplexNDArray to ComplexMatrix");
-
-  return retval;
-}
-
 void
 ComplexNDArray::increment_index (Array<octave_idx_type>& ra_idx,
                                  const dim_vector& dimensions,
--- a/liboctave/array/CNDArray.h	Fri Feb 06 08:31:09 2015 -0800
+++ b/liboctave/array/CNDArray.h	Fri Feb 06 08:31:49 2015 -0800
@@ -24,7 +24,6 @@
 #define octave_CNDArray_h 1
 
 #include "MArray.h"
-#include "CMatrix.h"
 
 #include "mx-defs.h"
 #include "mx-op-decl.h"
@@ -36,8 +35,6 @@
 {
 public:
 
-  typedef ComplexMatrix matrix_type;
-
   ComplexNDArray (void) : MArray<Complex> () { }
 
   ComplexNDArray (const dim_vector& dv) : MArray<Complex> (dv) { }
@@ -47,8 +44,6 @@
 
   ComplexNDArray (const ComplexNDArray& a) : MArray<Complex> (a) { }
 
-  ComplexNDArray (const ComplexMatrix& a) : MArray<Complex> (a) { }
-
   template <class U>
   ComplexNDArray (const MArray<U>& a) : MArray<Complex> (a) { }
 
@@ -124,8 +119,6 @@
   ComplexNDArray fourierNd (void) const;
   ComplexNDArray ifourierNd (void) const;
 
-  ComplexMatrix matrix_value (void) const;
-
   ComplexNDArray squeeze (void) const { return MArray<Complex>::squeeze (); }
 
   static void increment_index (Array<octave_idx_type>& ra_idx,
--- a/liboctave/array/CSparse.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/liboctave/array/CSparse.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -36,6 +36,12 @@
 #include "lo-mappers.h"
 #include "f77-fcn.h"
 #include "dRowVector.h"
+#include "mx-m-cs.h"
+#include "mx-cs-m.h"
+#include "mx-cm-s.h"
+#include "mx-fcm-fs.h"
+#include "mx-s-cm.h"
+#include "mx-fs-fcm.h"
 #include "oct-locbuf.h"
 
 #include "dDiagMatrix.h"
@@ -51,10 +57,11 @@
 #include "SparseCmplxCHOL.h"
 #include "SparseCmplxQR.h"
 
+#include "Sparse-op-defs.h"
+
 #include "Sparse-diag-op-defs.h"
 
 #include "Sparse-perm-op-defs.h"
-#include "mx-inlines.cc"
 
 // Define whether to use a basic QR solver or one that uses a Dulmange
 // Mendelsohn factorization to seperate the problem into under-determined,
@@ -160,7 +167,8 @@
 SparseComplexMatrix::SparseComplexMatrix (const ComplexDiagMatrix& a)
   : MSparse<Complex> (a.rows (), a.cols (), a.length ())
 {
-  octave_idx_type j = 0, l = a.length ();
+  octave_idx_type j = 0;
+  octave_idx_type l = a.length ();
   for (octave_idx_type i = 0; i < l; i++)
     {
       cidx (i) = j;
@@ -348,7 +356,7 @@
         found[i] = 0;
 
       for (octave_idx_type j = 0; j < nc; j++)
-        for (octave_idx_type i = cidx(j); i < cidx(j+1); i++)
+        for (octave_idx_type i = cidx (j); i < cidx (j+1); i++)
           if (found[ridx (i)] == -j)
             found[ridx (i)] = -j - 1;
 
@@ -505,7 +513,7 @@
         found[i] = 0;
 
       for (octave_idx_type j = 0; j < nc; j++)
-        for (octave_idx_type i = cidx(j); i < cidx(j+1); i++)
+        for (octave_idx_type i = cidx (j); i < cidx (j+1); i++)
           if (found[ridx (i)] == -j)
             found[ridx (i)] = -j - 1;
 
@@ -777,7 +785,8 @@
 
           if (calccond)
             {
-              double dmax = 0., dmin = octave_Inf;
+              double dmax = 0.;
+              double dmin = octave_Inf;
               for (octave_idx_type i = 0; i < nr; i++)
                 {
                   double tmp = std::abs (v[i]);
@@ -1116,7 +1125,6 @@
             {
               // Matrix is either singular or not positive definite
               mattype.mark_as_unsymmetric ();
-              typ = MatrixType::Full;
             }
         }
 
@@ -1321,7 +1329,8 @@
 
           if (calc_cond)
             {
-              double dmax = 0., dmin = octave_Inf;
+              double dmax = 0.;
+              double dmin = octave_Inf;
               for (octave_idx_type i = 0; i < nm; i++)
                 {
                   double tmp = std::abs (data (i));
@@ -1412,7 +1421,8 @@
 
           if (calc_cond)
             {
-              double dmax = 0., dmin = octave_Inf;
+              double dmax = 0.;
+              double dmin = octave_Inf;
               for (octave_idx_type i = 0; i < nm; i++)
                 {
                   double tmp = std::abs (data (i));
@@ -1473,7 +1483,8 @@
 
           if (calc_cond)
             {
-              double dmax = 0., dmin = octave_Inf;
+              double dmax = 0.;
+              double dmin = octave_Inf;
               for (octave_idx_type i = 0; i < nr; i++)
                 {
                   double tmp = std::abs (data (i));
@@ -1564,7 +1575,8 @@
 
           if (calc_cond)
             {
-              double dmax = 0., dmin = octave_Inf;
+              double dmax = 0.;
+              double dmin = octave_Inf;
               for (octave_idx_type i = 0; i < nm; i++)
                 {
                   double tmp = std::abs (data (i));
@@ -1792,9 +1804,7 @@
                   mattype.mark_as_rectangular ();
                 }
               else
-                (*current_liboctave_error_handler)
-                  ("SparseComplexMatrix::solve matrix singular to machine precision, rcond = %g",
-                   rcond);
+                gripe_singular_matrix (rcond);
             }
 
           volatile double rcond_plus_one = rcond + 1.0;
@@ -1809,9 +1819,7 @@
                   mattype.mark_as_rectangular ();
                 }
               else
-                (*current_liboctave_error_handler)
-                  ("matrix singular to machine precision, rcond = %g",
-                   rcond);
+                gripe_singular_matrix (rcond);
             }
         }
       else
@@ -1912,7 +1920,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++)
@@ -2008,7 +2016,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++)
@@ -2080,9 +2088,7 @@
                   mattype.mark_as_rectangular ();
                 }
               else
-                (*current_liboctave_error_handler)
-                  ("SparseComplexMatrix::solve matrix singular to machine precision, rcond = %g",
-                   rcond);
+                gripe_singular_matrix (rcond);
             }
 
           volatile double rcond_plus_one = rcond + 1.0;
@@ -2097,9 +2103,7 @@
                   mattype.mark_as_rectangular ();
                 }
               else
-                (*current_liboctave_error_handler)
-                  ("matrix singular to machine precision, rcond = %g",
-                   rcond);
+                gripe_singular_matrix (rcond);
             }
         }
       else
@@ -2315,9 +2319,7 @@
                   mattype.mark_as_rectangular ();
                 }
               else
-                (*current_liboctave_error_handler)
-                  ("SparseComplexMatrix::solve matrix singular to machine precision, rcond = %g",
-                   rcond);
+                gripe_singular_matrix (rcond);
             }
 
           volatile double rcond_plus_one = rcond + 1.0;
@@ -2332,9 +2334,7 @@
                   mattype.mark_as_rectangular ();
                 }
               else
-                (*current_liboctave_error_handler)
-                  ("matrix singular to machine precision, rcond = %g",
-                   rcond);
+                gripe_singular_matrix (rcond);
             }
         }
       else
@@ -2435,7 +2435,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++)
@@ -2531,7 +2531,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++)
@@ -2603,9 +2603,7 @@
                   mattype.mark_as_rectangular ();
                 }
               else
-                (*current_liboctave_error_handler)
-                  ("SparseComplexMatrix::solve matrix singular to machine precision, rcond = %g",
-                   rcond);
+                gripe_singular_matrix (rcond);
             }
 
           volatile double rcond_plus_one = rcond + 1.0;
@@ -2620,9 +2618,7 @@
                   mattype.mark_as_rectangular ();
                 }
               else
-                (*current_liboctave_error_handler)
-                  ("matrix singular to machine precision, rcond = %g",
-                   rcond);
+                gripe_singular_matrix (rcond);
             }
         }
       else
@@ -2859,9 +2855,7 @@
                   mattype.mark_as_rectangular ();
                 }
               else
-                (*current_liboctave_error_handler)
-                  ("SparseComplexMatrix::solve matrix singular to machine precision, rcond = %g",
-                   rcond);
+                gripe_singular_matrix (rcond);
             }
 
           volatile double rcond_plus_one = rcond + 1.0;
@@ -2876,9 +2870,7 @@
                   mattype.mark_as_rectangular ();
                 }
               else
-                (*current_liboctave_error_handler)
-                  ("matrix singular to machine precision, rcond = %g",
-                   rcond);
+                gripe_singular_matrix (rcond);
             }
         }
       else
@@ -2985,7 +2977,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++)
@@ -3094,7 +3086,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++)
@@ -3167,9 +3159,7 @@
                   mattype.mark_as_rectangular ();
                 }
               else
-                (*current_liboctave_error_handler)
-                  ("SparseComplexMatrix::solve matrix singular to machine precision, rcond = %g",
-                   rcond);
+                gripe_singular_matrix (rcond);
             }
 
           volatile double rcond_plus_one = rcond + 1.0;
@@ -3184,9 +3174,7 @@
                   mattype.mark_as_rectangular ();
                 }
               else
-                (*current_liboctave_error_handler)
-                  ("matrix singular to machine precision, rcond = %g",
-                   rcond);
+                gripe_singular_matrix (rcond);
             }
         }
       else
@@ -3427,9 +3415,7 @@
                   mattype.mark_as_rectangular ();
                 }
               else
-                (*current_liboctave_error_handler)
-                  ("SparseComplexMatrix::solve matrix singular to machine precision, rcond = %g",
-                   rcond);
+                gripe_singular_matrix (rcond);
             }
 
           volatile double rcond_plus_one = rcond + 1.0;
@@ -3444,9 +3430,7 @@
                   mattype.mark_as_rectangular ();
                 }
               else
-                (*current_liboctave_error_handler)
-                  ("matrix singular to machine precision, rcond = %g",
-                   rcond);
+                gripe_singular_matrix (rcond);
             }
         }
       else
@@ -3552,7 +3536,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++)
@@ -3661,7 +3645,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++)
@@ -3734,9 +3718,7 @@
                   mattype.mark_as_rectangular ();
                 }
               else
-                (*current_liboctave_error_handler)
-                  ("SparseComplexMatrix::solve matrix singular to machine precision, rcond = %g",
-                   rcond);
+                gripe_singular_matrix (rcond);
             }
 
           volatile double rcond_plus_one = rcond + 1.0;
@@ -3751,9 +3733,7 @@
                   mattype.mark_as_rectangular ();
                 }
               else
-                (*current_liboctave_error_handler)
-                  ("matrix singular to machine precision, rcond = %g",
-                   rcond);
+                gripe_singular_matrix (rcond);
             }
         }
       else
@@ -3900,8 +3880,7 @@
                   mattype.mark_as_rectangular ();
                 }
               else
-                (*current_liboctave_error_handler)
-                  ("matrix singular to machine precision");
+                gripe_singular_matrix ();
 
             }
           else
@@ -3998,9 +3977,7 @@
                   mattype.mark_as_rectangular ();
                 }
               else
-                (*current_liboctave_error_handler)
-                  ("matrix singular to machine precision");
-
+                gripe_singular_matrix ();
             }
           else
             {
@@ -4027,7 +4004,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++)
@@ -4202,8 +4179,7 @@
                   mattype.mark_as_rectangular ();
                 }
               else
-                (*current_liboctave_error_handler)
-                  ("matrix singular to machine precision");
+                gripe_singular_matrix ();
             }
         }
       else if (typ != MatrixType::Tridiagonal_Hermitian)
@@ -4298,8 +4274,7 @@
                   mattype.mark_as_rectangular ();
                 }
               else
-                (*current_liboctave_error_handler)
-                  ("matrix singular to machine precision");
+                gripe_singular_matrix ();
             }
           else
             {
@@ -4309,7 +4284,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;
@@ -4320,7 +4295,7 @@
                 {
 
                   for (octave_idx_type i = 0; i < b_nr; i++)
-                    Bx[i] = b (i,j);
+                    Bx[i] = b(i,j);
 
                   F77_XFCN (zgttrs, ZGTTRS,
                             (F77_CONST_CHAR_ARG2 (&job, 1),
@@ -4337,7 +4312,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++)
@@ -4468,9 +4443,7 @@
                           mattype.mark_as_rectangular ();
                         }
                       else
-                        (*current_liboctave_error_handler)
-                          ("matrix singular to machine precision, rcond = %g",
-                           rcond);
+                        gripe_singular_matrix (rcond);
                     }
                 }
               else
@@ -4523,7 +4496,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++)
@@ -4555,8 +4528,7 @@
                   mattype.mark_as_rectangular ();
                 }
               else
-                (*current_liboctave_error_handler)
-                  ("matrix singular to machine precision");
+                gripe_singular_matrix ();
             }
           else
             {
@@ -4589,9 +4561,7 @@
                           mattype.mark_as_rectangular ();
                         }
                       else
-                        (*current_liboctave_error_handler)
-                          ("matrix singular to machine precision, rcond = %g",
-                           rcond);
+                        gripe_singular_matrix (rcond);
                     }
                 }
               else
@@ -4715,9 +4685,7 @@
                           mattype.mark_as_rectangular ();
                         }
                       else
-                        (*current_liboctave_error_handler)
-                          ("matrix singular to machine precision, rcond = %g",
-                           rcond);
+                        gripe_singular_matrix (rcond);
                     }
                 }
               else
@@ -4729,7 +4697,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;
@@ -4805,7 +4773,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++)
@@ -4835,9 +4803,7 @@
                   mattype.mark_as_rectangular ();
                 }
               else
-                (*current_liboctave_error_handler)
-                  ("matrix singular to machine precision");
-
+                gripe_singular_matrix ();
             }
           else
             {
@@ -4870,9 +4836,7 @@
                           mattype.mark_as_rectangular ();
                         }
                       else
-                        (*current_liboctave_error_handler)
-                          ("matrix singular to machine precision, rcond = %g",
-                           rcond);
+                        gripe_singular_matrix (rcond);
                     }
                 }
               else
@@ -4903,7 +4867,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++)
@@ -5035,9 +4999,7 @@
                           mattype.mark_as_rectangular ();
                         }
                       else
-                        (*current_liboctave_error_handler)
-                          ("matrix singular to machine precision, rcond = %g",
-                           rcond);
+                        gripe_singular_matrix (rcond);
                     }
                 }
               else
@@ -5090,7 +5052,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++)
@@ -5120,8 +5082,7 @@
                   mattype.mark_as_rectangular ();
                 }
               else
-                (*current_liboctave_error_handler)
-                  ("matrix singular to machine precision");
+                gripe_singular_matrix ();
             }
           else
             {
@@ -5154,9 +5115,7 @@
                           mattype.mark_as_rectangular ();
                         }
                       else
-                        (*current_liboctave_error_handler)
-                          ("matrix singular to machine precision, rcond = %g",
-                           rcond);
+                        gripe_singular_matrix (rcond);
                     }
                 }
               else
@@ -5282,9 +5241,7 @@
                           mattype.mark_as_rectangular ();
                         }
                       else
-                        (*current_liboctave_error_handler)
-                          ("matrix singular to machine precision, rcond = %g",
-                           rcond);
+                        gripe_singular_matrix (rcond);
                     }
                 }
               else
@@ -5296,7 +5253,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;
@@ -5307,7 +5264,7 @@
                     {
 
                       for (octave_idx_type i = 0; i < b_nr; i++)
-                        Bx[i] = b (i,j);
+                        Bx[i] = b(i,j);
 
                       F77_XFCN (zpbtrs, ZPBTRS,
                                 (F77_CONST_CHAR_ARG2 (&job, 1),
@@ -5323,7 +5280,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++)
@@ -5377,7 +5334,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++)
@@ -5407,9 +5364,7 @@
                   mattype.mark_as_rectangular ();
                 }
               else
-                (*current_liboctave_error_handler)
-                  ("matrix singular to machine precision");
-
+                gripe_singular_matrix ();
             }
           else
             {
@@ -5442,9 +5397,7 @@
                           mattype.mark_as_rectangular ();
                         }
                       else
-                        (*current_liboctave_error_handler)
-                          ("matrix singular to machine precision, rcond = %g",
-                           rcond);
+                        gripe_singular_matrix (rcond);
                     }
                 }
               else
@@ -5476,7 +5429,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++)
@@ -5597,10 +5550,7 @@
           if (sing_handler)
             sing_handler (rcond);
           else
-            (*current_liboctave_error_handler)
-              ("SparseComplexMatrix::solve matrix singular to machine precision, rcond = %g",
-               rcond);
-
+            gripe_singular_matrix (rcond);
         }
       else if (status < 0)
         {
@@ -5664,17 +5614,17 @@
           if (spu == 0.)
             {
               cm->print = -1;
-              cm->print_function = 0;
+              SUITESPARSE_ASSIGN_FPTR (printf_func, cm->print_function, 0);
             }
           else
             {
               cm->print = static_cast<int> (spu) + 2;
-              cm->print_function =&SparseCholPrint;
+              SUITESPARSE_ASSIGN_FPTR (printf_func, cm->print_function, &SparseCholPrint);
             }
 
           cm->error_handler = &SparseCholError;
-          cm->complex_divide = CHOLMOD_NAME(divcomplex);
-          cm->hypotenuse = CHOLMOD_NAME(hypot);
+          SUITESPARSE_ASSIGN_FPTR2 (divcomplex_func, cm->complex_divide, divcomplex);
+          SUITESPARSE_ASSIGN_FPTR2 (hypot_func, cm->hypotenuse, hypot);
 
           cm->final_ll = true;
 
@@ -5748,9 +5698,7 @@
                       mattype.mark_as_rectangular ();
                     }
                   else
-                    (*current_liboctave_error_handler)
-                      ("SparseMatrix::solve matrix singular to machine precision, rcond = %g",
-                       rcond);
+                    gripe_singular_matrix (rcond);
 
                   return retval;
                 }
@@ -5777,8 +5725,8 @@
               END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
             }
 #else
-          (*current_liboctave_warning_handler)
-            ("CHOLMOD not installed");
+          (*current_liboctave_warning_with_id_handler)
+            ("Octave:missing-dependency", "CHOLMOD not installed");
 
           mattype.mark_as_unsymmetric ();
           typ = MatrixType::Full;
@@ -5907,17 +5855,17 @@
           if (spu == 0.)
             {
               cm->print = -1;
-              cm->print_function = 0;
+              SUITESPARSE_ASSIGN_FPTR (printf_func, cm->print_function, 0);
             }
           else
             {
               cm->print = static_cast<int> (spu) + 2;
-              cm->print_function =&SparseCholPrint;
+              SUITESPARSE_ASSIGN_FPTR (printf_func, cm->print_function, &SparseCholPrint);
             }
 
           cm->error_handler = &SparseCholError;
-          cm->complex_divide = CHOLMOD_NAME(divcomplex);
-          cm->hypotenuse = CHOLMOD_NAME(hypot);
+          SUITESPARSE_ASSIGN_FPTR2 (divcomplex_func, cm->complex_divide, divcomplex);
+          SUITESPARSE_ASSIGN_FPTR2 (hypot_func, cm->hypotenuse, hypot);
 
           cm->final_ll = true;
 
@@ -6001,9 +5949,7 @@
                       mattype.mark_as_rectangular ();
                     }
                   else
-                    (*current_liboctave_error_handler)
-                      ("SparseMatrix::solve matrix singular to machine precision, rcond = %g",
-                       rcond);
+                    gripe_singular_matrix (rcond);
 
                   return retval;
                 }
@@ -6036,8 +5982,8 @@
               END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
             }
 #else
-          (*current_liboctave_warning_handler)
-            ("CHOLMOD not installed");
+          (*current_liboctave_warning_with_id_handler)
+            ("Octave:missing-dependency", "CHOLMOD not installed");
 
           mattype.mark_as_unsymmetric ();
           typ = MatrixType::Full;
@@ -6071,7 +6017,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;
@@ -6198,17 +6144,17 @@
           if (spu == 0.)
             {
               cm->print = -1;
-              cm->print_function = 0;
+              SUITESPARSE_ASSIGN_FPTR (printf_func, cm->print_function, 0);
             }
           else
             {
               cm->print = static_cast<int> (spu) + 2;
-              cm->print_function =&SparseCholPrint;
+              SUITESPARSE_ASSIGN_FPTR (printf_func, cm->print_function, &SparseCholPrint);
             }
 
           cm->error_handler = &SparseCholError;
-          cm->complex_divide = CHOLMOD_NAME(divcomplex);
-          cm->hypotenuse = CHOLMOD_NAME(hypot);
+          SUITESPARSE_ASSIGN_FPTR2 (divcomplex_func, cm->complex_divide, divcomplex);
+          SUITESPARSE_ASSIGN_FPTR2 (hypot_func, cm->hypotenuse, hypot);
 
           cm->final_ll = true;
 
@@ -6282,9 +6228,7 @@
                       mattype.mark_as_rectangular ();
                     }
                   else
-                    (*current_liboctave_error_handler)
-                      ("SparseMatrix::solve matrix singular to machine precision, rcond = %g",
-                       rcond);
+                    gripe_singular_matrix (rcond);
 
                   return retval;
                 }
@@ -6311,8 +6255,8 @@
               END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
             }
 #else
-          (*current_liboctave_warning_handler)
-            ("CHOLMOD not installed");
+          (*current_liboctave_warning_with_id_handler)
+            ("Octave:missing-dependency", "CHOLMOD not installed");
 
           mattype.mark_as_unsymmetric ();
           typ = MatrixType::Full;
@@ -6420,17 +6364,17 @@
           if (spu == 0.)
             {
               cm->print = -1;
-              cm->print_function = 0;
+              SUITESPARSE_ASSIGN_FPTR (printf_func, cm->print_function, 0);
             }
           else
             {
               cm->print = static_cast<int> (spu) + 2;
-              cm->print_function =&SparseCholPrint;
+              SUITESPARSE_ASSIGN_FPTR (printf_func, cm->print_function, &SparseCholPrint);
             }
 
           cm->error_handler = &SparseCholError;
-          cm->complex_divide = CHOLMOD_NAME(divcomplex);
-          cm->hypotenuse = CHOLMOD_NAME(hypot);
+          SUITESPARSE_ASSIGN_FPTR2 (divcomplex_func, cm->complex_divide, divcomplex);
+          SUITESPARSE_ASSIGN_FPTR2 (hypot_func, cm->hypotenuse, hypot);
 
           cm->final_ll = true;
 
@@ -6514,9 +6458,7 @@
                       mattype.mark_as_rectangular ();
                     }
                   else
-                    (*current_liboctave_error_handler)
-                      ("SparseMatrix::solve matrix singular to machine precision, rcond = %g",
-                       rcond);
+                    gripe_singular_matrix (rcond);
 
                   return retval;
                 }
@@ -6549,8 +6491,8 @@
               END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
             }
 #else
-          (*current_liboctave_warning_handler)
-            ("CHOLMOD not installed");
+          (*current_liboctave_warning_with_id_handler)
+            ("Octave:missing-dependency", "CHOLMOD not installed");
 
           mattype.mark_as_unsymmetric ();
           typ = MatrixType::Full;
@@ -6577,7 +6519,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;
@@ -6589,7 +6531,7 @@
               for (octave_idx_type j = 0; j < b_nc; j++)
                 {
                   for (octave_idx_type i = 0; i < b_nr; i++)
-                    Bx[i] = b (i,j);
+                    Bx[i] = b(i,j);
 
                   status = UMFPACK_ZNAME (solve) (UMFPACK_A, Ap,
                                                   Ai,
@@ -6645,10 +6587,7 @@
                   if (sing_handler)
                     sing_handler (rcond);
                   else
-                    (*current_liboctave_error_handler)
-                      ("SparseComplexMatrix::solve matrix singular to machine precision, rcond = %g",
-                       rcond);
-
+                    gripe_singular_matrix (rcond);
                 }
 
               UMFPACK_ZNAME (report_info) (control, info);
@@ -7682,87 +7621,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;
 }
@@ -7777,7 +7714,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);
@@ -7802,91 +7739,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/CSparse.h	Fri Feb 06 08:31:09 2015 -0800
+++ b/liboctave/array/CSparse.h	Fri Feb 06 08:31:49 2015 -0800
@@ -26,6 +26,7 @@
 
 #include "dMatrix.h"
 #include "dNDArray.h"
+#include "CMatrix.h"
 #include "CNDArray.h"
 #include "dColVector.h"
 #include "CColVector.h"
@@ -34,7 +35,9 @@
 #include "DET.h"
 #include "MSparse.h"
 #include "MSparse-defs.h"
-#include "Sparse-op-defs.h"
+
+#include "Sparse-op-decls.h"
+
 #include "MatrixType.h"
 
 class PermMatrix;
--- a/liboctave/array/DiagArray2.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/liboctave/array/DiagArray2.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -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/MArray.h	Fri Feb 06 08:31:09 2015 -0800
+++ b/liboctave/array/MArray.h	Fri Feb 06 08:31:49 2015 -0800
@@ -49,12 +49,6 @@
 
   MArray (void) : Array<T> () { }
 
-  explicit MArray (octave_idx_type n) GCC_ATTR_DEPRECATED
-    : Array<T> (dim_vector (n, 1)) { }
-
-  MArray (octave_idx_type n, const T& val) GCC_ATTR_DEPRECATED
-    : Array<T> (dim_vector (n, 1), val) { }
-
   explicit MArray (const dim_vector& dv)
     : Array<T> (dv) { }
 
--- a/liboctave/array/MArray2.h	Fri Feb 06 08:31:09 2015 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,37 +0,0 @@
-// Template array classes with like-type math ops
-/*
-
-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/>.
-
-*/
-
-#if !defined (octave_MArray2_h)
-#define octave_MArray2_h 1
-
-#include "MArray.h"
-#define MArray2 MArray
-
-// If we're with GNU C++, issue a warning.
-#ifdef __GNUC__
-#warning Using MArray2<T> is deprecated. Use MArray<T>.
-#endif
-
-
-
-#endif
--- a/liboctave/array/MArrayN.h	Fri Feb 06 08:31:09 2015 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,35 +0,0 @@
-// Template array classes with like-type math ops
-/*
-
-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/>.
-
-*/
-
-#if !defined (octave_MArrayN_h)
-#define octave_MArrayN_h 1
-
-#include "MArray.h"
-#define MArrayN MArray
-
-// If we're with GNU C++, issue a warning.
-#ifdef __GNUC__
-#warning Using MArrayN<T> is deprecated. Use MArray<T>.
-#endif
-
-#endif
--- a/liboctave/array/MDiagArray2.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/liboctave/array/MDiagArray2.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -38,7 +38,8 @@
   bool retval = this->rows () == this->cols ();
   if (retval)
     {
-      octave_idx_type len = this->length (), i = 0;
+      octave_idx_type len = this->length ();
+      octave_idx_type i = 0;
       for (; i < len; i++)
         if (DiagArray2<T>::elem (i, i) != val) break;
       retval = i == len;
--- a/liboctave/array/MSparse.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/liboctave/array/MSparse.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -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 Feb 06 08:31:09 2015 -0800
+++ b/liboctave/array/MatrixType.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -30,12 +30,35 @@
 
 #include "MatrixType.h"
 #include "dMatrix.h"
+#include "fMatrix.h"
 #include "CMatrix.h"
+#include "fCMatrix.h"
 #include "dSparse.h"
 #include "CSparse.h"
 #include "oct-spparms.h"
 #include "oct-locbuf.h"
 
+static void
+warn_cached (void)
+{
+  (*current_liboctave_warning_with_id_handler)
+    ("Octave:matrix-type-info", "using cached matrix type");
+}
+
+static void
+warn_invalid (void)
+{
+  (*current_liboctave_warning_with_id_handler)
+    ("Octave:matrix-type-info", "invalid matrix type");
+}
+
+static void
+warn_calculating_sparse_type (void)
+{
+  (*current_liboctave_warning_with_id_handler)
+    ("Octave:matrix-type-info", "calculating sparse matrix type");
+}
+
 // FIXME: There is a large code duplication here
 
 MatrixType::MatrixType (void)
@@ -91,7 +114,8 @@
         {
           for (octave_idx_type i = 0; i < j; i++)
             {
-              double aij = a.elem (i,j), aji = a.elem (j,i);
+              double aij = a.elem (i,j);
+              double aji = a.elem (j,i);
               lower = lower && (aij == zero);
               upper = upper && (aji == zero);
               hermitian = hermitian && (aij == aji
@@ -118,7 +142,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 ();
 
@@ -149,7 +173,8 @@
         {
           for (octave_idx_type i = 0; i < j; i++)
             {
-              std::complex<T> aij = a.elem (i,j), aji = a.elem (j,i);
+              std::complex<T> aij = a.elem (i,j);
+              std::complex<T> aji = a.elem (j,i);
               lower = lower && (aij == zero);
               upper = upper && (aji == zero);
               hermitian = hermitian && (aij == std::conj (aji)
@@ -217,8 +242,7 @@
   octave_idx_type nnz = a.nnz ();
 
   if (octave_sparse_params::get_key ("spumoni") != 0.)
-    (*current_liboctave_warning_handler)
-      ("Calculating Sparse Matrix Type");
+    warn_calculating_sparse_type ();
 
   sp_bandden = octave_sparse_params::get_bandden ();
   bool maybe_hermitian = false;
@@ -536,8 +560,7 @@
   octave_idx_type nnz = a.nnz ();
 
   if (octave_sparse_params::get_key ("spumoni") != 0.)
-    (*current_liboctave_warning_handler)
-      ("Calculating Sparse Matrix Type");
+    warn_calculating_sparse_type ();
 
   sp_bandden = octave_sparse_params::get_bandden ();
   bool maybe_hermitian = false;
@@ -857,7 +880,7 @@
       || t == MatrixType::Rectangular)
     typ = t;
   else
-    (*current_liboctave_warning_handler) ("Invalid matrix type");
+    warn_invalid ();
 }
 
 MatrixType::MatrixType (const matrix_type t, const octave_idx_type np,
@@ -877,7 +900,7 @@
         perm[i] = p[i];
     }
   else
-    (*current_liboctave_warning_handler) ("Invalid matrix type");
+    warn_invalid ();
 }
 
 MatrixType::MatrixType (const matrix_type t, const octave_idx_type ku,
@@ -894,7 +917,7 @@
       lower_band = kl;
     }
   else
-    (*current_liboctave_warning_handler) ("Invalid sparse matrix type");
+    warn_invalid ();
 }
 
 MatrixType::~MatrixType (void)
@@ -944,16 +967,15 @@
     {
       if (!quiet &&
           octave_sparse_params::get_key ("spumoni") != 0.)
-        (*current_liboctave_warning_handler)
-          ("Using Cached Matrix Type");
+        warn_cached ();
 
       return typ;
     }
 
   if (typ != MatrixType::Unknown &&
       octave_sparse_params::get_key ("spumoni") != 0.)
-    (*current_liboctave_warning_handler)
-      ("Invalidating Matrix Type");
+    (*current_liboctave_warning_with_id_handler)
+      ("Octave:matrix-type-info", "invalidating matrix type");
 
   typ = MatrixType::Unknown;
 
@@ -967,8 +989,7 @@
       && (full || sp_bandden == octave_sparse_params::get_bandden ()))
     {
       if (octave_sparse_params::get_key ("spumoni") != 0.)
-        (*current_liboctave_warning_handler)
-          ("Using Cached Matrix Type");
+        warn_cached ();
 
       return typ;
     }
@@ -1000,8 +1021,7 @@
       && (full || sp_bandden == octave_sparse_params::get_bandden ()))
     {
       if (octave_sparse_params::get_key ("spumoni") != 0.)
-        (*current_liboctave_warning_handler)
-          ("Using Cached Matrix Type");
+        warn_cached ();
 
       return typ;
     }
@@ -1032,8 +1052,7 @@
   if (typ != MatrixType::Unknown)
     {
       if (octave_sparse_params::get_key ("spumoni") != 0.)
-        (*current_liboctave_warning_handler)
-          ("Using Cached Matrix Type");
+        warn_cached ();
 
       return typ;
     }
@@ -1059,8 +1078,7 @@
   if (typ != MatrixType::Unknown)
     {
       if (octave_sparse_params::get_key ("spumoni") != 0.)
-        (*current_liboctave_warning_handler)
-          ("Using Cached Matrix Type");
+        warn_cached ();
 
       return typ;
     }
@@ -1086,8 +1104,7 @@
   if (typ != MatrixType::Unknown)
     {
       if (octave_sparse_params::get_key ("spumoni") != 0.)
-        (*current_liboctave_warning_handler)
-          ("Using Cached Matrix Type");
+        warn_cached ();
 
       return typ;
     }
@@ -1113,8 +1130,7 @@
   if (typ != MatrixType::Unknown)
     {
       if (octave_sparse_params::get_key ("spumoni") != 0.)
-        (*current_liboctave_warning_handler)
-          ("Using Cached Matrix Type");
+        warn_cached ();
 
       return typ;
     }
@@ -1140,49 +1156,52 @@
   if (octave_sparse_params::get_key ("spumoni") != 0.)
     {
       if (typ == MatrixType::Unknown)
-        (*current_liboctave_warning_handler)
-          ("Unknown Matrix Type");
+        (*current_liboctave_warning_with_id_handler)
+          ("Octave:matrix-type-info", "unknown matrix type");
       else if (typ == MatrixType::Diagonal)
-        (*current_liboctave_warning_handler)
-          ("Diagonal Sparse Matrix");
+        (*current_liboctave_warning_with_id_handler)
+          ("Octave:matrix-type-info", "diagonal sparse matrix");
       else if (typ == MatrixType::Permuted_Diagonal)
-        (*current_liboctave_warning_handler)
-          ("Permuted Diagonal Sparse Matrix");
+        (*current_liboctave_warning_with_id_handler)
+          ("Octave:matrix-type-info", "permuted diagonal sparse matrix");
       else if (typ == MatrixType::Upper)
-        (*current_liboctave_warning_handler)
-          ("Upper Triangular Matrix");
+        (*current_liboctave_warning_with_id_handler)
+          ("Octave:matrix-type-info", "upper triangular matrix");
       else if (typ == MatrixType::Lower)
-        (*current_liboctave_warning_handler)
-          ("Lower Triangular Matrix");
+        (*current_liboctave_warning_with_id_handler)
+          ("Octave:matrix-type-info", "lower triangular matrix");
       else if (typ == MatrixType::Permuted_Upper)
-        (*current_liboctave_warning_handler)
-          ("Permuted Upper Triangular Matrix");
+        (*current_liboctave_warning_with_id_handler)
+          ("Octave:matrix-type-info", "permuted upper triangular matrix");
       else if (typ == MatrixType::Permuted_Lower)
-        (*current_liboctave_warning_handler)
-          ("Permuted Lower Triangular Matrix");
+        (*current_liboctave_warning_with_id_handler)
+          ("Octave:matrix-type-info", "permuted lower triangular Matrix");
       else if (typ == MatrixType::Banded)
-        (*current_liboctave_warning_handler)
-          ("Banded Sparse Matrix %d-1-%d (Density %f)", lower_band,
-           upper_band, bandden);
+        (*current_liboctave_warning_with_id_handler)
+          ("Octave:matrix-type-info",
+           "banded sparse matrix %d-1-%d (density %f)",
+           lower_band, upper_band, bandden);
       else if (typ == MatrixType::Banded_Hermitian)
-        (*current_liboctave_warning_handler)
-          ("Banded Hermitian/Symmetric Sparse Matrix %d-1-%d (Density %f)",
+        (*current_liboctave_warning_with_id_handler)
+          ("Octave:matrix-type-info",
+           "banded hermitian/symmetric sparse matrix %d-1-%d (density %f)",
            lower_band, upper_band, bandden);
       else if (typ == MatrixType::Hermitian)
-        (*current_liboctave_warning_handler)
-          ("Hermitian/Symmetric Matrix");
+        (*current_liboctave_warning_with_id_handler)
+          ("Octave:matrix-type-info", "hermitian/symmetric matrix");
       else if (typ == MatrixType::Tridiagonal)
-        (*current_liboctave_warning_handler)
-          ("Tridiagonal Sparse Matrix");
+        (*current_liboctave_warning_with_id_handler)
+          ("Octave:matrix-type-info", "tridiagonal sparse matrix");
       else if (typ == MatrixType::Tridiagonal_Hermitian)
-        (*current_liboctave_warning_handler)
-          ("Hermitian/Symmetric Tridiagonal Sparse Matrix");
+        (*current_liboctave_warning_with_id_handler)
+          ("Octave:matrix-type-info",
+           "hermitian/symmetric tridiagonal sparse matrix");
       else if (typ == MatrixType::Rectangular)
-        (*current_liboctave_warning_handler)
-          ("Rectangular/Singular Matrix");
+        (*current_liboctave_warning_with_id_handler)
+          ("Octave:matrix-type-info", "rectangular/singular matrix");
       else if (typ == MatrixType::Full)
-        (*current_liboctave_warning_handler)
-          ("Full Matrix");
+        (*current_liboctave_warning_with_id_handler)
+          ("Octave:matrix-type-info", "full matrix");
     }
 }
 
--- a/liboctave/array/PermMatrix.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/liboctave/array/PermMatrix.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -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;
 }
 
@@ -119,7 +156,8 @@
 
   for (octave_idx_type i = 0; i < len; i++)
     {
-      octave_idx_type j = p[i], k = q[i];
+      octave_idx_type j = p[i];
+      octave_idx_type k = q[i];
       if (j != i)
         {
           p[k] = p[i];
@@ -132,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);
@@ -175,42 +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 (), 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 Feb 06 08:31:09 2015 -0800
+++ b/liboctave/array/PermMatrix.h	Fri Feb 06 08:31:49 2015 -0800
@@ -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 Feb 06 08:31:09 2015 -0800
+++ b/liboctave/array/Sparse.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -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;
@@ -144,7 +136,8 @@
 {
   if (remove_zeros)
     {
-      octave_idx_type i = 0, k = 0;
+      octave_idx_type i = 0;
+      octave_idx_type k = 0;
       for (octave_idx_type j = 1; j <= ncols; j++)
         {
           octave_idx_type u = c[j];
@@ -177,13 +170,13 @@
       octave_idx_type min_nzmx = std::min (nz, nzmx);
 
       octave_idx_type * new_ridx = new octave_idx_type [nz];
-      copy_or_memcpy (min_nzmx, r, new_ridx);
+      std::copy (r, r + min_nzmx, new_ridx);
 
       delete [] r;
       r = new_ridx;
 
       T * new_data = new T [nz];
-      copy_or_memcpy (min_nzmx, d, new_data);
+      std::copy (d, d + min_nzmx, new_data);
 
       delete [] d;
       d = new_data;
@@ -303,7 +296,9 @@
 
   dimensions = dim_vector (nr, nc);
 
-  octave_idx_type n = a.numel (), rl = r.length (nr), cl = c.length (nc);
+  octave_idx_type n = a.numel ();
+  octave_idx_type rl = r.length (nr);
+  octave_idx_type cl = c.length (nc);
   bool a_scalar = n == 1;
   if (a_scalar)
     {
@@ -324,9 +319,9 @@
       if (n == 1 && a(0) != T ())
         {
           change_capacity (nzm > 1 ? nzm : 1);
-          xcidx(0) = 0;
-          xridx(0) = r(0);
-          xdata(0) = a(0);
+          xcidx (0) = 0;
+          xridx (0) = r(0);
+          xdata (0) = a(0);
 
           for (octave_idx_type j = 0; j < nc; j++)
             xcidx (j+1) = j >= c(0);
@@ -361,7 +356,8 @@
 
           octave_quit ();
 
-          octave_idx_type k = -1, l = -1;
+          octave_idx_type k = -1;
+          octave_idx_type l = -1;
 
           if (sum_terms)
             {
@@ -395,8 +391,10 @@
         }
       else
         {
-          idx_vector rr = r, cc = c;
-          const octave_idx_type *rd = rr.raw (), *cd = cc.raw ();
+          idx_vector rr = r;
+          idx_vector cc = c;
+          const octave_idx_type *rd = rr.raw ();
+          const octave_idx_type *cd = cc.raw ();
           OCTAVE_LOCAL_BUFFER_INIT (octave_idx_type, ci, nc+1, 0);
           ci[0] = 0;
           // Bin counts of column indices.
@@ -425,7 +423,8 @@
           for (octave_idx_type j = 0; j < nc; j++)
             {
               std::sort (sidx + ci[j], sidx + ci[j+1]);
-              octave_idx_type l = -1, nzj = 0;
+              octave_idx_type l = -1;
+              octave_idx_type nzj = 0;
               // Count.
               for (octave_idx_type i = ci[j]; i < ci[j+1]; i++)
                 {
@@ -490,15 +489,16 @@
 
       octave_quit ();
 
-      const octave_idx_type *rd = rs.raw (), *rdi = rsi.data ();
+      const octave_idx_type *rd = rs.raw ();
+      const octave_idx_type *rdi = rsi.data ();
       // Count unique indices.
       octave_idx_type new_nz = 1;
       for (octave_idx_type i = 1; i < n; i++)
         new_nz += rd[i-1] != rd[i];
       // Allocate result.
       change_capacity (nzm > new_nz ? nzm : new_nz);
-      xcidx(0) = 0;
-      xcidx(1) = new_nz;
+      xcidx (0) = 0;
+      xcidx (1) = new_nz;
       octave_idx_type *rri = ridx ();
       T *rrd = data ();
 
@@ -537,8 +537,10 @@
     }
   else
     {
-      idx_vector rr = r, cc = c;
-      const octave_idx_type *rd = rr.raw (), *cd = cc.raw ();
+      idx_vector rr = r;
+      idx_vector cc = c;
+      const octave_idx_type *rd = rr.raw ();
+      const octave_idx_type *cd = cc.raw ();
       OCTAVE_LOCAL_BUFFER_INIT (octave_idx_type, ci, nc+1, 0);
       ci[0] = 0;
       // Bin counts of column indices.
@@ -572,7 +574,8 @@
       for (octave_idx_type j = 0; j < nc; j++)
         {
           std::sort (spairs + ci[j], spairs + ci[j+1]);
-          octave_idx_type l = -1, nzj = 0;
+          octave_idx_type l = -1;
+          octave_idx_type nzj = 0;
           // Count.
           for (octave_idx_type i = ci[j]; i < ci[j+1]; i++)
             {
@@ -646,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++;
@@ -816,8 +819,9 @@
 
   if (dims2.length () > 2)
     {
-      (*current_liboctave_warning_handler)
-        ("reshape: sparse reshape to N-d array smashes dims");
+      (*current_liboctave_warning_with_id_handler)
+        ("Octave:reshape-smashes-dims",
+         "reshape: sparse reshape to N-d array smashes dims");
 
       for (octave_idx_type i = 2; i < dims2.length (); i++)
         dims2(1) *= dims2(i);
@@ -905,7 +909,8 @@
 void
 Sparse<T>::resize1 (octave_idx_type n)
 {
-  octave_idx_type nr = rows (), nc = cols ();
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
 
   if (nr == 0)
     resize (1, std::max (nc, n));
@@ -954,7 +959,8 @@
 
   if (r < rows ())
     {
-      octave_idx_type i = 0, k = 0;
+      octave_idx_type i = 0;
+      octave_idx_type k = 0;
       for (octave_idx_type j = 1; j <= rep->ncols; j++)
         {
           octave_idx_type u = xcidx (j);
@@ -973,13 +979,13 @@
   if (c != rep->ncols)
     {
       octave_idx_type *new_cidx = new octave_idx_type [c+1];
-      copy_or_memcpy (std::min (c, rep->ncols)+1, rep->c, new_cidx);
+      std::copy (rep->c, rep->c + std::min (c, rep->ncols) + 1, new_cidx);
       delete [] rep->c;
       rep->c = new_cidx;
 
       if (c > rep->ncols)
-        fill_or_memset (c - rep->ncols, rep->c[rep->ncols],
-                        rep->c + rep->ncols + 1);
+        std::fill_n (rep->c + rep->ncols + 1, c - rep->ncols,
+          rep->c[rep->ncols]);
     }
 
   rep->ncols = dimensions(1) = c;
@@ -1175,9 +1181,9 @@
           // Copy data and adjust indices.
           octave_idx_type nz_new = nz - (ui - li);
           *this = Sparse<T> (nr - (ub - lb), 1, nz_new);
-          copy_or_memcpy (li, tmp.data (), data ());
-          copy_or_memcpy (li, tmp.ridx (), xridx ());
-          copy_or_memcpy (nz - ui, tmp.data () + ui, xdata () + li);
+          std::copy (tmp.data (), tmp.data () + li, data ());
+          std::copy (tmp.ridx (), tmp.ridx () + li, xridx ());
+          std::copy (tmp.data () + ui, tmp.data () + nz, xdata () + li);
           mx_inline_sub (nz - ui, xridx () + li, tmp.ridx () + ui, ub - lb);
           xcidx (1) = nz_new;
         }
@@ -1187,7 +1193,9 @@
           OCTAVE_LOCAL_BUFFER (T, data_new, nz);
           idx_vector sidx = idx.sorted (true);
           const octave_idx_type *sj = sidx.raw ();
-          octave_idx_type sl = sidx.length (nel), nz_new = 0, j = 0;
+          octave_idx_type sl = sidx.length (nel);
+          octave_idx_type nz_new = 0;
+          octave_idx_type j = 0;
           for (octave_idx_type i = 0; i < nz; i++)
             {
               octave_idx_type r = tmp.ridx (i);
@@ -1200,8 +1208,8 @@
             }
 
           *this = Sparse<T> (nr - sl, 1, nz_new);
-          copy_or_memcpy (nz_new, ridx_new, ridx ());
-          copy_or_memcpy (nz_new, data_new, xdata ());
+          std::copy (ridx_new, ridx_new + nz_new, ridx ());
+          std::copy (data_new, data_new + nz_new, xdata ());
           xcidx (1) = nz_new;
         }
     }
@@ -1216,10 +1224,10 @@
           octave_idx_type ubi = tmp.cidx (ub);
           octave_idx_type new_nz = nz - (ubi - lbi);
           *this = Sparse<T> (1, nc - (ub - lb), new_nz);
-          copy_or_memcpy (lbi, tmp.data (), data ());
-          copy_or_memcpy (nz - ubi, tmp.data () + ubi, xdata () + lbi);
-          fill_or_memset (new_nz, static_cast<octave_idx_type> (0), ridx ());
-          copy_or_memcpy (lb, tmp.cidx () + 1, cidx () + 1);
+          std::copy (tmp.data (), tmp.data () + lbi, data ());
+          std::copy (tmp.data () + ubi, tmp.data () + nz , xdata () + lbi);
+          std::fill_n (ridx (), new_nz, static_cast<octave_idx_type> (0));
+          std::copy (tmp.cidx () + 1, tmp.cidx () + 1 + lb, cidx () + 1);
           mx_inline_sub (nc - ub, xcidx () + 1, tmp.cidx () + ub + 1,
                          ubi - lbi);
         }
@@ -1270,16 +1278,16 @@
           else
             {
               const Sparse<T> tmp = *this;
-              octave_idx_type lbi = tmp.cidx(lb);
-              octave_idx_type ubi = tmp.cidx(ub);
+              octave_idx_type lbi = tmp.cidx (lb);
+              octave_idx_type ubi = tmp.cidx (ub);
               octave_idx_type new_nz = nz - (ubi - lbi);
 
               *this = Sparse<T> (nr, nc - (ub - lb), new_nz);
-              copy_or_memcpy (lbi, tmp.data (), data ());
-              copy_or_memcpy (lbi, tmp.ridx (), ridx ());
-              copy_or_memcpy (nz - ubi, tmp.data () + ubi, xdata () + lbi);
-              copy_or_memcpy (nz - ubi, tmp.ridx () + ubi, xridx () + lbi);
-              copy_or_memcpy (lb, tmp.cidx () + 1, cidx () + 1);
+              std::copy (tmp.data (), tmp.data () + lbi, data ());
+              std::copy (tmp.ridx (), tmp.ridx () + lbi, ridx ());
+              std::copy (tmp.data () + ubi, tmp.data () + nz, xdata () + lbi);
+              std::copy (tmp.ridx () + ubi, tmp.ridx () + nz, xridx () + lbi);
+              std::copy (tmp.cidx () + 1, tmp.cidx () + 1 + lb, cidx () + 1);
               mx_inline_sub (nc - ub, xcidx () + lb + 1,
                              tmp.cidx () + ub + 1, ubi - lbi);
             }
@@ -1314,20 +1322,20 @@
                                  tmpl.nnz () + tmpu.nnz ());
               for (octave_idx_type j = 0, k = 0; j < nc; j++)
                 {
-                  for (octave_idx_type i = tmpl.cidx(j); i < tmpl.cidx(j+1);
+                  for (octave_idx_type i = tmpl.cidx (j); i < tmpl.cidx (j+1);
                        i++)
                     {
-                      xdata(k) = tmpl.data(i);
-                      xridx(k++) = tmpl.ridx(i);
+                      xdata (k) = tmpl.data (i);
+                      xridx (k++) = tmpl.ridx (i);
                     }
-                  for (octave_idx_type i = tmpu.cidx(j); i < tmpu.cidx(j+1);
+                  for (octave_idx_type i = tmpu.cidx (j); i < tmpu.cidx (j+1);
                        i++)
                     {
-                      xdata(k) = tmpu.data(i);
-                      xridx(k++) = tmpu.ridx(i) + lb;
+                      xdata (k) = tmpu.data (i);
+                      xridx (k++) = tmpu.ridx (i) + lb;
                     }
 
-                  xcidx(j+1) = k;
+                  xcidx (j+1) = k;
                 }
             }
         }
@@ -1388,12 +1396,9 @@
 
   octave_idx_type nel = numel (); // Can throw.
 
-  const dim_vector idx_dims = idx.orig_dimensions ();
-
-  if (idx_dims.length () > 2)
-    (*current_liboctave_error_handler)
-      ("cannot index sparse matrix with an N-D Array");
-  else if (idx.is_colon ())
+  const dim_vector idx_dims = idx.orig_dimensions ().redim (2);
+
+  if (idx.is_colon ())
     {
       if (nc == 1)
         retval = *this;
@@ -1460,7 +1465,7 @@
           // Copy data and adjust indices.
           octave_idx_type nz_new = ui - li;
           retval = Sparse<T> (ub - lb, 1, nz_new);
-          copy_or_memcpy (nz_new, data () + li, retval.data ());
+          std::copy (data () + li, data () + li + nz_new, retval.data ());
           mx_inline_sub (nz_new, retval.xridx (), ridx () + li, lb);
           retval.xcidx (1) = nz_new;
         }
@@ -1473,7 +1478,7 @@
               for (octave_idx_type j = 0; j < nz; j++)
                 retval.ridx (j) = nr - ridx (nz - j - 1) - 1;
 
-              copy_or_memcpy (2, cidx (), retval.cidx ());
+              std::copy (cidx (), cidx () + 2, retval.cidx ());
               std::reverse_copy (data (), data () + nz, retval.data ());
             }
           else
@@ -1488,11 +1493,15 @@
           // If indexing a sparse column vector by a vector, the result is a
           // sparse column vector, otherwise it inherits the shape of index.
           // Vector transpose is cheap, so do it right here.
+
+          Array<octave_idx_type> tmp_idx = idx.as_array ().as_matrix ();
+
           const Array<octave_idx_type> idxa = (idx_dims(0) == 1
-                                               ? idx.as_array ().transpose ()
-                                               : idx.as_array ());
-
-          octave_idx_type new_nr = idxa.rows (), new_nc = idxa.cols ();
+                                               ? tmp_idx.transpose ()
+                                               : tmp_idx);
+
+          octave_idx_type new_nr = idxa.rows ();
+          octave_idx_type new_nc = idxa.cols ();
 
           // Lookup.
           // FIXME: Could specialize for sorted idx?
@@ -1540,11 +1549,12 @@
       else if (idx.is_cont_range (nel, lb, ub))
         {
           // Special-case a contiguous range.
-          octave_idx_type lbi = cidx (lb), ubi = cidx (ub), new_nz = ubi - lbi;
+          octave_idx_type lbi = cidx (lb);
+          octave_idx_type ubi = cidx (ub);
+          octave_idx_type new_nz = ubi - lbi;
           retval = Sparse<T> (1, ub - lb, new_nz);
-          copy_or_memcpy (new_nz, data () + lbi, retval.data ());
-          fill_or_memset (new_nz, static_cast<octave_idx_type> (0),
-                          retval.ridx ());
+          std::copy (data () + lbi, data () + lbi + new_nz, retval.data ());
+          std::fill_n (retval.ridx (), new_nz, static_cast<octave_idx_type> (0));
           mx_inline_sub (ub - lb + 1, retval.cidx (), cidx () + lb, lbi);
         }
       else
@@ -1625,10 +1635,12 @@
       else if (idx_j.is_cont_range (nc, lb, ub))
         {
           // Special-case a contiguous range.
-          octave_idx_type lbi = cidx (lb), ubi = cidx (ub), new_nz = ubi - lbi;
+          octave_idx_type lbi = cidx (lb);
+          octave_idx_type ubi = cidx (ub);
+          octave_idx_type new_nz = ubi - lbi;
           retval = Sparse<T> (nr, ub - lb, new_nz);
-          copy_or_memcpy (new_nz, data () + lbi, retval.data ());
-          copy_or_memcpy (new_nz, ridx () + lbi, retval.ridx ());
+          std::copy (data () + lbi, data () + lbi + new_nz, retval.data ());
+          std::copy (ridx () + lbi, ridx () + lbi + new_nz, retval.ridx ());
           mx_inline_sub (ub - lb + 1, retval.cidx (), cidx () + lb, lbi);
         }
       else
@@ -1650,8 +1662,8 @@
               octave_idx_type lj = retval.xcidx (j);
               octave_idx_type nzj = retval.xcidx (j+1) - lj;
 
-              copy_or_memcpy (nzj, data () + ljj, retval.data () + lj);
-              copy_or_memcpy (nzj, ridx () + ljj, retval.ridx () + lj);
+              std::copy (data () + ljj, data () + ljj + nzj, retval.data () + lj);
+              std::copy (ridx () + ljj, ridx () + ljj + nzj, retval.ridx () + lj);
             }
         }
     }
@@ -1756,7 +1768,8 @@
               octave_idx_type jj = idx_j(j);
               octave_idx_type lj = cidx (jj);
               octave_idx_type nzj = cidx (jj+1) - cidx (jj);
-              octave_idx_type li = retval.xcidx (j), uj = lj + nzj - 1;
+              octave_idx_type li = retval.xcidx (j);
+              octave_idx_type uj = lj + nzj - 1;
               for (octave_idx_type i = 0; i < nzj; i++)
                 {
                   retval.xdata (li + i) = data (uj - i); // Copy in reverse order.
@@ -1863,7 +1876,8 @@
               // Look-up indices first.
               octave_idx_type li = lblookup (ridx (), nz, lb);
               octave_idx_type ui = lblookup (ridx (), nz, ub);
-              octave_idx_type rnz = rhs.nnz (), new_nz = nz - (ui - li) + rnz;
+              octave_idx_type rnz = rhs.nnz ();
+              octave_idx_type new_nz = nz - (ui - li) + rnz;
 
               if (new_nz >= nz && new_nz <= capacity ())
                 {
@@ -1879,7 +1893,7 @@
                     }
 
                   // Copy data and adjust indices from rhs.
-                  copy_or_memcpy (rnz, rhs.data (), data () + li);
+                  std::copy (rhs.data (), rhs.data () + rnz, data () + li);
                   mx_inline_add (rnz, ridx () + li, rhs.ridx (), lb);
                 }
               else
@@ -1890,17 +1904,17 @@
                   *this = Sparse<T> (nr, 1, new_nz);
 
                   // Head ...
-                  copy_or_memcpy (li, tmp.data (), data ());
-                  copy_or_memcpy (li, tmp.ridx (), ridx ());
+                  std::copy (tmp.data (), tmp.data () + li, data ());
+                  std::copy (tmp.ridx (), tmp.ridx () + li, ridx ());
 
                   // new stuff ...
-                  copy_or_memcpy (rnz, rhs.data (), data () + li);
+                  std::copy (rhs.data (), rhs.data () + rnz, data () + li);
                   mx_inline_add (rnz, ridx () + li, rhs.ridx (), lb);
 
                   // ...tail
-                  copy_or_memcpy (nz - ui, tmp.data () + ui,
+                  std::copy (tmp.data () + ui, tmp.data () + nz,
                                   data () + li + rnz);
-                  copy_or_memcpy (nz - ui, tmp.ridx () + ui,
+                  std::copy (tmp.ridx () + ui, tmp.ridx () + nz,
                                   ridx () + li + rnz);
                 }
 
@@ -1936,8 +1950,8 @@
               // Disassembly our matrix...
               Array<octave_idx_type> new_ri (dim_vector (new_nz, 1));
               Array<T> new_data (dim_vector (new_nz, 1));
-              copy_or_memcpy (nz, tmp.ridx (), new_ri.fortran_vec ());
-              copy_or_memcpy (nz, tmp.data (), new_data.fortran_vec ());
+              std::copy (tmp.ridx (), tmp.ridx () + nz, new_ri.fortran_vec ());
+              std::copy (tmp.data (), tmp.data () + nz, new_data.fortran_vec ());
               // ... insert new data (densified) ...
               idx.copy_data (new_ri.fortran_vec () + nz);
               new_data.assign (idx_vector (nz, new_nz), rhs.array_value ());
@@ -2043,8 +2057,10 @@
           else if (idx_j.is_cont_range (nc, lb, ub))
             {
               // Special-case a contiguous range.
-              octave_idx_type li = cidx (lb), ui = cidx (ub);
-              octave_idx_type rnz = rhs.nnz (), new_nz = nz - (ui - li) + rnz;
+              octave_idx_type li = cidx (lb);
+              octave_idx_type ui = cidx (ub);
+              octave_idx_type rnz = rhs.nnz ();
+              octave_idx_type new_nz = nz - (ui - li) + rnz;
 
               if (new_nz >= nz && new_nz <= capacity ())
                 {
@@ -2061,8 +2077,8 @@
                     }
 
                   // Copy data and indices from rhs.
-                  copy_or_memcpy (rnz, rhs.data (), data () + li);
-                  copy_or_memcpy (rnz, rhs.ridx (), ridx () + li);
+                  std::copy (rhs.data (), rhs.data () + rnz, data () + li);
+                  std::copy (rhs.ridx (), rhs.ridx () + rnz, ridx () + li);
                   mx_inline_add (ub - lb, cidx () + lb + 1, rhs.cidx () + 1,
                                  li);
 
@@ -2076,20 +2092,20 @@
                   *this = Sparse<T> (nr, nc, new_nz);
 
                   // Head...
-                  copy_or_memcpy (li, tmp.data (), data ());
-                  copy_or_memcpy (li, tmp.ridx (), ridx ());
-                  copy_or_memcpy (lb, tmp.cidx () + 1, cidx () + 1);
+                  std::copy (tmp.data (), tmp.data () + li, data ());
+                  std::copy (tmp.ridx (), tmp.ridx () + li, ridx ());
+                  std::copy (tmp.cidx () + 1, tmp.cidx () + 1 + lb, cidx () + 1);
 
                   // new stuff...
-                  copy_or_memcpy (rnz, rhs.data (), data () + li);
-                  copy_or_memcpy (rnz, rhs.ridx (), ridx () + li);
+                  std::copy (rhs.data (), rhs.data () + rnz, data () + li);
+                  std::copy (rhs.ridx (), rhs.ridx () + rnz, ridx () + li);
                   mx_inline_add (ub - lb, cidx () + lb + 1, rhs.cidx () + 1,
                                  li);
 
                   // ...tail.
-                  copy_or_memcpy (nz - ui, tmp.data () + ui,
+                  std::copy (tmp.data () + ui, tmp.data () + nz,
                                   data () + li + rnz);
-                  copy_or_memcpy (nz - ui, tmp.ridx () + ui,
+                  std::copy (tmp.ridx () + ui, tmp.ridx () + nz,
                                   ridx () + li + rnz);
                   mx_inline_add (nc - ub, cidx () + ub + 1,
                                  tmp.cidx () + ub + 1, new_nz - nz);
@@ -2133,20 +2149,26 @@
               // Merge columns.
               for (octave_idx_type i = 0; i < nc; i++)
                 {
-                  octave_idx_type l = xcidx (i), u = xcidx (i+1), j = jsav[i];
+                  octave_idx_type l = xcidx (i);
+                  octave_idx_type u = xcidx (i+1);
+                  octave_idx_type j = jsav[i];
                   if (j >= 0)
                     {
                       // from rhs
                       octave_idx_type k = rhs.cidx (j);
-                      copy_or_memcpy (u - l, rhs.data () + k, xdata () + l);
-                      copy_or_memcpy (u - l, rhs.ridx () + k, xridx () + l);
+                      std::copy (rhs.data () + k, rhs.data () + k + u - l,
+                        xdata () + l);
+                      std::copy (rhs.ridx () + k, rhs.ridx () + k + u - l,
+                        xridx () + l);
                     }
                   else
                     {
                       // original
                       octave_idx_type k = tmp.cidx (i);
-                      copy_or_memcpy (u - l, tmp.data () + k, xdata () + l);
-                      copy_or_memcpy (u - l, tmp.ridx () + k, xridx () + l);
+                      std::copy (tmp.data () + k, tmp.data () + k + u - l,
+                        xdata () + l);
+                      std::copy (tmp.ridx () + k, tmp.ridx () + k + u - l,
+                        xridx () + l);
                     }
                 }
 
@@ -2405,7 +2427,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)
             {
@@ -2413,7 +2435,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.)
@@ -2443,7 +2465,7 @@
                     }
                 }
             }
-          else if ( k < 0)
+          else if (k < 0)
             {
               for (octave_idx_type i = 0; i < ndiag; i++)
                 {
@@ -2469,8 +2491,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)
     {
@@ -2609,7 +2638,8 @@
                 if (spi.is_empty ())
                   continue;
 
-                octave_idx_type kl = spi.cidx (j), ku = spi.cidx (j+1);
+                octave_idx_type kl = spi.cidx (j);
+                octave_idx_type ku = spi.cidx (j+1);
                 for (octave_idx_type k = kl; k < ku; k++, l++)
                   {
                     retval.xridx (l) = spi.ridx (k) + rcum;
--- a/liboctave/array/Sparse.h	Fri Feb 06 08:31:09 2015 -0800
+++ b/liboctave/array/Sparse.h	Fri Feb 06 08:31:49 2015 -0800
@@ -38,7 +38,6 @@
 #include "lo-utils.h"
 
 #include "oct-sort.h"
-#include "oct-mem.h"
 
 class idx_vector;
 class PermMatrix;
@@ -102,9 +101,9 @@
         nzmx (a.nzmx), nrows (a.nrows), ncols (a.ncols), count (1)
     {
       octave_idx_type nz = a.nnz ();
-      copy_or_memcpy (nz, a.d, d);
-      copy_or_memcpy (nz, a.r, r);
-      copy_or_memcpy (ncols + 1, a.c, c);
+      std::copy (a.d, a.d + nz, d);
+      std::copy (a.r, a.r + nz, r);
+      std::copy (a.c, a.c + ncols + 1, c);
     }
 
     ~SparseRep (void) { delete [] d; delete [] r; delete [] c; }
@@ -213,8 +212,8 @@
   {
     octave_idx_type nz = a.nnz ();
     std::copy (a.rep->d, a.rep->d + nz, rep->d);
-    copy_or_memcpy (nz, a.rep->r, rep->r);
-    copy_or_memcpy (rep->ncols + 1, a.rep->c, rep->c);
+    std::copy (a.rep->r, a.rep->r + nz, rep->r);
+    std::copy (a.rep->c, a.rep->c + rep->ncols + 1, rep->c);
   }
 
   // No type conversion case.
@@ -242,7 +241,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 (); }
@@ -300,13 +299,15 @@
 
   T& xelem (octave_idx_type n)
   {
-    octave_idx_type i = n % rows (), j = n / rows ();
+    octave_idx_type i = n % rows ();
+    octave_idx_type j = n / rows ();
     return xelem (i, j);
   }
 
   T xelem (octave_idx_type n) const
   {
-    octave_idx_type i = n % rows (), j = n / rows ();
+    octave_idx_type i = n % rows ();
+    octave_idx_type j = n / rows ();
     return xelem (i, j);
   }
 
--- a/liboctave/array/boolMatrix.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/liboctave/array/boolMatrix.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -29,9 +29,9 @@
 #include <iostream>
 
 #include "Array-util.h"
+#include "boolMatrix.h"
 #include "lo-error.h"
 #include "str-vec.h"
-#include "mx-base.h"
 #include "mx-inlines.cc"
 #include "mx-op-defs.h"
 
@@ -84,20 +84,6 @@
   return Array<bool>::diag (k);
 }
 
-// FIXME: Do these really belong here?  Maybe they should be in a base class?
-
-boolMatrix
-boolMatrix::all (int dim) const
-{
-  return do_mx_red_op<bool, bool> (*this, dim, mx_inline_all);
-}
-
-boolMatrix
-boolMatrix::any (int dim) const
-{
-  return do_mx_red_op<bool, bool> (*this, dim, mx_inline_any);
-}
-
 MM_BOOL_OPS (boolMatrix, boolMatrix)
 MS_BOOL_OPS (boolMatrix, bool)
 SM_BOOL_OPS (bool, boolMatrix)
--- a/liboctave/array/boolMatrix.h	Fri Feb 06 08:31:09 2015 -0800
+++ b/liboctave/array/boolMatrix.h	Fri Feb 06 08:31:49 2015 -0800
@@ -25,37 +25,33 @@
 #define octave_boolMatrix_h 1
 
 #include "Array.h"
+#include "boolNDArray.h"
 
 #include "mx-defs.h"
 #include "mx-op-decl.h"
 
 class
 OCTAVE_API
-boolMatrix : public Array<bool>
+boolMatrix : public boolNDArray
 {
 public:
 
-  boolMatrix (void) : Array<bool> () { }
+  boolMatrix (void) : boolNDArray () { }
 
   boolMatrix (octave_idx_type r, octave_idx_type c)
-    : Array<bool> (dim_vector (r, c)) { }
+    : boolNDArray (dim_vector (r, c)) { }
 
   boolMatrix (octave_idx_type r, octave_idx_type c, bool val)
-    : Array<bool> (dim_vector (r, c), val) { }
-
-  boolMatrix (const dim_vector& dv) : Array<bool> (dv) { }
+    : boolNDArray (dim_vector (r, c), val) { }
 
-  boolMatrix (const dim_vector& dv, bool val) : Array<bool> (dv, val) { }
-
-  boolMatrix (const Array<bool>& a) : Array<bool> (a.as_matrix ()) { }
+  boolMatrix (const dim_vector& dv) : boolNDArray (dv.redim (2)) { }
 
-  boolMatrix (const boolMatrix& a) : Array<bool> (a) { }
+  boolMatrix (const dim_vector& dv, bool val)
+    : boolNDArray (dv.redim (2), val) { }
 
-  boolMatrix& operator = (const boolMatrix& a)
-  {
-    Array<bool>::operator = (a);
-    return *this;
-  }
+  boolMatrix (const Array<bool>& a) : boolNDArray (a.as_matrix ()) { }
+
+  boolMatrix (const boolMatrix& a) : boolNDArray (a) { }
 
   bool operator == (const boolMatrix& a) const;
   bool operator != (const boolMatrix& a) const;
@@ -75,9 +71,6 @@
 
   boolMatrix diag (octave_idx_type k = 0) const;
 
-  boolMatrix all (int dim = -1) const;
-  boolMatrix any (int dim = -1) const;
-
 #if 0
   // i/o
 
--- a/liboctave/array/boolNDArray.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/liboctave/array/boolNDArray.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -27,6 +27,7 @@
 #endif
 
 #include "Array-util.h"
+#include "boolNDArray.h"
 #include "CNDArray.h"
 #include "mx-base.h"
 #include "lo-ieee.h"
@@ -106,14 +107,6 @@
   return *this;
 }
 
-
-
-boolMatrix
-boolNDArray::matrix_value (void) const
-{
-  return *this;
-}
-
 void
 boolNDArray::increment_index (Array<octave_idx_type>& ra_idx,
                               const dim_vector& dimensions,
--- a/liboctave/array/boolNDArray.h	Fri Feb 06 08:31:09 2015 -0800
+++ b/liboctave/array/boolNDArray.h	Fri Feb 06 08:31:49 2015 -0800
@@ -29,9 +29,6 @@
 #include "mx-op-decl.h"
 #include "bsxfun-decl.h"
 
-#include "boolMatrix.h"
-
-
 class
 OCTAVE_API
 boolNDArray : public Array<bool>
@@ -49,8 +46,6 @@
 
   boolNDArray (const boolNDArray& a) : Array<bool> (a) { }
 
-  boolNDArray (const boolMatrix& a) : Array<bool> (a) { }
-
   boolNDArray (const Array<bool>& a) : Array<bool> (a) { }
 
   boolNDArray& operator = (const boolNDArray& a)
@@ -83,8 +78,6 @@
   boolNDArray& insert (const boolNDArray& a,
                        const Array<octave_idx_type>& ra_idx);
 
-  boolMatrix matrix_value (void) const;
-
   boolNDArray squeeze (void) const { return Array<bool>::squeeze (); }
 
   static void increment_index (Array<octave_idx_type>& ra_idx,
--- a/liboctave/array/boolSparse.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/liboctave/array/boolSparse.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -35,9 +35,10 @@
 
 #include "boolSparse.h"
 #include "dSparse.h"
-#include "oct-mem.h"
 #include "oct-locbuf.h"
 
+#include "Sparse-op-defs.h"
+
 // SparseBoolMatrix class.
 
 bool
@@ -143,7 +144,9 @@
 SparseBoolMatrix::any (int dim) const
 {
   Sparse<bool> retval;
-  octave_idx_type nr = rows (), nc = cols (), nz = nnz ();
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+  octave_idx_type nz = nnz ();
   if (dim == -1)
     dim = (nr == 1 && nc != 1) ? 1 : 0;
 
@@ -156,8 +159,8 @@
         retval.xcidx (i+1) = retval.xcidx (i) + (cidx (i+1) > cidx (i));
       octave_idx_type new_nz = retval.xcidx (nc);
       retval.change_capacity (new_nz);
-      fill_or_memset (new_nz, static_cast<octave_idx_type> (0), retval.ridx ());
-      fill_or_memset (new_nz, true, retval.data ());
+      std::fill_n (retval.ridx (), new_nz, static_cast<octave_idx_type> (0));
+      std::fill_n (retval.data (), new_nz, true);
     }
   else if (dim == 1)
     {
@@ -173,7 +176,7 @@
       else
         {
           Array<octave_idx_type> tmp (dim_vector (nz, 1));
-          copy_or_memcpy (nz, ridx (), tmp.fortran_vec ());
+          std::copy (ridx (), ridx () + nz, tmp.fortran_vec ());
           retval = Sparse<bool> (Array<bool> (dim_vector (1, 1), true),
                                  idx_vector (tmp),
                                  idx_vector (static_cast<octave_idx_type> (0)),
@@ -188,7 +191,9 @@
 SparseBoolMatrix::sum (int dim) const
 {
   Sparse<double> retval;
-  octave_idx_type nr = rows (), nc = cols (), nz = nnz ();
+  octave_idx_type nr = rows ();
+  octave_idx_type nc = cols ();
+  octave_idx_type nz = nnz ();
   if (dim == -1)
     dim = (nr == 1 && nc != 1) ? 1 : 0;
 
@@ -200,7 +205,7 @@
         retval.xcidx (i+1) = retval.xcidx (i) + (cidx (i+1) > cidx (i));
       octave_idx_type new_nz = retval.xcidx (nc);
       retval.change_capacity (new_nz);
-      fill_or_memset (new_nz, static_cast<octave_idx_type> (0), retval.ridx ());
+      std::fill_n (retval.ridx (), new_nz, static_cast<octave_idx_type> (0));
       for (octave_idx_type i = 0, k = 0; i < nc; i++)
         {
           octave_idx_type c = cidx (i+1) - cidx (i);
@@ -222,7 +227,7 @@
       else
         {
           Array<octave_idx_type> tmp (dim_vector (nz, 1));
-          copy_or_memcpy (nz, ridx (), tmp.fortran_vec ());
+          std::copy (ridx (), ridx () + nz, tmp.fortran_vec ());
           retval = Sparse<double> (Array<double> (dim_vector (1, 1), 1.0),
                                    idx_vector (tmp),
                                    idx_vector (static_cast<octave_idx_type> (0)),
--- a/liboctave/array/boolSparse.h	Fri Feb 06 08:31:09 2015 -0800
+++ b/liboctave/array/boolSparse.h	Fri Feb 06 08:31:49 2015 -0800
@@ -26,7 +26,12 @@
 
 #include "Sparse.h"
 #include "MSparse-defs.h"
-#include "Sparse-op-defs.h"
+
+#include "boolMatrix.h"
+#include "boolNDArray.h"
+#include "PermMatrix.h"
+
+#include "Sparse-op-decls.h"
 
 class SparseMatrix;
 
--- a/liboctave/array/chMatrix.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/liboctave/array/chMatrix.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -39,55 +39,6 @@
 
 // charMatrix class.
 
-charMatrix::charMatrix (char c)
-  : Array<char> ()
-{
-  octave_idx_type nc = 1;
-  octave_idx_type nr = 1;
-
-  resize (nr, nc);
-
-  elem (0, 0) = c;
-}
-
-charMatrix::charMatrix (const char *s)
-  : Array<char> ()
-{
-  octave_idx_type nc = s ? strlen (s) : 0;
-  octave_idx_type nr = s && nc > 0 ? 1 : 0;
-
-  resize (nr, nc);
-
-  for (octave_idx_type i = 0; i < nc; i++)
-    elem (0, i) = s[i];
-}
-
-charMatrix::charMatrix (const std::string& s)
-  : Array<char> ()
-{
-  octave_idx_type nc = s.length ();
-  octave_idx_type nr = nc > 0 ? 1 : 0;
-
-  resize (nr, nc);
-
-  for (octave_idx_type i = 0; i < nc; i++)
-    elem (0, i) = s[i];
-}
-
-charMatrix::charMatrix (const string_vector& s, char fill_value)
-  : Array<char> (dim_vector (s.length (), s.max_length ()), fill_value)
-{
-  octave_idx_type nr = rows ();
-
-  for (octave_idx_type i = 0; i < nr; i++)
-    {
-      const std::string si = s(i);
-      octave_idx_type nc = si.length ();
-      for (octave_idx_type j = 0; j < nc; j++)
-        elem (i, j) = si[j];
-    }
-}
-
 bool
 charMatrix::operator == (const charMatrix& a) const
 {
@@ -185,26 +136,6 @@
   return result;
 }
 
-charMatrix
-charMatrix::diag (octave_idx_type k) const
-{
-  return Array<char>::diag (k);
-}
-
-// FIXME: Do these really belong here?  Maybe they should be in a base class?
-
-boolMatrix
-charMatrix::all (int dim) const
-{
-  return do_mx_red_op<bool, char> (*this, dim, mx_inline_all);
-}
-
-boolMatrix
-charMatrix::any (int dim) const
-{
-  return do_mx_red_op<bool, char> (*this, dim, mx_inline_any);
-}
-
 MS_CMP_OPS (charMatrix, char)
 MS_BOOL_OPS (charMatrix, char)
 
--- a/liboctave/array/chMatrix.h	Fri Feb 06 08:31:09 2015 -0800
+++ b/liboctave/array/chMatrix.h	Fri Feb 06 08:31:49 2015 -0800
@@ -27,6 +27,7 @@
 #include <string>
 
 #include "Array.h"
+#include "chNDArray.h"
 
 #include "mx-defs.h"
 #include "mx-op-decl.h"
@@ -34,41 +35,37 @@
 
 class
 OCTAVE_API
-charMatrix : public Array<char>
+charMatrix : public charNDArray
 {
   friend class ComplexMatrix;
 
 public:
 
-  charMatrix (void) : Array<char> () { }
+  charMatrix (void) : charNDArray () { }
 
   charMatrix (octave_idx_type r, octave_idx_type c)
-    : Array<char> (dim_vector (r, c)) { }
+    : charNDArray (dim_vector (r, c)) { }
 
   charMatrix (octave_idx_type r, octave_idx_type c, char val)
-    : Array<char> (dim_vector (r, c), val) { }
+    : charNDArray (dim_vector (r, c), val) { }
 
-  charMatrix (const dim_vector& dv) : Array<char> (dv) { }
-
-  charMatrix (const dim_vector& dv, char val) : Array<char> (dv, val) { }
+  charMatrix (const dim_vector& dv) : charNDArray (dv.redim (2)) { }
 
-  charMatrix (const Array<char>& a) : Array<char> (a.as_matrix ()) { }
+  charMatrix (const dim_vector& dv, char val)
+    : charNDArray (dv.redim (2), val) { }
 
-  charMatrix (const charMatrix& a) : Array<char> (a) { }
-
-  charMatrix (char c);
+  charMatrix (const Array<char>& a) : charNDArray (a.as_matrix ()) { }
 
-  charMatrix (const char *s);
+  charMatrix (const charMatrix& a) : charNDArray (a) { }
 
-  charMatrix (const std::string& s);
-
-  charMatrix (const string_vector& s, char fill_value = '\0');
+  charMatrix (char c) : charNDArray (c) {}
 
-  charMatrix& operator = (const charMatrix& a)
-  {
-    Array<char>::operator = (a);
-    return *this;
-  }
+  charMatrix (const char *s) : charNDArray (s) {}
+
+  charMatrix (const std::string& s) : charNDArray (s) {}
+
+  charMatrix (const string_vector& s, char fill_value = '\0')
+    : charNDArray (s, fill_value) {}
 
   bool operator == (const charMatrix& a) const;
   bool operator != (const charMatrix& a) const;
@@ -93,11 +90,6 @@
     Array<char>::resize (dim_vector (nr, nc), rfv);
   }
 
-  charMatrix diag (octave_idx_type k = 0) const;
-
-  boolMatrix all (int dim = -1) const;
-  boolMatrix any (int dim = -1) const;
-
 #if 0
   // i/o
 
--- a/liboctave/array/chNDArray.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/liboctave/array/chNDArray.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -25,15 +25,64 @@
 #include <config.h>
 #endif
 
+#include <string>
+
 #include "Array-util.h"
 #include "chNDArray.h"
 #include "mx-base.h"
 #include "lo-ieee.h"
 #include "lo-mappers.h"
 #include "mx-op-defs.h"
+#include "str-vec.h"
 
 #include "bsxfun-defs.cc"
 
+charNDArray::charNDArray (char c)
+  : Array<char> ()
+{
+  octave_idx_type n = 1;
+
+  resize1 (n);
+
+  elem (0) = c;
+}
+
+charNDArray::charNDArray (const char *s)
+  : Array<char> ()
+{
+  octave_idx_type n = s ? strlen (s) : 0;
+
+  resize1 (n);
+
+  for (octave_idx_type i = 0; i < n; i++)
+    elem (i) = s[i];
+}
+
+charNDArray::charNDArray (const std::string& s)
+  : Array<char> ()
+{
+  octave_idx_type n = s.length ();
+
+  resize1 (n);
+
+  for (octave_idx_type i = 0; i < n; i++)
+    elem (i) = s[i];
+}
+
+charNDArray::charNDArray (const string_vector& s, char fill_value)
+  : Array<char> (dim_vector (s.length (), s.max_length ()), fill_value)
+{
+  octave_idx_type nr = rows ();
+
+  for (octave_idx_type i = 0; i < nr; i++)
+    {
+      const std::string si = s(i);
+      octave_idx_type nc = si.length ();
+      for (octave_idx_type j = 0; j < nc; j++)
+        elem (i, j) = si[j];
+    }
+}
+
 // FIXME: this is not quite the right thing.
 
 boolNDArray
@@ -130,12 +179,6 @@
   return *this;
 }
 
-charMatrix
-charNDArray::matrix_value (void) const
-{
-  return *this;
-}
-
 void
 charNDArray::increment_index (Array<octave_idx_type>& ra_idx,
                               const dim_vector& dimensions,
--- a/liboctave/array/chNDArray.h	Fri Feb 06 08:31:09 2015 -0800
+++ b/liboctave/array/chNDArray.h	Fri Feb 06 08:31:49 2015 -0800
@@ -23,12 +23,14 @@
 #if !defined (octave_chNDArray_h)
 #define octave_chNDArray_h 1
 
+#include <string>
+
 #include "Array.h"
-#include "chMatrix.h"
 
 #include "mx-defs.h"
 #include "mx-op-decl.h"
 #include "bsxfun-decl.h"
+#include "str-vec.h"
 
 class
 OCTAVE_API
@@ -46,17 +48,15 @@
 
   charNDArray (const charNDArray& a) : Array<char> (a) { }
 
-  charNDArray (const charMatrix& a) : Array<char> (a) { }
+  charNDArray (const Array<char>& a) : Array<char> (a) { }
 
-  charNDArray (char c) : Array<char> (charMatrix (c)) { }
-
-  charNDArray (const char *s) : Array<char> (charMatrix (s)) { }
+  charNDArray (char c);
 
-  charNDArray (const std::string& s) : Array<char> (charMatrix (s)) { }
+  charNDArray (const char *s);
 
-  charNDArray (const string_vector& s) : Array<char> (charMatrix (s)) { }
+  charNDArray (const std::string& s);
 
-  charNDArray (const Array<char>& a) : Array<char> (a) { }
+  charNDArray (const string_vector& s, char fill_value = '\0');
 
   charNDArray& operator = (const charNDArray& a)
   {
@@ -84,8 +84,6 @@
   charNDArray& insert (const charNDArray& a,
                        const Array<octave_idx_type>& ra_idx);
 
-  charMatrix matrix_value (void) const;
-
   charNDArray squeeze (void) const { return Array<char>::squeeze (); }
 
   static void increment_index (Array<octave_idx_type>& ra_idx,
--- a/liboctave/array/dDiagMatrix.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/liboctave/array/dDiagMatrix.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -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;
@@ -329,7 +330,8 @@
 
   DiagMatrix c (a_nr, b_nc);
 
-  octave_idx_type len = c.length (), lenm = len < a_nc ? len : a_nc;
+  octave_idx_type len = c.length ();
+  octave_idx_type lenm = len < a_nc ? len : a_nc;
 
   for (octave_idx_type i = 0; i < lenm; i++)
     c.dgxelem (i) = a.dgelem (i) * b.dgelem (i);
@@ -364,7 +366,8 @@
 DiagMatrix::rcond (void) const
 {
   ColumnVector av = extract_diag (0).map<double> (fabs);
-  double amx = av.max (), amn = av.min ();
+  double amx = av.max ();
+  double amn = av.min ();
   return amx == 0 ? 0.0 : amn / amx;
 }
 
--- a/liboctave/array/dDiagMatrix.h	Fri Feb 06 08:31:09 2015 -0800
+++ b/liboctave/array/dDiagMatrix.h	Fri Feb 06 08:31:49 2015 -0800
@@ -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 Feb 06 08:31:09 2015 -0800
+++ b/liboctave/array/dMatrix.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -34,8 +34,15 @@
 
 #include "Array-util.h"
 #include "byte-swap.h"
+#include "boolMatrix.h"
+#include "chMatrix.h"
 #include "dMatrix.h"
-#include "dbleAEPBAL.h"
+#include "dDiagMatrix.h"
+#include "CMatrix.h"
+#include "dColVector.h"
+#include "dRowVector.h"
+#include "CColVector.h"
+#include "PermMatrix.h"
 #include "DET.h"
 #include "dbleSCHUR.h"
 #include "dbleSVD.h"
@@ -47,7 +54,6 @@
 #include "lo-ieee.h"
 #include "lo-mappers.h"
 #include "lo-utils.h"
-#include "mx-base.h"
 #include "mx-m-dm.h"
 #include "mx-dm-m.h"
 #include "mx-inlines.cc"
@@ -240,44 +246,54 @@
 // Matrix class.
 
 Matrix::Matrix (const RowVector& rv)
-  : MArray<double> (rv)
+  : NDArray (rv)
 {
 }
 
 Matrix::Matrix (const ColumnVector& cv)
-  : MArray<double> (cv)
+  : NDArray (cv)
 {
 }
 
 Matrix::Matrix (const DiagMatrix& a)
-  : MArray<double> (a.dims (), 0.0)
+  : NDArray (a.dims (), 0.0)
+{
+  for (octave_idx_type i = 0; i < a.length (); i++)
+    elem (i, i) = a.elem (i, i);
+}
+
+Matrix::Matrix (const MDiagArray2<double>& a)
+  : NDArray (a.dims (), 0.0)
+{
+  for (octave_idx_type i = 0; i < a.length (); i++)
+    elem (i, i) = a.elem (i, i);
+}
+
+Matrix::Matrix (const DiagArray2<double>& a)
+  : NDArray (a.dims (), 0.0)
 {
   for (octave_idx_type i = 0; i < a.length (); i++)
     elem (i, i) = a.elem (i, i);
 }
 
 Matrix::Matrix (const PermMatrix& a)
-  : MArray<double> (a.dims (), 0.0)
+  : NDArray (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?
 
 Matrix::Matrix (const boolMatrix& a)
-  : MArray<double> (a)
+  : NDArray (a)
 {
 }
 
 Matrix::Matrix (const charMatrix& a)
-  : MArray<double> (a.dims ())
+  : NDArray (a.dims ())
 {
   for (octave_idx_type i = 0; i < a.rows (); i++)
     for (octave_idx_type j = 0; j < a.cols (); j++)
@@ -1382,7 +1398,7 @@
 double
 Matrix::rcond (MatrixType &mattype) const
 {
-  double rcon;
+  double rcon = octave_NaN;
   octave_idx_type nr = rows ();
   octave_idx_type nc = cols ();
 
@@ -1577,11 +1593,27 @@
             {
               const double *tmp_data = fortran_vec ();
 
+              retval = b;
+              double *result = retval.fortran_vec ();
+
+              char uplo = 'U';
+              char trans = get_blas_char (transt);
+              char dia = 'N';
+
+              F77_XFCN (dtrtrs, DTRTRS, (F77_CONST_CHAR_ARG2 (&uplo, 1),
+                                         F77_CONST_CHAR_ARG2 (&trans, 1),
+                                         F77_CONST_CHAR_ARG2 (&dia, 1),
+                                         nr, b_nc, tmp_data, nr,
+                                         result, nr, info
+                                         F77_CHAR_ARG_LEN (1)
+                                         F77_CHAR_ARG_LEN (1)
+                                         F77_CHAR_ARG_LEN (1)));
+
               if (calc_cond)
                 {
                   char norm = '1';
-                  char uplo = 'U';
-                  char dia = 'N';
+                  uplo = 'U';
+                  dia = 'N';
 
                   Array<double> z (dim_vector (3 * nc, 1));
                   double *pz = z.fortran_vec ();
@@ -1609,30 +1641,9 @@
                       if (sing_handler)
                         sing_handler (rcon);
                       else
-                        (*current_liboctave_error_handler)
-                          ("matrix singular to machine precision, rcond = %g",
-                           rcon);
+                        gripe_singular_matrix (rcon);
                     }
                 }
-
-              if (info == 0)
-                {
-                  retval = b;
-                  double *result = retval.fortran_vec ();
-
-                  char uplo = 'U';
-                  char trans = get_blas_char (transt);
-                  char dia = 'N';
-
-                  F77_XFCN (dtrtrs, DTRTRS, (F77_CONST_CHAR_ARG2 (&uplo, 1),
-                                             F77_CONST_CHAR_ARG2 (&trans, 1),
-                                             F77_CONST_CHAR_ARG2 (&dia, 1),
-                                             nr, b_nc, tmp_data, nr,
-                                             result, nr, info
-                                             F77_CHAR_ARG_LEN (1)
-                                             F77_CHAR_ARG_LEN (1)
-                                             F77_CHAR_ARG_LEN (1)));
-                }
             }
         }
       else
@@ -1677,11 +1688,27 @@
             {
               const double *tmp_data = fortran_vec ();
 
+              retval = b;
+              double *result = retval.fortran_vec ();
+
+              char uplo = 'L';
+              char trans = get_blas_char (transt);
+              char dia = 'N';
+
+              F77_XFCN (dtrtrs, DTRTRS, (F77_CONST_CHAR_ARG2 (&uplo, 1),
+                                         F77_CONST_CHAR_ARG2 (&trans, 1),
+                                         F77_CONST_CHAR_ARG2 (&dia, 1),
+                                         nr, b_nc, tmp_data, nr,
+                                         result, nr, info
+                                         F77_CHAR_ARG_LEN (1)
+                                         F77_CHAR_ARG_LEN (1)
+                                         F77_CHAR_ARG_LEN (1)));
+
               if (calc_cond)
                 {
                   char norm = '1';
-                  char uplo = 'L';
-                  char dia = 'N';
+                  uplo = 'L';
+                  dia = 'N';
 
                   Array<double> z (dim_vector (3 * nc, 1));
                   double *pz = z.fortran_vec ();
@@ -1709,30 +1736,9 @@
                       if (sing_handler)
                         sing_handler (rcon);
                       else
-                        (*current_liboctave_error_handler)
-                          ("matrix singular to machine precision, rcond = %g",
-                           rcon);
+                        gripe_singular_matrix (rcon);
                     }
                 }
-
-              if (info == 0)
-                {
-                  retval = b;
-                  double *result = retval.fortran_vec ();
-
-                  char uplo = 'L';
-                  char trans = get_blas_char (transt);
-                  char dia = 'N';
-
-                  F77_XFCN (dtrtrs, DTRTRS, (F77_CONST_CHAR_ARG2 (&uplo, 1),
-                                             F77_CONST_CHAR_ARG2 (&trans, 1),
-                                             F77_CONST_CHAR_ARG2 (&dia, 1),
-                                             nr, b_nc, tmp_data, nr,
-                                             result, nr, info
-                                             F77_CHAR_ARG_LEN (1)
-                                             F77_CHAR_ARG_LEN (1)
-                                             F77_CHAR_ARG_LEN (1)));
-                }
             }
         }
       else
@@ -1813,9 +1819,7 @@
                       if (sing_handler)
                         sing_handler (rcon);
                       else
-                        (*current_liboctave_error_handler)
-                          ("matrix singular to machine precision, rcond = %g",
-                           rcon);
+                        gripe_singular_matrix (rcon);
                     }
                 }
 
@@ -1868,8 +1872,7 @@
               if (sing_handler)
                 sing_handler (rcon);
               else
-                (*current_liboctave_error_handler)
-                  ("matrix singular to machine precision");
+                gripe_singular_matrix ();
 
               mattype.mark_as_rectangular ();
             }
@@ -1897,9 +1900,7 @@
                       if (sing_handler)
                         sing_handler (rcon);
                       else
-                        (*current_liboctave_error_handler)
-                          ("matrix singular to machine precision, rcond = %g",
-                           rcon);
+                        gripe_singular_matrix (rcon);
                     }
                 }
 
@@ -1962,9 +1963,9 @@
 
   // Only calculate the condition number for LU/Cholesky
   if (typ == MatrixType::Upper || typ == MatrixType::Permuted_Upper)
-    retval = utsolve (mattype, b, info, rcon, sing_handler, false, transt);
+    retval = utsolve (mattype, b, info, rcon, sing_handler, true, transt);
   else if (typ == MatrixType::Lower || typ == MatrixType::Permuted_Lower)
-    retval = ltsolve (mattype, b, info, rcon, sing_handler, false, transt);
+    retval = ltsolve (mattype, b, info, rcon, sing_handler, true, transt);
   else if (transt == blas_trans || transt == blas_conj_trans)
     return transpose ().solve (mattype, b, info, rcon, sing_handler,
                                singular_fallback);
@@ -2012,7 +2013,9 @@
 static Matrix
 stack_complex_matrix (const ComplexMatrix& cm)
 {
-  octave_idx_type m = cm.rows (), n = cm.cols (), nel = m*n;
+  octave_idx_type m = cm.rows ();
+  octave_idx_type n = cm.cols ();
+  octave_idx_type nel = m*n;
   Matrix retval (m, 2*n);
   const Complex *cmd = cm.data ();
   double *rd = retval.fortran_vec ();
@@ -2027,7 +2030,9 @@
 static ComplexMatrix
 unstack_complex_matrix (const Matrix& sm)
 {
-  octave_idx_type m = sm.rows (), n = sm.cols () / 2, nel = m*n;
+  octave_idx_type m = sm.rows ();
+  octave_idx_type n = sm.cols () / 2;
+  octave_idx_type nel = m*n;
   ComplexMatrix retval (m, n);
   const double *smd = sm.data ();
   Complex *rd = retval.fortran_vec ();
@@ -2626,15 +2631,6 @@
 
 // unary operations
 
-boolMatrix
-Matrix::operator ! (void) const
-{
-  if (any_element_is_nan ())
-    gripe_nan_to_logical_conversion ();
-
-  return do_mx_unary_op<bool, double> (*this, mx_inline_not);
-}
-
 // column vector by row vector -> matrix operations
 
 Matrix
@@ -2664,137 +2660,60 @@
 
 // other operations.
 
-bool
-Matrix::any_element_is_negative (bool neg_zero) const
-{
-  return (neg_zero ? test_all (xnegative_sign)
-          : do_mx_check<double> (*this, mx_inline_any_negative));
-}
-
-bool
-Matrix::any_element_is_positive (bool neg_zero) const
-{
-  return (neg_zero ? test_all (xpositive_sign)
-          : do_mx_check<double> (*this, mx_inline_any_positive));
-}
-
-bool
-Matrix::any_element_is_nan (void) const
-{
-  return do_mx_check<double> (*this, mx_inline_any_nan);
-}
-
-bool
-Matrix::any_element_is_inf_or_nan (void) const
-{
-  return ! do_mx_check<double> (*this, mx_inline_all_finite);
-}
-
-bool
-Matrix::any_element_not_one_or_zero (void) const
-{
-  return ! test_all (xis_one_or_zero);
-}
-
-bool
-Matrix::all_elements_are_int_or_inf_or_nan (void) const
-{
-  return test_all (xis_int_or_inf_or_nan);
-}
-
-// Return nonzero if any element of M is not an integer.  Also extract
-// the largest and smallest values and return them in MAX_VAL and MIN_VAL.
-
-bool
-Matrix::all_integers (double& max_val, double& min_val) const
-{
-  octave_idx_type nel = nelem ();
-
-  if (nel > 0)
-    {
-      max_val = elem (0);
-      min_val = elem (0);
-    }
-  else
-    return false;
-
-  for (octave_idx_type i = 0; i < nel; i++)
-    {
-      double val = elem (i);
-
-      if (val > max_val)
-        max_val = val;
-
-      if (val < min_val)
-        min_val = val;
-
-      if (! xisinteger (val))
-        return false;
-    }
-
-  return true;
-}
-
-bool
-Matrix::too_large_for_float (void) const
-{
-  return test_any (xtoo_large_for_float);
-}
-
 // FIXME: Do these really belong here?  Maybe they should be in a base class?
 
 boolMatrix
 Matrix::all (int dim) const
 {
-  return do_mx_red_op<bool, double> (*this, dim, mx_inline_all);
+  return NDArray::all (dim);
 }
 
 boolMatrix
 Matrix::any (int dim) const
 {
-  return do_mx_red_op<bool, double> (*this, dim, mx_inline_any);
+  return NDArray::any (dim);
 }
 
 Matrix
 Matrix::cumprod (int dim) const
 {
-  return do_mx_cum_op<double, double> (*this, dim, mx_inline_cumprod);
+  return NDArray::cumprod (dim);
 }
 
 Matrix
 Matrix::cumsum (int dim) const
 {
-  return do_mx_cum_op<double, double> (*this, dim, mx_inline_cumsum);
+  return NDArray::cumsum (dim);
 }
 
 Matrix
 Matrix::prod (int dim) const
 {
-  return do_mx_red_op<double, double> (*this, dim, mx_inline_prod);
+  return NDArray::prod (dim);
 }
 
 Matrix
 Matrix::sum (int dim) const
 {
-  return do_mx_red_op<double, double> (*this, dim, mx_inline_sum);
+  return NDArray::sum (dim);
 }
 
 Matrix
 Matrix::sumsq (int dim) const
 {
-  return do_mx_red_op<double, double> (*this, dim, mx_inline_sumsq);
+  return NDArray::sumsq (dim);
 }
 
 Matrix
 Matrix::abs (void) const
 {
-  return do_mx_unary_map<double, double, std::abs> (*this);
+  return NDArray::abs ();
 }
 
 Matrix
 Matrix::diag (octave_idx_type k) const
 {
-  return MArray<double>::diag (k);
+  return NDArray::diag (k);
 }
 
 DiagMatrix
@@ -3135,7 +3054,7 @@
 
   // FIXME: check info?
 
-  retval = -ua*cx*ub.transpose ();
+  retval = ua*cx*ub.transpose ();
 
   return retval;
 }
@@ -3180,7 +3099,8 @@
 {
   Matrix retval;
 
-  bool tra = transa != blas_no_trans, trb = transb != blas_no_trans;
+  bool tra = transa != blas_no_trans;
+  bool trb = transb != blas_no_trans;
 
   octave_idx_type a_nr = tra ? a.cols () : a.rows ();
   octave_idx_type a_nc = tra ? a.rows () : a.cols ();
@@ -3215,8 +3135,10 @@
         }
       else
         {
-          octave_idx_type lda = a.rows (), tda = a.cols ();
-          octave_idx_type ldb = b.rows (), tdb = b.cols ();
+          octave_idx_type lda = a.rows ();
+          octave_idx_type tda = a.cols ();
+          octave_idx_type ldb = b.rows ();
+          octave_idx_type tdb = b.cols ();
 
           retval = Matrix (a_nr, b_nc);
           double *c = retval.fortran_vec ();
@@ -3285,7 +3207,7 @@
     for (octave_idx_type i = 0; i < nr; i++)
       {
         octave_quit ();
-        result (i, j) = xmin (d, m (i, j));
+        result(i, j) = xmin (d, m(i, j));
       }
 
   return result;
@@ -3305,7 +3227,7 @@
     for (octave_idx_type i = 0; i < nr; i++)
       {
         octave_quit ();
-        result (i, j) = xmin (m (i, j), d);
+        result(i, j) = xmin (m(i, j), d);
       }
 
   return result;
@@ -3332,7 +3254,7 @@
     for (octave_idx_type i = 0; i < nr; i++)
       {
         octave_quit ();
-        result (i, j) = xmin (a (i, j), b (i, j));
+        result(i, j) = xmin (a(i, j), b(i, j));
       }
 
   return result;
@@ -3352,7 +3274,7 @@
     for (octave_idx_type i = 0; i < nr; i++)
       {
         octave_quit ();
-        result (i, j) = xmax (d, m (i, j));
+        result(i, j) = xmax (d, m(i, j));
       }
 
   return result;
@@ -3372,7 +3294,7 @@
     for (octave_idx_type i = 0; i < nr; i++)
       {
         octave_quit ();
-        result (i, j) = xmax (m (i, j), d);
+        result(i, j) = xmax (m(i, j), d);
       }
 
   return result;
@@ -3399,7 +3321,7 @@
     for (octave_idx_type i = 0; i < nr; i++)
       {
         octave_quit ();
-        result (i, j) = xmax (a (i, j), b (i, j));
+        result(i, j) = xmax (a(i, j), b(i, j));
       }
 
   return result;
--- a/liboctave/array/dMatrix.h	Fri Feb 06 08:31:09 2015 -0800
+++ b/liboctave/array/dMatrix.h	Fri Feb 06 08:31:49 2015 -0800
@@ -23,6 +23,7 @@
 #if !defined (octave_dMatrix_h)
 #define octave_dMatrix_h 1
 
+#include "dNDArray.h"
 #include "MArray.h"
 #include "MDiagArray2.h"
 #include "MatrixType.h"
@@ -33,7 +34,7 @@
 
 class
 OCTAVE_API
-Matrix : public MArray<double>
+Matrix : public NDArray
 {
 public:
 
@@ -42,26 +43,26 @@
 
   typedef void (*solve_singularity_handler) (double rcon);
 
-  Matrix (void) : MArray<double> () { }
+  Matrix (void) : NDArray () { }
 
   Matrix (octave_idx_type r, octave_idx_type c)
-    : MArray<double> (dim_vector (r, c)) { }
+    : NDArray (dim_vector (r, c)) { }
 
   Matrix (octave_idx_type r, octave_idx_type c, double val)
-    : MArray<double> (dim_vector (r, c), val) { }
+    : NDArray (dim_vector (r, c), val) { }
 
-  Matrix (const dim_vector& dv) : MArray<double> (dv.redim (2)) { }
+  Matrix (const dim_vector& dv) : NDArray (dv.redim (2)) { }
 
   Matrix (const dim_vector& dv, double val)
-    : MArray<double> (dv.redim (2), val) { }
+    : NDArray (dv.redim (2), val) { }
 
-  Matrix (const Matrix& a) : MArray<double> (a) { }
+  Matrix (const Matrix& a) : NDArray (a) { }
 
   template <class U>
-  Matrix (const MArray<U>& a) : MArray<double> (a.as_matrix ()) { }
+  Matrix (const MArray<U>& a) : NDArray (a.as_matrix ()) { }
 
   template <class U>
-  Matrix (const Array<U>& a) : MArray<double> (a.as_matrix ()) { }
+  Matrix (const Array<U>& a) : NDArray (a.as_matrix ()) { }
 
   explicit Matrix (const RowVector& rv);
 
@@ -69,18 +70,16 @@
 
   explicit Matrix (const DiagMatrix& a);
 
+  explicit Matrix (const MDiagArray2<double>& a);
+
+  explicit Matrix (const DiagArray2<double>& a);
+
   explicit Matrix (const PermMatrix& a);
 
   explicit Matrix (const boolMatrix& a);
 
   explicit Matrix (const charMatrix& a);
 
-  Matrix& operator = (const Matrix& a)
-  {
-    MArray<double>::operator = (a);
-    return *this;
-  }
-
   bool operator == (const Matrix& a) const;
   bool operator != (const Matrix& a) const;
 
@@ -303,19 +302,8 @@
 
   // unary operations
 
-  boolMatrix operator ! (void) const;
-
   // other operations
 
-  bool any_element_is_negative (bool = false) const;
-  bool any_element_is_positive (bool = false) const;
-  bool any_element_is_nan (void) const;
-  bool any_element_is_inf_or_nan (void) const;
-  bool any_element_not_one_or_zero (void) const;
-  bool all_elements_are_int_or_inf_or_nan (void) const;
-  bool all_integers (double& max_val, double& min_val) const;
-  bool too_large_for_float (void) const;
-
   boolMatrix all (int dim = -1) const;
   boolMatrix any (int dim = -1) const;
 
--- a/liboctave/array/dNDArray.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/liboctave/array/dNDArray.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -257,7 +257,7 @@
   ComplexNDArray retval (dv);
   octave_idx_type npts = dv(dim);
   octave_idx_type nn = 4*npts+15;
-  Array<Complex> wsave (nn);
+  Array<Complex> wsave (dim_vector (nn, 1));
   Complex *pwsave = wsave.fortran_vec ();
 
   OCTAVE_LOCAL_BUFFER (Complex, tmp, npts);
@@ -304,7 +304,7 @@
   ComplexNDArray retval (dv);
   octave_idx_type npts = dv(dim);
   octave_idx_type nn = 4*npts+15;
-  Array<Complex> wsave (nn);
+  Array<Complex> wsave (dim_vector (nn, 1));
   Complex *pwsave = wsave.fortran_vec ();
 
   OCTAVE_LOCAL_BUFFER (Complex, tmp, npts);
@@ -354,9 +354,9 @@
     {
       octave_idx_type npts = dv2(i);
       octave_idx_type nn = 4*npts+15;
-      Array<Complex> wsave (nn);
+      Array<Complex> wsave (dim_vector (nn, 1));
       Complex *pwsave = wsave.fortran_vec ();
-      Array<Complex> row (npts);
+      Array<Complex> row (dim_vector (npts, 1));
       Complex *prow = row.fortran_vec ();
 
       octave_idx_type howmany = numel () / npts;
@@ -402,9 +402,9 @@
     {
       octave_idx_type npts = dv2(i);
       octave_idx_type nn = 4*npts+15;
-      Array<Complex> wsave (nn);
+      Array<Complex> wsave (dim_vector (nn, 1));
       Complex *pwsave = wsave.fortran_vec ();
-      Array<Complex> row (npts);
+      Array<Complex> row (dim_vector (npts, 1));
       Complex *prow = row.fortran_vec ();
 
       octave_idx_type howmany = numel () / npts;
@@ -450,9 +450,9 @@
     {
       octave_idx_type npts = dv(i);
       octave_idx_type nn = 4*npts+15;
-      Array<Complex> wsave (nn);
+      Array<Complex> wsave (dim_vector (nn, 1));
       Complex *pwsave = wsave.fortran_vec ();
-      Array<Complex> row (npts);
+      Array<Complex> row (dim_vector (npts, 1));
       Complex *prow = row.fortran_vec ();
 
       octave_idx_type howmany = numel () / npts;
@@ -497,9 +497,9 @@
     {
       octave_idx_type npts = dv(i);
       octave_idx_type nn = 4*npts+15;
-      Array<Complex> wsave (nn);
+      Array<Complex> wsave (dim_vector (nn, 1));
       Complex *pwsave = wsave.fortran_vec ();
-      Array<Complex> row (npts);
+      Array<Complex> row (dim_vector (npts, 1));
       Complex *prow = row.fortran_vec ();
 
       octave_idx_type howmany = numel () / npts;
@@ -841,20 +841,6 @@
   return do_mx_unary_map<bool, double, xfinite> (*this);
 }
 
-Matrix
-NDArray::matrix_value (void) const
-{
-  Matrix retval;
-
-  if (ndims () == 2)
-    retval = Matrix (Array<double> (*this));
-  else
-    (*current_liboctave_error_handler)
-      ("invalid conversion of NDArray to Matrix");
-
-  return retval;
-}
-
 void
 NDArray::increment_index (Array<octave_idx_type>& ra_idx,
                           const dim_vector& dimensions,
--- a/liboctave/array/dNDArray.h	Fri Feb 06 08:31:09 2015 -0800
+++ b/liboctave/array/dNDArray.h	Fri Feb 06 08:31:49 2015 -0800
@@ -24,7 +24,6 @@
 #define octave_dNDArray_h 1
 
 #include "MArray.h"
-#include "dMatrix.h"
 #include "intNDArray.h"
 
 #include "mx-defs.h"
@@ -37,8 +36,6 @@
 {
 public:
 
-  typedef Matrix matrix_type;
-
   NDArray (void) : MArray<double> () { }
 
   NDArray (const dim_vector& dv) : MArray<double> (dv) { }
@@ -48,8 +45,6 @@
 
   NDArray (const NDArray& a) : MArray<double> (a) { }
 
-  NDArray (const Matrix& a) : MArray<double> (a) { }
-
   NDArray (const Array<octave_idx_type>& a, bool zero_based = false,
            bool negative_to_nan = false);
 
@@ -141,8 +136,6 @@
 
   friend class ComplexNDArray;
 
-  Matrix matrix_value (void) const;
-
   NDArray squeeze (void) const { return MArray<double>::squeeze (); }
 
   static void increment_index (Array<octave_idx_type>& ra_idx,
--- a/liboctave/array/dSparse.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/liboctave/array/dSparse.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -52,6 +52,8 @@
 #include "SparsedbleCHOL.h"
 #include "SparseQR.h"
 
+#include "Sparse-op-defs.h"
+
 #include "Sparse-diag-op-defs.h"
 
 #include "Sparse-perm-op-defs.h"
@@ -165,7 +167,8 @@
 SparseMatrix::SparseMatrix (const DiagMatrix& a)
   : MSparse<double> (a.rows (), a.cols (), a.length ())
 {
-  octave_idx_type j = 0, l = a.length ();
+  octave_idx_type j = 0;
+  octave_idx_type l = a.length ();
   for (octave_idx_type i = 0; i < l; i++)
     {
       cidx (i) = j;
@@ -360,7 +363,7 @@
         found[i] = 0;
 
       for (octave_idx_type j = 0; j < nc; j++)
-        for (octave_idx_type i = cidx(j); i < cidx(j+1); i++)
+        for (octave_idx_type i = cidx (j); i < cidx (j+1); i++)
           if (found[ridx (i)] == -j)
             found[ridx (i)] = -j - 1;
 
@@ -511,7 +514,7 @@
         found[i] = 0;
 
       for (octave_idx_type j = 0; j < nc; j++)
-        for (octave_idx_type i = cidx(j); i < cidx(j+1); i++)
+        for (octave_idx_type i = cidx (j); i < cidx (j+1); i++)
           if (found[ridx (i)] == -j)
             found[ridx (i)] = -j - 1;
 
@@ -776,7 +779,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) ||
@@ -788,8 +791,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;
@@ -877,7 +880,8 @@
 
           if (calccond)
             {
-              double dmax = 0., dmin = octave_Inf;
+              double dmax = 0.;
+              double dmin = octave_Inf;
               for (octave_idx_type i = 0; i < nr; i++)
                 {
                   double tmp = fabs (v[i]);
@@ -1214,7 +1218,6 @@
             {
               // Matrix is either singular or not positive definite
               mattype.mark_as_unsymmetric ();
-              typ = MatrixType::Full;
             }
         }
 
@@ -1412,7 +1415,8 @@
 
           if (calc_cond)
             {
-              double dmax = 0., dmin = octave_Inf;
+              double dmax = 0.;
+              double dmin = octave_Inf;
               for (octave_idx_type i = 0; i < nm; i++)
                 {
                   double tmp = fabs (data (i));
@@ -1502,7 +1506,8 @@
 
           if (calc_cond)
             {
-              double dmax = 0., dmin = octave_Inf;
+              double dmax = 0.;
+              double dmin = octave_Inf;
               for (octave_idx_type i = 0; i < nm; i++)
                 {
                   double tmp = fabs (data (i));
@@ -1562,7 +1567,8 @@
 
           if (calc_cond)
             {
-              double dmax = 0., dmin = octave_Inf;
+              double dmax = 0.;
+              double dmin = octave_Inf;
               for (octave_idx_type i = 0; i < nm; i++)
                 {
                   double tmp = fabs (data (i));
@@ -1652,7 +1658,8 @@
 
           if (calc_cond)
             {
-              double dmax = 0., dmin = octave_Inf;
+              double dmax = 0.;
+              double dmin = octave_Inf;
               for (octave_idx_type i = 0; i < nm; i++)
                 {
                   double tmp = fabs (data (i));
@@ -1879,9 +1886,7 @@
                   mattype.mark_as_rectangular ();
                 }
               else
-                (*current_liboctave_error_handler)
-                  ("SparseMatrix::solve matrix singular to machine precision, rcond = %g",
-                   rcond);
+                gripe_singular_matrix (rcond);
             }
 
           volatile double rcond_plus_one = rcond + 1.0;
@@ -1896,9 +1901,7 @@
                   mattype.mark_as_rectangular ();
                 }
               else
-                (*current_liboctave_error_handler)
-                  ("matrix singular to machine precision, rcond = %g",
-                   rcond);
+                gripe_singular_matrix (rcond);
             }
         }
       else
@@ -1999,7 +2002,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++)
@@ -2095,7 +2098,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++)
@@ -2167,9 +2170,7 @@
                   mattype.mark_as_rectangular ();
                 }
               else
-                (*current_liboctave_error_handler)
-                  ("SparseMatrix::solve matrix singular to machine precision, rcond = %g",
-                   rcond);
+                gripe_singular_matrix (rcond);
             }
 
           volatile double rcond_plus_one = rcond + 1.0;
@@ -2184,9 +2185,7 @@
                   mattype.mark_as_rectangular ();
                 }
               else
-                (*current_liboctave_error_handler)
-                  ("matrix singular to machine precision, rcond = %g",
-                   rcond);
+                gripe_singular_matrix (rcond);
             }
         }
       else
@@ -2404,9 +2403,7 @@
                   mattype.mark_as_rectangular ();
                 }
               else
-                (*current_liboctave_error_handler)
-                  ("SparseMatrix::solve matrix singular to machine precision, rcond = %g",
-                   rcond);
+                gripe_singular_matrix (rcond);
             }
 
           volatile double rcond_plus_one = rcond + 1.0;
@@ -2421,9 +2418,7 @@
                   mattype.mark_as_rectangular ();
                 }
               else
-                (*current_liboctave_error_handler)
-                  ("matrix singular to machine precision, rcond = %g",
-                   rcond);
+                gripe_singular_matrix (rcond);
             }
         }
       else
@@ -2524,7 +2519,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++)
@@ -2621,7 +2616,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++)
@@ -2694,9 +2689,7 @@
                   mattype.mark_as_rectangular ();
                 }
               else
-                (*current_liboctave_error_handler)
-                  ("SparseMatrix::solve matrix singular to machine precision, rcond = %g",
-                   rcond);
+                gripe_singular_matrix (rcond);
             }
 
           volatile double rcond_plus_one = rcond + 1.0;
@@ -2711,9 +2704,7 @@
                   mattype.mark_as_rectangular ();
                 }
               else
-                (*current_liboctave_error_handler)
-                  ("matrix singular to machine precision, rcond = %g",
-                   rcond);
+                gripe_singular_matrix (rcond);
             }
         }
       else
@@ -2954,9 +2945,7 @@
                   mattype.mark_as_rectangular ();
                 }
               else
-                (*current_liboctave_error_handler)
-                  ("SparseMatrix::solve matrix singular to machine precision, rcond = %g",
-                   rcond);
+                gripe_singular_matrix (rcond);
             }
 
           volatile double rcond_plus_one = rcond + 1.0;
@@ -2971,9 +2960,7 @@
                   mattype.mark_as_rectangular ();
                 }
               else
-                (*current_liboctave_error_handler)
-                  ("matrix singular to machine precision, rcond = %g",
-                   rcond);
+                gripe_singular_matrix (rcond);
             }
         }
       else
@@ -3079,7 +3066,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++)
@@ -3188,7 +3175,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++)
@@ -3261,9 +3248,7 @@
                   mattype.mark_as_rectangular ();
                 }
               else
-                (*current_liboctave_error_handler)
-                  ("SparseMatrix::solve matrix singular to machine precision, rcond = %g",
-                   rcond);
+                gripe_singular_matrix (rcond);
             }
 
           volatile double rcond_plus_one = rcond + 1.0;
@@ -3278,9 +3263,7 @@
                   mattype.mark_as_rectangular ();
                 }
               else
-                (*current_liboctave_error_handler)
-                  ("matrix singular to machine precision, rcond = %g",
-                   rcond);
+                gripe_singular_matrix (rcond);
             }
         }
       else
@@ -3522,9 +3505,7 @@
                   mattype.mark_as_rectangular ();
                 }
               else
-                (*current_liboctave_error_handler)
-                  ("SparseMatrix::solve matrix singular to machine precision, rcond = %g",
-                   rcond);
+                gripe_singular_matrix (rcond);
             }
 
           volatile double rcond_plus_one = rcond + 1.0;
@@ -3539,9 +3520,7 @@
                   mattype.mark_as_rectangular ();
                 }
               else
-                (*current_liboctave_error_handler)
-                  ("matrix singular to machine precision, rcond = %g",
-                   rcond);
+                gripe_singular_matrix (rcond);
             }
         }
       else
@@ -3647,7 +3626,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++)
@@ -3757,7 +3736,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++)
@@ -3831,9 +3810,7 @@
                   mattype.mark_as_rectangular ();
                 }
               else
-                (*current_liboctave_error_handler)
-                  ("SparseMatrix::solve matrix singular to machine precision, rcond = %g",
-                   rcond);
+                gripe_singular_matrix (rcond);
             }
 
           volatile double rcond_plus_one = rcond + 1.0;
@@ -3848,9 +3825,7 @@
                   mattype.mark_as_rectangular ();
                 }
               else
-                (*current_liboctave_error_handler)
-                  ("matrix singular to machine precision, rcond = %g",
-                   rcond);
+                gripe_singular_matrix (rcond);
             }
         }
       else
@@ -3997,9 +3972,7 @@
                   mattype.mark_as_rectangular ();
                 }
               else
-                (*current_liboctave_error_handler)
-                  ("matrix singular to machine precision");
-
+                gripe_singular_matrix ();
             }
           else
             rcond = 1.;
@@ -4095,9 +4068,7 @@
                   mattype.mark_as_rectangular ();
                 }
               else
-                (*current_liboctave_error_handler)
-                  ("matrix singular to machine precision");
-
+                gripe_singular_matrix ();
             }
           else
             {
@@ -4124,7 +4095,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++)
@@ -4299,8 +4270,7 @@
                   mattype.mark_as_rectangular ();
                 }
               else
-                (*current_liboctave_error_handler)
-                  ("matrix singular to machine precision");
+                gripe_singular_matrix ();
             }
         }
       else if (typ != MatrixType::Tridiagonal_Hermitian)
@@ -4394,8 +4364,7 @@
                   mattype.mark_as_rectangular ();
                 }
               else
-                (*current_liboctave_error_handler)
-                  ("matrix singular to machine precision");
+                gripe_singular_matrix ();
             }
           else
             {
@@ -4406,7 +4375,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;
@@ -4418,7 +4387,7 @@
 
                   for (octave_idx_type i = 0; i < b_nr; i++)
                     {
-                      Complex c = b (i,j);
+                      Complex c = b(i,j);
                       Bx[i] = std::real (c);
                       Bz[i] = std::imag (c);
                     }
@@ -4453,7 +4422,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++)
@@ -4585,9 +4554,7 @@
                           mattype.mark_as_rectangular ();
                         }
                       else
-                        (*current_liboctave_error_handler)
-                          ("matrix singular to machine precision, rcond = %g",
-                           rcond);
+                        gripe_singular_matrix (rcond);
                     }
                 }
               else
@@ -4640,7 +4607,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++)
@@ -4672,9 +4639,7 @@
                   mattype.mark_as_rectangular ();
                 }
               else
-                (*current_liboctave_error_handler)
-                  ("matrix singular to machine precision");
-
+                gripe_singular_matrix ();
             }
           else
             {
@@ -4707,9 +4672,7 @@
                           mattype.mark_as_rectangular ();
                         }
                       else
-                        (*current_liboctave_error_handler)
-                          ("matrix singular to machine precision, rcond = %g",
-                           rcond);
+                        gripe_singular_matrix (rcond);
                     }
                 }
               else
@@ -4833,9 +4796,7 @@
                           mattype.mark_as_rectangular ();
                         }
                       else
-                        (*current_liboctave_error_handler)
-                          ("matrix singular to machine precision, rcond = %g",
-                           rcond);
+                        gripe_singular_matrix (rcond);
                     }
                 }
               else
@@ -4847,7 +4808,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;
@@ -4953,9 +4914,7 @@
                   mattype.mark_as_rectangular ();
                 }
               else
-                (*current_liboctave_error_handler)
-                  ("matrix singular to machine precision");
-
+                gripe_singular_matrix ();
             }
           else
             {
@@ -4988,9 +4947,7 @@
                           mattype.mark_as_rectangular ();
                         }
                       else
-                        (*current_liboctave_error_handler)
-                          ("matrix singular to machine precision, rcond = %g",
-                           rcond);
+                        gripe_singular_matrix (rcond);
                     }
                 }
               else
@@ -5021,7 +4978,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++)
@@ -5153,9 +5110,7 @@
                           mattype.mark_as_rectangular ();
                         }
                       else
-                        (*current_liboctave_error_handler)
-                          ("matrix singular to machine precision, rcond = %g",
-                           rcond);
+                        gripe_singular_matrix (rcond);
                     }
                 }
               else
@@ -5175,7 +5130,7 @@
                     {
                       for (octave_idx_type i = 0; i < b_nr; i++)
                         {
-                          Complex c = b (i,j);
+                          Complex c = b(i,j);
                           Bx[i] = std::real (c);
                           Bz[i] = std::imag (c);
                         }
@@ -5269,9 +5224,7 @@
                   mattype.mark_as_rectangular ();
                 }
               else
-                (*current_liboctave_error_handler)
-                  ("matrix singular to machine precision");
-
+                gripe_singular_matrix ();
             }
           else
             {
@@ -5304,9 +5257,7 @@
                           mattype.mark_as_rectangular ();
                         }
                       else
-                        (*current_liboctave_error_handler)
-                          ("matrix singular to machine precision, rcond = %g",
-                           rcond);
+                        gripe_singular_matrix (rcond);
                     }
                 }
               else
@@ -5325,7 +5276,7 @@
                     {
                       for (octave_idx_type i = 0; i < nr; i++)
                         {
-                          Complex c = b (i, j);
+                          Complex c = b(i, j);
                           Bx[i] = std::real (c);
                           Bz[i] = std::imag  (c);
                         }
@@ -5453,9 +5404,7 @@
                           mattype.mark_as_rectangular ();
                         }
                       else
-                        (*current_liboctave_error_handler)
-                          ("matrix singular to machine precision, rcond = %g",
-                           rcond);
+                        gripe_singular_matrix (rcond);
                     }
                 }
               else
@@ -5468,7 +5417,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;
@@ -5480,7 +5429,7 @@
 
                       for (octave_idx_type i = 0; i < b_nr; i++)
                         {
-                          Complex c = b (i,j);
+                          Complex c = b(i,j);
                           Bx[i] = std::real (c);
                           Bz[i] = std::imag (c);
                         }
@@ -5514,7 +5463,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++)
@@ -5599,9 +5548,7 @@
                   mattype.mark_as_rectangular ();
                 }
               else
-                (*current_liboctave_error_handler)
-                  ("matrix singular to machine precision");
-
+                gripe_singular_matrix ();
             }
           else
             {
@@ -5634,9 +5581,7 @@
                           mattype.mark_as_rectangular ();
                         }
                       else
-                        (*current_liboctave_error_handler)
-                          ("matrix singular to machine precision, rcond = %g",
-                           rcond);
+                        gripe_singular_matrix (rcond);
                     }
                 }
               else
@@ -5681,7 +5626,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++)
@@ -5798,10 +5743,7 @@
           if (sing_handler)
             sing_handler (rcond);
           else
-            (*current_liboctave_error_handler)
-              ("SparseMatrix::solve matrix singular to machine precision, rcond = %g",
-               rcond);
-
+            gripe_singular_matrix (rcond);
         }
       else if (status < 0)
         {
@@ -5866,17 +5808,17 @@
           if (spu == 0.)
             {
               cm->print = -1;
-              cm->print_function = 0;
+              SUITESPARSE_ASSIGN_FPTR (printf_func, cm->print_function, 0);
             }
           else
             {
               cm->print = static_cast<int> (spu) + 2;
-              cm->print_function =&SparseCholPrint;
+              SUITESPARSE_ASSIGN_FPTR (printf_func, cm->print_function, &SparseCholPrint);
             }
 
           cm->error_handler = &SparseCholError;
-          cm->complex_divide = CHOLMOD_NAME(divcomplex);
-          cm->hypotenuse = CHOLMOD_NAME(hypot);
+          SUITESPARSE_ASSIGN_FPTR2 (divcomplex_func, cm->complex_divide, divcomplex);
+          SUITESPARSE_ASSIGN_FPTR2 (hypot_func, cm->hypotenuse, hypot);
 
           cm->final_ll = true;
 
@@ -5951,9 +5893,7 @@
                       mattype.mark_as_rectangular ();
                     }
                   else
-                    (*current_liboctave_error_handler)
-                      ("SparseMatrix::solve matrix singular to machine precision, rcond = %g",
-                       rcond);
+                    gripe_singular_matrix (rcond);
 
                   return retval;
                 }
@@ -5980,8 +5920,8 @@
               END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
             }
 #else
-          (*current_liboctave_warning_handler)
-            ("CHOLMOD not installed");
+          (*current_liboctave_warning_with_id_handler)
+            ("Octave:missing-dependency", "CHOLMOD not installed");
 
           mattype.mark_as_unsymmetric ();
           typ = MatrixType::Full;
@@ -6083,17 +6023,17 @@
           if (spu == 0.)
             {
               cm->print = -1;
-              cm->print_function = 0;
+              SUITESPARSE_ASSIGN_FPTR (printf_func, cm->print_function, 0);
             }
           else
             {
               cm->print = static_cast<int> (spu) + 2;
-              cm->print_function =&SparseCholPrint;
+              SUITESPARSE_ASSIGN_FPTR (printf_func, cm->print_function, &SparseCholPrint);
             }
 
           cm->error_handler = &SparseCholError;
-          cm->complex_divide = CHOLMOD_NAME(divcomplex);
-          cm->hypotenuse = CHOLMOD_NAME(hypot);
+          SUITESPARSE_ASSIGN_FPTR2 (divcomplex_func, cm->complex_divide, divcomplex);
+          SUITESPARSE_ASSIGN_FPTR2 (hypot_func, cm->hypotenuse, hypot);
 
           cm->final_ll = true;
 
@@ -6177,9 +6117,7 @@
                       mattype.mark_as_rectangular ();
                     }
                   else
-                    (*current_liboctave_error_handler)
-                      ("SparseMatrix::solve matrix singular to machine precision, rcond = %g",
-                       rcond);
+                    gripe_singular_matrix (rcond);
 
                   return retval;
                 }
@@ -6211,8 +6149,8 @@
               END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
             }
 #else
-          (*current_liboctave_warning_handler)
-            ("CHOLMOD not installed");
+          (*current_liboctave_warning_with_id_handler)
+            ("Octave:missing-dependency", "CHOLMOD not installed");
 
           mattype.mark_as_unsymmetric ();
           typ = MatrixType::Full;
@@ -6240,7 +6178,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;
@@ -6345,17 +6283,17 @@
           if (spu == 0.)
             {
               cm->print = -1;
-              cm->print_function = 0;
+              SUITESPARSE_ASSIGN_FPTR (printf_func, cm->print_function, 0);
             }
           else
             {
               cm->print = static_cast<int> (spu) + 2;
-              cm->print_function =&SparseCholPrint;
+              SUITESPARSE_ASSIGN_FPTR (printf_func, cm->print_function, &SparseCholPrint);
             }
 
           cm->error_handler = &SparseCholError;
-          cm->complex_divide = CHOLMOD_NAME(divcomplex);
-          cm->hypotenuse = CHOLMOD_NAME(hypot);
+          SUITESPARSE_ASSIGN_FPTR2 (divcomplex_func, cm->complex_divide, divcomplex);
+          SUITESPARSE_ASSIGN_FPTR2 (hypot_func, cm->hypotenuse, hypot);
 
           cm->final_ll = true;
 
@@ -6429,9 +6367,7 @@
                       mattype.mark_as_rectangular ();
                     }
                   else
-                    (*current_liboctave_error_handler)
-                      ("SparseMatrix::solve matrix singular to machine precision, rcond = %g",
-                       rcond);
+                    gripe_singular_matrix (rcond);
 
                   return retval;
                 }
@@ -6458,8 +6394,8 @@
               END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
             }
 #else
-          (*current_liboctave_warning_handler)
-            ("CHOLMOD not installed");
+          (*current_liboctave_warning_with_id_handler)
+            ("Octave:missing-dependency", "CHOLMOD not installed");
 
           mattype.mark_as_unsymmetric ();
           typ = MatrixType::Full;
@@ -6496,7 +6432,7 @@
                 {
                   for (octave_idx_type i = 0; i < b_nr; i++)
                     {
-                      Complex c = b (i,j);
+                      Complex c = b(i,j);
                       Bx[i] = std::real (c);
                       Bz[i] = std::imag (c);
                     }
@@ -6579,17 +6515,17 @@
           if (spu == 0.)
             {
               cm->print = -1;
-              cm->print_function = 0;
+              SUITESPARSE_ASSIGN_FPTR (printf_func, cm->print_function, 0);
             }
           else
             {
               cm->print = static_cast<int> (spu) + 2;
-              cm->print_function =&SparseCholPrint;
+              SUITESPARSE_ASSIGN_FPTR (printf_func, cm->print_function, &SparseCholPrint);
             }
 
           cm->error_handler = &SparseCholError;
-          cm->complex_divide = CHOLMOD_NAME(divcomplex);
-          cm->hypotenuse = CHOLMOD_NAME(hypot);
+          SUITESPARSE_ASSIGN_FPTR2 (divcomplex_func, cm->complex_divide, divcomplex);
+          SUITESPARSE_ASSIGN_FPTR2 (hypot_func, cm->hypotenuse, hypot);
 
           cm->final_ll = true;
 
@@ -6673,9 +6609,7 @@
                       mattype.mark_as_rectangular ();
                     }
                   else
-                    (*current_liboctave_error_handler)
-                      ("SparseMatrix::solve matrix singular to machine precision, rcond = %g",
-                       rcond);
+                    gripe_singular_matrix (rcond);
 
                   return retval;
                 }
@@ -6708,8 +6642,8 @@
               END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE;
             }
 #else
-          (*current_liboctave_warning_handler)
-            ("CHOLMOD not installed");
+          (*current_liboctave_warning_with_id_handler)
+            ("Octave:missing-dependency", "CHOLMOD not installed");
 
           mattype.mark_as_unsymmetric ();
           typ = MatrixType::Full;
@@ -6737,7 +6671,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;
@@ -6751,7 +6685,7 @@
                 {
                   for (octave_idx_type i = 0; i < b_nr; i++)
                     {
-                      Complex c = b (i,j);
+                      Complex c = b(i,j);
                       Bx[i] = std::real (c);
                       Bz[i] = std::imag (c);
                     }
@@ -7737,7 +7671,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);
@@ -7795,84 +7729,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;
 }
@@ -7887,7 +7822,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);
@@ -7945,84 +7880,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/dSparse.h	Fri Feb 06 08:31:09 2015 -0800
+++ b/liboctave/array/dSparse.h	Fri Feb 06 08:31:49 2015 -0800
@@ -33,7 +33,9 @@
 #include "DET.h"
 #include "MSparse.h"
 #include "MSparse-defs.h"
-#include "Sparse-op-defs.h"
+
+#include "Sparse-op-decls.h"
+
 #include "MatrixType.h"
 
 class PermMatrix;
@@ -120,10 +122,13 @@
   friend OCTAVE_API SparseMatrix real (const SparseComplexMatrix& a);
   friend OCTAVE_API SparseMatrix imag (const SparseComplexMatrix& a);
 
-  friend OCTAVE_API SparseMatrix atan2 (const double& x, const SparseMatrix& y);
-  friend OCTAVE_API SparseMatrix atan2 (const SparseMatrix& x, const double& y);
+  friend OCTAVE_API SparseMatrix atan2 (const double& x, const SparseMatrix& y)
+                                        GCC_ATTR_DEPRECATED ;
+  friend OCTAVE_API SparseMatrix atan2 (const SparseMatrix& x, const double& y)
+                                        GCC_ATTR_DEPRECATED ;
   friend OCTAVE_API SparseMatrix atan2 (const SparseMatrix& x,
-                                        const SparseMatrix& y);
+                                        const SparseMatrix& y)
+                                        GCC_ATTR_DEPRECATED ;
 
   SparseMatrix transpose (void) const
   {
--- a/liboctave/array/dim-vector.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/liboctave/array/dim-vector.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -176,7 +176,8 @@
 bool
 dim_vector::concat (const dim_vector& dvb, int dim)
 {
-  int orig_nd = ndims (), ndb = dvb.ndims ();
+  int orig_nd = ndims ();
+  int ndb = dvb.ndims ();
   int new_nd = dim < ndb ? ndb : dim + 1;
   if (new_nd > orig_nd)
     resize (new_nd, 1);
--- a/liboctave/array/dim-vector.h	Fri Feb 06 08:31:09 2015 -0800
+++ b/liboctave/array/dim-vector.h	Fri Feb 06 08:31:49 2015 -0800
@@ -62,7 +62,7 @@
 
   octave_idx_type& count (void) const { return rep[-2]; }
 
-  // Construct a new rep with count = 1 and ndims given.
+  //! Construct a new rep with count = 1 and ndims given.
 
   static octave_idx_type *newrep (int ndims)
   {
@@ -74,7 +74,7 @@
     return r;
   }
 
-  // Clone this->rep.
+  //! Clone this->rep.
 
   octave_idx_type *clonerep (void)
   {
@@ -91,7 +91,7 @@
     return r;
   }
 
-  // Clone and resize this->rep to length n, filling by given value.
+  //! Clone and resize this->rep to length n, filling by given value.
 
   octave_idx_type *resizerep (int n, octave_idx_type fill_value)
   {
@@ -117,7 +117,7 @@
     return r;
   }
 
-  // Free the rep.
+  //! Free the rep.
 
   void freerep (void)
   {
@@ -140,27 +140,6 @@
 
 public:
 
-  // The constructor
-  //
-  //   dim_vector (n)
-  //
-  // creates an dimension vector with N rows and 1 column.  It is
-  // deprecated because of the potentiol for confusion that it causes.
-  // Additional constructors of the form
-  //
-  //   dim_vector (r, c)
-  //   dim_vector (r, c, p)
-  //   dim_vector (d1, d2, d3, d4, ...)
-  //
-  // are available for up to 7 dimensions.
-
-  explicit dim_vector (octave_idx_type n) GCC_ATTR_DEPRECATED
-    : rep (newrep (2))
-  {
-    rep[0] = n;
-    rep[1] = 1;
-  }
-
 #define ASSIGN_REP(i) rep[i] = d ## i;
 #define DIM_VECTOR_CTOR(N) \
   dim_vector (OCT_MAKE_DECL_LIST (octave_idx_type, d, N)) \
@@ -337,9 +316,12 @@
     return (num_ones () == length ());
   }
 
-  // Return the number of elements that a matrix with this dimension
-  // vector would have, NOT the number of dimensions (elements in the
-  // dimension vector).
+  //! Number of elements that a matrix with this dimensions would have.
+   /*!
+      Return the number of elements that a matrix with this dimension
+      vector would have, NOT the number of dimensions (elements in the
+      dimension vector).
+  */
 
   octave_idx_type numel (int n = 0) const
   {
@@ -353,13 +335,15 @@
     return retval;
   }
 
-  // The following function will throw a std::bad_alloc ()
-  // exception if the requested size is larger than can be indexed by
-  // octave_idx_type. This may be smaller than the actual amount of
-  // memory that can be safely allocated on a system.  However, if we
-  // don't fail here, we can end up with a mysterious crash inside a
-  // function that is iterating over an array using octave_idx_type
-  // indices.
+   /*!
+      The following function will throw a std::bad_alloc ()
+      exception if the requested size is larger than can be indexed by
+      octave_idx_type. This may be smaller than the actual amount of
+      memory that can be safely allocated on a system.  However, if we
+      don't fail here, we can end up with a mysterious crash inside a
+      function that is iterating over an array using octave_idx_type
+      indices.
+  */
 
   octave_idx_type safe_numel (void) const;
 
@@ -377,18 +361,19 @@
 
   dim_vector squeeze (void) const;
 
-  // This corresponds to cat().
+  //! This corresponds to cat().
   bool concat (const dim_vector& dvb, int dim);
 
-  // This corresponds to [,] (horzcat, dim = 0) and [;] (vertcat, dim = 1).
+  //! This corresponds to [,] (horzcat, dim = 0) and [;] (vertcat, dim = 1).
   // The rules are more relaxed here.
   bool hvcat (const dim_vector& dvb, int dim);
 
-  // Force certain dimensionality, preserving numel ().  Missing
-  // dimensions are set to 1, redundant are folded into the trailing
-  // one.  If n = 1, the result is 2d and the second dim is 1
-  // (dim_vectors are always at least 2D).
-
+  /*!
+      Force certain dimensionality, preserving numel ().  Missing
+      dimensions are set to 1, redundant are folded into the trailing
+      one.  If n = 1, the result is 2d and the second dim is 1
+      (dim_vectors are always at least 2D).
+  */
   dim_vector redim (int n) const;
 
   dim_vector as_column (void) const
@@ -423,7 +408,7 @@
     return def;
   }
 
-  // Compute a linear index from an index tuple.
+  //! Compute a linear index from an index tuple.
 
   octave_idx_type compute_index (const octave_idx_type *idx) const
   {
@@ -434,7 +419,7 @@
     return k;
   }
 
-  // Ditto, but the tuple may be incomplete (nidx < length ()).
+  //! Ditto, but the tuple may be incomplete (nidx < length ()).
 
   octave_idx_type compute_index (const octave_idx_type *idx, int nidx) const
   {
@@ -445,9 +430,11 @@
     return k;
   }
 
-  // Increment a multi-dimensional index tuple, optionally starting
-  // from an offset position and return the index of the last index
-  // position that was changed, or length () if just cycled over.
+  /*/!
+      Increment a multi-dimensional index tuple, optionally starting
+      from an offset position and return the index of the last index
+      position that was changed, or length () if just cycled over.
+  */
 
   int increment_index (octave_idx_type *idx, int start = 0) const
   {
@@ -462,7 +449,7 @@
     return i;
   }
 
-  // Return cumulative dimensions.
+  //! Return cumulative dimensions.
 
   dim_vector cumulative (void) const
   {
@@ -476,8 +463,8 @@
     return retval;
   }
 
-  // Compute a linear index from an index tuple.  Dimensions are
-  // required to be cumulative.
+  //! Compute a linear index from an index tuple.  Dimensions are
+  //! required to be cumulative.
 
   octave_idx_type cum_compute_index (const octave_idx_type *idx) const
   {
--- a/liboctave/array/fCDiagMatrix.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/liboctave/array/fCDiagMatrix.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -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;
@@ -452,7 +453,8 @@
 
   FloatComplexDiagMatrix c (a_nr, b_nc);
 
-  octave_idx_type len = c.length (), lenm = len < a_nc ? len : a_nc;
+  octave_idx_type len = c.length ();
+  octave_idx_type lenm = len < a_nc ? len : a_nc;
 
   for (octave_idx_type i = 0; i < lenm; i++)
     c.dgxelem (i) = a.dgelem (i) * b.dgelem (i);
@@ -553,7 +555,8 @@
 FloatComplexDiagMatrix::rcond (void) const
 {
   FloatColumnVector av = extract_diag (0).map<float> (std::abs);
-  float amx = av.max (), amn = av.min ();
+  float amx = av.max ();
+  float amn = av.min ();
   return amx == 0 ? 0.0f : amn / amx;
 }
 
--- a/liboctave/array/fCDiagMatrix.h	Fri Feb 06 08:31:09 2015 -0800
+++ b/liboctave/array/fCDiagMatrix.h	Fri Feb 06 08:31:49 2015 -0800
@@ -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 Feb 06 08:31:09 2015 -0800
+++ b/liboctave/array/fCMatrix.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -38,7 +38,13 @@
 #include "Array-util.h"
 #include "DET.h"
 #include "f77-fcn.h"
+#include "boolMatrix.h"
+#include "chMatrix.h"
 #include "fCMatrix.h"
+#include "fCNDArray.h"
+#include "fCDiagMatrix.h"
+#include "fCColVector.h"
+#include "fCRowVector.h"
 #include "fCmplxCHOL.h"
 #include "fCmplxSCHUR.h"
 #include "fCmplxSVD.h"
@@ -47,7 +53,6 @@
 #include "lo-ieee.h"
 #include "lo-mappers.h"
 #include "lo-utils.h"
-#include "mx-base.h"
 #include "mx-fcm-fdm.h"
 #include "mx-fcm-fs.h"
 #include "mx-fdm-fcm.h"
@@ -264,39 +269,67 @@
 // FloatComplex Matrix class
 
 FloatComplexMatrix::FloatComplexMatrix (const FloatMatrix& a)
-  : MArray<FloatComplex> (a)
+  : FloatComplexNDArray (a)
 {
 }
 
 FloatComplexMatrix::FloatComplexMatrix (const FloatRowVector& rv)
-  : MArray<FloatComplex> (rv)
+  : FloatComplexNDArray (rv)
 {
 }
 
 FloatComplexMatrix::FloatComplexMatrix (const FloatColumnVector& cv)
-  : MArray<FloatComplex> (cv)
+  : FloatComplexNDArray (cv)
 {
 }
 
 FloatComplexMatrix::FloatComplexMatrix (const FloatDiagMatrix& a)
-  : MArray<FloatComplex> (a.dims (), 0.0)
+  : FloatComplexNDArray (a.dims (), 0.0)
+{
+  for (octave_idx_type i = 0; i < a.length (); i++)
+    elem (i, i) = a.elem (i, i);
+}
+
+FloatComplexMatrix::FloatComplexMatrix (const MDiagArray2<float>& a)
+  : FloatComplexNDArray (a.dims (), 0.0)
+{
+  for (octave_idx_type i = 0; i < a.length (); i++)
+    elem (i, i) = a.elem (i, i);
+}
+
+FloatComplexMatrix::FloatComplexMatrix (const DiagArray2<float>& a)
+  : FloatComplexNDArray (a.dims (), 0.0)
 {
   for (octave_idx_type i = 0; i < a.length (); i++)
     elem (i, i) = a.elem (i, i);
 }
 
 FloatComplexMatrix::FloatComplexMatrix (const FloatComplexRowVector& rv)
-  : MArray<FloatComplex> (rv)
+  : FloatComplexNDArray (rv)
 {
 }
 
 FloatComplexMatrix::FloatComplexMatrix (const FloatComplexColumnVector& cv)
-  : MArray<FloatComplex> (cv)
+  : FloatComplexNDArray (cv)
 {
 }
 
 FloatComplexMatrix::FloatComplexMatrix (const FloatComplexDiagMatrix& a)
-  : MArray<FloatComplex> (a.dims (), 0.0)
+  : FloatComplexNDArray (a.dims (), 0.0)
+{
+  for (octave_idx_type i = 0; i < a.length (); i++)
+    elem (i, i) = a.elem (i, i);
+}
+
+FloatComplexMatrix::FloatComplexMatrix (const MDiagArray2<FloatComplex>& a)
+  : FloatComplexNDArray (a.dims (), 0.0)
+{
+  for (octave_idx_type i = 0; i < a.length (); i++)
+    elem (i, i) = a.elem (i, i);
+}
+
+FloatComplexMatrix::FloatComplexMatrix (const DiagArray2<FloatComplex>& a)
+  : FloatComplexNDArray (a.dims (), 0.0)
 {
   for (octave_idx_type i = 0; i < a.length (); i++)
     elem (i, i) = a.elem (i, i);
@@ -306,12 +339,12 @@
 // here?
 
 FloatComplexMatrix::FloatComplexMatrix (const boolMatrix& a)
-  : MArray<FloatComplex> (a)
+  : FloatComplexNDArray (a)
 {
 }
 
 FloatComplexMatrix::FloatComplexMatrix (const charMatrix& a)
-  : MArray<FloatComplex> (a.dims (), 0.0)
+  : FloatComplexNDArray (a.dims (), 0.0)
 {
   for (octave_idx_type i = 0; i < a.rows (); i++)
     for (octave_idx_type j = 0; j < a.cols (); j++)
@@ -320,7 +353,7 @@
 
 FloatComplexMatrix::FloatComplexMatrix (const FloatMatrix& re,
                                         const FloatMatrix& im)
-  : MArray<FloatComplex> (re.dims ())
+  : FloatComplexNDArray (re.dims ())
 {
   if (im.rows () != rows () || im.cols () != cols ())
     (*current_liboctave_error_handler) ("complex: internal error");
@@ -1727,7 +1760,7 @@
 float
 FloatComplexMatrix::rcond (MatrixType &mattype) const
 {
-  float rcon;
+  float rcon = octave_NaN;
   octave_idx_type nr = rows ();
   octave_idx_type nc = cols ();
 
@@ -1925,11 +1958,27 @@
             {
               const FloatComplex *tmp_data = fortran_vec ();
 
+              retval = b;
+              FloatComplex *result = retval.fortran_vec ();
+
+              char uplo = 'U';
+              char trans = get_blas_char (transt);
+              char dia = 'N';
+
+              F77_XFCN (ctrtrs, CTRTRS, (F77_CONST_CHAR_ARG2 (&uplo, 1),
+                                         F77_CONST_CHAR_ARG2 (&trans, 1),
+                                         F77_CONST_CHAR_ARG2 (&dia, 1),
+                                         nr, b_nc, tmp_data, nr,
+                                         result, nr, info
+                                         F77_CHAR_ARG_LEN (1)
+                                         F77_CHAR_ARG_LEN (1)
+                                         F77_CHAR_ARG_LEN (1)));
+
               if (calc_cond)
                 {
                   char norm = '1';
-                  char uplo = 'U';
-                  char dia = 'N';
+                  uplo = 'U';
+                  dia = 'N';
 
                   Array<FloatComplex> z (dim_vector (2 * nc, 1));
                   FloatComplex *pz = z.fortran_vec ();
@@ -1957,30 +2006,9 @@
                       if (sing_handler)
                         sing_handler (rcon);
                       else
-                        (*current_liboctave_error_handler)
-                          ("matrix singular to machine precision, rcond = %g",
-                           rcon);
+                        gripe_singular_matrix (rcon);
                     }
                 }
-
-              if (info == 0)
-                {
-                  retval = b;
-                  FloatComplex *result = retval.fortran_vec ();
-
-                  char uplo = 'U';
-                  char trans = get_blas_char (transt);
-                  char dia = 'N';
-
-                  F77_XFCN (ctrtrs, CTRTRS, (F77_CONST_CHAR_ARG2 (&uplo, 1),
-                                             F77_CONST_CHAR_ARG2 (&trans, 1),
-                                             F77_CONST_CHAR_ARG2 (&dia, 1),
-                                             nr, b_nc, tmp_data, nr,
-                                             result, nr, info
-                                             F77_CHAR_ARG_LEN (1)
-                                             F77_CHAR_ARG_LEN (1)
-                                             F77_CHAR_ARG_LEN (1)));
-                }
             }
         }
       else
@@ -2026,11 +2054,27 @@
             {
               const FloatComplex *tmp_data = fortran_vec ();
 
+              retval = b;
+              FloatComplex *result = retval.fortran_vec ();
+
+              char uplo = 'L';
+              char trans = get_blas_char (transt);
+              char dia = 'N';
+
+              F77_XFCN (ctrtrs, CTRTRS, (F77_CONST_CHAR_ARG2 (&uplo, 1),
+                                         F77_CONST_CHAR_ARG2 (&trans, 1),
+                                         F77_CONST_CHAR_ARG2 (&dia, 1),
+                                         nr, b_nc, tmp_data, nr,
+                                         result, nr, info
+                                         F77_CHAR_ARG_LEN (1)
+                                         F77_CHAR_ARG_LEN (1)
+                                         F77_CHAR_ARG_LEN (1)));
+
               if (calc_cond)
                 {
                   char norm = '1';
-                  char uplo = 'L';
-                  char dia = 'N';
+                  uplo = 'L';
+                  dia = 'N';
 
                   Array<FloatComplex> z (dim_vector (2 * nc, 1));
                   FloatComplex *pz = z.fortran_vec ();
@@ -2058,30 +2102,9 @@
                       if (sing_handler)
                         sing_handler (rcon);
                       else
-                        (*current_liboctave_error_handler)
-                          ("matrix singular to machine precision, rcond = %g",
-                           rcon);
+                        gripe_singular_matrix (rcon);
                     }
                 }
-
-              if (info == 0)
-                {
-                  retval = b;
-                  FloatComplex *result = retval.fortran_vec ();
-
-                  char uplo = 'L';
-                  char trans = get_blas_char (transt);
-                  char dia = 'N';
-
-                  F77_XFCN (ctrtrs, CTRTRS, (F77_CONST_CHAR_ARG2 (&uplo, 1),
-                                             F77_CONST_CHAR_ARG2 (&trans, 1),
-                                             F77_CONST_CHAR_ARG2 (&dia, 1),
-                                             nr, b_nc, tmp_data, nr,
-                                             result, nr, info
-                                             F77_CHAR_ARG_LEN (1)
-                                             F77_CHAR_ARG_LEN (1)
-                                             F77_CHAR_ARG_LEN (1)));
-                }
             }
         }
       else
@@ -2164,9 +2187,7 @@
                       if (sing_handler)
                         sing_handler (rcon);
                       else
-                        (*current_liboctave_error_handler)
-                          ("matrix singular to machine precision, rcond = %g",
-                           rcon);
+                        gripe_singular_matrix (rcon);
                     }
                 }
 
@@ -2221,8 +2242,7 @@
               if (sing_handler)
                 sing_handler (rcon);
               else
-                (*current_liboctave_error_handler)
-                  ("matrix singular to machine precision");
+                gripe_singular_matrix ();
 
               mattype.mark_as_rectangular ();
             }
@@ -2250,9 +2270,7 @@
                       if (sing_handler)
                         sing_handler (rcon);
                       else
-                        (*current_liboctave_error_handler)
-                          ("matrix singular to machine precision, rcond = %g",
-                           rcon);
+                        gripe_singular_matrix (rcon);
                     }
                 }
 
@@ -2349,9 +2367,9 @@
 
   // Only calculate the condition number for LU/Cholesky
   if (typ == MatrixType::Upper || typ == MatrixType::Permuted_Upper)
-    retval = utsolve (mattype, b, info, rcon, sing_handler, false, transt);
+    retval = utsolve (mattype, b, info, rcon, sing_handler, true, transt);
   else if (typ == MatrixType::Lower || typ == MatrixType::Permuted_Lower)
-    retval = ltsolve (mattype, b, info, rcon, sing_handler, false, transt);
+    retval = ltsolve (mattype, b, info, rcon, sing_handler, true, transt);
   else if (transt == blas_trans)
     return transpose ().solve (mattype, b, info, rcon, sing_handler,
                                singular_fallback);
@@ -3118,154 +3136,56 @@
 // unary operations
 
 boolMatrix
-FloatComplexMatrix::operator ! (void) const
-{
-  if (any_element_is_nan ())
-    gripe_nan_to_logical_conversion ();
-
-  return do_mx_unary_op<bool, FloatComplex> (*this, mx_inline_not);
-}
-
-// other operations
-
-bool
-FloatComplexMatrix::any_element_is_nan (void) const
-{
-  return do_mx_check<FloatComplex> (*this, mx_inline_any_nan);
-}
-
-bool
-FloatComplexMatrix::any_element_is_inf_or_nan (void) const
-{
-  return ! do_mx_check<FloatComplex> (*this, mx_inline_all_finite);
-}
-
-// Return true if no elements have imaginary components.
-
-bool
-FloatComplexMatrix::all_elements_are_real (void) const
-{
-  return do_mx_check<FloatComplex> (*this, mx_inline_all_real);
-}
-
-// Return nonzero if any element of CM has a non-integer real or
-// imaginary part.  Also extract the largest and smallest (real or
-// imaginary) values and return them in MAX_VAL and MIN_VAL.
-
-bool
-FloatComplexMatrix::all_integers (float& max_val, float& min_val) const
-{
-  octave_idx_type nr = rows ();
-  octave_idx_type nc = cols ();
-
-  if (nr > 0 && nc > 0)
-    {
-      FloatComplex val = elem (0, 0);
-
-      float r_val = std::real (val);
-      float i_val = std::imag (val);
-
-      max_val = r_val;
-      min_val = r_val;
-
-      if (i_val > max_val)
-        max_val = i_val;
-
-      if (i_val < max_val)
-        min_val = i_val;
-    }
-  else
-    return false;
-
-  for (octave_idx_type j = 0; j < nc; j++)
-    for (octave_idx_type i = 0; i < nr; i++)
-      {
-        FloatComplex val = elem (i, j);
-
-        float r_val = std::real (val);
-        float i_val = std::imag (val);
-
-        if (r_val > max_val)
-          max_val = r_val;
-
-        if (i_val > max_val)
-          max_val = i_val;
-
-        if (r_val < min_val)
-          min_val = r_val;
-
-        if (i_val < min_val)
-          min_val = i_val;
-
-        if (D_NINT (r_val) != r_val || D_NINT (i_val) != i_val)
-          return false;
-      }
-
-  return true;
-}
-
-bool
-FloatComplexMatrix::too_large_for_float (void) const
-{
-  return false;
-}
-
-// FIXME: Do these really belong here?  Maybe they should be
-// in a base class?
-
-boolMatrix
 FloatComplexMatrix::all (int dim) const
 {
-  return do_mx_red_op<bool, FloatComplex> (*this, dim, mx_inline_all);
+  return FloatComplexNDArray::all (dim);
 }
 
 boolMatrix
 FloatComplexMatrix::any (int dim) const
 {
-  return do_mx_red_op<bool, FloatComplex> (*this, dim, mx_inline_any);
+  return FloatComplexNDArray::any (dim);
 }
 
 FloatComplexMatrix
 FloatComplexMatrix::cumprod (int dim) const
 {
-  return do_mx_cum_op<FloatComplex, FloatComplex> (*this, dim,
-                                                   mx_inline_cumprod);
+  return FloatComplexNDArray::cumprod (dim);
 }
 
 FloatComplexMatrix
 FloatComplexMatrix::cumsum (int dim) const
 {
-  return do_mx_cum_op<FloatComplex, FloatComplex> (*this, dim,
-                                                   mx_inline_cumsum);
+  return FloatComplexNDArray::cumsum (dim);
 }
 
 FloatComplexMatrix
 FloatComplexMatrix::prod (int dim) const
 {
-  return do_mx_red_op<FloatComplex, FloatComplex> (*this, dim, mx_inline_prod);
+  return FloatComplexNDArray::prod (dim);
 }
 
 FloatComplexMatrix
 FloatComplexMatrix::sum (int dim) const
 {
-  return do_mx_red_op<FloatComplex, FloatComplex> (*this, dim, mx_inline_sum);
+  return FloatComplexNDArray::sum (dim);
 }
 
 FloatComplexMatrix
 FloatComplexMatrix::sumsq (int dim) const
 {
-  return do_mx_red_op<float, FloatComplex> (*this, dim, mx_inline_sumsq);
+  return FloatComplexNDArray::sumsq (dim);
 }
 
 FloatMatrix FloatComplexMatrix::abs (void) const
 {
-  return do_mx_unary_map<float, FloatComplex, std::abs> (*this);
+  return FloatComplexNDArray::abs ();
 }
 
 FloatComplexMatrix
 FloatComplexMatrix::diag (octave_idx_type k) const
 {
-  return MArray<FloatComplex>::diag (k);
+  return FloatComplexNDArray::diag (k);
 }
 
 FloatComplexDiagMatrix
@@ -3729,7 +3649,7 @@
 
   // FIXME: check info?
 
-  retval = -ua * cx * ub.hermitian ();
+  retval = ua * cx * ub.hermitian ();
 
   return retval;
 }
@@ -3789,8 +3709,10 @@
 {
   FloatComplexMatrix retval;
 
-  bool tra = transa != blas_no_trans, trb = transb != blas_no_trans;
-  bool cja = transa == blas_conj_trans, cjb = transb == blas_conj_trans;
+  bool tra = transa != blas_no_trans;
+  bool trb = transb != blas_no_trans;
+  bool cja = transa == blas_conj_trans;
+  bool cjb = transb == blas_conj_trans;
 
   octave_idx_type a_nr = tra ? a.cols () : a.rows ();
   octave_idx_type a_nc = tra ? a.rows () : a.cols ();
@@ -3846,8 +3768,10 @@
         }
       else
         {
-          octave_idx_type lda = a.rows (), tda = a.cols ();
-          octave_idx_type ldb = b.rows (), tdb = b.cols ();
+          octave_idx_type lda = a.rows ();
+          octave_idx_type tda = a.cols ();
+          octave_idx_type ldb = b.rows ();
+          octave_idx_type tdb = b.cols ();
 
           retval = FloatComplexMatrix (a_nr, b_nc, 0.0);
           FloatComplex *c = retval.fortran_vec ();
@@ -3927,7 +3851,7 @@
     for (octave_idx_type i = 0; i < nr; i++)
       {
         octave_quit ();
-        result (i, j) = xmin (c, m (i, j));
+        result(i, j) = xmin (c, m(i, j));
       }
 
   return result;
@@ -3947,7 +3871,7 @@
     for (octave_idx_type i = 0; i < nr; i++)
       {
         octave_quit ();
-        result (i, j) = xmin (m (i, j), c);
+        result(i, j) = xmin (m(i, j), c);
       }
 
   return result;
@@ -3976,7 +3900,7 @@
       for (octave_idx_type i = 0; i < nr; i++)
         {
           octave_quit ();
-          if (std::imag (a (i, j)) != 0.0 || std::imag (b (i, j)) != 0.0)
+          if (std::imag (a(i, j)) != 0.0 || std::imag (b(i, j)) != 0.0)
             {
               columns_are_real_only = 0;
               break;
@@ -3986,14 +3910,14 @@
       if (columns_are_real_only)
         {
           for (octave_idx_type i = 0; i < nr; i++)
-            result (i, j) = xmin (std::real (a (i, j)), std::real (b (i, j)));
+            result(i, j) = xmin (std::real (a(i, j)), std::real (b(i, j)));
         }
       else
         {
           for (octave_idx_type i = 0; i < nr; i++)
             {
               octave_quit ();
-              result (i, j) = xmin (a (i, j), b (i, j));
+              result(i, j) = xmin (a(i, j), b(i, j));
             }
         }
     }
@@ -4015,7 +3939,7 @@
     for (octave_idx_type i = 0; i < nr; i++)
       {
         octave_quit ();
-        result (i, j) = xmax (c, m (i, j));
+        result(i, j) = xmax (c, m(i, j));
       }
 
   return result;
@@ -4035,7 +3959,7 @@
     for (octave_idx_type i = 0; i < nr; i++)
       {
         octave_quit ();
-        result (i, j) = xmax (m (i, j), c);
+        result(i, j) = xmax (m(i, j), c);
       }
 
   return result;
@@ -4064,7 +3988,7 @@
       for (octave_idx_type i = 0; i < nr; i++)
         {
           octave_quit ();
-          if (std::imag (a (i, j)) != 0.0 || std::imag (b (i, j)) != 0.0)
+          if (std::imag (a(i, j)) != 0.0 || std::imag (b(i, j)) != 0.0)
             {
               columns_are_real_only = 0;
               break;
@@ -4076,7 +4000,7 @@
           for (octave_idx_type i = 0; i < nr; i++)
             {
               octave_quit ();
-              result (i, j) = xmax (std::real (a (i, j)), std::real (b (i, j)));
+              result(i, j) = xmax (std::real (a(i, j)), std::real (b(i, j)));
             }
         }
       else
@@ -4084,7 +4008,7 @@
           for (octave_idx_type i = 0; i < nr; i++)
             {
               octave_quit ();
-              result (i, j) = xmax (a (i, j), b (i, j));
+              result(i, j) = xmax (a(i, j), b(i, j));
             }
         }
     }
--- a/liboctave/array/fCMatrix.h	Fri Feb 06 08:31:09 2015 -0800
+++ b/liboctave/array/fCMatrix.h	Fri Feb 06 08:31:49 2015 -0800
@@ -23,6 +23,7 @@
 #if !defined (octave_fCMatrix_h)
 #define octave_fCMatrix_h 1
 
+#include "fCNDArray.h"
 #include "MArray.h"
 #include "MDiagArray2.h"
 #include "MatrixType.h"
@@ -34,7 +35,7 @@
 
 class
 OCTAVE_API
-FloatComplexMatrix : public MArray<FloatComplex>
+FloatComplexMatrix : public FloatComplexNDArray
 {
 public:
 
@@ -43,31 +44,31 @@
 
   typedef void (*solve_singularity_handler) (float rcon);
 
-  FloatComplexMatrix (void) : MArray<FloatComplex> () { }
+  FloatComplexMatrix (void) : FloatComplexNDArray () { }
 
   FloatComplexMatrix (octave_idx_type r, octave_idx_type c)
-    : MArray<FloatComplex> (dim_vector (r, c)) { }
+    : FloatComplexNDArray (dim_vector (r, c)) { }
 
   FloatComplexMatrix (octave_idx_type r, octave_idx_type c,
                       const FloatComplex& val)
-    : MArray<FloatComplex> (dim_vector (r, c), val) { }
+    : FloatComplexNDArray (dim_vector (r, c), val) { }
 
   FloatComplexMatrix (const dim_vector& dv)
-    : MArray<FloatComplex> (dv.redim (2)) { }
+    : FloatComplexNDArray (dv.redim (2)) { }
 
   FloatComplexMatrix (const dim_vector& dv, const FloatComplex& val)
-    : MArray<FloatComplex> (dv.redim (2), val) { }
+    : FloatComplexNDArray (dv.redim (2), val) { }
 
   FloatComplexMatrix (const FloatComplexMatrix& a)
-    : MArray<FloatComplex> (a) { }
+    : FloatComplexNDArray (a) { }
 
   template <class U>
   FloatComplexMatrix (const MArray<U>& a)
-    : MArray<FloatComplex> (a.as_matrix ()) { }
+    : FloatComplexNDArray (a.as_matrix ()) { }
 
   template <class U>
   FloatComplexMatrix (const Array<U>& a)
-    : MArray<FloatComplex> (a.as_matrix ()) { }
+    : FloatComplexNDArray (a.as_matrix ()) { }
 
   explicit FloatComplexMatrix (const FloatMatrix& a);
 
@@ -77,24 +78,26 @@
 
   explicit FloatComplexMatrix (const FloatDiagMatrix& a);
 
+  explicit FloatComplexMatrix (const MDiagArray2<float>& a);
+
+  explicit FloatComplexMatrix (const DiagArray2<float>& a);
+
   explicit FloatComplexMatrix (const FloatComplexRowVector& rv);
 
   explicit FloatComplexMatrix (const FloatComplexColumnVector& cv);
 
   explicit FloatComplexMatrix (const FloatComplexDiagMatrix& a);
 
+  explicit FloatComplexMatrix (const MDiagArray2<FloatComplex>& a);
+
+  explicit FloatComplexMatrix (const DiagArray2<FloatComplex>& a);
+
   explicit FloatComplexMatrix (const boolMatrix& a);
 
   explicit FloatComplexMatrix (const charMatrix& a);
 
   FloatComplexMatrix (const FloatMatrix& re, const FloatMatrix& im);
 
-  FloatComplexMatrix& operator = (const FloatComplexMatrix& a)
-  {
-    MArray<FloatComplex>::operator = (a);
-    return *this;
-  }
-
   bool operator == (const FloatComplexMatrix& a) const;
   bool operator != (const FloatComplexMatrix& a) const;
 
@@ -380,12 +383,6 @@
 
   // other operations
 
-  bool any_element_is_nan (void) const;
-  bool any_element_is_inf_or_nan (void) const;
-  bool all_elements_are_real (void) const;
-  bool all_integers (float& max_val, float& min_val) const;
-  bool too_large_for_float (void) const;
-
   boolMatrix all (int dim = -1) const;
   boolMatrix any (int dim = -1) const;
 
--- a/liboctave/array/fCNDArray.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/liboctave/array/fCNDArray.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -39,6 +39,7 @@
 #include "MArray-defs.h"
 #include "mx-base.h"
 #include "mx-op-defs.h"
+#include "mx-fcnda-fs.h"
 #include "oct-fftw.h"
 #include "oct-locbuf.h"
 
@@ -213,7 +214,7 @@
   FloatComplexNDArray retval (dv);
   octave_idx_type npts = dv(dim);
   octave_idx_type nn = 4*npts+15;
-  Array<FloatComplex> wsave (nn, 1);
+  Array<FloatComplex> wsave (dim_vector (nn, 1));
   FloatComplex *pwsave = wsave.fortran_vec ();
 
   OCTAVE_LOCAL_BUFFER (FloatComplex, tmp, npts);
@@ -260,7 +261,7 @@
   FloatComplexNDArray retval (dv);
   octave_idx_type npts = dv(dim);
   octave_idx_type nn = 4*npts+15;
-  Array<FloatComplex> wsave (nn, 1);
+  Array<FloatComplex> wsave (dim_vector (nn, 1));
   FloatComplex *pwsave = wsave.fortran_vec ();
 
   OCTAVE_LOCAL_BUFFER (FloatComplex, tmp, npts);
@@ -310,9 +311,9 @@
     {
       octave_idx_type npts = dv2(i);
       octave_idx_type nn = 4*npts+15;
-      Array<FloatComplex> wsave (nn, 1);
+      Array<FloatComplex> wsave (dim_vector (nn, 1));
       FloatComplex *pwsave = wsave.fortran_vec ();
-      Array<FloatComplex> row (npts, 1);
+      Array<FloatComplex> row (dim_vector (npts, 1));
       FloatComplex *prow = row.fortran_vec ();
 
       octave_idx_type howmany = numel () / npts;
@@ -358,9 +359,9 @@
     {
       octave_idx_type npts = dv2(i);
       octave_idx_type nn = 4*npts+15;
-      Array<FloatComplex> wsave (nn, 1);
+      Array<FloatComplex> wsave (dim_vector (nn, 1));
       FloatComplex *pwsave = wsave.fortran_vec ();
-      Array<FloatComplex> row (npts, 1);
+      Array<FloatComplex> row (dim_vector (npts, 1));
       FloatComplex *prow = row.fortran_vec ();
 
       octave_idx_type howmany = numel () / npts;
@@ -406,9 +407,9 @@
     {
       octave_idx_type npts = dv(i);
       octave_idx_type nn = 4*npts+15;
-      Array<FloatComplex> wsave (nn, 1);
+      Array<FloatComplex> wsave (dim_vector (nn, 1));
       FloatComplex *pwsave = wsave.fortran_vec ();
-      Array<FloatComplex> row (npts, 1);
+      Array<FloatComplex> row (dim_vector (npts, 1));
       FloatComplex *prow = row.fortran_vec ();
 
       octave_idx_type howmany = numel () / npts;
@@ -453,9 +454,9 @@
     {
       octave_idx_type npts = dv(i);
       octave_idx_type nn = 4*npts+15;
-      Array<FloatComplex> wsave (nn, 1);
+      Array<FloatComplex> wsave (dim_vector (nn, 1));
       FloatComplex *pwsave = wsave.fortran_vec ();
-      Array<FloatComplex> row (npts, 1);
+      Array<FloatComplex> row (dim_vector (npts, 1));
       FloatComplex *prow = row.fortran_vec ();
 
       octave_idx_type howmany = numel () / npts;
@@ -616,6 +617,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
 {
@@ -819,20 +826,6 @@
   return *this;
 }
 
-FloatComplexMatrix
-FloatComplexNDArray::matrix_value (void) const
-{
-  FloatComplexMatrix retval;
-
-  if (ndims () == 2)
-    retval = FloatComplexMatrix (Array<FloatComplex> (*this));
-  else
-    (*current_liboctave_error_handler)
-      ("invalid conversion of FloatComplexNDArray to FloatComplexMatrix");
-
-  return retval;
-}
-
 void
 FloatComplexNDArray::increment_index (Array<octave_idx_type>& ra_idx,
                                       const dim_vector& dimensions,
--- a/liboctave/array/fCNDArray.h	Fri Feb 06 08:31:09 2015 -0800
+++ b/liboctave/array/fCNDArray.h	Fri Feb 06 08:31:49 2015 -0800
@@ -24,7 +24,6 @@
 #define octave_fCNDArray_h 1
 
 #include "MArray.h"
-#include "fCMatrix.h"
 
 #include "mx-defs.h"
 #include "mx-op-decl.h"
@@ -36,8 +35,6 @@
 {
 public:
 
-  typedef FloatComplexMatrix matrix_type;
-
   FloatComplexNDArray (void) : MArray<FloatComplex> () { }
 
   FloatComplexNDArray (const dim_vector& dv) : MArray<FloatComplex> (dv) { }
@@ -48,9 +45,6 @@
   FloatComplexNDArray (const FloatComplexNDArray& a)
     : MArray<FloatComplex> (a) { }
 
-  FloatComplexNDArray (const FloatComplexMatrix& a)
-    : MArray<FloatComplex> (a) { }
-
   template <class U>
   FloatComplexNDArray (const MArray<U>& a) : MArray<FloatComplex> (a) { }
 
@@ -83,6 +77,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;
@@ -128,8 +123,6 @@
   FloatComplexNDArray fourierNd (void) const;
   FloatComplexNDArray ifourierNd (void) const;
 
-  FloatComplexMatrix matrix_value (void) const;
-
   FloatComplexNDArray squeeze (void) const
   { return MArray<FloatComplex>::squeeze (); }
 
--- a/liboctave/array/fDiagMatrix.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/liboctave/array/fDiagMatrix.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -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;
@@ -329,7 +330,8 @@
 
   FloatDiagMatrix c (a_nr, b_nc);
 
-  octave_idx_type len = c.length (), lenm = len < a_nc ? len : a_nc;
+  octave_idx_type len = c.length ();
+  octave_idx_type lenm = len < a_nc ? len : a_nc;
 
   for (octave_idx_type i = 0; i < lenm; i++)
     c.dgxelem (i) = a.dgelem (i) * b.dgelem (i);
@@ -364,7 +366,8 @@
 FloatDiagMatrix::rcond (void) const
 {
   FloatColumnVector av = extract_diag (0).map<float> (fabsf);
-  float amx = av.max (), amn = av.min ();
+  float amx = av.max ();
+  float amn = av.min ();
   return amx == 0 ? 0.0f : amn / amx;
 }
 
--- a/liboctave/array/fDiagMatrix.h	Fri Feb 06 08:31:09 2015 -0800
+++ b/liboctave/array/fDiagMatrix.h	Fri Feb 06 08:31:49 2015 -0800
@@ -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 Feb 06 08:31:09 2015 -0800
+++ b/liboctave/array/fMatrix.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -32,7 +32,17 @@
 #include <iostream>
 #include <vector>
 
+#include "fNDArray.h"
 #include "Array-util.h"
+#include "boolMatrix.h"
+#include "chMatrix.h"
+#include "fMatrix.h"
+#include "fDiagMatrix.h"
+#include "fCMatrix.h"
+#include "fColVector.h"
+#include "fRowVector.h"
+#include "fCColVector.h"
+#include "PermMatrix.h"
 #include "DET.h"
 #include "byte-swap.h"
 #include "f77-fcn.h"
@@ -45,7 +55,6 @@
 #include "lo-ieee.h"
 #include "lo-mappers.h"
 #include "lo-utils.h"
-#include "mx-base.h"
 #include "mx-fdm-fm.h"
 #include "mx-fm-fdm.h"
 #include "mx-inlines.cc"
@@ -240,44 +249,54 @@
 // Matrix class.
 
 FloatMatrix::FloatMatrix (const FloatRowVector& rv)
-  : MArray<float> (rv)
+  : FloatNDArray (rv)
 {
 }
 
 FloatMatrix::FloatMatrix (const FloatColumnVector& cv)
-  : MArray<float> (cv)
+  : FloatNDArray (cv)
 {
 }
 
 FloatMatrix::FloatMatrix (const FloatDiagMatrix& a)
-  : MArray<float> (a.dims (), 0.0)
+  : FloatNDArray (a.dims (), 0.0)
+{
+  for (octave_idx_type i = 0; i < a.length (); i++)
+    elem (i, i) = a.elem (i, i);
+}
+
+FloatMatrix::FloatMatrix (const MDiagArray2<float>& a)
+  : FloatNDArray (a.dims (), 0.0)
+{
+  for (octave_idx_type i = 0; i < a.length (); i++)
+    elem (i, i) = a.elem (i, i);
+}
+
+FloatMatrix::FloatMatrix (const DiagArray2<float>& a)
+  : FloatNDArray (a.dims (), 0.0)
 {
   for (octave_idx_type i = 0; i < a.length (); i++)
     elem (i, i) = a.elem (i, i);
 }
 
 FloatMatrix::FloatMatrix (const PermMatrix& a)
-  : MArray<float> (a.dims (), 0.0)
+  : FloatNDArray (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?
 
 FloatMatrix::FloatMatrix (const boolMatrix& a)
-  : MArray<float> (a)
+  : FloatNDArray (a)
 {
 }
 
 FloatMatrix::FloatMatrix (const charMatrix& a)
-  : MArray<float> (a.dims ())
+  : FloatNDArray (a.dims ())
 {
   for (octave_idx_type i = 0; i < a.rows (); i++)
     for (octave_idx_type j = 0; j < a.cols (); j++)
@@ -319,7 +338,7 @@
 FloatMatrix::insert (const FloatMatrix& a,
                      octave_idx_type r, octave_idx_type c)
 {
-  Array<float>::insert (a, r, c);
+  FloatNDArray::insert (a, r, c);
   return *this;
 }
 
@@ -1390,7 +1409,7 @@
 float
 FloatMatrix::rcond (MatrixType &mattype) const
 {
-  float rcon;
+  float rcon = octave_NaN;
   octave_idx_type nr = rows ();
   octave_idx_type nc = cols ();
 
@@ -1586,11 +1605,27 @@
             {
               const float *tmp_data = fortran_vec ();
 
+              retval = b;
+              float *result = retval.fortran_vec ();
+
+              char uplo = 'U';
+              char trans = get_blas_char (transt);
+              char dia = 'N';
+
+              F77_XFCN (strtrs, STRTRS, (F77_CONST_CHAR_ARG2 (&uplo, 1),
+                                         F77_CONST_CHAR_ARG2 (&trans, 1),
+                                         F77_CONST_CHAR_ARG2 (&dia, 1),
+                                         nr, b_nc, tmp_data, nr,
+                                         result, nr, info
+                                         F77_CHAR_ARG_LEN (1)
+                                         F77_CHAR_ARG_LEN (1)
+                                         F77_CHAR_ARG_LEN (1)));
+
               if (calc_cond)
                 {
                   char norm = '1';
-                  char uplo = 'U';
-                  char dia = 'N';
+                  uplo = 'U';
+                  dia = 'N';
 
                   Array<float> z (dim_vector (3 * nc, 1));
                   float *pz = z.fortran_vec ();
@@ -1618,30 +1653,10 @@
                       if (sing_handler)
                         sing_handler (rcon);
                       else
-                        (*current_liboctave_error_handler)
-                          ("matrix singular to machine precision, rcond = %g",
-                           rcon);
+                        gripe_singular_matrix (rcon);
                     }
                 }
 
-              if (info == 0)
-                {
-                  retval = b;
-                  float *result = retval.fortran_vec ();
-
-                  char uplo = 'U';
-                  char trans = get_blas_char (transt);
-                  char dia = 'N';
-
-                  F77_XFCN (strtrs, STRTRS, (F77_CONST_CHAR_ARG2 (&uplo, 1),
-                                             F77_CONST_CHAR_ARG2 (&trans, 1),
-                                             F77_CONST_CHAR_ARG2 (&dia, 1),
-                                             nr, b_nc, tmp_data, nr,
-                                             result, nr, info
-                                             F77_CHAR_ARG_LEN (1)
-                                             F77_CHAR_ARG_LEN (1)
-                                             F77_CHAR_ARG_LEN (1)));
-                }
             }
         }
       else
@@ -1687,11 +1702,27 @@
             {
               const float *tmp_data = fortran_vec ();
 
+              retval = b;
+              float *result = retval.fortran_vec ();
+
+              char uplo = 'L';
+              char trans = get_blas_char (transt);
+              char dia = 'N';
+
+              F77_XFCN (strtrs, STRTRS, (F77_CONST_CHAR_ARG2 (&uplo, 1),
+                                         F77_CONST_CHAR_ARG2 (&trans, 1),
+                                         F77_CONST_CHAR_ARG2 (&dia, 1),
+                                         nr, b_nc, tmp_data, nr,
+                                         result, nr, info
+                                         F77_CHAR_ARG_LEN (1)
+                                         F77_CHAR_ARG_LEN (1)
+                                         F77_CHAR_ARG_LEN (1)));
+
               if (calc_cond)
                 {
                   char norm = '1';
-                  char uplo = 'L';
-                  char dia = 'N';
+                  uplo = 'L';
+                  dia = 'N';
 
                   Array<float> z (dim_vector (3 * nc, 1));
                   float *pz = z.fortran_vec ();
@@ -1719,30 +1750,9 @@
                       if (sing_handler)
                         sing_handler (rcon);
                       else
-                        (*current_liboctave_error_handler)
-                          ("matrix singular to machine precision, rcond = %g",
-                           rcon);
+                        gripe_singular_matrix (rcon);
                     }
                 }
-
-              if (info == 0)
-                {
-                  retval = b;
-                  float *result = retval.fortran_vec ();
-
-                  char uplo = 'L';
-                  char trans = get_blas_char (transt);
-                  char dia = 'N';
-
-                  F77_XFCN (strtrs, STRTRS, (F77_CONST_CHAR_ARG2 (&uplo, 1),
-                                             F77_CONST_CHAR_ARG2 (&trans, 1),
-                                             F77_CONST_CHAR_ARG2 (&dia, 1),
-                                             nr, b_nc, tmp_data, nr,
-                                             result, nr, info
-                                             F77_CHAR_ARG_LEN (1)
-                                             F77_CHAR_ARG_LEN (1)
-                                             F77_CHAR_ARG_LEN (1)));
-                }
             }
         }
       else
@@ -1824,9 +1834,7 @@
                       if (sing_handler)
                         sing_handler (rcon);
                       else
-                        (*current_liboctave_error_handler)
-                          ("matrix singular to machine precision, rcond = %g",
-                           rcon);
+                        gripe_singular_matrix (rcon);
                     }
                 }
 
@@ -1879,8 +1887,7 @@
               if (sing_handler)
                 sing_handler (rcon);
               else
-                (*current_liboctave_error_handler)
-                  ("matrix singular to machine precision");
+                gripe_singular_matrix ();
 
               mattype.mark_as_rectangular ();
             }
@@ -1908,9 +1915,7 @@
                       if (sing_handler)
                         sing_handler (rcon);
                       else
-                        (*current_liboctave_error_handler)
-                          ("matrix singular to machine precision, rcond = %g",
-                           rcon);
+                        gripe_singular_matrix (rcon);
                     }
                 }
 
@@ -1975,9 +1980,9 @@
 
   // Only calculate the condition number for LU/Cholesky
   if (typ == MatrixType::Upper || typ == MatrixType::Permuted_Upper)
-    retval = utsolve (mattype, b, info, rcon, sing_handler, false, transt);
+    retval = utsolve (mattype, b, info, rcon, sing_handler, true, transt);
   else if (typ == MatrixType::Lower || typ == MatrixType::Permuted_Lower)
-    retval = ltsolve (mattype, b, info, rcon, sing_handler, false, transt);
+    retval = ltsolve (mattype, b, info, rcon, sing_handler, true, transt);
   else if (transt == blas_trans || transt == blas_conj_trans)
     return transpose ().solve (mattype, b, info, rcon, sing_handler,
                                singular_fallback);
@@ -2026,7 +2031,9 @@
 static FloatMatrix
 stack_complex_matrix (const FloatComplexMatrix& cm)
 {
-  octave_idx_type m = cm.rows (), n = cm.cols (), nel = m*n;
+  octave_idx_type m = cm.rows ();
+  octave_idx_type n = cm.cols ();
+  octave_idx_type nel = m*n;
   FloatMatrix retval (m, 2*n);
   const FloatComplex *cmd = cm.data ();
   float *rd = retval.fortran_vec ();
@@ -2041,7 +2048,9 @@
 static FloatComplexMatrix
 unstack_complex_matrix (const FloatMatrix& sm)
 {
-  octave_idx_type m = sm.rows (), n = sm.cols () / 2, nel = m*n;
+  octave_idx_type m = sm.rows ();
+  octave_idx_type n = sm.cols () / 2;
+  octave_idx_type nel = m*n;
   FloatComplexMatrix retval (m, n);
   const float *smd = sm.data ();
   FloatComplex *rd = retval.fortran_vec ();
@@ -2645,17 +2654,6 @@
   return *this;
 }
 
-// unary operations
-
-boolMatrix
-FloatMatrix::operator ! (void) const
-{
-  if (any_element_is_nan ())
-    gripe_nan_to_logical_conversion ();
-
-  return do_mx_unary_op<bool, float> (*this, mx_inline_not);
-}
-
 // column vector by row vector -> matrix operations
 
 FloatMatrix
@@ -2683,139 +2681,48 @@
   return retval;
 }
 
-// other operations.
-
-bool
-FloatMatrix::any_element_is_negative (bool neg_zero) const
-{
-  return (neg_zero ? test_all (xnegative_sign)
-          : do_mx_check<float> (*this, mx_inline_any_negative));
-}
-
-bool
-FloatMatrix::any_element_is_positive (bool neg_zero) const
-{
-  return (neg_zero ? test_all (xpositive_sign)
-          : do_mx_check<float> (*this, mx_inline_any_positive));
-}
-
-bool
-FloatMatrix::any_element_is_nan (void) const
-{
-  return do_mx_check<float> (*this, mx_inline_any_nan);
-}
-
-bool
-FloatMatrix::any_element_is_inf_or_nan (void) const
-{
-  return ! do_mx_check<float> (*this, mx_inline_all_finite);
-}
-
-bool
-FloatMatrix::any_element_not_one_or_zero (void) const
-{
-  return ! test_all (xis_one_or_zero);
-}
-
-bool
-FloatMatrix::all_elements_are_int_or_inf_or_nan (void) const
-{
-  return test_all (xis_int_or_inf_or_nan);
-}
-
-// Return nonzero if any element of M is not an integer.  Also extract
-// the largest and smallest values and return them in MAX_VAL and MIN_VAL.
-
-bool
-FloatMatrix::all_integers (float& max_val, float& min_val) const
-{
-  octave_idx_type nel = nelem ();
-
-  if (nel > 0)
-    {
-      max_val = elem (0);
-      min_val = elem (0);
-    }
-  else
-    return false;
-
-  for (octave_idx_type i = 0; i < nel; i++)
-    {
-      float val = elem (i);
-
-      if (val > max_val)
-        max_val = val;
-
-      if (val < min_val)
-        min_val = val;
-
-      if (! xisinteger (val))
-        return false;
-    }
-
-  return true;
-}
-
-bool
-FloatMatrix::too_large_for_float (void) const
-{
-  return false;
-}
-
 // FIXME: Do these really belong here?  Maybe they should be in a base class?
 
-boolMatrix
-FloatMatrix::all (int dim) const
-{
-  return do_mx_red_op<bool, float> (*this, dim, mx_inline_all);
-}
-
-boolMatrix
-FloatMatrix::any (int dim) const
-{
-  return do_mx_red_op<bool, float> (*this, dim, mx_inline_any);
-}
-
 FloatMatrix
 FloatMatrix::cumprod (int dim) const
 {
-  return do_mx_cum_op<float, float> (*this, dim, mx_inline_cumprod);
+  return FloatNDArray::cumprod (dim);
 }
 
 FloatMatrix
 FloatMatrix::cumsum (int dim) const
 {
-  return do_mx_cum_op<float, float> (*this, dim, mx_inline_cumsum);
+  return FloatNDArray::cumsum (dim);
 }
 
 FloatMatrix
 FloatMatrix::prod (int dim) const
 {
-  return do_mx_red_op<float, float> (*this, dim, mx_inline_prod);
+  return FloatNDArray::prod (dim);
 }
 
 FloatMatrix
 FloatMatrix::sum (int dim) const
 {
-  return do_mx_red_op<float, float> (*this, dim, mx_inline_sum);
+  return FloatNDArray::sum (dim);
 }
 
 FloatMatrix
 FloatMatrix::sumsq (int dim) const
 {
-  return do_mx_red_op<float, float> (*this, dim, mx_inline_sumsq);
+  return FloatNDArray::sumsq (dim);
 }
 
 FloatMatrix
 FloatMatrix::abs (void) const
 {
-  return do_mx_unary_map<float, float, std::abs> (*this);
+  return FloatNDArray::abs ();
 }
 
 FloatMatrix
 FloatMatrix::diag (octave_idx_type k) const
 {
-  return MArray<float>::diag (k);
+  return FloatNDArray::diag (k);
 }
 
 FloatDiagMatrix
@@ -3157,7 +3064,7 @@
 
   // FIXME: check info?
 
-  retval = -ua*cx*ub.transpose ();
+  retval = ua*cx*ub.transpose ();
 
   return retval;
 }
@@ -3197,7 +3104,8 @@
 {
   FloatMatrix retval;
 
-  bool tra = transa != blas_no_trans, trb = transb != blas_no_trans;
+  bool tra = transa != blas_no_trans;
+  bool trb = transb != blas_no_trans;
 
   octave_idx_type a_nr = tra ? a.cols () : a.rows ();
   octave_idx_type a_nc = tra ? a.rows () : a.cols ();
@@ -3232,8 +3140,10 @@
         }
       else
         {
-          octave_idx_type lda = a.rows (), tda = a.cols ();
-          octave_idx_type ldb = b.rows (), tdb = b.cols ();
+          octave_idx_type lda = a.rows ();
+          octave_idx_type tda = a.cols ();
+          octave_idx_type ldb = b.rows ();
+          octave_idx_type tdb = b.cols ();
 
           retval = FloatMatrix (a_nr, b_nc);
           float *c = retval.fortran_vec ();
@@ -3302,7 +3212,7 @@
     for (octave_idx_type i = 0; i < nr; i++)
       {
         octave_quit ();
-        result (i, j) = xmin (d, m (i, j));
+        result(i, j) = xmin (d, m(i, j));
       }
 
   return result;
@@ -3322,7 +3232,7 @@
     for (octave_idx_type i = 0; i < nr; i++)
       {
         octave_quit ();
-        result (i, j) = xmin (m (i, j), d);
+        result(i, j) = xmin (m(i, j), d);
       }
 
   return result;
@@ -3349,7 +3259,7 @@
     for (octave_idx_type i = 0; i < nr; i++)
       {
         octave_quit ();
-        result (i, j) = xmin (a (i, j), b (i, j));
+        result(i, j) = xmin (a(i, j), b(i, j));
       }
 
   return result;
@@ -3369,7 +3279,7 @@
     for (octave_idx_type i = 0; i < nr; i++)
       {
         octave_quit ();
-        result (i, j) = xmax (d, m (i, j));
+        result(i, j) = xmax (d, m(i, j));
       }
 
   return result;
@@ -3389,7 +3299,7 @@
     for (octave_idx_type i = 0; i < nr; i++)
       {
         octave_quit ();
-        result (i, j) = xmax (m (i, j), d);
+        result(i, j) = xmax (m(i, j), d);
       }
 
   return result;
@@ -3416,7 +3326,7 @@
     for (octave_idx_type i = 0; i < nr; i++)
       {
         octave_quit ();
-        result (i, j) = xmax (a (i, j), b (i, j));
+        result(i, j) = xmax (a(i, j), b(i, j));
       }
 
   return result;
--- a/liboctave/array/fMatrix.h	Fri Feb 06 08:31:09 2015 -0800
+++ b/liboctave/array/fMatrix.h	Fri Feb 06 08:31:49 2015 -0800
@@ -23,6 +23,7 @@
 #if !defined (octave_fMatrix_h)
 #define octave_fMatrix_h 1
 
+#include "fNDArray.h"
 #include "MArray.h"
 #include "MDiagArray2.h"
 #include "MatrixType.h"
@@ -33,7 +34,7 @@
 
 class
 OCTAVE_API
-FloatMatrix : public MArray<float>
+FloatMatrix : public FloatNDArray
 {
 public:
 
@@ -42,26 +43,26 @@
 
   typedef void (*solve_singularity_handler) (float rcon);
 
-  FloatMatrix (void) : MArray<float> () { }
+  FloatMatrix (void) : FloatNDArray () { }
 
   FloatMatrix (octave_idx_type r, octave_idx_type c)
-    : MArray<float> (dim_vector (r, c)) { }
+    : FloatNDArray (dim_vector (r, c)) { }
 
   FloatMatrix (octave_idx_type r, octave_idx_type c, float val)
-    : MArray<float> (dim_vector (r, c), val) { }
+    : FloatNDArray (dim_vector (r, c), val) { }
 
-  FloatMatrix (const dim_vector& dv) : MArray<float> (dv.redim (2)) { }
+  FloatMatrix (const dim_vector& dv) : FloatNDArray (dv.redim (2)) { }
 
   FloatMatrix (const dim_vector& dv, float val)
-    : MArray<float> (dv.redim (2), val) { }
+    : FloatNDArray (dv.redim (2), val) { }
 
-  FloatMatrix (const FloatMatrix& a) : MArray<float> (a) { }
+  FloatMatrix (const FloatMatrix& a) : FloatNDArray (a) { }
 
   template <class U>
-  FloatMatrix (const MArray<U>& a) : MArray<float> (a.as_matrix ()) { }
+  FloatMatrix (const MArray<U>& a) : FloatNDArray (a.as_matrix ()) { }
 
   template <class U>
-  FloatMatrix (const Array<U>& a) : MArray<float> (a.as_matrix ()) { }
+  FloatMatrix (const Array<U>& a) : FloatNDArray (a.as_matrix ()) { }
 
   explicit FloatMatrix (const FloatRowVector& rv);
 
@@ -69,19 +70,16 @@
 
   explicit FloatMatrix (const FloatDiagMatrix& a);
 
+  explicit FloatMatrix (const MDiagArray2<float>& a);
+
+  explicit FloatMatrix (const DiagArray2<float>& a);
+
   explicit FloatMatrix (const PermMatrix& a);
 
   explicit FloatMatrix (const boolMatrix& a);
 
   explicit FloatMatrix (const charMatrix& a);
 
-
-  FloatMatrix& operator = (const FloatMatrix& a)
-  {
-    MArray<float>::operator = (a);
-    return *this;
-  }
-
   bool operator == (const FloatMatrix& a) const;
   bool operator != (const FloatMatrix& a) const;
 
@@ -323,24 +321,6 @@
   FloatMatrix& operator += (const FloatDiagMatrix& a);
   FloatMatrix& operator -= (const FloatDiagMatrix& a);
 
-  // unary operations
-
-  boolMatrix operator ! (void) const;
-
-  // other operations
-
-  bool any_element_is_negative (bool = false) const;
-  bool any_element_is_positive (bool = false) const;
-  bool any_element_is_nan (void) const;
-  bool any_element_is_inf_or_nan (void) const;
-  bool any_element_not_one_or_zero (void) const;
-  bool all_elements_are_int_or_inf_or_nan (void) const;
-  bool all_integers (float& max_val, float& min_val) const;
-  bool too_large_for_float (void) const;
-
-  boolMatrix all (int dim = -1) const;
-  boolMatrix any (int dim = -1) const;
-
   FloatMatrix cumprod (int dim = -1) const;
   FloatMatrix cumsum (int dim = -1) const;
   FloatMatrix prod (int dim = -1) const;
--- a/liboctave/array/fNDArray.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/liboctave/array/fNDArray.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -217,7 +217,7 @@
   FloatComplexNDArray retval (dv);
   octave_idx_type npts = dv(dim);
   octave_idx_type nn = 4*npts+15;
-  Array<FloatComplex> wsave (nn);
+  Array<FloatComplex> wsave (dim_vector (nn, 1));
   FloatComplex *pwsave = wsave.fortran_vec ();
 
   OCTAVE_LOCAL_BUFFER (FloatComplex, tmp, npts);
@@ -264,7 +264,7 @@
   FloatComplexNDArray retval (dv);
   octave_idx_type npts = dv(dim);
   octave_idx_type nn = 4*npts+15;
-  Array<FloatComplex> wsave (nn);
+  Array<FloatComplex> wsave (dim_vector (nn, 1));
   FloatComplex *pwsave = wsave.fortran_vec ();
 
   OCTAVE_LOCAL_BUFFER (FloatComplex, tmp, npts);
@@ -314,9 +314,9 @@
     {
       octave_idx_type npts = dv2(i);
       octave_idx_type nn = 4*npts+15;
-      Array<FloatComplex> wsave (nn);
+      Array<FloatComplex> wsave (dim_vector (nn, 1));
       FloatComplex *pwsave = wsave.fortran_vec ();
-      Array<FloatComplex> row (npts);
+      Array<FloatComplex> row (dim_vector (npts, 1));
       FloatComplex *prow = row.fortran_vec ();
 
       octave_idx_type howmany = numel () / npts;
@@ -362,9 +362,9 @@
     {
       octave_idx_type npts = dv2(i);
       octave_idx_type nn = 4*npts+15;
-      Array<FloatComplex> wsave (nn);
+      Array<FloatComplex> wsave (dim_vector (nn, 1));
       FloatComplex *pwsave = wsave.fortran_vec ();
-      Array<FloatComplex> row (npts);
+      Array<FloatComplex> row (dim_vector (npts, 1));
       FloatComplex *prow = row.fortran_vec ();
 
       octave_idx_type howmany = numel () / npts;
@@ -410,9 +410,9 @@
     {
       octave_idx_type npts = dv(i);
       octave_idx_type nn = 4*npts+15;
-      Array<FloatComplex> wsave (nn);
+      Array<FloatComplex> wsave (dim_vector (nn, 1));
       FloatComplex *pwsave = wsave.fortran_vec ();
-      Array<FloatComplex> row (npts);
+      Array<FloatComplex> row (dim_vector (npts, 1));
       FloatComplex *prow = row.fortran_vec ();
 
       octave_idx_type howmany = numel () / npts;
@@ -457,9 +457,9 @@
     {
       octave_idx_type npts = dv(i);
       octave_idx_type nn = 4*npts+15;
-      Array<FloatComplex> wsave (nn);
+      Array<FloatComplex> wsave (dim_vector (nn, 1));
       FloatComplex *pwsave = wsave.fortran_vec ();
-      Array<FloatComplex> row (npts);
+      Array<FloatComplex> row (dim_vector (npts, 1));
       FloatComplex *prow = row.fortran_vec ();
 
       octave_idx_type howmany = numel () / npts;
@@ -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
 {
@@ -806,20 +812,6 @@
   return do_mx_unary_map<bool, float, xfinite> (*this);
 }
 
-FloatMatrix
-FloatNDArray::matrix_value (void) const
-{
-  FloatMatrix retval;
-
-  if (ndims () == 2)
-    retval = FloatMatrix (Array<float> (*this));
-  else
-    (*current_liboctave_error_handler)
-      ("invalid conversion of FloatNDArray to FloatMatrix");
-
-  return retval;
-}
-
 void
 FloatNDArray::increment_index (Array<octave_idx_type>& ra_idx,
                                const dim_vector& dimensions,
--- a/liboctave/array/fNDArray.h	Fri Feb 06 08:31:09 2015 -0800
+++ b/liboctave/array/fNDArray.h	Fri Feb 06 08:31:49 2015 -0800
@@ -24,7 +24,6 @@
 #define octave_fNDArray_h 1
 
 #include "MArray.h"
-#include "fMatrix.h"
 #include "intNDArray.h"
 
 #include "mx-defs.h"
@@ -37,8 +36,6 @@
 {
 public:
 
-  typedef FloatMatrix matrix_type;
-
   FloatNDArray (void) : MArray<float> () { }
 
   FloatNDArray (const dim_vector& dv) : MArray<float> (dv) { }
@@ -48,8 +45,6 @@
 
   FloatNDArray (const FloatNDArray& a) : MArray<float> (a) { }
 
-  FloatNDArray (const FloatMatrix& a) : MArray<float> (a) { }
-
   template <class U>
   FloatNDArray (const MArray<U>& a) : MArray<float> (a) { }
 
@@ -90,6 +85,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;
@@ -136,8 +132,6 @@
 
   friend class FloatComplexNDArray;
 
-  FloatMatrix matrix_value (void) const;
-
   FloatNDArray squeeze (void) const { return MArray<float>::squeeze (); }
 
   static void increment_index (Array<octave_idx_type>& ra_idx,
--- a/liboctave/array/idx-vector.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/liboctave/array/idx-vector.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -63,7 +63,6 @@
   return Array<octave_idx_type> ();
 }
 
-DEFINE_OCTAVE_ALLOCATOR(idx_vector::idx_colon_rep);
 
 idx_vector::idx_colon_rep::idx_colon_rep (char c)
 {
@@ -103,7 +102,6 @@
   return os << ":";
 }
 
-DEFINE_OCTAVE_ALLOCATOR(idx_vector::idx_range_rep);
 
 idx_vector::idx_range_rep::idx_range_rep (octave_idx_type _start,
                                           octave_idx_type _limit,
@@ -258,7 +256,6 @@
   return convert_index (i, conv_error, ext);
 }
 
-DEFINE_OCTAVE_ALLOCATOR(idx_vector::idx_scalar_rep);
 
 template <class T>
 idx_vector::idx_scalar_rep::idx_scalar_rep (T x)
@@ -317,7 +314,6 @@
   return Array<octave_idx_type> (dim_vector (1, 1), data);
 }
 
-DEFINE_OCTAVE_ALLOCATOR(idx_vector::idx_vector_rep);
 
 template <class T>
 idx_vector::idx_vector_rep::idx_vector_rep (const Array<T>& nda)
@@ -440,7 +436,7 @@
       octave_idx_type nr = bnda.rows ();
 
       for (octave_idx_type j = 0; j < nc; j++)
-        for (octave_idx_type i = bnda.cidx(j); i < bnda.cidx(j+1); i++)
+        for (octave_idx_type i = bnda.cidx (j); i < bnda.cidx (j+1); i++)
           if (bnda.data (i))
             d[k++] = j * nr + bnda.ridx (i);
 
@@ -595,7 +591,8 @@
 
       for (octave_idx_type i = 0; i < len; i++)
         {
-          octave_idx_type j = data[i], k = cnt[j]++;
+          octave_idx_type j = data[i];
+          octave_idx_type k = cnt[j]++;
           new_data[k] = j;
           idx_data[k] = i;
         }
@@ -644,7 +641,6 @@
     }
 }
 
-DEFINE_OCTAVE_ALLOCATOR(idx_vector::idx_mask_rep);
 
 idx_vector::idx_mask_rep::idx_mask_rep (bool b)
   : data (0), len (b ? 1 : 0), ext (0), lsti (-1), lste (-1),
@@ -836,7 +832,8 @@
           {
             // (i:k:end,:) reduces to a range if i <= k and k divides n.
             idx_range_rep * r = dynamic_cast<idx_range_rep *> (rep);
-            octave_idx_type s = r->get_start (), l = r->length (n);
+            octave_idx_type s = r->get_start ();
+            octave_idx_type l = r->length (n);
             octave_idx_type t = r->get_step ();
             if (l*t == n)
               {
@@ -860,7 +857,8 @@
             idx_range_rep * rj = dynamic_cast<idx_range_rep *> (j.rep);
             if (rj->get_step () == 1)
               {
-                octave_idx_type sj = rj->get_start (), lj = rj->length (nj);
+                octave_idx_type sj = rj->get_start ();
+                octave_idx_type lj = rj->length (nj);
                 *this = new idx_range_rep (sj * n, lj * n, 1, DIRECT);
                 reduced = true;
               }
@@ -873,7 +871,8 @@
             idx_scalar_rep * r = dynamic_cast<idx_scalar_rep *> (rep);
             idx_range_rep * rj = dynamic_cast<idx_range_rep *> (j.rep);
             octave_idx_type k = r->get_data ();
-            octave_idx_type sj = rj->get_start (), lj = rj->length (nj);
+            octave_idx_type sj = rj->get_start ();
+            octave_idx_type lj = rj->length (nj);
             octave_idx_type tj = rj->get_step ();
             *this = new idx_range_rep (n * sj + k, lj, n * tj, DIRECT);
             reduced = true;
@@ -885,10 +884,12 @@
             // (i:k:end,p:q) reduces to a range if i <= k and k divides n.
             // (ones (1, m), ones (1, n)) reduces to (ones (1, m*n))
             idx_range_rep * r = dynamic_cast<idx_range_rep *> (rep);
-            octave_idx_type s = r->get_start (), l = r->length (n);
+            octave_idx_type s = r->get_start ();
+            octave_idx_type l = r->length (n);
             octave_idx_type t = r->get_step ();
             idx_range_rep * rj = dynamic_cast<idx_range_rep *> (j.rep);
-            octave_idx_type sj = rj->get_start (), lj = rj->length (nj);
+            octave_idx_type sj = rj->get_start ();
+            octave_idx_type lj = rj->length (nj);
             octave_idx_type tj = rj->get_step ();
             if ((l*t == n && tj == 1) || (t == 0 && tj == 0))
               {
@@ -922,7 +923,8 @@
             // (i:d:j,k) reduces to a range.
             idx_range_rep * r = dynamic_cast<idx_range_rep *> (rep);
             idx_scalar_rep * rj = dynamic_cast<idx_scalar_rep *> (j.rep);
-            octave_idx_type s = r->get_start (), l = r->length (nj);
+            octave_idx_type s = r->get_start ();
+            octave_idx_type l = r->length (nj);
             octave_idx_type t = r->get_step ();
             octave_idx_type k = rj->get_data ();
             *this = new idx_range_rep (n * k + s, l, t, DIRECT);
@@ -989,7 +991,8 @@
     case class_mask:
       {
         idx_mask_rep * r = dynamic_cast<idx_mask_rep *> (rep);
-        octave_idx_type ext = r->extent (0), len = r->length (0);
+        octave_idx_type ext = r->extent (0);
+        octave_idx_type len = r->length (0);
         if (ext == len)
           {
             l = 0;
@@ -1062,7 +1065,8 @@
     case class_range:
       {
         idx_range_rep * r = dynamic_cast<idx_range_rep *> (rep);
-        octave_idx_type start = r->get_start (), step = r->get_step ();
+        octave_idx_type start = r->get_start ();
+        octave_idx_type step = r->get_step ();
         octave_idx_type i, j;
         if (step == 1)
           for (i = start, j = start + len; i < j; i++) *data++ = i;
@@ -1084,7 +1088,7 @@
       {
         idx_vector_rep * r = dynamic_cast<idx_vector_rep *> (rep);
         const octave_idx_type *rdata = r->get_data ();
-        copy_or_memcpy (len, rdata, data);
+        std::copy (rdata, rdata + len, data);
       }
       break;
 
@@ -1116,7 +1120,8 @@
   if (idx_class () == class_mask)
     {
       idx_mask_rep * r = dynamic_cast<idx_mask_rep *> (rep);
-      octave_idx_type nz = r->length (0), ext = r->extent (0);
+      octave_idx_type nz = r->length (0);
+      octave_idx_type ext = r->extent (0);
       Array<bool> mask (dim_vector (n, 1));
       const bool *data = r->get_data ();
       bool *ndata = mask.fortran_vec ();
@@ -1207,7 +1212,8 @@
     {
       idx_mask_rep * r = dynamic_cast<idx_mask_rep *> (rep);
       const bool *data = r->get_data ();
-      octave_idx_type ext = r->extent (0), len = r->length (0);
+      octave_idx_type ext = r->extent (0);
+      octave_idx_type len = r->length (0);
       octave_idx_type *idata = new octave_idx_type [len];
 
       for (octave_idx_type i = 0, j = 0; i < ext; i++)
--- a/liboctave/array/idx-vector.h	Fri Feb 06 08:31:09 2015 -0800
+++ b/liboctave/array/idx-vector.h	Fri Feb 06 08:31:49 2015 -0800
@@ -26,6 +26,7 @@
 #define octave_idx_vector_h 1
 
 #include <cassert>
+#include <cstring>
 
 #include <algorithm>
 #include <iosfwd>
@@ -33,8 +34,6 @@
 
 #include "dim-vector.h"
 #include "oct-inttypes.h"
-#include "oct-alloc.h"
-#include "oct-mem.h"
 #include "oct-refcount.h"
 
 template<class T> class Array;
@@ -146,7 +145,6 @@
 
   private:
 
-    DECLARE_OCTAVE_ALLOCATOR
 
     // No copying!
     idx_colon_rep (const idx_colon_rep& idx);
@@ -208,7 +206,6 @@
 
   private:
 
-    DECLARE_OCTAVE_ALLOCATOR
 
     // No copying!
     idx_range_rep (const idx_range_rep& idx);
@@ -265,7 +262,6 @@
 
   private:
 
-    DECLARE_OCTAVE_ALLOCATOR
 
     // No copying!
     idx_scalar_rep (const idx_scalar_rep& idx);
@@ -332,7 +328,6 @@
 
   private:
 
-    DECLARE_OCTAVE_ALLOCATOR
 
     // No copying!
     idx_vector_rep (const idx_vector_rep& idx);
@@ -406,7 +401,6 @@
 
   private:
 
-    DECLARE_OCTAVE_ALLOCATOR
 
     // No copying!
     idx_mask_rep (const idx_mask_rep& idx);
@@ -631,16 +625,17 @@
     switch (rep->idx_class ())
       {
       case class_colon:
-        copy_or_memcpy (len, src, dest);
+        std::copy (src, src + len, dest);
         break;
 
       case class_range:
         {
           idx_range_rep * r = dynamic_cast<idx_range_rep *> (rep);
-          octave_idx_type start = r->get_start (), step = r->get_step ();
+          octave_idx_type start = r->get_start ();
+          octave_idx_type step = r->get_step ();
           const T *ssrc = src + start;
           if (step == 1)
-            copy_or_memcpy (len, ssrc, dest);
+            std::copy (ssrc, ssrc + len, dest);
           else if (step == -1)
             std::reverse_copy (ssrc - len + 1, ssrc + 1, dest);
           else if (step == 0)
@@ -704,16 +699,17 @@
     switch (rep->idx_class ())
       {
       case class_colon:
-        copy_or_memcpy (len, src, dest);
+        std::copy (src, src + len, dest);
         break;
 
       case class_range:
         {
           idx_range_rep * r = dynamic_cast<idx_range_rep *> (rep);
-          octave_idx_type start = r->get_start (), step = r->get_step ();
+          octave_idx_type start = r->get_start ();
+          octave_idx_type step = r->get_step ();
           T *sdest = dest + start;
           if (step == 1)
-            copy_or_memcpy (len, src, sdest);
+            std::copy (src, src + len, sdest);
           else if (step == -1)
             std::reverse_copy (src, src + len, sdest - len + 1);
           else
@@ -781,7 +777,8 @@
       case class_range:
         {
           idx_range_rep * r = dynamic_cast<idx_range_rep *> (rep);
-          octave_idx_type start = r->get_start (), step = r->get_step ();
+          octave_idx_type start = r->get_start ();
+          octave_idx_type step = r->get_step ();
           T *sdest = dest + start;
           if (step == 1)
             std::fill (sdest, sdest + len, val);
@@ -850,7 +847,8 @@
       case class_range:
         {
           idx_range_rep * r = dynamic_cast<idx_range_rep *> (rep);
-          octave_idx_type start = r->get_start (), step = r->get_step ();
+          octave_idx_type start = r->get_start ();
+          octave_idx_type step = r->get_step ();
           octave_idx_type i, j;
           if (step == 1)
             for (i = start, j = start + len; i < j; i++) body (i);
@@ -921,7 +919,8 @@
       case class_range:
         {
           idx_range_rep * r = dynamic_cast<idx_range_rep *> (rep);
-          octave_idx_type start = r->get_start (), step = r->get_step ();
+          octave_idx_type start = r->get_start ();
+          octave_idx_type step = r->get_step ();
           octave_idx_type i, j;
           if (step == 1)
             for (i = start, j = start + len; i < j && body (i); i++) ;
@@ -954,7 +953,8 @@
         {
           idx_mask_rep * r = dynamic_cast<idx_mask_rep *> (rep);
           const bool *data = r->get_data ();
-          octave_idx_type ext = r->extent (0), j = 0;
+          octave_idx_type ext = r->extent (0);
+          octave_idx_type j = 0;
           for (octave_idx_type i = 0; i < ext; i++)
             {
               if (data[i])
--- a/liboctave/array/intNDArray.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/liboctave/array/intNDArray.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -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 Feb 06 08:31:09 2015 -0800
+++ b/liboctave/array/intNDArray.h	Fri Feb 06 08:31:49 2015 -0800
@@ -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/array/module.mk	Fri Feb 06 08:31:09 2015 -0800
+++ b/liboctave/array/module.mk	Fri Feb 06 08:31:49 2015 -0800
@@ -2,10 +2,7 @@
   array/module.mk
 
 ARRAY_INC = \
-  array/Array2.h \
-  array/Array3.h \
   array/Array.h \
-  array/ArrayN.h \
   array/Array-util.h \
   array/boolMatrix.h \
   array/boolNDArray.h \
@@ -42,11 +39,9 @@
   array/int64NDArray.h \
   array/int8NDArray.h \
   array/intNDArray.h \
-  array/MArray2.h \
   array/MArray-decl.h \
   array/MArray-defs.h \
   array/MArray.h \
-  array/MArrayN.h \
   array/Matrix.h \
   array/MatrixType.h \
   array/MDiagArray2.h \
@@ -139,5 +134,7 @@
 array_libarray_la_SOURCES = $(ARRAY_SRC)
 array_libarray_la_CPPFLAGS = \
   $(liboctave_la_CPPFLAGS) \
+  $(FFTW_XCPPFLAGS) \
   $(SPARSE_XCPPFLAGS)
 
+liboctave_la_LIBADD += array/libarray.la
--- a/liboctave/cruft/Faddeeva/module.mk	Fri Feb 06 08:31:09 2015 -0800
+++ b/liboctave/cruft/Faddeeva/module.mk	Fri Feb 06 08:31:49 2015 -0800
@@ -1,3 +1,5 @@
-EXTRA_DIST += Faddeeva/module.mk
+EXTRA_DIST += cruft/Faddeeva/module.mk
 
-libcruft_la_SOURCES += Faddeeva/Faddeeva.cc Faddeeva/Faddeeva.hh
+CRUFT_SOURCES += \
+  cruft/Faddeeva/Faddeeva.cc \
+  cruft/Faddeeva/Faddeeva.hh
--- a/liboctave/cruft/Makefile.am	Fri Feb 06 08:31:09 2015 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,69 +0,0 @@
-# Makefile for Octave's liboctave/cruft directory
-#
-# Copyright (C) 1993-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/>.
-
-include $(top_srcdir)/build-aux/common.mk
-
-## Search local directories before those specified by the user.
-AM_CPPFLAGS = \
-  -I$(top_builddir)/libgnu -I$(top_srcdir)/libgnu
-
-EXTRA_DIST = mkf77def.in
-
-noinst_LTLIBRARIES = libcruft.la
-
-libcruft_la_SOURCES =
-
-nodist_libcruft_la_SOURCES =
-
-libcruft_la_FFLAGS = $(F77_INTEGER_8_FLAG)
-
-libcruft_la_CPPFLAGS = @CRUFT_DLL_DEFS@ $(AM_CPPFLAGS)
-
-libcruft_la_DEPENDENCIES = cruft.def
-
-octinclude_HEADERS =
-
-include amos/module.mk
-include blas-xtra/module.mk
-include daspk/module.mk
-include dasrt/module.mk
-include dassl/module.mk
-include Faddeeva/module.mk
-include fftpack/module.mk
-include lapack-xtra/module.mk
-include misc/module.mk
-include odepack/module.mk
-include ordered-qz/module.mk
-include quadpack/module.mk
-include ranlib/module.mk
-include slatec-err/module.mk
-include slatec-fn/module.mk
-
-## Special rules for files which must be built before compilation
-cruft.def: $(libcruft_la_SOURCES) mkf77def
-	chmod a+rx mkf77def
-	./mkf77def $(srcdir) $(libcruft_la_SOURCES) > $@-t
-	mv $@-t $@
-
-DISTCLEANFILES = \
-  cruft.def \
-  ranlib/ranlib.def \
-  $(nodist_libcruft_la_SOURCES)
-
--- a/liboctave/cruft/amos/module.mk	Fri Feb 06 08:31:09 2015 -0800
+++ b/liboctave/cruft/amos/module.mk	Fri Feb 06 08:31:49 2015 -0800
@@ -1,69 +1,69 @@
-EXTRA_DIST += amos/module.mk
+EXTRA_DIST += cruft/amos/module.mk
 
-libcruft_la_SOURCES += \
-  amos/cacai.f \
-  amos/cacon.f \
-  amos/cbesh.f \
-  amos/cbesi.f \
-  amos/cbesj.f \
-  amos/cbesk.f \
-  amos/cbesy.f \
-  amos/cbinu.f \
-  amos/cbuni.f \
-  amos/cbunk.f \
-  amos/cunk1.f \
-  amos/cunk2.f \
-  amos/crati.f \
-  amos/cshch.f \
-  amos/cuni1.f \
-  amos/cuoik.f \
-  amos/cairy.f \
-  amos/cbiry.f \
-  amos/ckscl.f \
-  amos/cs1s2.f \
-  amos/cuchk.f \
-  amos/cuni2.f \
-  amos/cwrsk.f \
-  amos/casyi.f \
-  amos/cbknu.f \
-  amos/cmlri.f \
-  amos/cseri.f \
-  amos/cunhj.f \
-  amos/cunik.f \
-  amos/dgamln.f \
-  amos/gamln.f \
-  amos/xzabs.f \
-  amos/xzexp.f \
-  amos/xzlog.f \
-  amos/xzsqrt.f \
-  amos/zacai.f \
-  amos/zacon.f \
-  amos/zairy.f \
-  amos/zasyi.f \
-  amos/zbesh.f \
-  amos/zbesi.f \
-  amos/zbesj.f \
-  amos/zbesk.f \
-  amos/zbesy.f \
-  amos/zbinu.f \
-  amos/zbiry.f \
-  amos/zbknu.f \
-  amos/zbuni.f \
-  amos/zbunk.f \
-  amos/zdiv.f \
-  amos/zkscl.f \
-  amos/zmlri.f \
-  amos/zmlt.f \
-  amos/zrati.f \
-  amos/zs1s2.f \
-  amos/zseri.f \
-  amos/zshch.f \
-  amos/zuchk.f \
-  amos/zunhj.f \
-  amos/zuni1.f \
-  amos/zuni2.f \
-  amos/zunik.f \
-  amos/zunk1.f \
-  amos/zunk2.f \
-  amos/zuoik.f \
-  amos/zwrsk.f
+CRUFT_SOURCES += \
+  cruft/amos/cacai.f \
+  cruft/amos/cacon.f \
+  cruft/amos/cbesh.f \
+  cruft/amos/cbesi.f \
+  cruft/amos/cbesj.f \
+  cruft/amos/cbesk.f \
+  cruft/amos/cbesy.f \
+  cruft/amos/cbinu.f \
+  cruft/amos/cbuni.f \
+  cruft/amos/cbunk.f \
+  cruft/amos/cunk1.f \
+  cruft/amos/cunk2.f \
+  cruft/amos/crati.f \
+  cruft/amos/cshch.f \
+  cruft/amos/cuni1.f \
+  cruft/amos/cuoik.f \
+  cruft/amos/cairy.f \
+  cruft/amos/cbiry.f \
+  cruft/amos/ckscl.f \
+  cruft/amos/cs1s2.f \
+  cruft/amos/cuchk.f \
+  cruft/amos/cuni2.f \
+  cruft/amos/cwrsk.f \
+  cruft/amos/casyi.f \
+  cruft/amos/cbknu.f \
+  cruft/amos/cmlri.f \
+  cruft/amos/cseri.f \
+  cruft/amos/cunhj.f \
+  cruft/amos/cunik.f \
+  cruft/amos/dgamln.f \
+  cruft/amos/gamln.f \
+  cruft/amos/xzabs.f \
+  cruft/amos/xzexp.f \
+  cruft/amos/xzlog.f \
+  cruft/amos/xzsqrt.f \
+  cruft/amos/zacai.f \
+  cruft/amos/zacon.f \
+  cruft/amos/zairy.f \
+  cruft/amos/zasyi.f \
+  cruft/amos/zbesh.f \
+  cruft/amos/zbesi.f \
+  cruft/amos/zbesj.f \
+  cruft/amos/zbesk.f \
+  cruft/amos/zbesy.f \
+  cruft/amos/zbinu.f \
+  cruft/amos/zbiry.f \
+  cruft/amos/zbknu.f \
+  cruft/amos/zbuni.f \
+  cruft/amos/zbunk.f \
+  cruft/amos/zdiv.f \
+  cruft/amos/zkscl.f \
+  cruft/amos/zmlri.f \
+  cruft/amos/zmlt.f \
+  cruft/amos/zrati.f \
+  cruft/amos/zs1s2.f \
+  cruft/amos/zseri.f \
+  cruft/amos/zshch.f \
+  cruft/amos/zuchk.f \
+  cruft/amos/zunhj.f \
+  cruft/amos/zuni1.f \
+  cruft/amos/zuni2.f \
+  cruft/amos/zunik.f \
+  cruft/amos/zunk1.f \
+  cruft/amos/zunk2.f \
+  cruft/amos/zuoik.f \
+  cruft/amos/zwrsk.f
--- a/liboctave/cruft/blas-xtra/module.mk	Fri Feb 06 08:31:09 2015 -0800
+++ b/liboctave/cruft/blas-xtra/module.mk	Fri Feb 06 08:31:49 2015 -0800
@@ -1,28 +1,28 @@
-EXTRA_DIST += blas-xtra/module.mk
+EXTRA_DIST += cruft/blas-xtra/module.mk
 
-libcruft_la_SOURCES += \
-  blas-xtra/ddot3.f \
-  blas-xtra/zdotc3.f \
-  blas-xtra/sdot3.f \
-  blas-xtra/cdotc3.f \
-  blas-xtra/dmatm3.f \
-  blas-xtra/zmatm3.f \
-  blas-xtra/smatm3.f \
-  blas-xtra/cmatm3.f \
-  blas-xtra/xddot.f \
-  blas-xtra/xdnrm2.f \
-  blas-xtra/xdznrm2.f \
-  blas-xtra/xzdotc.f \
-  blas-xtra/xzdotu.f \
-  blas-xtra/xsdot.f \
-  blas-xtra/xsnrm2.f \
-  blas-xtra/xscnrm2.f \
-  blas-xtra/xcdotc.f \
-  blas-xtra/xcdotu.f \
-  blas-xtra/xerbla.f \
-  blas-xtra/cconv2.f \
-  blas-xtra/csconv2.f \
-  blas-xtra/dconv2.f \
-  blas-xtra/sconv2.f \
-  blas-xtra/zconv2.f \
-  blas-xtra/zdconv2.f
+CRUFT_SOURCES += \
+  cruft/blas-xtra/ddot3.f \
+  cruft/blas-xtra/zdotc3.f \
+  cruft/blas-xtra/sdot3.f \
+  cruft/blas-xtra/cdotc3.f \
+  cruft/blas-xtra/dmatm3.f \
+  cruft/blas-xtra/zmatm3.f \
+  cruft/blas-xtra/smatm3.f \
+  cruft/blas-xtra/cmatm3.f \
+  cruft/blas-xtra/xddot.f \
+  cruft/blas-xtra/xdnrm2.f \
+  cruft/blas-xtra/xdznrm2.f \
+  cruft/blas-xtra/xzdotc.f \
+  cruft/blas-xtra/xzdotu.f \
+  cruft/blas-xtra/xsdot.f \
+  cruft/blas-xtra/xsnrm2.f \
+  cruft/blas-xtra/xscnrm2.f \
+  cruft/blas-xtra/xcdotc.f \
+  cruft/blas-xtra/xcdotu.f \
+  cruft/blas-xtra/xerbla.f \
+  cruft/blas-xtra/cconv2.f \
+  cruft/blas-xtra/csconv2.f \
+  cruft/blas-xtra/dconv2.f \
+  cruft/blas-xtra/sconv2.f \
+  cruft/blas-xtra/zconv2.f \
+  cruft/blas-xtra/zdconv2.f
--- a/liboctave/cruft/daspk/module.mk	Fri Feb 06 08:31:09 2015 -0800
+++ b/liboctave/cruft/daspk/module.mk	Fri Feb 06 08:31:49 2015 -0800
@@ -1,31 +1,31 @@
-EXTRA_DIST += daspk/module.mk
+EXTRA_DIST += cruft/daspk/module.mk
 
-libcruft_la_SOURCES += \
-  daspk/datv.f \
-  daspk/dcnst0.f \
-  daspk/dcnstr.f \
-  daspk/ddasic.f \
-  daspk/ddasid.f \
-  daspk/ddasik.f \
-  daspk/ddaspk.f \
-  daspk/ddstp.f \
-  daspk/ddwnrm.f \
-  daspk/dfnrmd.f \
-  daspk/dfnrmk.f \
-  daspk/dhels.f \
-  daspk/dheqr.f \
-  daspk/dinvwt.f \
-  daspk/dlinsd.f \
-  daspk/dlinsk.f \
-  daspk/dmatd.f \
-  daspk/dnedd.f \
-  daspk/dnedk.f \
-  daspk/dnsd.f \
-  daspk/dnsid.f \
-  daspk/dnsik.f \
-  daspk/dnsk.f \
-  daspk/dorth.f \
-  daspk/dslvd.f \
-  daspk/dslvk.f \
-  daspk/dspigm.f \
-  daspk/dyypnw.f
+CRUFT_SOURCES += \
+  cruft/daspk/datv.f \
+  cruft/daspk/dcnst0.f \
+  cruft/daspk/dcnstr.f \
+  cruft/daspk/ddasic.f \
+  cruft/daspk/ddasid.f \
+  cruft/daspk/ddasik.f \
+  cruft/daspk/ddaspk.f \
+  cruft/daspk/ddstp.f \
+  cruft/daspk/ddwnrm.f \
+  cruft/daspk/dfnrmd.f \
+  cruft/daspk/dfnrmk.f \
+  cruft/daspk/dhels.f \
+  cruft/daspk/dheqr.f \
+  cruft/daspk/dinvwt.f \
+  cruft/daspk/dlinsd.f \
+  cruft/daspk/dlinsk.f \
+  cruft/daspk/dmatd.f \
+  cruft/daspk/dnedd.f \
+  cruft/daspk/dnedk.f \
+  cruft/daspk/dnsd.f \
+  cruft/daspk/dnsid.f \
+  cruft/daspk/dnsik.f \
+  cruft/daspk/dnsk.f \
+  cruft/daspk/dorth.f \
+  cruft/daspk/dslvd.f \
+  cruft/daspk/dslvk.f \
+  cruft/daspk/dspigm.f \
+  cruft/daspk/dyypnw.f
--- a/liboctave/cruft/dasrt/module.mk	Fri Feb 06 08:31:09 2015 -0800
+++ b/liboctave/cruft/dasrt/module.mk	Fri Feb 06 08:31:49 2015 -0800
@@ -1,6 +1,6 @@
-EXTRA_DIST += dasrt/module.mk
+EXTRA_DIST += cruft/dasrt/module.mk
 
-libcruft_la_SOURCES += \
-  dasrt/ddasrt.f \
-  dasrt/drchek.f \
-  dasrt/droots.f
+CRUFT_SOURCES += \
+  cruft/dasrt/ddasrt.f \
+  cruft/dasrt/drchek.f \
+  cruft/dasrt/droots.f
--- a/liboctave/cruft/dassl/module.mk	Fri Feb 06 08:31:09 2015 -0800
+++ b/liboctave/cruft/dassl/module.mk	Fri Feb 06 08:31:49 2015 -0800
@@ -1,11 +1,11 @@
-EXTRA_DIST += dassl/module.mk
+EXTRA_DIST += cruft/dassl/module.mk
 
-libcruft_la_SOURCES += \
-  dassl/ddaini.f \
-  dassl/ddajac.f \
-  dassl/ddanrm.f \
-  dassl/ddaslv.f \
-  dassl/ddassl.f \
-  dassl/ddastp.f \
-  dassl/ddatrp.f \
-  dassl/ddawts.f
+CRUFT_SOURCES += \
+  cruft/dassl/ddaini.f \
+  cruft/dassl/ddajac.f \
+  cruft/dassl/ddanrm.f \
+  cruft/dassl/ddaslv.f \
+  cruft/dassl/ddassl.f \
+  cruft/dassl/ddastp.f \
+  cruft/dassl/ddatrp.f \
+  cruft/dassl/ddawts.f
--- a/liboctave/cruft/fftpack/module.mk	Fri Feb 06 08:31:09 2015 -0800
+++ b/liboctave/cruft/fftpack/module.mk	Fri Feb 06 08:31:49 2015 -0800
@@ -1,43 +1,43 @@
 EXTRA_DIST += \
-  fftpack/module.mk \
-  fftpack/fftpack.doc
+  cruft/fftpack/module.mk \
+  cruft/fftpack/fftpack.doc
 
 FFTPACK_SRC = \
-  fftpack/cfftb.f \
-  fftpack/cfftb1.f \
-  fftpack/cfftf.f \
-  fftpack/cfftf1.f \
-  fftpack/cffti.f \
-  fftpack/cffti1.f \
-  fftpack/passb.f \
-  fftpack/passb2.f \
-  fftpack/passb3.f \
-  fftpack/passb4.f \
-  fftpack/passb5.f \
-  fftpack/passf.f \
-  fftpack/passf2.f \
-  fftpack/passf3.f \
-  fftpack/passf4.f \
-  fftpack/passf5.f \
-  fftpack/zfftb.f \
-  fftpack/zfftb1.f \
-  fftpack/zfftf.f \
-  fftpack/zfftf1.f \
-  fftpack/zffti.f \
-  fftpack/zffti1.f \
-  fftpack/zpassb.f \
-  fftpack/zpassb2.f \
-  fftpack/zpassb3.f \
-  fftpack/zpassb4.f \
-  fftpack/zpassb5.f \
-  fftpack/zpassf.f \
-  fftpack/zpassf2.f \
-  fftpack/zpassf3.f \
-  fftpack/zpassf4.f \
-  fftpack/zpassf5.f
+  cruft/fftpack/cfftb.f \
+  cruft/fftpack/cfftb1.f \
+  cruft/fftpack/cfftf.f \
+  cruft/fftpack/cfftf1.f \
+  cruft/fftpack/cffti.f \
+  cruft/fftpack/cffti1.f \
+  cruft/fftpack/passb.f \
+  cruft/fftpack/passb2.f \
+  cruft/fftpack/passb3.f \
+  cruft/fftpack/passb4.f \
+  cruft/fftpack/passb5.f \
+  cruft/fftpack/passf.f \
+  cruft/fftpack/passf2.f \
+  cruft/fftpack/passf3.f \
+  cruft/fftpack/passf4.f \
+  cruft/fftpack/passf5.f \
+  cruft/fftpack/zfftb.f \
+  cruft/fftpack/zfftb1.f \
+  cruft/fftpack/zfftf.f \
+  cruft/fftpack/zfftf1.f \
+  cruft/fftpack/zffti.f \
+  cruft/fftpack/zffti1.f \
+  cruft/fftpack/zpassb.f \
+  cruft/fftpack/zpassb2.f \
+  cruft/fftpack/zpassb3.f \
+  cruft/fftpack/zpassb4.f \
+  cruft/fftpack/zpassb5.f \
+  cruft/fftpack/zpassf.f \
+  cruft/fftpack/zpassf2.f \
+  cruft/fftpack/zpassf3.f \
+  cruft/fftpack/zpassf4.f \
+  cruft/fftpack/zpassf5.f
 
 if AMCOND_HAVE_FFTW
   EXTRA_DIST += $(FFTPACK_SRC)
 else
-  libcruft_la_SOURCES += $(FFTPACK_SRC)
+  CRUFT_SOURCES += $(FFTPACK_SRC)
 endif
--- a/liboctave/cruft/lapack-xtra/module.mk	Fri Feb 06 08:31:09 2015 -0800
+++ b/liboctave/cruft/lapack-xtra/module.mk	Fri Feb 06 08:31:49 2015 -0800
@@ -1,12 +1,12 @@
-EXTRA_DIST += lapack-xtra/module.mk
+EXTRA_DIST += cruft/lapack-xtra/module.mk
 
-libcruft_la_SOURCES += \
-  lapack-xtra/xclange.f \
-  lapack-xtra/xdlamch.f \
-  lapack-xtra/xdlange.f \
-  lapack-xtra/xilaenv.f \
-  lapack-xtra/xslamch.f \
-  lapack-xtra/xslange.f \
-  lapack-xtra/xzlange.f \
-  lapack-xtra/zrsf2csf.f \
-  lapack-xtra/crsf2csf.f
+CRUFT_SOURCES += \
+  cruft/lapack-xtra/xclange.f \
+  cruft/lapack-xtra/xdlamch.f \
+  cruft/lapack-xtra/xdlange.f \
+  cruft/lapack-xtra/xilaenv.f \
+  cruft/lapack-xtra/xslamch.f \
+  cruft/lapack-xtra/xslange.f \
+  cruft/lapack-xtra/xzlange.f \
+  cruft/lapack-xtra/zrsf2csf.f \
+  cruft/lapack-xtra/crsf2csf.f
--- a/liboctave/cruft/misc/module.mk	Fri Feb 06 08:31:09 2015 -0800
+++ b/liboctave/cruft/misc/module.mk	Fri Feb 06 08:31:49 2015 -0800
@@ -1,19 +1,19 @@
 EXTRA_DIST += \
-  misc/module.mk \
-  misc/d1mach-tst.for
+  cruft/misc/module.mk \
+  cruft/misc/d1mach-tst.for
 
-libcruft_la_SOURCES += \
-  misc/blaswrap.c \
-  misc/cquit.c \
-  misc/d1mach.f \
-  misc/f77-extern.cc \
-  misc/f77-fcn.c \
-  misc/i1mach.f \
-  misc/lo-error.c \
-  misc/quit.cc \
-  misc/r1mach.f
+CRUFT_SOURCES += \
+  cruft/misc/blaswrap.c \
+  cruft/misc/cquit.c \
+  cruft/misc/d1mach.f \
+  cruft/misc/f77-extern.cc \
+  cruft/misc/f77-fcn.c \
+  cruft/misc/i1mach.f \
+  cruft/misc/lo-error.c \
+  cruft/misc/quit.cc \
+  cruft/misc/r1mach.f
 
-octinclude_HEADERS += \
-  misc/f77-fcn.h \
-  misc/lo-error.h \
-  misc/quit.h
+CRUFT_INC += \
+  cruft/misc/f77-fcn.h \
+  cruft/misc/lo-error.h \
+  cruft/misc/quit.h
--- a/liboctave/cruft/misc/quit.h	Fri Feb 06 08:31:09 2015 -0800
+++ b/liboctave/cruft/misc/quit.h	Fri Feb 06 08:31:49 2015 -0800
@@ -23,16 +23,16 @@
 #if !defined (octave_quit_h)
 #define octave_quit_h 1
 
+#include <stdio.h>
+
+#include <signal.h>
+#include <setjmp.h>
+
 #ifdef __cplusplus
 #include <new>
 extern "C" {
 #endif
 
-#include <stdio.h>
-
-#include <signal.h>
-#include <setjmp.h>
-
 #if defined (__WIN32__) && ! defined (_POSIX_VERSION)
 
 #define WIN32_LEAN_AND_MEAN
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/liboctave/cruft/module.mk	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,47 @@
+EXTRA_DIST += cruft/mkf77def.in
+
+nodist_cruft_libcruft_la_SOURCES =
+
+cruft_libcruft_la_FFLAGS = $(F77_INTEGER_8_FLAG)
+
+cruft_libcruft_la_DEPENDENCIES = cruft/cruft.def
+
+CRUFT_INC =
+
+CRUFT_SOURCES =
+
+include cruft/amos/module.mk
+include cruft/blas-xtra/module.mk
+include cruft/daspk/module.mk
+include cruft/dasrt/module.mk
+include cruft/dassl/module.mk
+include cruft/Faddeeva/module.mk
+include cruft/fftpack/module.mk
+include cruft/lapack-xtra/module.mk
+include cruft/misc/module.mk
+include cruft/odepack/module.mk
+include cruft/ordered-qz/module.mk
+include cruft/quadpack/module.mk
+include cruft/ranlib/module.mk
+include cruft/slatec-err/module.mk
+include cruft/slatec-fn/module.mk
+
+## Special rules for files which must be built before compilation
+cruft/cruft.def: $(cruft_libcruft_la_SOURCES) cruft/mkf77def
+	chmod a+rx cruft/mkf77def
+	./cruft/mkf77def $(srcdir) $(cruft_libcruft_la_SOURCES) > $@-t
+	mv $@-t $@
+
+DISTCLEANFILES += \
+  cruft/cruft.def \
+  cruft/mkf77def \
+  cruft/ranlib/ranlib.def \
+  $(nodist_cruft_libcruft_la_SOURCES)
+
+noinst_LTLIBRARIES += cruft/libcruft.la
+
+cruft_libcruft_la_SOURCES = $(CRUFT_SOURCES)
+cruft_libcruft_la_CPPFLAGS = \
+  $(liboctave_la_CPPFLAGS)
+
+liboctave_la_LIBADD += cruft/libcruft.la
--- a/liboctave/cruft/odepack/module.mk	Fri Feb 06 08:31:09 2015 -0800
+++ b/liboctave/cruft/odepack/module.mk	Fri Feb 06 08:31:49 2015 -0800
@@ -1,19 +1,19 @@
-EXTRA_DIST += odepack/module.mk
+EXTRA_DIST += cruft/odepack/module.mk
 
-libcruft_la_SOURCES += \
-  odepack/cfode.f \
-  odepack/dlsode.f \
-  odepack/ewset.f \
-  odepack/intdy.f \
-  odepack/prepj.f \
-  odepack/solsy.f \
-  odepack/stode.f \
-  odepack/vnorm.f \
-  odepack/scfode.f \
-  odepack/sewset.f \
-  odepack/sintdy.f \
-  odepack/slsode.f \
-  odepack/sprepj.f \
-  odepack/ssolsy.f \
-  odepack/sstode.f \
-  odepack/svnorm.f
+CRUFT_SOURCES += \
+  cruft/odepack/cfode.f \
+  cruft/odepack/dlsode.f \
+  cruft/odepack/ewset.f \
+  cruft/odepack/intdy.f \
+  cruft/odepack/prepj.f \
+  cruft/odepack/solsy.f \
+  cruft/odepack/stode.f \
+  cruft/odepack/vnorm.f \
+  cruft/odepack/scfode.f \
+  cruft/odepack/sewset.f \
+  cruft/odepack/sintdy.f \
+  cruft/odepack/slsode.f \
+  cruft/odepack/sprepj.f \
+  cruft/odepack/ssolsy.f \
+  cruft/odepack/sstode.f \
+  cruft/odepack/svnorm.f
--- a/liboctave/cruft/ordered-qz/module.mk	Fri Feb 06 08:31:09 2015 -0800
+++ b/liboctave/cruft/ordered-qz/module.mk	Fri Feb 06 08:31:49 2015 -0800
@@ -1,7 +1,7 @@
-EXTRA_DIST += ordered-qz/module.mk
+EXTRA_DIST += cruft/ordered-qz/module.mk
 
-libcruft_la_SOURCES += \
-  ordered-qz/dsubsp.f \
-  ordered-qz/exchqz.f \
-  ordered-qz/ssubsp.f \
-  ordered-qz/sexchqz.f
+CRUFT_SOURCES += \
+  cruft/ordered-qz/dsubsp.f \
+  cruft/ordered-qz/exchqz.f \
+  cruft/ordered-qz/ssubsp.f \
+  cruft/ordered-qz/sexchqz.f
--- a/liboctave/cruft/quadpack/module.mk	Fri Feb 06 08:31:09 2015 -0800
+++ b/liboctave/cruft/quadpack/module.mk	Fri Feb 06 08:31:49 2015 -0800
@@ -1,20 +1,20 @@
-EXTRA_DIST += quadpack/module.mk
+EXTRA_DIST += cruft/quadpack/module.mk
 
-libcruft_la_SOURCES += \
-  quadpack/dqagi.f \
-  quadpack/dqagie.f \
-  quadpack/dqagp.f \
-  quadpack/dqagpe.f \
-  quadpack/dqelg.f \
-  quadpack/dqk15i.f \
-  quadpack/dqk21.f \
-  quadpack/dqpsrt.f \
-  quadpack/qagie.f \
-  quadpack/qagi.f \
-  quadpack/qagpe.f \
-  quadpack/qagp.f \
-  quadpack/qelg.f \
-  quadpack/qk15i.f \
-  quadpack/qk21.f \
-  quadpack/qpsrt.f \
-  quadpack/xerror.f
+CRUFT_SOURCES += \
+  cruft/quadpack/dqagi.f \
+  cruft/quadpack/dqagie.f \
+  cruft/quadpack/dqagp.f \
+  cruft/quadpack/dqagpe.f \
+  cruft/quadpack/dqelg.f \
+  cruft/quadpack/dqk15i.f \
+  cruft/quadpack/dqk21.f \
+  cruft/quadpack/dqpsrt.f \
+  cruft/quadpack/qagie.f \
+  cruft/quadpack/qagi.f \
+  cruft/quadpack/qagpe.f \
+  cruft/quadpack/qagp.f \
+  cruft/quadpack/qelg.f \
+  cruft/quadpack/qk15i.f \
+  cruft/quadpack/qk21.f \
+  cruft/quadpack/qpsrt.f \
+  cruft/quadpack/xerror.f
--- a/liboctave/cruft/ranlib/ignpoi.f	Fri Feb 06 08:31:09 2015 -0800
+++ b/liboctave/cruft/ranlib/ignpoi.f	Fri Feb 06 08:31:49 2015 -0800
@@ -99,7 +99,7 @@
 C     JJV added this for case: mu unchanged
 C     .. Save statement ..
       SAVE s, d, l, ll, omega, c3, c2, c1, c0, c, m, p, q, p0,
-     +     a0, a1, a2, a3, a4, a5, a6, a7, fact, muprev, muold
+     +     a0, a1, a2, a3, a4, a5, a6, a7, fact, pp, muprev, muold
 C     ..
 C     JJV end addition - I am including vars in Data statements
 C     .. Data statements ..
@@ -110,6 +110,7 @@
       DATA a0,a1,a2,a3,a4,a5,a6,a7/-.5,.3333333,-.2500068,.2000118,
      +     -.1661269,.1421878,-.1384794,.1250060/
       DATA fact/1.,1.,2.,6.,24.,120.,720.,5040.,40320.,362880./
+      DATA pp/35*0.0/
 C     ..
 C     .. Executable Statements ..
 
--- a/liboctave/cruft/ranlib/module.mk	Fri Feb 06 08:31:09 2015 -0800
+++ b/liboctave/cruft/ranlib/module.mk	Fri Feb 06 08:31:49 2015 -0800
@@ -1,64 +1,65 @@
 EXTRA_DIST += \
-  ranlib/module.mk \
-  ranlib/Basegen.doc \
-  ranlib/HOWTOGET \
-  ranlib/README \
-  ranlib/randlib.chs \
-  ranlib/randlib.fdoc \
-  ranlib/tstbot.for \
-  ranlib/tstgmn.for \
-  ranlib/tstmid.for
+  cruft/ranlib/module.mk \
+  cruft/ranlib/Basegen.doc \
+  cruft/ranlib/HOWTOGET \
+  cruft/ranlib/README \
+  cruft/ranlib/randlib.chs \
+  cruft/ranlib/randlib.fdoc \
+  cruft/ranlib/tstbot.for \
+  cruft/ranlib/tstgmn.for \
+  cruft/ranlib/tstmid.for
 
 RANLIB_SRC = \
-  ranlib/advnst.f \
-  ranlib/genbet.f \
-  ranlib/genchi.f \
-  ranlib/genexp.f \
-  ranlib/genf.f \
-  ranlib/gengam.f \
-  ranlib/genmn.f \
-  ranlib/genmul.f \
-  ranlib/gennch.f \
-  ranlib/gennf.f \
-  ranlib/gennor.f \
-  ranlib/genprm.f \
-  ranlib/genunf.f \
-  ranlib/getcgn.f \
-  ranlib/getsd.f \
-  ranlib/ignbin.f \
-  ranlib/ignlgi.f \
-  ranlib/ignnbn.f \
-  ranlib/ignpoi.f \
-  ranlib/ignuin.f \
-  ranlib/initgn.f \
-  ranlib/inrgcm.f \
-  ranlib/lennob.f \
-  ranlib/mltmod.f \
-  ranlib/phrtsd.f \
-  ranlib/qrgnin.f \
-  ranlib/ranf.f \
-  ranlib/setall.f \
-  ranlib/setant.f \
-  ranlib/setgmn.f \
-  ranlib/setsd.f \
-  ranlib/sexpo.f \
-  ranlib/sgamma.f \
-  ranlib/snorm.f \
-  ranlib/wrap.f
+  cruft/ranlib/advnst.f \
+  cruft/ranlib/genbet.f \
+  cruft/ranlib/genchi.f \
+  cruft/ranlib/genexp.f \
+  cruft/ranlib/genf.f \
+  cruft/ranlib/gengam.f \
+  cruft/ranlib/genmn.f \
+  cruft/ranlib/genmul.f \
+  cruft/ranlib/gennch.f \
+  cruft/ranlib/gennf.f \
+  cruft/ranlib/gennor.f \
+  cruft/ranlib/genprm.f \
+  cruft/ranlib/genunf.f \
+  cruft/ranlib/getcgn.f \
+  cruft/ranlib/getsd.f \
+  cruft/ranlib/ignbin.f \
+  cruft/ranlib/ignlgi.f \
+  cruft/ranlib/ignnbn.f \
+  cruft/ranlib/ignpoi.f \
+  cruft/ranlib/ignuin.f \
+  cruft/ranlib/initgn.f \
+  cruft/ranlib/inrgcm.f \
+  cruft/ranlib/lennob.f \
+  cruft/ranlib/mltmod.f \
+  cruft/ranlib/phrtsd.f \
+  cruft/ranlib/qrgnin.f \
+  cruft/ranlib/ranf.f \
+  cruft/ranlib/setall.f \
+  cruft/ranlib/setant.f \
+  cruft/ranlib/setgmn.f \
+  cruft/ranlib/setsd.f \
+  cruft/ranlib/sexpo.f \
+  cruft/ranlib/sgamma.f \
+  cruft/ranlib/snorm.f \
+  cruft/ranlib/wrap.f
 
-noinst_LTLIBRARIES += ranlib/libranlib.la
+noinst_LTLIBRARIES += cruft/ranlib/libranlib.la
 
-ranlib_libranlib_la_SOURCES = $(RANLIB_SRC)
+cruft_ranlib_libranlib_la_SOURCES = $(RANLIB_SRC)
 
-ranlib_libranlib_la_DEPENDENCIES = ranlib/ranlib.def
+cruft_ranlib_libranlib_la_DEPENDENCIES = cruft/ranlib/ranlib.def
 
 ## Special rules for files which must be built before compilation
 ## ranlib directory may not exist in VPATH build; create it if necessary.
-ranlib/ranlib.def: $(RANLIB_SRC) mkf77def
-	@-if ! test -d ranlib; then \
-		mkdir ranlib ; \
+cruft/ranlib/ranlib.def: $(RANLIB_SRC) cruft/mkf77def
+	@-if ! test -d cruft/ranlib; then \
+		mkdir cruft/ranlib ; \
 	fi
-	chmod a+rx mkf77def
-	./mkf77def $(srcdir) $(RANLIB_SRC) > $@-t
+	chmod a+rx cruft/mkf77def
+	./cruft/mkf77def $(srcdir) $(RANLIB_SRC) > $@-t
 	mv $@-t $@
 
+liboctave_la_LIBADD += cruft/ranlib/libranlib.la
--- a/liboctave/cruft/slatec-err/module.mk	Fri Feb 06 08:31:09 2015 -0800
+++ b/liboctave/cruft/slatec-err/module.mk	Fri Feb 06 08:31:49 2015 -0800
@@ -1,17 +1,17 @@
-EXTRA_DIST += slatec-err/module.mk
+EXTRA_DIST += cruft/slatec-err/module.mk
 
-libcruft_la_SOURCES += \
-  slatec-err/fdump.f \
-  slatec-err/ixsav.f \
-  slatec-err/j4save.f \
-  slatec-err/xerclr.f \
-  slatec-err/xercnt.f \
-  slatec-err/xerhlt.f \
-  slatec-err/xermsg.f \
-  slatec-err/xerprn.f \
-  slatec-err/xerrwd.f \
-  slatec-err/xersve.f \
-  slatec-err/xgetf.f \
-  slatec-err/xgetua.f \
-  slatec-err/xsetf.f \
-  slatec-err/xsetua.f
+CRUFT_SOURCES += \
+  cruft/slatec-err/fdump.f \
+  cruft/slatec-err/ixsav.f \
+  cruft/slatec-err/j4save.f \
+  cruft/slatec-err/xerclr.f \
+  cruft/slatec-err/xercnt.f \
+  cruft/slatec-err/xerhlt.f \
+  cruft/slatec-err/xermsg.f \
+  cruft/slatec-err/xerprn.f \
+  cruft/slatec-err/xerrwd.f \
+  cruft/slatec-err/xersve.f \
+  cruft/slatec-err/xgetf.f \
+  cruft/slatec-err/xgetua.f \
+  cruft/slatec-err/xsetf.f \
+  cruft/slatec-err/xsetua.f
--- a/liboctave/cruft/slatec-fn/module.mk	Fri Feb 06 08:31:09 2015 -0800
+++ b/liboctave/cruft/slatec-fn/module.mk	Fri Feb 06 08:31:49 2015 -0800
@@ -1,88 +1,88 @@
 EXTRA_DIST += \
-  slatec-fn/module.mk \
-  slatec-fn/derfc.in.f \
-  slatec-fn/erfc.in.f
+  cruft/slatec-fn/module.mk \
+  cruft/slatec-fn/derfc.in.f \
+  cruft/slatec-fn/erfc.in.f
 
-libcruft_la_SOURCES += \
-  slatec-fn/albeta.f \
-  slatec-fn/alngam.f \
-  slatec-fn/alnrel.f \
-  slatec-fn/algams.f \
-  slatec-fn/acosh.f \
-  slatec-fn/asinh.f \
-  slatec-fn/atanh.f \
-  slatec-fn/betai.f \
-  slatec-fn/csevl.f \
-  slatec-fn/d9gmit.f \
-  slatec-fn/d9lgic.f \
-  slatec-fn/d9lgit.f \
-  slatec-fn/d9lgmc.f \
-  slatec-fn/dacosh.f \
-  slatec-fn/dasinh.f \
-  slatec-fn/datanh.f \
-  slatec-fn/dbetai.f \
-  slatec-fn/dcsevl.f \
-  slatec-fn/derf.f \
-  slatec-fn/dgami.f \
-  slatec-fn/dgamit.f \
-  slatec-fn/dgamlm.f \
-  slatec-fn/dgamma.f \
-  slatec-fn/dgamr.f \
-  slatec-fn/dlbeta.f \
-  slatec-fn/dlgams.f \
-  slatec-fn/dlngam.f \
-  slatec-fn/dlnrel.f \
-  slatec-fn/dpchim.f \
-  slatec-fn/dpchst.f \
-  slatec-fn/erf.f \
-  slatec-fn/gami.f \
-  slatec-fn/gamit.f \
-  slatec-fn/gamlim.f \
-  slatec-fn/gamma.f \
-  slatec-fn/gamr.f \
-  slatec-fn/initds.f \
-  slatec-fn/inits.f \
-  slatec-fn/pchim.f \
-  slatec-fn/pchst.f \
-  slatec-fn/r9lgmc.f \
-  slatec-fn/r9lgit.f \
-  slatec-fn/r9gmit.f \
-  slatec-fn/r9lgic.f \
-  slatec-fn/xdacosh.f \
-  slatec-fn/xdasinh.f \
-  slatec-fn/xdatanh.f \
-  slatec-fn/xdbetai.f \
-  slatec-fn/xderf.f \
-  slatec-fn/xderfc.f \
-  slatec-fn/xdgami.f \
-  slatec-fn/xdgamit.f \
-  slatec-fn/xdgamma.f \
-  slatec-fn/xgmainc.f \
-  slatec-fn/xacosh.f \
-  slatec-fn/xasinh.f \
-  slatec-fn/xatanh.f \
-  slatec-fn/xerf.f \
-  slatec-fn/xerfc.f \
-  slatec-fn/xsgmainc.f \
-  slatec-fn/xgamma.f \
-  slatec-fn/xbetai.f
+CRUFT_SOURCES += \
+  cruft/slatec-fn/albeta.f \
+  cruft/slatec-fn/alngam.f \
+  cruft/slatec-fn/alnrel.f \
+  cruft/slatec-fn/algams.f \
+  cruft/slatec-fn/acosh.f \
+  cruft/slatec-fn/asinh.f \
+  cruft/slatec-fn/atanh.f \
+  cruft/slatec-fn/betai.f \
+  cruft/slatec-fn/csevl.f \
+  cruft/slatec-fn/d9gmit.f \
+  cruft/slatec-fn/d9lgic.f \
+  cruft/slatec-fn/d9lgit.f \
+  cruft/slatec-fn/d9lgmc.f \
+  cruft/slatec-fn/dacosh.f \
+  cruft/slatec-fn/dasinh.f \
+  cruft/slatec-fn/datanh.f \
+  cruft/slatec-fn/dbetai.f \
+  cruft/slatec-fn/dcsevl.f \
+  cruft/slatec-fn/derf.f \
+  cruft/slatec-fn/dgami.f \
+  cruft/slatec-fn/dgamit.f \
+  cruft/slatec-fn/dgamlm.f \
+  cruft/slatec-fn/dgamma.f \
+  cruft/slatec-fn/dgamr.f \
+  cruft/slatec-fn/dlbeta.f \
+  cruft/slatec-fn/dlgams.f \
+  cruft/slatec-fn/dlngam.f \
+  cruft/slatec-fn/dlnrel.f \
+  cruft/slatec-fn/dpchim.f \
+  cruft/slatec-fn/dpchst.f \
+  cruft/slatec-fn/erf.f \
+  cruft/slatec-fn/gami.f \
+  cruft/slatec-fn/gamit.f \
+  cruft/slatec-fn/gamlim.f \
+  cruft/slatec-fn/gamma.f \
+  cruft/slatec-fn/gamr.f \
+  cruft/slatec-fn/initds.f \
+  cruft/slatec-fn/inits.f \
+  cruft/slatec-fn/pchim.f \
+  cruft/slatec-fn/pchst.f \
+  cruft/slatec-fn/r9lgmc.f \
+  cruft/slatec-fn/r9lgit.f \
+  cruft/slatec-fn/r9gmit.f \
+  cruft/slatec-fn/r9lgic.f \
+  cruft/slatec-fn/xdacosh.f \
+  cruft/slatec-fn/xdasinh.f \
+  cruft/slatec-fn/xdatanh.f \
+  cruft/slatec-fn/xdbetai.f \
+  cruft/slatec-fn/xderf.f \
+  cruft/slatec-fn/xderfc.f \
+  cruft/slatec-fn/xdgami.f \
+  cruft/slatec-fn/xdgamit.f \
+  cruft/slatec-fn/xdgamma.f \
+  cruft/slatec-fn/xgmainc.f \
+  cruft/slatec-fn/xacosh.f \
+  cruft/slatec-fn/xasinh.f \
+  cruft/slatec-fn/xatanh.f \
+  cruft/slatec-fn/xerf.f \
+  cruft/slatec-fn/xerfc.f \
+  cruft/slatec-fn/xsgmainc.f \
+  cruft/slatec-fn/xgamma.f \
+  cruft/slatec-fn/xbetai.f
 
-nodist_libcruft_la_SOURCES += \
-  slatec-fn/derfc.f \
-  slatec-fn/erfc.f
+nodist_cruft_libcruft_la_SOURCES += \
+  cruft/slatec-fn/derfc.f \
+  cruft/slatec-fn/erfc.f
 
 ## slatec-fn directory may not exist in VPATH build; create it if necessary.
 
-slatec-fn/erfc.f: slatec-fn/erfc.in.f Makefile
-	@-if ! test -d slatec-fn; then \
-		mkdir slatec-fn ; \
+cruft/slatec-fn/erfc.f: cruft/slatec-fn/erfc.in.f Makefile
+	@-if ! test -d cruft/slatec-fn; then \
+		mkdir cruft/slatec-fn ; \
 	fi
 	$(SED) -e "${F77_ISNAN_MACRO}" < $< > $@-t
 	mv $@-t $@
 
-slatec-fn/derfc.f: slatec-fn/derfc.in.f Makefile
-	@-if ! test -d slatec-fn; then \
-		mkdir slatec-fn ; \
+cruft/slatec-fn/derfc.f: cruft/slatec-fn/derfc.in.f Makefile
+	@-if ! test -d cruft/slatec-fn; then \
+		mkdir cruft/slatec-fn ; \
 	fi
 	$(SED) -e "${F77_ISNAN_MACRO}" < $< > $@-t
 	mv $@-t $@
--- a/liboctave/numeric/CmplxLU.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/liboctave/numeric/CmplxLU.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -100,7 +100,8 @@
 
   if (u.length () == m && v.length () == n)
     {
-      ComplexColumnVector utmp = u, vtmp = v;
+      ComplexColumnVector utmp = u;
+      ComplexColumnVector vtmp = v;
       F77_XFCN (zlu1up, ZLU1UP, (m, n, l.fortran_vec (), m, r.fortran_vec (), k,
                                  utmp.fortran_vec (), vtmp.fortran_vec ()));
     }
@@ -124,7 +125,8 @@
     {
       for (volatile octave_idx_type i = 0; i < u.cols (); i++)
         {
-          ComplexColumnVector utmp = u.column (i), vtmp = v.column (i);
+          ComplexColumnVector utmp = u.column (i);
+          ComplexColumnVector vtmp = v.column (i);
           F77_XFCN (zlu1up, ZLU1UP, (m, n, l.fortran_vec (),
                                      m, r.fortran_vec (), k,
                                      utmp.fortran_vec (), vtmp.fortran_vec ()));
@@ -149,7 +151,8 @@
 
   if (u.length () == m && v.length () == n)
     {
-      ComplexColumnVector utmp = u, vtmp = v;
+      ComplexColumnVector utmp = u;
+      ComplexColumnVector vtmp = v;
       OCTAVE_LOCAL_BUFFER (Complex, w, m);
       for (octave_idx_type i = 0; i < m; i++) ipvt(i) += 1; // increment
       F77_XFCN (zlup1up, ZLUP1UP, (m, n, l.fortran_vec (),
@@ -180,7 +183,8 @@
       for (octave_idx_type i = 0; i < m; i++) ipvt(i) += 1; // increment
       for (volatile octave_idx_type i = 0; i < u.cols (); i++)
         {
-          ComplexColumnVector utmp = u.column (i), vtmp = v.column (i);
+          ComplexColumnVector utmp = u.column (i);
+          ComplexColumnVector vtmp = v.column (i);
           F77_XFCN (zlup1up, ZLUP1UP, (m, n, l.fortran_vec (),
                                        m, r.fortran_vec (), k,
                                        ipvt.fortran_vec (),
--- a/liboctave/numeric/CmplxQR.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/liboctave/numeric/CmplxQR.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -137,7 +137,8 @@
 void ComplexQR::form (octave_idx_type n, ComplexMatrix& afact,
                       Complex *tau, qr_type_t qr_type)
 {
-  octave_idx_type m = afact.rows (), min_mn = std::min (m, n);
+  octave_idx_type m = afact.rows ();
+  octave_idx_type min_mn = std::min (m, n);
   octave_idx_type info;
 
   if (qr_type == qr_type_raw)
@@ -213,7 +214,8 @@
 
   if (u.length () == m && v.length () == n)
     {
-      ComplexColumnVector utmp = u, vtmp = v;
+      ComplexColumnVector utmp = u;
+      ComplexColumnVector vtmp = v;
       OCTAVE_LOCAL_BUFFER (Complex, w, k);
       OCTAVE_LOCAL_BUFFER (double, rw, k);
       F77_XFCN (zqr1up, ZQR1UP, (m, n, k, q.fortran_vec (),
@@ -238,7 +240,8 @@
       OCTAVE_LOCAL_BUFFER (double, rw, k);
       for (volatile octave_idx_type i = 0; i < u.cols (); i++)
         {
-          ComplexColumnVector utmp = u.column (i), vtmp = v.column (i);
+          ComplexColumnVector utmp = u.column (i);
+          ComplexColumnVector vtmp = v.column (i);
           F77_XFCN (zqr1up, ZQR1UP, (m, n, k, q.fortran_vec (),
                                      m, r.fortran_vec (), k,
                                      utmp.fortran_vec (), vtmp.fortran_vec (),
@@ -546,7 +549,7 @@
                           octave_idx_type i, octave_idx_type j)
 {
   octave_idx_type n = a.columns ();
-  Array<octave_idx_type> p (n);
+  Array<octave_idx_type> p (dim_vector (n, 1));
   for (octave_idx_type k = 0; k < n; k++) p(k) = k;
   if (i < j)
     {
@@ -615,7 +618,6 @@
 {
   warn_qrupdate_once ();
 
-  octave_idx_type m = q.rows ();
   octave_idx_type n = r.columns ();
 
   if (j < 0 || j > n-1)
@@ -631,7 +633,6 @@
 {
   warn_qrupdate_once ();
 
-  octave_idx_type m = q.rows ();
   octave_idx_type n = r.columns ();
 
   Array<octave_idx_type> jsi;
@@ -678,7 +679,6 @@
   warn_qrupdate_once ();
 
   octave_idx_type m = r.rows ();
-  octave_idx_type n = r.columns ();
 
   if (! q.is_square ())
     (*current_liboctave_error_handler) ("qrdelete: dimensions mismatch");
@@ -695,7 +695,6 @@
 {
   warn_qrupdate_once ();
 
-  octave_idx_type m = q.rows ();
   octave_idx_type n = r.columns ();
 
   if (i < 0 || i > n-1 || j < 0 || j > n-1)
--- a/liboctave/numeric/CmplxQRP.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/liboctave/numeric/CmplxQRP.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -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 Feb 06 08:31:09 2015 -0800
+++ b/liboctave/numeric/DASPK-opts.in	Fri Feb 06 08:31:49 2015 -0800
@@ -209,10 +209,10 @@
 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
+@qcode{\"compute consistent initial condition\"} and
 @qcode{\"exclude algebraic variables from error test\"} options.
 
   END_DOC_ITEM
--- a/liboctave/numeric/base-lu.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/liboctave/numeric/base-lu.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -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/base-qr.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/liboctave/numeric/base-qr.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -30,8 +30,10 @@
 base_qr<qr_type>::base_qr (const qr_type& q_arg, const qr_type& r_arg)
   : q (q_arg), r (r_arg)
 {
-  octave_idx_type q_nr = q.rows (), q_nc = q.columns ();
-  octave_idx_type r_nr = r.rows (), r_nc = r.columns ();
+  octave_idx_type q_nr = q.rows ();
+  octave_idx_type q_nc = q.columns ();
+  octave_idx_type r_nr = r.rows ();
+  octave_idx_type r_nc = r.columns ();
 
   if (! (q_nc == r_nr && (q_nr == q_nc || (q_nr > q_nc && r_nr == r_nc))))
     {
--- a/liboctave/numeric/bsxfun-defs.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/liboctave/numeric/bsxfun-defs.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -41,14 +41,16 @@
               void (*op_vs) (size_t, R *, const X *, Y))
 {
   int nd = std::max (x.ndims (), y.ndims ());
-  dim_vector dvx = x.dims ().redim (nd), dvy = y.dims ().redim (nd);
+  dim_vector dvx = x.dims ().redim (nd);
+  dim_vector dvy = y.dims ().redim (nd);
 
   // Construct the result dimensions.
   dim_vector dvr;
   dvr.resize (nd);
   for (int i = 0; i < nd; i++)
     {
-      octave_idx_type xk = dvx(i), yk = dvy(i);
+      octave_idx_type xk = dvx(i);
+      octave_idx_type yk = dvy(i);
       if (xk == 1)
         dvr(i) = yk;
       else if (yk == 1 || xk == yk)
@@ -84,7 +86,8 @@
   else
     {
       // Determine the type of the low-level loop.
-      bool xsing = false, ysing = false;
+      bool xsing = false;
+      bool ysing = false;
       if (ldr == 1)
         {
           xsing = dvx(start) == 1;
@@ -95,7 +98,8 @@
               start++;
             }
         }
-      dim_vector cdvx = dvx.cumulative (), cdvy = dvy.cumulative ();
+      dim_vector cdvx = dvx.cumulative ();
+      dim_vector cdvy = dvy.cumulative ();
       // Nullify singleton dims to achieve a spread effect.
       for (int i = std::max (start, octave_idx_type (1)); i < nd; i++)
         {
@@ -139,7 +143,8 @@
                       void (*op_vv) (size_t, R *, const X *),
                       void (*op_vs) (size_t, R *, X))
 {
-  dim_vector dvr = r.dims (), dvx = x.dims ();
+  dim_vector dvr = r.dims ();
+  dim_vector dvx = x.dims ();
   octave_idx_type nd = r.ndims ();
   dvx.redim (nd);
 
--- a/liboctave/numeric/bsxfun.h	Fri Feb 06 08:31:09 2015 -0800
+++ b/liboctave/numeric/bsxfun.h	Fri Feb 06 08:31:49 2015 -0800
@@ -38,9 +38,10 @@
 {
   for (int i = 0; i < std::min (dx.length (), dy.length ()); i++)
     {
-      octave_idx_type xk = dx(i), yk = dy(i);
+      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;
     }
 
@@ -59,16 +60,18 @@
 is_valid_inplace_bsxfun (const std::string& name, const dim_vector& dr,
                          const dim_vector& dx)
 {
-  octave_idx_type drl = dr.length (), dxl = dx.length ();
+  octave_idx_type drl = dr.length ();
+  octave_idx_type dxl = dx.length ();
   if (drl < dxl)
     return false;
 
   for (int i = 0; i < drl; i++)
     {
-      octave_idx_type rk = dr(i), xk = dx(i);
+      octave_idx_type rk = dr(i);
+      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/dbleLU.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/liboctave/numeric/dbleLU.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -99,7 +99,8 @@
 
   if (u.length () == m && v.length () == n)
     {
-      ColumnVector utmp = u, vtmp = v;
+      ColumnVector utmp = u;
+      ColumnVector vtmp = v;
       F77_XFCN (dlu1up, DLU1UP, (m, n, l.fortran_vec (), m, r.fortran_vec (), k,
                                  utmp.fortran_vec (), vtmp.fortran_vec ()));
     }
@@ -123,7 +124,8 @@
     {
       for (volatile octave_idx_type i = 0; i < u.cols (); i++)
         {
-          ColumnVector utmp = u.column (i), vtmp = v.column (i);
+          ColumnVector utmp = u.column (i);
+          ColumnVector vtmp = v.column (i);
           F77_XFCN (dlu1up, DLU1UP, (m, n, l.fortran_vec (),
                                      m, r.fortran_vec (), k,
                                      utmp.fortran_vec (), vtmp.fortran_vec ()));
@@ -147,7 +149,8 @@
 
   if (u.length () == m && v.length () == n)
     {
-      ColumnVector utmp = u, vtmp = v;
+      ColumnVector utmp = u;
+      ColumnVector vtmp = v;
       OCTAVE_LOCAL_BUFFER (double, w, m);
       for (octave_idx_type i = 0; i < m; i++) ipvt(i) += 1; // increment
       F77_XFCN (dlup1up, DLUP1UP, (m, n, l.fortran_vec (),
@@ -178,7 +181,8 @@
       for (octave_idx_type i = 0; i < m; i++) ipvt(i) += 1; // increment
       for (volatile octave_idx_type i = 0; i < u.cols (); i++)
         {
-          ColumnVector utmp = u.column (i), vtmp = v.column (i);
+          ColumnVector utmp = u.column (i);
+          ColumnVector vtmp = v.column (i);
           F77_XFCN (dlup1up, DLUP1UP, (m, n, l.fortran_vec (),
                                        m, r.fortran_vec (), k,
                                        ipvt.fortran_vec (),
--- a/liboctave/numeric/dbleQR.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/liboctave/numeric/dbleQR.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -138,7 +138,8 @@
 void QR::form (octave_idx_type n, Matrix& afact,
                double *tau, qr_type_t qr_type)
 {
-  octave_idx_type m = afact.rows (), min_mn = std::min (m, n);
+  octave_idx_type m = afact.rows ();
+  octave_idx_type min_mn = std::min (m, n);
   octave_idx_type info;
 
   if (qr_type == qr_type_raw)
@@ -214,7 +215,8 @@
 
   if (u.length () == m && v.length () == n)
     {
-      ColumnVector utmp = u, vtmp = v;
+      ColumnVector utmp = u;
+      ColumnVector vtmp = v;
       OCTAVE_LOCAL_BUFFER (double, w, 2*k);
       F77_XFCN (dqr1up, DQR1UP, (m, n, k, q.fortran_vec (),
                                  m, r.fortran_vec (), k,
@@ -236,7 +238,8 @@
       OCTAVE_LOCAL_BUFFER (double, w, 2*k);
       for (volatile octave_idx_type i = 0; i < u.cols (); i++)
         {
-          ColumnVector utmp = u.column (i), vtmp = v.column (i);
+          ColumnVector utmp = u.column (i);
+          ColumnVector vtmp = v.column (i);
           F77_XFCN (dqr1up, DQR1UP, (m, n, k, q.fortran_vec (),
                                      m, r.fortran_vec (), k,
                                      utmp.fortran_vec (), vtmp.fortran_vec (),
@@ -541,7 +544,7 @@
                    octave_idx_type i, octave_idx_type j)
 {
   octave_idx_type n = a.columns ();
-  Array<octave_idx_type> p (n);
+  Array<octave_idx_type> p (dim_vector (n, 1));
   for (octave_idx_type k = 0; k < n; k++) p(k) = k;
   if (i < j)
     {
@@ -610,7 +613,6 @@
 {
   warn_qrupdate_once ();
 
-  octave_idx_type m = q.rows ();
   octave_idx_type n = r.columns ();
 
   if (j < 0 || j > n-1)
@@ -626,7 +628,6 @@
 {
   warn_qrupdate_once ();
 
-  octave_idx_type m = q.rows ();
   octave_idx_type n = r.columns ();
 
   Array<octave_idx_type> jsi;
@@ -671,7 +672,6 @@
 QR::delete_row (octave_idx_type j)
 {
   octave_idx_type m = r.rows ();
-  octave_idx_type n = r.columns ();
 
   if (! q.is_square ())
     (*current_liboctave_error_handler) ("qrdelete: dimensions mismatch");
@@ -688,7 +688,6 @@
 {
   warn_qrupdate_once ();
 
-  octave_idx_type m = q.rows ();
   octave_idx_type n = r.columns ();
 
   if (i < 0 || i > n-1 || j < 0 || j > n-1)
@@ -704,11 +703,13 @@
   static bool warned = false;
   if (! warned)
     {
-      (*current_liboctave_warning_handler)
-        ("In this version of Octave, QR & Cholesky updating routines\n"
-         "simply update the matrix and recalculate factorizations.\n"
-         "To use fast algorithms, link Octave with the qrupdate library.\n"
-         "See <http://sourceforge.net/projects/qrupdate>.\n");
+      (*current_liboctave_warning_with_id_handler)
+        ("Octave:missing-dependency",
+         "In this version of Octave, QR & Cholesky updating routines "
+         "simply update the matrix and recalculate factorizations. "
+         "To use fast algorithms, link Octave with the qrupdate library. "
+         "See <http://sourceforge.net/projects/qrupdate>.");
+
       warned = true;
     }
 }
--- a/liboctave/numeric/dbleQRP.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/liboctave/numeric/dbleQRP.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -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/eigs-base.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/liboctave/numeric/eigs-base.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -30,6 +30,7 @@
 #include <iostream>
 
 #include "f77-fcn.h"
+#include "oct-locbuf.h"
 #include "quit.h"
 #include "SparsedbleLU.h"
 #include "SparseCmplxLU.h"
@@ -206,6 +207,15 @@
 
 #endif
 
+static void
+warn_convergence (void)
+{
+  (*current_liboctave_warning_with_id_handler)
+    ("Octave:convergence",
+     "eigs: 'A - sigma*B' is singular, indicating sigma is exactly "
+     "an eigenvalue so convergence is not guaranteed");
+}
+
 template <class M, class SM>
 static octave_idx_type
 lusolve (const SM& L, const SM& U, M& m)
@@ -507,12 +517,7 @@
   volatile double rcond_plus_one = rcond + 1.0;
 
   if (rcond_plus_one == 1.0 || xisnan (rcond))
-    {
-      (*current_liboctave_warning_handler)
-        ("eigs: 'A - sigma*B' is singular, indicating sigma is exactly");
-      (*current_liboctave_warning_handler)
-        ("       an eigenvalue. Convergence is not guaranteed");
-    }
+    warn_convergence ();
 
   return true;
 }
@@ -584,12 +589,7 @@
   volatile double rcond_plus_one = rcond + 1.0;
 
   if (rcond_plus_one == 1.0 || xisnan (rcond))
-    {
-      (*current_liboctave_warning_handler)
-        ("eigs: 'A - sigma*B' is singular, indicating sigma is exactly");
-      (*current_liboctave_warning_handler)
-        ("       an eigenvalue. Convergence is not guaranteed");
-    }
+    warn_convergence ();
 
   return true;
 }
@@ -681,12 +681,7 @@
   volatile double rcond_plus_one = rcond + 1.0;
 
   if (rcond_plus_one == 1.0 || xisnan (rcond))
-    {
-      (*current_liboctave_warning_handler)
-        ("eigs: 'A - sigma*B' is singular, indicating sigma is exactly");
-      (*current_liboctave_warning_handler)
-        ("       an eigenvalue. Convergence is not guaranteed");
-    }
+    warn_convergence ();
 
   return true;
 }
@@ -758,12 +753,7 @@
   volatile double rcond_plus_one = rcond + 1.0;
 
   if (rcond_plus_one == 1.0 || xisnan (rcond))
-    {
-      (*current_liboctave_warning_handler)
-        ("eigs: 'A - sigma*B' is singular, indicating sigma is exactly");
-      (*current_liboctave_warning_handler)
-        ("       an eigenvalue. Convergence is not guaranteed");
-    }
+    warn_convergence ();
 
   return true;
 }
--- a/liboctave/numeric/fCmplxLU.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/liboctave/numeric/fCmplxLU.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -100,7 +100,8 @@
 
   if (u.length () == m && v.length () == n)
     {
-      FloatComplexColumnVector utmp = u, vtmp = v;
+      FloatComplexColumnVector utmp = u;
+      FloatComplexColumnVector vtmp = v;
       F77_XFCN (clu1up, CLU1UP, (m, n, l.fortran_vec (), m, r.fortran_vec (), k,
                                  utmp.fortran_vec (), vtmp.fortran_vec ()));
     }
@@ -125,7 +126,8 @@
     {
       for (volatile octave_idx_type i = 0; i < u.cols (); i++)
         {
-          FloatComplexColumnVector utmp = u.column (i), vtmp = v.column (i);
+          FloatComplexColumnVector utmp = u.column (i);
+          FloatComplexColumnVector vtmp = v.column (i);
           F77_XFCN (clu1up, CLU1UP, (m, n, l.fortran_vec (),
                                      m, r.fortran_vec (), k,
                                      utmp.fortran_vec (), vtmp.fortran_vec ()));
@@ -150,7 +152,8 @@
 
   if (u.length () == m && v.length () == n)
     {
-      FloatComplexColumnVector utmp = u, vtmp = v;
+      FloatComplexColumnVector utmp = u;
+      FloatComplexColumnVector vtmp = v;
       OCTAVE_LOCAL_BUFFER (FloatComplex, w, m);
       for (octave_idx_type i = 0; i < m; i++) ipvt(i) += 1; // increment
       F77_XFCN (clup1up, CLUP1UP, (m, n, l.fortran_vec (),
@@ -182,7 +185,8 @@
       for (octave_idx_type i = 0; i < m; i++) ipvt(i) += 1; // increment
       for (volatile octave_idx_type i = 0; i < u.cols (); i++)
         {
-          FloatComplexColumnVector utmp = u.column (i), vtmp = v.column (i);
+          FloatComplexColumnVector utmp = u.column (i);
+          FloatComplexColumnVector vtmp = v.column (i);
           F77_XFCN (clup1up, CLUP1UP, (m, n, l.fortran_vec (),
                                        m, r.fortran_vec (), k,
                                        ipvt.fortran_vec (),
--- a/liboctave/numeric/fCmplxQR.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/liboctave/numeric/fCmplxQR.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -140,7 +140,8 @@
 void FloatComplexQR::form (octave_idx_type n, FloatComplexMatrix& afact,
                            FloatComplex *tau, qr_type_t qr_type)
 {
-  octave_idx_type m = afact.rows (), min_mn = std::min (m, n);
+  octave_idx_type m = afact.rows ();
+  octave_idx_type min_mn = std::min (m, n);
   octave_idx_type info;
 
   if (qr_type == qr_type_raw)
@@ -217,7 +218,8 @@
 
   if (u.length () == m && v.length () == n)
     {
-      FloatComplexColumnVector utmp = u, vtmp = v;
+      FloatComplexColumnVector utmp = u;
+      FloatComplexColumnVector vtmp = v;
       OCTAVE_LOCAL_BUFFER (FloatComplex, w, k);
       OCTAVE_LOCAL_BUFFER (float, rw, k);
       F77_XFCN (cqr1up, CQR1UP, (m, n, k, q.fortran_vec (),
@@ -243,7 +245,8 @@
       OCTAVE_LOCAL_BUFFER (float, rw, k);
       for (volatile octave_idx_type i = 0; i < u.cols (); i++)
         {
-          FloatComplexColumnVector utmp = u.column (i), vtmp = v.column (i);
+          FloatComplexColumnVector utmp = u.column (i);
+          FloatComplexColumnVector vtmp = v.column (i);
           F77_XFCN (cqr1up, CQR1UP, (m, n, k, q.fortran_vec (),
                                      m, r.fortran_vec (), k,
                                      utmp.fortran_vec (), vtmp.fortran_vec (),
@@ -554,7 +557,7 @@
                                octave_idx_type i, octave_idx_type j)
 {
   octave_idx_type n = a.columns ();
-  Array<octave_idx_type> p (n);
+  Array<octave_idx_type> p (dim_vector (n, 1));
   for (octave_idx_type k = 0; k < n; k++) p(k) = k;
   if (i < j)
     {
@@ -625,7 +628,6 @@
 {
   warn_qrupdate_once ();
 
-  octave_idx_type m = q.rows ();
   octave_idx_type n = r.columns ();
 
   if (j < 0 || j > n-1)
@@ -641,7 +643,6 @@
 {
   warn_qrupdate_once ();
 
-  octave_idx_type m = q.rows ();
   octave_idx_type n = r.columns ();
 
   Array<octave_idx_type> jsi;
@@ -688,7 +689,6 @@
   warn_qrupdate_once ();
 
   octave_idx_type m = r.rows ();
-  octave_idx_type n = r.columns ();
 
   if (! q.is_square ())
     (*current_liboctave_error_handler) ("qrdelete: dimensions mismatch");
@@ -705,7 +705,6 @@
 {
   warn_qrupdate_once ();
 
-  octave_idx_type m = q.rows ();
   octave_idx_type n = r.columns ();
 
   if (i < 0 || i > n-1 || j < 0 || j > n-1)
--- a/liboctave/numeric/fCmplxQRP.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/liboctave/numeric/fCmplxQRP.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -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/floatLU.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/liboctave/numeric/floatLU.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -99,7 +99,8 @@
 
   if (u.length () == m && v.length () == n)
     {
-      FloatColumnVector utmp = u, vtmp = v;
+      FloatColumnVector utmp = u;
+      FloatColumnVector vtmp = v;
       F77_XFCN (slu1up, SLU1UP, (m, n, l.fortran_vec (),
                                  m, r.fortran_vec (), k,
                                  utmp.fortran_vec (), vtmp.fortran_vec ()));
@@ -124,7 +125,8 @@
     {
       for (volatile octave_idx_type i = 0; i < u.cols (); i++)
         {
-          FloatColumnVector utmp = u.column (i), vtmp = v.column (i);
+          FloatColumnVector utmp = u.column (i);
+          FloatColumnVector vtmp = v.column (i);
           F77_XFCN (slu1up, SLU1UP, (m, n, l.fortran_vec (),
                                      m, r.fortran_vec (), k,
                                      utmp.fortran_vec (), vtmp.fortran_vec ()));
@@ -149,7 +151,8 @@
 
   if (u.length () == m && v.length () == n)
     {
-      FloatColumnVector utmp = u, vtmp = v;
+      FloatColumnVector utmp = u;
+      FloatColumnVector vtmp = v;
       OCTAVE_LOCAL_BUFFER (float, w, m);
       for (octave_idx_type i = 0; i < m; i++) ipvt(i) += 1; // increment
       F77_XFCN (slup1up, SLUP1UP, (m, n, l.fortran_vec (),
@@ -180,7 +183,8 @@
       for (octave_idx_type i = 0; i < m; i++) ipvt(i) += 1; // increment
       for (volatile octave_idx_type i = 0; i < u.cols (); i++)
         {
-          FloatColumnVector utmp = u.column (i), vtmp = v.column (i);
+          FloatColumnVector utmp = u.column (i);
+          FloatColumnVector vtmp = v.column (i);
           F77_XFCN (slup1up, SLUP1UP, (m, n, l.fortran_vec (),
                                        m, r.fortran_vec (), k,
                                        ipvt.fortran_vec (),
--- a/liboctave/numeric/floatQR.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/liboctave/numeric/floatQR.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -136,7 +136,8 @@
 void FloatQR::form (octave_idx_type n, FloatMatrix& afact,
                     float *tau, qr_type_t qr_type)
 {
-  octave_idx_type m = afact.rows (), min_mn = std::min (m, n);
+  octave_idx_type m = afact.rows ();
+  octave_idx_type min_mn = std::min (m, n);
   octave_idx_type info;
 
   if (qr_type == qr_type_raw)
@@ -212,7 +213,8 @@
 
   if (u.length () == m && v.length () == n)
     {
-      FloatColumnVector utmp = u, vtmp = v;
+      FloatColumnVector utmp = u;
+      FloatColumnVector vtmp = v;
       OCTAVE_LOCAL_BUFFER (float, w, 2*k);
       F77_XFCN (sqr1up, SQR1UP, (m, n, k, q.fortran_vec (),
                                  m, r.fortran_vec (), k,
@@ -234,7 +236,8 @@
       OCTAVE_LOCAL_BUFFER (float, w, 2*k);
       for (volatile octave_idx_type i = 0; i < u.cols (); i++)
         {
-          FloatColumnVector utmp = u.column (i), vtmp = v.column (i);
+          FloatColumnVector utmp = u.column (i);
+          FloatColumnVector vtmp = v.column (i);
           F77_XFCN (sqr1up, SQR1UP, (m, n, k, q.fortran_vec (),
                                      m, r.fortran_vec (), k,
                                      utmp.fortran_vec (), vtmp.fortran_vec (),
@@ -539,7 +542,7 @@
                         octave_idx_type i, octave_idx_type j)
 {
   octave_idx_type n = a.columns ();
-  Array<octave_idx_type> p (n);
+  Array<octave_idx_type> p (dim_vector (n, 1));
   for (octave_idx_type k = 0; k < n; k++) p(k) = k;
   if (i < j)
     {
@@ -608,7 +611,6 @@
 {
   warn_qrupdate_once ();
 
-  octave_idx_type m = q.rows ();
   octave_idx_type n = r.columns ();
 
   if (j < 0 || j > n-1)
@@ -624,7 +626,6 @@
 {
   warn_qrupdate_once ();
 
-  octave_idx_type m = q.rows ();
   octave_idx_type n = r.columns ();
 
   Array<octave_idx_type> jsi;
@@ -671,7 +672,6 @@
   warn_qrupdate_once ();
 
   octave_idx_type m = r.rows ();
-  octave_idx_type n = r.columns ();
 
   if (! q.is_square ())
     (*current_liboctave_error_handler) ("qrdelete: dimensions mismatch");
@@ -688,7 +688,6 @@
 {
   warn_qrupdate_once ();
 
-  octave_idx_type m = q.rows ();
   octave_idx_type n = r.columns ();
 
   if (i < 0 || i > n-1 || j < 0 || j > n-1)
--- a/liboctave/numeric/floatQRP.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/liboctave/numeric/floatQRP.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -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 Feb 06 08:31:09 2015 -0800
+++ b/liboctave/numeric/lo-mappers.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -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);
@@ -169,12 +169,6 @@
   return lo_ieee_is_NA (x);
 }
 
-bool
-octave_is_NaN_or_NA (double x)
-{
-  return lo_ieee_isnan (x);
-}
-
 // (double, double) -> double mappers.
 
 // complex -> complex mappers.
@@ -184,7 +178,20 @@
 {
   static Complex i (0, 1);
 
-  return -i * (log (x + i * (sqrt (1.0 - x*x))));
+  Complex tmp;
+
+  if (imag (x) == 0.0)
+    {
+      // If the imaginary part of X is 0, then avoid generating an
+      // imaginary part of -0 for the expression 1-x*x.
+      // This effectively chooses the same phase of the branch cut as Matlab.
+      double xr = real (x);
+      tmp = Complex (1.0 - xr*xr);
+    }
+  else
+    tmp = 1.0 - x*x;
+
+  return -i * log (x + i * sqrt (tmp));
 }
 
 Complex
@@ -198,7 +205,20 @@
 {
   static Complex i (0, 1);
 
-  return -i * log (i*x + sqrt (1.0 - x*x));
+  Complex tmp;
+
+  if (imag (x) == 0.0)
+    {
+      // If the imaginary part of X is 0, then avoid generating an
+      // imaginary part of -0 for the expression 1-x*x.
+      // This effectively chooses the same phase of the branch cut as Matlab.
+      double xr = real (x);
+      tmp = Complex (1.0 - xr*xr);
+    }
+  else
+    tmp = 1.0 - x*x;
+
+  return -i * log (i*x + sqrt (tmp));
 }
 
 Complex
@@ -386,12 +406,6 @@
   return lo_ieee_is_NA (x);
 }
 
-bool
-octave_is_NaN_or_NA (float x)
-{
-  return lo_ieee_isnan (x);
-}
-
 // (float, float) -> float mappers.
 
 // complex -> complex mappers.
@@ -401,7 +415,20 @@
 {
   static FloatComplex i (0, 1);
 
-  return -i * (log (x + i * (sqrt (static_cast<float>(1.0) - x*x))));
+  FloatComplex tmp;
+
+  if (imag (x) == 0.0f)
+    {
+      // If the imaginary part of X is 0, then avoid generating an
+      // imaginary part of -0 for the expression 1-x*x.
+      // This effectively chooses the same phase of the branch cut as Matlab.
+      float xr = real (x);
+      tmp = FloatComplex (1.0f - xr*xr);
+    }
+  else
+    tmp = 1.0f - x*x;
+
+  return -i * log (x + i * sqrt (tmp));
 }
 
 FloatComplex
@@ -415,7 +442,20 @@
 {
   static FloatComplex i (0, 1);
 
-  return -i * log (i*x + sqrt (static_cast<float>(1.0) - x*x));
+  FloatComplex tmp;
+
+  if (imag (x) == 0.0f)
+    {
+      // If the imaginary part of X is 0, then avoid generating an
+      // imaginary part of -0 for the expression 1-x*x.
+      // This effectively chooses the same phase of the branch cut as Matlab.
+      float xr = real (x);
+      tmp = FloatComplex (1.0f - xr*xr);
+    }
+  else
+    tmp = 1.0f - x*x;
+
+  return -i * log (i*x + sqrt (tmp));
 }
 
 FloatComplex
@@ -522,14 +562,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-mappers.h	Fri Feb 06 08:31:09 2015 -0800
+++ b/liboctave/numeric/lo-mappers.h	Fri Feb 06 08:31:49 2015 -0800
@@ -72,7 +72,6 @@
 #endif
 
 extern OCTAVE_API bool octave_is_NA (double x);
-extern OCTAVE_API bool octave_is_NaN_or_NA (double x) GCC_ATTR_DEPRECATED;
 
 // Generic xmin, xmax definitions
 template <class T>
@@ -154,7 +153,6 @@
 #endif
 
 extern OCTAVE_API bool octave_is_NA (float x);
-extern OCTAVE_API bool octave_is_NaN_or_NA (float x) GCC_ATTR_DEPRECATED;
 
 inline float
 xmin (float x, float y)
--- a/liboctave/numeric/lo-specfun.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/liboctave/numeric/lo-specfun.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -633,7 +633,7 @@
       retval = 2 * (s + 1) * u;
     }
   else
-    retval = log (1 + x);
+    retval = gnulib::log (1 + x);
 
   return retval;
 }
@@ -685,14 +685,14 @@
   if (ax < 0.2)
     {
       // approximation log (1+x) ~ 2*sum ((x/(2+x)).^ii ./ ii), ii = 1:2:2n+1
-      float u = x / (2 + x), t = 1, s = 0;
+      float u = x / (2 + x), t = 1.0f, s = 0;
       for (int i = 2; i < 12; i += 2)
         s += (t *= u*u) / (i+1);
 
-      retval = 2 * (s + 1) * u;
+      retval = 2 * (s + 1.0f) * u;
     }
   else
-    retval = log (1 + x);
+    retval = gnulib::logf (1.0f + x);
 
   return retval;
 }
@@ -2580,12 +2580,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));
 
@@ -2698,7 +2694,7 @@
 
   for (octave_idx_type i = 0; i < nel; i++)
     {
-      result (i) = gammainc (x, a(i), err);
+      result(i) = gammainc (x, a(i), err);
 
       if (err)
         goto done;
@@ -2724,7 +2720,7 @@
 
   for (octave_idx_type i = 0; i < nel; i++)
     {
-      result (i) = gammainc (x(i), a, err);
+      result(i) = gammainc (x(i), a, err);
 
       if (err)
         goto done;
@@ -2754,7 +2750,7 @@
 
       for (octave_idx_type i = 0; i < nel; i++)
         {
-          result (i) = gammainc (x(i), a(i), err);
+          result(i) = gammainc (x(i), a(i), err);
 
           if (err)
             goto done;
@@ -2785,12 +2781,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));
 
@@ -2903,7 +2895,7 @@
 
   for (octave_idx_type i = 0; i < nel; i++)
     {
-      result (i) = gammainc (x, a(i), err);
+      result(i) = gammainc (x, a(i), err);
 
       if (err)
         goto done;
@@ -2929,7 +2921,7 @@
 
   for (octave_idx_type i = 0; i < nel; i++)
     {
-      result (i) = gammainc (x(i), a, err);
+      result(i) = gammainc (x(i), a, err);
 
       if (err)
         goto done;
@@ -2959,7 +2951,7 @@
 
       for (octave_idx_type i = 0; i < nel; i++)
         {
-          result (i) = gammainc (x(i), a(i), err);
+          result(i) = gammainc (x(i), a(i), err);
 
           if (err)
             goto done;
@@ -2986,14 +2978,17 @@
 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)
-                   : FloatComplex (log1pf (x));
+  return (x < -1.0f
+          ? FloatComplex (gnulib::logf (-(1.0f + x)), pi)
+          : FloatComplex (log1pf (x)));
 }
 
 // This algorithm is due to P. J. Acklam.
@@ -3046,7 +3041,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);
@@ -3124,10 +3119,16 @@
   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;
+
       if (x < pbreak_lo)
         y = -y;
     }
@@ -3243,8 +3244,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)
             {
@@ -3342,7 +3343,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);
 
@@ -3363,7 +3364,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
         {
@@ -3371,7 +3372,7 @@
 
           if (t <= 1.0)
             {
-              value = exp ((log (a * pp) + beta) / pp);
+              value = exp ((gnulib::log (a * pp) + beta) / pp);
             }
           else
             {
@@ -3413,7 +3414,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)
         {
@@ -3634,16 +3636,18 @@
 
   if (m < 0 || m > 1)
     {
-      (*current_liboctave_warning_handler)
-        ("ellipj: expecting 0 <= M <= 1");
+      (*current_liboctave_warning_with_id_handler)
+        ("Octave:ellipj-invalid-m", "ellipj: expecting 0 <= M <= 1");
+
       sn = cn = dn = lo_ieee_nan_value ();
+
       return;
     }
 
   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);
@@ -3653,7 +3657,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);
@@ -3665,8 +3669,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);
@@ -3687,12 +3691,11 @@
       phi = ii*a[Nn]*u;
       for (n = Nn; n > 0; --n)
         {
-          t = phi;
           phi = (asin ((c[n]/a[n])* sin (phi)) + phi)/2;
         }
       sn = sin (phi);
       cn = cos (phi);
-      dn = cn/cos (t - phi);
+      dn = sqrt (1 - m*sn*sn);
     }
 }
 
--- a/liboctave/numeric/module.mk	Fri Feb 06 08:31:09 2015 -0800
+++ b/liboctave/numeric/module.mk	Fri Feb 06 08:31:49 2015 -0800
@@ -180,8 +180,8 @@
 numeric_libnumeric_la_SOURCES = $(NUMERIC_SRC)
 numeric_libnumeric_la_CPPFLAGS = \
   $(liboctave_la_CPPFLAGS) \
-  $(ARPACK_CPPFLAGS) \
   -I$(srcdir)/cruft/Faddeeva \
   $(FFTW_XCPPFLAGS) \
   $(SPARSE_XCPPFLAGS)
 
+liboctave_la_LIBADD += numeric/libnumeric.la
--- a/liboctave/numeric/oct-convn.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/liboctave/numeric/oct-convn.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -116,7 +116,8 @@
     return MArray<T> ();
 
   int nd = std::max (a.ndims (), b.ndims ());
-  const dim_vector adims = a.dims ().redim (nd), bdims = b.dims ().redim (nd);
+  const dim_vector adims = a.dims ().redim (nd);
+  const dim_vector bdims = b.dims ().redim (nd);
   dim_vector cdims = dim_vector::alloc (nd);
 
   for (int i = 0; i < nd; i++)
--- a/liboctave/numeric/oct-norm.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/liboctave/numeric/oct-norm.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -36,6 +36,10 @@
 #include "oct-cmplx.h"
 #include "lo-error.h"
 #include "lo-ieee.h"
+#include "mx-cm-s.h"
+#include "mx-s-cm.h"
+#include "mx-fcm-fs.h"
+#include "mx-fs-fcm.h"
 #include "Array.h"
 #include "Array-util.h"
 #include "CMatrix.h"
@@ -327,7 +331,9 @@
   for (octave_idx_type i = 0; i < nsamp; i++)
     {
       octave_quit ();
-      R fi = i*M_PI/nsamp, lambda1 = cos (fi), mu1 = sin (fi);
+      R fi = i*M_PI/nsamp;
+      R lambda1 = cos (fi);
+      R mu1 = sin (fi);
       R lmnr = std::pow (std::pow (std::abs (lambda1), p) +
                          std::pow (std::abs (mu1), p), 1/p);
       lambda1 /= lmnr; mu1 /= lmnr;
@@ -358,7 +364,9 @@
   for (octave_idx_type i = 0; i < nsamp; i++)
     {
       octave_quit ();
-      R fi = i*M_PI/nsamp, lambda1 = cos (fi), mu1 = sin (fi);
+      R fi = i*M_PI/nsamp;
+      R lambda1 = cos (fi);
+      R mu1 = sin (fi);
       R lmnr = std::pow (std::pow (std::abs (lambda1), p) +
                          std::pow (std::abs (mu1), p), 1/p);
       lambda1 /= lmnr; mu1 /= lmnr;
@@ -415,7 +423,8 @@
   // the OSE part
   VectorT y(m.rows (), 1, 0), z(m.rows (), 1);
   typedef typename VectorT::element_type RR;
-  RR lambda = 0, mu = 1;
+  RR lambda = 0;
+  RR mu = 1;
   for (octave_idx_type k = 0; k < m.columns (); k++)
     {
       octave_quit ();
--- a/liboctave/numeric/randmtzig.c	Fri Feb 06 08:31:09 2015 -0800
+++ b/liboctave/numeric/randmtzig.c	Fri Feb 06 08:31:49 2015 -0800
@@ -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/numeric/sparse-base-chol.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/liboctave/numeric/sparse-base-chol.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -105,17 +105,17 @@
   if (spu == 0.)
     {
       cm->print = -1;
-      cm->print_function = 0;
+      SUITESPARSE_ASSIGN_FPTR (printf_func, cm->print_function, 0);
     }
   else
     {
       cm->print = static_cast<int> (spu) + 2;
-      cm->print_function =&SparseCholPrint;
+      SUITESPARSE_ASSIGN_FPTR (printf_func, cm->print_function, &SparseCholPrint);
     }
 
   cm->error_handler = &SparseCholError;
-  cm->complex_divide = CHOLMOD_NAME(divcomplex);
-  cm->hypotenuse = CHOLMOD_NAME(hypot);
+  SUITESPARSE_ASSIGN_FPTR2 (divcomplex_func, cm->complex_divide, divcomplex);
+  SUITESPARSE_ASSIGN_FPTR2 (hypot_func, cm->hypotenuse, hypot);
 
   cm->final_asis = false;
   cm->final_super = false;
--- a/liboctave/numeric/sparse-base-lu.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/liboctave/numeric/sparse-base-lu.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -27,6 +27,8 @@
 
 #include "sparse-base-lu.h"
 
+#include "PermMatrix.h"
+
 template <class lu_type, class lu_elt_type, class p_type, class p_elt_type>
 lu_type
 sparse_base_lu <lu_type, lu_elt_type, p_type, p_elt_type> :: Y (void) const
--- a/liboctave/numeric/sparse-dmsolve.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/liboctave/numeric/sparse-dmsolve.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -43,7 +43,8 @@
                  octave_idx_type cend, octave_idx_type maxnz = -1,
                  bool lazy = false)
 {
-  octave_idx_type nr = rend - rst, nc = cend - cst;
+  octave_idx_type nr = rend - rst;
+  octave_idx_type nc = cend - cst;
   maxnz = (maxnz < 0 ? A.nnz () : maxnz);
   octave_idx_type nz;
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/liboctave/operators/Sparse-op-decls.h	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,184 @@
+/*
+
+Copyright (C) 2004-2013 David Bateman
+Copyright (C) 1998-2004 Andy Adler
+Copyright (C) 2008 Jaroslav Hajek
+
+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_Sparse_op_decls_h)
+#define octave_Sparse_op_decls_h 1
+
+class SparseBoolMatrix;
+
+#define SPARSE_BIN_OP_DECL(R, OP, X, Y, API) \
+  extern API R OP (const X&, const Y&)
+
+#define SPARSE_CMP_OP_DECL(OP, X, Y, API) \
+  extern API SparseBoolMatrix OP (const X&, const Y&)
+
+#define SPARSE_BOOL_OP_DECL(OP, X, Y, API) \
+  extern API SparseBoolMatrix OP (const X&, const Y&)
+
+// sparse matrix by scalar operations.
+
+#define SPARSE_SMS_BIN_OP_DECLS(R1, R2, M, S, API)  \
+  SPARSE_BIN_OP_DECL (R1, operator +, M, S, API); \
+  SPARSE_BIN_OP_DECL (R1, operator -, M, S, API); \
+  SPARSE_BIN_OP_DECL (R2, operator *, M, S, API); \
+  SPARSE_BIN_OP_DECL (R2, operator /, M, S, API);
+
+#define SPARSE_SMS_CMP_OP_DECLS(M, S, API) \
+  SPARSE_CMP_OP_DECL (mx_el_lt, M, S, API); \
+  SPARSE_CMP_OP_DECL (mx_el_le, M, S, API); \
+  SPARSE_CMP_OP_DECL (mx_el_ge, M, S, API); \
+  SPARSE_CMP_OP_DECL (mx_el_gt, M, S, API); \
+  SPARSE_CMP_OP_DECL (mx_el_eq, M, S, API); \
+  SPARSE_CMP_OP_DECL (mx_el_ne, M, S, API);
+
+#define SPARSE_SMS_EQNE_OP_DECLS(M, S, API) \
+  SPARSE_CMP_OP_DECL (mx_el_eq, M, S, API); \
+  SPARSE_CMP_OP_DECL (mx_el_ne, M, S, API);
+
+#define SPARSE_SMS_BOOL_OP_DECLS(M, S, API) \
+  SPARSE_BOOL_OP_DECL (mx_el_and, M, S, API); \
+  SPARSE_BOOL_OP_DECL (mx_el_or,  M, S, API);
+
+#define SPARSE_SMS_OP_DECLS(R1, R2, M, S, API) \
+  SPARSE_SMS_BIN_OP_DECLS (R1, R2, M, S, API)    \
+  SPARSE_SMS_CMP_OP_DECLS (M, S, API) \
+  SPARSE_SMS_BOOL_OP_DECLS (M, S, API)
+
+// scalar by sparse matrix operations.
+
+#define SPARSE_SSM_BIN_OP_DECLS(R1, R2, S, M, API)    \
+  SPARSE_BIN_OP_DECL (R1, operator +, S, M, API); \
+  SPARSE_BIN_OP_DECL (R1, operator -, S, M, API); \
+  SPARSE_BIN_OP_DECL (R2, operator *, S, M, API); \
+  SPARSE_BIN_OP_DECL (R2, operator /, S, M, API);
+
+#define SPARSE_SSM_CMP_OP_DECLS(S, M, API) \
+  SPARSE_CMP_OP_DECL (mx_el_lt, S, M, API); \
+  SPARSE_CMP_OP_DECL (mx_el_le, S, M, API); \
+  SPARSE_CMP_OP_DECL (mx_el_ge, S, M, API); \
+  SPARSE_CMP_OP_DECL (mx_el_gt, S, M, API); \
+  SPARSE_CMP_OP_DECL (mx_el_eq, S, M, API); \
+  SPARSE_CMP_OP_DECL (mx_el_ne, S, M, API);
+
+#define SPARSE_SSM_EQNE_OP_DECLS(S, M, API) \
+  SPARSE_CMP_OP_DECL (mx_el_eq, S, M, API); \
+  SPARSE_CMP_OP_DECL (mx_el_ne, S, M, API);
+
+#define SPARSE_SSM_BOOL_OP_DECLS(S, M, API) \
+  SPARSE_BOOL_OP_DECL (mx_el_and, S, M, API); \
+  SPARSE_BOOL_OP_DECL (mx_el_or,  S, M, API); \
+
+#define SPARSE_SSM_OP_DECLS(R1, R2, S, M, API) \
+  SPARSE_SSM_BIN_OP_DECLS (R1, R2, S, M, API)    \
+  SPARSE_SSM_CMP_OP_DECLS (S, M, API) \
+  SPARSE_SSM_BOOL_OP_DECLS (S, M, API) \
+
+// sparse matrix by sparse matrix operations.
+
+#define SPARSE_SMSM_BIN_OP_DECLS(R1, R2, M1, M2, API)   \
+  SPARSE_BIN_OP_DECL (R1, operator +, M1, M2, API); \
+  SPARSE_BIN_OP_DECL (R1, operator -, M1, M2, API); \
+  SPARSE_BIN_OP_DECL (R2, product,    M1, M2, API); \
+  SPARSE_BIN_OP_DECL (R2, quotient,   M1, M2, API);
+
+#define SPARSE_SMSM_CMP_OP_DECLS(M1, M2, API) \
+  SPARSE_CMP_OP_DECL (mx_el_lt, M1, M2, API); \
+  SPARSE_CMP_OP_DECL (mx_el_le, M1, M2, API); \
+  SPARSE_CMP_OP_DECL (mx_el_ge, M1, M2, API); \
+  SPARSE_CMP_OP_DECL (mx_el_gt, M1, M2, API); \
+  SPARSE_CMP_OP_DECL (mx_el_eq, M1, M2, API); \
+  SPARSE_CMP_OP_DECL (mx_el_ne, M1, M2, API);
+
+#define SPARSE_SMSM_EQNE_OP_DECLS(M1, M2, API) \
+  SPARSE_CMP_OP_DECL (mx_el_eq, M1, M2, API); \
+  SPARSE_CMP_OP_DECL (mx_el_ne, M1, M2, API);
+
+#define SPARSE_SMSM_BOOL_OP_DECLS(M1, M2, API) \
+  SPARSE_BOOL_OP_DECL (mx_el_and, M1, M2, API); \
+  SPARSE_BOOL_OP_DECL (mx_el_or,  M1, M2, API);
+
+#define SPARSE_SMSM_OP_DECLS(R1, R2, M1, M2, API) \
+  SPARSE_SMSM_BIN_OP_DECLS (R1, R2, M1, M2, API) \
+  SPARSE_SMSM_CMP_OP_DECLS (M1, M2, API) \
+  SPARSE_SMSM_BOOL_OP_DECLS (M1, M2, API)
+
+// matrix by sparse matrix operations.
+
+#define SPARSE_MSM_BIN_OP_DECLS(R1, R2, M1, M2, API)    \
+  SPARSE_BIN_OP_DECL (R1, operator +, M1, M2, API); \
+  SPARSE_BIN_OP_DECL (R1, operator -, M1, M2, API); \
+  SPARSE_BIN_OP_DECL (R2, product,    M1, M2, API); \
+  SPARSE_BIN_OP_DECL (R2, quotient,   M1, M2, API);
+
+#define SPARSE_MSM_CMP_OP_DECLS(M1, M2, API) \
+  SPARSE_CMP_OP_DECL (mx_el_lt, M1, M2, API); \
+  SPARSE_CMP_OP_DECL (mx_el_le, M1, M2, API); \
+  SPARSE_CMP_OP_DECL (mx_el_ge, M1, M2, API); \
+  SPARSE_CMP_OP_DECL (mx_el_gt, M1, M2, API); \
+  SPARSE_CMP_OP_DECL (mx_el_eq, M1, M2, API); \
+  SPARSE_CMP_OP_DECL (mx_el_ne, M1, M2, API);
+
+#define SPARSE_MSM_EQNE_OP_DECLS(M1, M2, API) \
+  SPARSE_CMP_OP_DECL (mx_el_eq, M1, M2, API); \
+  SPARSE_CMP_OP_DECL (mx_el_ne, M1, M2, API);
+
+#define SPARSE_MSM_BOOL_OP_DECLS(M1, M2, API) \
+  SPARSE_BOOL_OP_DECL (mx_el_and, M1, M2, API); \
+  SPARSE_BOOL_OP_DECL (mx_el_or,  M1, M2, API);
+
+#define SPARSE_MSM_OP_DECLS(R1, R2, M1, M2, API) \
+  SPARSE_MSM_BIN_OP_DECLS (R1, R2, M1, M2, API) \
+  SPARSE_MSM_CMP_OP_DECLS (M1, M2, API) \
+  SPARSE_MSM_BOOL_OP_DECLS (M1, M2, API)
+
+// sparse matrix by matrix operations.
+
+#define SPARSE_SMM_BIN_OP_DECLS(R1, R2, M1, M2, API)    \
+  SPARSE_BIN_OP_DECL (R1, operator +, M1, M2, API); \
+  SPARSE_BIN_OP_DECL (R1, operator -, M1, M2, API); \
+  SPARSE_BIN_OP_DECL (R2, product,    M1, M2, API); \
+  SPARSE_BIN_OP_DECL (R2, quotient,   M1, M2, API);
+
+#define SPARSE_SMM_CMP_OP_DECLS(M1, M2, API) \
+  SPARSE_CMP_OP_DECL (mx_el_lt, M1, M2, API); \
+  SPARSE_CMP_OP_DECL (mx_el_le, M1, M2, API); \
+  SPARSE_CMP_OP_DECL (mx_el_ge, M1, M2, API); \
+  SPARSE_CMP_OP_DECL (mx_el_gt, M1, M2, API); \
+  SPARSE_CMP_OP_DECL (mx_el_eq, M1, M2, API); \
+  SPARSE_CMP_OP_DECL (mx_el_ne, M1, M2, API);
+
+#define SPARSE_SMM_EQNE_OP_DECLS(M1, M2, API) \
+  SPARSE_CMP_OP_DECL (mx_el_eq, M1, M2, API); \
+  SPARSE_CMP_OP_DECL (mx_el_ne, M1, M2, API);
+
+#define SPARSE_SMM_BOOL_OP_DECLS(M1, M2, API) \
+  SPARSE_BOOL_OP_DECL (mx_el_and, M1, M2, API); \
+  SPARSE_BOOL_OP_DECL (mx_el_or,  M1, M2, API);
+
+#define SPARSE_SMM_OP_DECLS(R1, R2, M1, M2, API) \
+  SPARSE_SMM_BIN_OP_DECLS (R1, R2, M1, M2, API) \
+  SPARSE_SMM_CMP_OP_DECLS (M1, M2, API) \
+  SPARSE_SMM_BOOL_OP_DECLS (M1, M2, API)
+
+#endif
--- a/liboctave/operators/Sparse-op-defs.h	Fri Feb 06 08:31:09 2015 -0800
+++ b/liboctave/operators/Sparse-op-defs.h	Fri Feb 06 08:31:49 2015 -0800
@@ -26,26 +26,10 @@
 #define octave_Sparse_op_defs_h 1
 
 #include "Array-util.h"
-#include "mx-ops.h"
 #include "oct-locbuf.h"
 #include "mx-inlines.cc"
 
-#define SPARSE_BIN_OP_DECL(R, OP, X, Y, API) \
-  extern API R OP (const X&, const Y&)
-
-#define SPARSE_CMP_OP_DECL(OP, X, Y, API) \
-  extern API SparseBoolMatrix OP (const X&, const Y&)
-
-#define SPARSE_BOOL_OP_DECL(OP, X, Y, API) \
-  extern API SparseBoolMatrix OP (const X&, const Y&)
-
-// matrix by scalar operations.
-
-#define SPARSE_SMS_BIN_OP_DECLS(R1, R2, M, S, API)  \
-  SPARSE_BIN_OP_DECL (R1, operator +, M, S, API); \
-  SPARSE_BIN_OP_DECL (R1, operator -, M, S, API); \
-  SPARSE_BIN_OP_DECL (R2, operator *, M, S, API); \
-  SPARSE_BIN_OP_DECL (R2, operator /, M, S, API);
+// sparse matrix by scalar operations.
 
 #define SPARSE_SMS_BIN_OP_1(R, F, OP, M, S)     \
   R \
@@ -90,18 +74,6 @@
   SPARSE_SMS_BIN_OP_2 (R2, operator *, *, M, S) \
   SPARSE_SMS_BIN_OP_2 (R2, operator /, /, M, S)
 
-#define SPARSE_SMS_CMP_OP_DECLS(M, S, API) \
-  SPARSE_CMP_OP_DECL (mx_el_lt, M, S, API); \
-  SPARSE_CMP_OP_DECL (mx_el_le, M, S, API); \
-  SPARSE_CMP_OP_DECL (mx_el_ge, M, S, API); \
-  SPARSE_CMP_OP_DECL (mx_el_gt, M, S, API); \
-  SPARSE_CMP_OP_DECL (mx_el_eq, M, S, API); \
-  SPARSE_CMP_OP_DECL (mx_el_ne, M, S, API);
-
-#define SPARSE_SMS_EQNE_OP_DECLS(M, S, API) \
-  SPARSE_CMP_OP_DECL (mx_el_eq, M, S, API); \
-  SPARSE_CMP_OP_DECL (mx_el_ne, M, S, API);
-
 #define SPARSE_SMS_CMP_OP(F, OP, M, MZ, MC, S, SZ, SC)  \
   SparseBoolMatrix \
   F (const M& m, const S& s) \
@@ -151,10 +123,6 @@
   SPARSE_SMS_CMP_OP (mx_el_eq, ==, M, MZ,   , S, SZ,   )        \
   SPARSE_SMS_CMP_OP (mx_el_ne, !=, M, MZ,   , S, SZ,   )
 
-#define SPARSE_SMS_BOOL_OP_DECLS(M, S, API) \
-  SPARSE_BOOL_OP_DECL (mx_el_and, M, S, API); \
-  SPARSE_BOOL_OP_DECL (mx_el_or,  M, S, API);
-
 #define SPARSE_SMS_BOOL_OP(F, OP, M, S, LHS_ZERO, RHS_ZERO) \
   SparseBoolMatrix \
   F (const M& m, const S& s) \
@@ -202,18 +170,7 @@
 #define SPARSE_SMS_BOOL_OPS(M, S, ZERO) \
   SPARSE_SMS_BOOL_OPS2(M, S, ZERO, ZERO)
 
-#define SPARSE_SMS_OP_DECLS(R1, R2, M, S, API) \
-  SPARSE_SMS_BIN_OP_DECLS (R1, R2, M, S, API)    \
-  SPARSE_SMS_CMP_OP_DECLS (M, S, API) \
-  SPARSE_SMS_BOOL_OP_DECLS (M, S, API)
-
-// scalar by matrix operations.
-
-#define SPARSE_SSM_BIN_OP_DECLS(R1, R2, S, M, API)    \
-  SPARSE_BIN_OP_DECL (R1, operator +, S, M, API); \
-  SPARSE_BIN_OP_DECL (R1, operator -, S, M, API); \
-  SPARSE_BIN_OP_DECL (R2, operator *, S, M, API); \
-  SPARSE_BIN_OP_DECL (R2, operator /, S, M, API);
+// scalar by sparse matrix operations.
 
 #define SPARSE_SSM_BIN_OP_1(R, F, OP, S, M) \
   R \
@@ -259,18 +216,6 @@
   SPARSE_SSM_BIN_OP_2 (R2, operator *, *, S, M) \
   SPARSE_SSM_BIN_OP_2 (R2, operator /, /, S, M)
 
-#define SPARSE_SSM_CMP_OP_DECLS(S, M, API) \
-  SPARSE_CMP_OP_DECL (mx_el_lt, S, M, API); \
-  SPARSE_CMP_OP_DECL (mx_el_le, S, M, API); \
-  SPARSE_CMP_OP_DECL (mx_el_ge, S, M, API); \
-  SPARSE_CMP_OP_DECL (mx_el_gt, S, M, API); \
-  SPARSE_CMP_OP_DECL (mx_el_eq, S, M, API); \
-  SPARSE_CMP_OP_DECL (mx_el_ne, S, M, API);
-
-#define SPARSE_SSM_EQNE_OP_DECLS(S, M, API) \
-  SPARSE_CMP_OP_DECL (mx_el_eq, S, M, API); \
-  SPARSE_CMP_OP_DECL (mx_el_ne, S, M, API);
-
 #define SPARSE_SSM_CMP_OP(F, OP, S, SZ, SC, M, MZ, MC)  \
   SparseBoolMatrix \
   F (const S& s, const M& m) \
@@ -320,10 +265,6 @@
   SPARSE_SSM_CMP_OP (mx_el_eq, ==, S, SZ,   , M, MZ,   )        \
   SPARSE_SSM_CMP_OP (mx_el_ne, !=, S, SZ,   , M, MZ,   )
 
-#define SPARSE_SSM_BOOL_OP_DECLS(S, M, API) \
-  SPARSE_BOOL_OP_DECL (mx_el_and, S, M, API); \
-  SPARSE_BOOL_OP_DECL (mx_el_or,  S, M, API); \
-
 #define SPARSE_SSM_BOOL_OP(F, OP, S, M, LHS_ZERO, RHS_ZERO) \
   SparseBoolMatrix \
   F (const S& s, const M& m) \
@@ -371,18 +312,7 @@
 #define SPARSE_SSM_BOOL_OPS(S, M, ZERO) \
   SPARSE_SSM_BOOL_OPS2(S, M, ZERO, ZERO)
 
-#define SPARSE_SSM_OP_DECLS(R1, R2, S, M, API) \
-  SPARSE_SSM_BIN_OP_DECLS (R1, R2, S, M, API)    \
-  SPARSE_SSM_CMP_OP_DECLS (S, M, API) \
-  SPARSE_SSM_BOOL_OP_DECLS (S, M, API) \
-
-// matrix by matrix operations.
-
-#define SPARSE_SMSM_BIN_OP_DECLS(R1, R2, M1, M2, API)   \
-  SPARSE_BIN_OP_DECL (R1, operator +, M1, M2, API); \
-  SPARSE_BIN_OP_DECL (R1, operator -, M1, M2, API); \
-  SPARSE_BIN_OP_DECL (R2, product,    M1, M2, API); \
-  SPARSE_BIN_OP_DECL (R2, quotient,   M1, M2, API);
+// sparse matrix by sparse matrix operations.
 
 #define SPARSE_SMSM_BIN_OP_1(R, F, OP, M1, M2)  \
   R \
@@ -456,7 +386,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 +398,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 +494,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 +502,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 +610,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 +621,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);  \
@@ -724,18 +654,6 @@
   SPARSE_SMSM_BIN_OP_2 (R2, product,     *, M1, M2) \
   SPARSE_SMSM_BIN_OP_3 (R2, quotient,    /, M1, M2)
 
-#define SPARSE_SMSM_CMP_OP_DECLS(M1, M2, API) \
-  SPARSE_CMP_OP_DECL (mx_el_lt, M1, M2, API); \
-  SPARSE_CMP_OP_DECL (mx_el_le, M1, M2, API); \
-  SPARSE_CMP_OP_DECL (mx_el_ge, M1, M2, API); \
-  SPARSE_CMP_OP_DECL (mx_el_gt, M1, M2, API); \
-  SPARSE_CMP_OP_DECL (mx_el_eq, M1, M2, API); \
-  SPARSE_CMP_OP_DECL (mx_el_ne, M1, M2, API);
-
-#define SPARSE_SMSM_EQNE_OP_DECLS(M1, M2, API) \
-  SPARSE_CMP_OP_DECL (mx_el_eq, M1, M2, API); \
-  SPARSE_CMP_OP_DECL (mx_el_ne, M1, M2, API);
-
 // FIXME: this macro duplicates the bodies of the template functions
 // defined in the SPARSE_SSM_CMP_OP and SPARSE_SMS_CMP_OP macros.
 
@@ -915,10 +833,6 @@
   SPARSE_SMSM_CMP_OP (mx_el_eq, ==, M1, Z1,   , M2, Z2,   ) \
   SPARSE_SMSM_CMP_OP (mx_el_ne, !=, M1, Z1,   , M2, Z2,   )
 
-#define SPARSE_SMSM_BOOL_OP_DECLS(M1, M2, API) \
-  SPARSE_BOOL_OP_DECL (mx_el_and, M1, M2, API); \
-  SPARSE_BOOL_OP_DECL (mx_el_or,  M1, M2, API);
-
 // FIXME: this macro duplicates the bodies of the template functions
 // defined in the SPARSE_SSM_BOOL_OP and SPARSE_SMS_BOOL_OP macros.
 
@@ -1062,18 +976,7 @@
 #define SPARSE_SMSM_BOOL_OPS(M1, M2, ZERO) \
   SPARSE_SMSM_BOOL_OPS2(M1, M2, ZERO, ZERO)
 
-#define SPARSE_SMSM_OP_DECLS(R1, R2, M1, M2, API) \
-  SPARSE_SMSM_BIN_OP_DECLS (R1, R2, M1, M2, API) \
-  SPARSE_SMSM_CMP_OP_DECLS (M1, M2, API) \
-  SPARSE_SMSM_BOOL_OP_DECLS (M1, M2, API)
-
-// matrix by matrix operations.
-
-#define SPARSE_MSM_BIN_OP_DECLS(R1, R2, M1, M2, API)    \
-  SPARSE_BIN_OP_DECL (R1, operator +, M1, M2, API); \
-  SPARSE_BIN_OP_DECL (R1, operator -, M1, M2, API); \
-  SPARSE_BIN_OP_DECL (R2, product,    M1, M2, API); \
-  SPARSE_BIN_OP_DECL (R2, quotient,   M1, M2, API);
+// matrix by sparse matrix operations.
 
 #define SPARSE_MSM_BIN_OP_1(R, F, OP, M1, M2)   \
   R \
@@ -1154,18 +1057,6 @@
   SPARSE_MSM_BIN_OP_2 (R2, product,     *, M1, M2) \
   SPARSE_MSM_BIN_OP_1 (R2, quotient,    /, M1, M2)
 
-#define SPARSE_MSM_CMP_OP_DECLS(M1, M2, API) \
-  SPARSE_CMP_OP_DECL (mx_el_lt, M1, M2, API); \
-  SPARSE_CMP_OP_DECL (mx_el_le, M1, M2, API); \
-  SPARSE_CMP_OP_DECL (mx_el_ge, M1, M2, API); \
-  SPARSE_CMP_OP_DECL (mx_el_gt, M1, M2, API); \
-  SPARSE_CMP_OP_DECL (mx_el_eq, M1, M2, API); \
-  SPARSE_CMP_OP_DECL (mx_el_ne, M1, M2, API);
-
-#define SPARSE_MSM_EQNE_OP_DECLS(M1, M2, API) \
-  SPARSE_CMP_OP_DECL (mx_el_eq, M1, M2, API); \
-  SPARSE_CMP_OP_DECL (mx_el_ne, M1, M2, API);
-
 #define SPARSE_MSM_CMP_OP(F, OP, M1, C1, M2, C2)        \
   SparseBoolMatrix \
   F (const M1& m1, const M2& m2) \
@@ -1184,7 +1075,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++) \
@@ -1230,10 +1121,6 @@
   SPARSE_MSM_CMP_OP (mx_el_eq, ==, M1,   , M2,   ) \
   SPARSE_MSM_CMP_OP (mx_el_ne, !=, M1,   , M2,   )
 
-#define SPARSE_MSM_BOOL_OP_DECLS(M1, M2, API) \
-  SPARSE_BOOL_OP_DECL (mx_el_and, M1, M2, API); \
-  SPARSE_BOOL_OP_DECL (mx_el_or,  M1, M2, API);
-
 #define SPARSE_MSM_BOOL_OP(F, OP, M1, M2, LHS_ZERO, RHS_ZERO) \
   SparseBoolMatrix \
   F (const M1& m1, const M2& m2) \
@@ -1252,7 +1139,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++) \
@@ -1295,18 +1182,7 @@
 #define SPARSE_MSM_BOOL_OPS(M1, M2, ZERO) \
   SPARSE_MSM_BOOL_OPS2(M1, M2, ZERO, ZERO)
 
-#define SPARSE_MSM_OP_DECLS(R1, R2, M1, M2, API) \
-  SPARSE_MSM_BIN_OP_DECLS (R1, R2, M1, M2, API) \
-  SPARSE_MSM_CMP_OP_DECLS (M1, M2, API) \
-  SPARSE_MSM_BOOL_OP_DECLS (M1, M2, API)
-
-// matrix by matrix operations.
-
-#define SPARSE_SMM_BIN_OP_DECLS(R1, R2, M1, M2, API)    \
-  SPARSE_BIN_OP_DECL (R1, operator +, M1, M2, API); \
-  SPARSE_BIN_OP_DECL (R1, operator -, M1, M2, API); \
-  SPARSE_BIN_OP_DECL (R2, product,    M1, M2, API); \
-  SPARSE_BIN_OP_DECL (R2, quotient,   M1, M2, API);
+// sparse matrix by matrix operations.
 
 #define SPARSE_SMM_BIN_OP_1(R, F, OP, M1, M2)   \
   R \
@@ -1394,18 +1270,6 @@
   SPARSE_SMM_BIN_OP_2 (R2, product,     *, M1, M2) \
   SPARSE_SMM_BIN_OP_2 (R2, quotient,    /, M1, M2)
 
-#define SPARSE_SMM_CMP_OP_DECLS(M1, M2, API) \
-  SPARSE_CMP_OP_DECL (mx_el_lt, M1, M2, API); \
-  SPARSE_CMP_OP_DECL (mx_el_le, M1, M2, API); \
-  SPARSE_CMP_OP_DECL (mx_el_ge, M1, M2, API); \
-  SPARSE_CMP_OP_DECL (mx_el_gt, M1, M2, API); \
-  SPARSE_CMP_OP_DECL (mx_el_eq, M1, M2, API); \
-  SPARSE_CMP_OP_DECL (mx_el_ne, M1, M2, API);
-
-#define SPARSE_SMM_EQNE_OP_DECLS(M1, M2, API) \
-  SPARSE_CMP_OP_DECL (mx_el_eq, M1, M2, API); \
-  SPARSE_CMP_OP_DECL (mx_el_ne, M1, M2, API);
-
 #define SPARSE_SMM_CMP_OP(F, OP, M1, C1, M2, C2)        \
   SparseBoolMatrix \
   F (const M1& m1, const M2& m2) \
@@ -1424,7 +1288,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++) \
@@ -1470,10 +1334,6 @@
   SPARSE_SMM_CMP_OP (mx_el_eq, ==, M1,   , M2,   ) \
   SPARSE_SMM_CMP_OP (mx_el_ne, !=, M1,   , M2,   )
 
-#define SPARSE_SMM_BOOL_OP_DECLS(M1, M2, API) \
-  SPARSE_BOOL_OP_DECL (mx_el_and, M1, M2, API); \
-  SPARSE_BOOL_OP_DECL (mx_el_or,  M1, M2, API);
-
 #define SPARSE_SMM_BOOL_OP(F, OP, M1, M2, LHS_ZERO, RHS_ZERO) \
   SparseBoolMatrix \
   F (const M1& m1, const M2& m2) \
@@ -1492,7 +1352,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++) \
@@ -1535,11 +1395,6 @@
 #define SPARSE_SMM_BOOL_OPS(M1, M2, ZERO) \
   SPARSE_SMM_BOOL_OPS2(M1, M2, ZERO, ZERO)
 
-#define SPARSE_SMM_OP_DECLS(R1, R2, M1, M2, API) \
-  SPARSE_SMM_BIN_OP_DECLS (R1, R2, M1, M2, API) \
-  SPARSE_SMM_CMP_OP_DECLS (M1, M2, API) \
-  SPARSE_SMM_BOOL_OP_DECLS (M1, M2, API)
-
 // Avoid some code duplication.  Maybe we should use templates.
 
 #define SPARSE_CUMSUM(RET_TYPE, ELT_TYPE, FCN)  \
@@ -1836,7 +1691,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 +1785,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 +1860,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 +1895,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 +1931,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 +1967,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 Feb 06 08:31:09 2015 -0800
+++ b/liboctave/operators/Sparse-perm-op-defs.h	Fri Feb 06 08:31:49 2015 -0800
@@ -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/module.mk	Fri Feb 06 08:31:09 2015 -0800
+++ b/liboctave/operators/module.mk	Fri Feb 06 08:31:49 2015 -0800
@@ -33,6 +33,7 @@
   operators/mx-op-decl.h \
   operators/mx-op-defs.h \
   operators/Sparse-diag-op-defs.h \
+  operators/Sparse-op-decls.h \
   operators/Sparse-op-defs.h \
   operators/Sparse-perm-op-defs.h
 
@@ -67,3 +68,4 @@
 
 DISTCLEANFILES += $(BUILT_LIBOPERATORS_SOURCES)
 
+liboctave_la_LIBADD += operators/liboperators.la
--- a/liboctave/operators/mx-inlines.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/liboctave/operators/mx-inlines.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -27,6 +27,7 @@
 
 #include <cstddef>
 #include <cmath>
+#include <cstring>
 #include <memory>
 
 #include "quit.h"
@@ -365,7 +366,8 @@
                  void (*op2) (size_t, R *, const X *, Y) throw (),
                  const char *opname)
 {
-  dim_vector dx = x.dims (), dy = y.dims ();
+  dim_vector dx = x.dims ();
+  dim_vector dy = y.dims ();
   if (dx == dy)
     {
       Array<R> r (dx);
@@ -410,7 +412,8 @@
                   void (*op1) (size_t, R *, X) throw (),
                   const char *opname)
 {
-  dim_vector dr = r.dims (), dx = x.dims ();
+  dim_vector dr = r.dims ();
+  dim_vector dx = x.dims ();
   if (dr == dx)
     {
       op (r.length (), r.fortran_vec (), x.data ());
@@ -483,6 +486,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)
@@ -512,6 +523,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)
@@ -537,6 +549,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)
 
@@ -610,6 +623,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)
@@ -856,7 +870,8 @@
 { \
   if (! n) return; \
   T tmp = v[0]; \
-  octave_idx_type i = 1, j = 0; \
+  octave_idx_type i = 1; \
+  octave_idx_type j = 0; \
   if (xisnan (tmp)) \
     { \
       for (; i < n && xisnan (v[i]); i++) ; \
@@ -876,7 +891,8 @@
 { \
   if (! n) return; \
   T tmp = v[0]; octave_idx_type tmpi = 0; \
-  octave_idx_type i = 1, j = 0; \
+  octave_idx_type i = 1; \
+  octave_idx_type j = 0; \
   if (xisnan (tmp)) \
     { \
       for (; i < n && xisnan (v[i]); i++) ; \
@@ -923,6 +939,8 @@
             { r[i] = r0[i]; nan = true; } \
           else if (xisnan (r0[i]) || v[i] OP r0[i]) \
             r[i] = v[i]; \
+          else \
+            r[i] = r0[i]; \
         } \
       j++; v += m; r0 = r; r += m; \
     } \
@@ -960,6 +978,8 @@
             { r[i] = r0[i]; ri[i] = r0i[i]; nan = true; } \
           else if (xisnan (r0[i]) || v[i] OP r0[i]) \
             { r[i] = v[i]; ri[i] = j; }\
+          else \
+            { r[i] = r0[i]; ri[i] = r0i[i]; }\
         } \
       j++; v += m; r0 = r; r += m; r0i = ri; ri += m;  \
     } \
@@ -1330,7 +1350,9 @@
 inline void twosum_accum (T& s, T& e,
                           const T& x)
 {
-  T s1 = s + x, t = s1 - s, e1 = (s - (s1 - t)) + (x - t);
+  T s1 = s + x;
+  T t = s1 - s;
+  T e1 = (s - (s1 - t)) + (x - t);
   s = s1;
   e += e1;
 }
@@ -1339,7 +1361,8 @@
 inline T
 mx_inline_xsum (const T *v, octave_idx_type n)
 {
-  T s = 0, 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 Feb 06 08:31:09 2015 -0800
+++ b/liboctave/operators/mx-op-defs.h	Fri Feb 06 08:31:49 2015 -0800
@@ -25,6 +25,7 @@
 #if !defined (octave_mx_op_defs_h)
 #define octave_mx_op_defs_h 1
 
+#include "lo-array-gripes.h"
 #include "mx-op-decl.h"
 #include "mx-inlines.cc"
 
@@ -599,19 +600,15 @@
 #define PMM_MULTIPLY_OP(PM, M) \
 M operator * (const PM& p, const M& x) \
 { \
-  octave_idx_type nr = x.rows (), nc = x.columns (); \
+  octave_idx_type nr = x.rows (); \
+  octave_idx_type nc = x.columns (); \
   M result; \
   if (p.columns () != nr) \
     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; \
@@ -620,20 +617,13 @@
 #define MPM_MULTIPLY_OP(M, PM) \
 M operator * (const M& x, const PM& p) \
 { \
-  octave_idx_type nr = x.rows (), nc = x.columns (); \
+  octave_idx_type nr = x.rows (); \
+  octave_idx_type nc = x.columns (); \
   M result; \
   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/operators/sparse-mk-ops.awk	Fri Feb 06 08:31:09 2015 -0800
+++ b/liboctave/operators/sparse-mk-ops.awk	Fri Feb 06 08:31:49 2015 -0800
@@ -170,6 +170,10 @@
                 printf ("#include \"%s\"\n", rhs_header) >> h_file;
             }
 
+          ## FIXME: it might be nice to only include the declarations
+          ## of the operators that are actually needed instead of
+          ## including all of them.
+          printf ("#include \"mx-ops.h\"\n") >> h_file;
           printf ("#include \"Sparse-op-defs.h\"\n") >> h_file;
 
           if (bin_ops)
--- a/liboctave/system/file-ops.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/liboctave/system/file-ops.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -39,6 +39,10 @@
 #include "pathmax.h"
 #include "canonicalize.h"
 
+extern "C" {
+#include <tempname.h>
+}
+
 #include "dir-ops.h"
 #include "file-ops.h"
 #include "file-stat.h"
@@ -362,6 +366,27 @@
             : dir + dir_sep_char () + file);
 }
 
+std::string
+file_ops::native_separator_path (const std::string& path)
+{
+  std::string retval;
+
+  if (dir_sep_char () == '/')
+    retval = path;
+  else
+    {
+      size_t n = path.length ();
+      for (size_t i = 0; i < n; i++)
+        {
+          if (path[i] == '/')
+            retval += dir_sep_char();
+          else
+            retval += path[i];
+        }
+    }
+
+  return retval;
+}
 
 int
 octave_mkdir (const std::string& nm, mode_t md)
@@ -657,20 +682,36 @@
 
   std::string retval;
 
-  const char *pdir = dir.empty () ? 0 : dir.c_str ();
+  // get dir path to use for template
+  std::string templatename;
+  if (dir.empty ())
+    templatename = octave_env::get_temp_directory ();
+  else if (! file_stat (dir, false).is_dir ())
+    templatename = octave_env::get_temp_directory ();
+  else
+    templatename = dir;
 
-  const char *ppfx = pfx.empty () ? 0 : pfx.c_str ();
-
-  char *tmp = tempnam (pdir, ppfx);
+  // add dir sep char if it is not there
+  if (*templatename.rbegin () != file_ops::dir_sep_char ())
+    templatename += file_ops::dir_sep_char ();
 
-  if (tmp)
-    {
-      retval = tmp;
+  if (pfx.empty ())
+    templatename += "file";
+  else
+    templatename += pfx;
+
+  // add the required XXXXXX for the template
+  templatename += "XXXXXX";
 
-      free (tmp);
-    }
+  // create and copy template to char array for call to gen_tempname
+  char tname [templatename.length () + 1];
+
+  strcpy (tname, templatename.c_str ());
+
+  if (gen_tempname (tname, 0, 0, GT_NOCREATE) == -1)
+    msg = gnulib::strerror (errno);
   else
-    msg = gnulib::strerror (errno);
+    retval = tname;
 
   return retval;
 }
@@ -689,8 +730,6 @@
 
   std::string retval;
 
-#if defined (HAVE_CANONICALIZE_FILE_NAME)
-
   char *tmp = gnulib::canonicalize_file_name (name.c_str ());
 
   if (tmp)
@@ -699,98 +738,6 @@
       free (tmp);
     }
 
-#elif defined (HAVE_RESOLVEPATH)
-
-#if !defined (errno)
-extern int errno;
-#endif
-
-#if !defined (__set_errno)
-# define __set_errno(Val) errno = (Val)
-#endif
-
-  if (name.empty ())
-    {
-      __set_errno (ENOENT);
-      return retval;
-    }
-
-  // All known hosts with resolvepath (e.g. Solaris 7) don't turn
-  // relative names into absolute ones, so prepend the working
-  // directory if the path is not absolute.
-
-  std::string absolute_name = octave_env::make_absolute (name);
-
-  size_t resolved_size = absolute_name.length ();
-
-  while (true)
-    {
-      resolved_size = 2 * resolved_size + 1;
-
-      OCTAVE_LOCAL_BUFFER (char, resolved, resolved_size);
-
-      int resolved_len
-        = resolvepath (absolute_name.c_str (), resolved, resolved_size);
-
-      if (resolved_len < 0)
-        break;
-
-      if (resolved_len < resolved_size)
-        {
-          retval = resolved;
-          break;
-        }
-    }
-
-#elif defined (__WIN32__)
-
-  int n = 1024;
-
-  std::string win_path (n, '\0');
-
-  while (true)
-    {
-      int status = GetFullPathName (name.c_str (), n, &win_path[0], 0);
-
-      if (status == 0)
-        break;
-      else if (status < n)
-        {
-          win_path.resize (status);
-          retval = win_path;
-          break;
-        }
-      else
-        {
-          n *= 2;
-          win_path.resize (n);
-        }
-    }
-
-#elif defined (HAVE_REALPATH)
-
-#if !defined (__set_errno)
-# define __set_errno(Val) errno = (Val)
-#endif
-
-  if (name.empty ())
-    {
-      __set_errno (ENOENT);
-      return retval;
-    }
-
-  OCTAVE_LOCAL_BUFFER (char, buf, PATH_MAX);
-
-  if (::realpath (name.c_str (), buf))
-    retval = buf;
-
-#else
-
-  // FIXME: provide replacement here...
-  retval = name;
-
-#endif
-
   if (retval.empty ())
     msg = gnulib::strerror (errno);
 
--- a/liboctave/system/file-ops.h	Fri Feb 06 08:31:09 2015 -0800
+++ b/liboctave/system/file-ops.h	Fri Feb 06 08:31:49 2015 -0800
@@ -95,6 +95,9 @@
     return path.substr (ipos);
   }
 
+  // convert path from UNIX type separators to whatever is the system separators
+  static std::string native_separator_path (const std::string& path);
+
 private:
 
   static file_ops *instance;
--- a/liboctave/system/module.mk	Fri Feb 06 08:31:09 2015 -0800
+++ b/liboctave/system/module.mk	Fri Feb 06 08:31:49 2015 -0800
@@ -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,11 +29,11 @@
   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
 
 system_libsystem_la_SOURCES = $(SYSTEM_SRC)
 system_libsystem_la_CPPFLAGS = $(liboctave_la_CPPFLAGS)
 
+liboctave_la_LIBADD += system/libsystem.la
--- a/liboctave/system/oct-env.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/liboctave/system/oct-env.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -150,6 +150,13 @@
 }
 
 std::string
+octave_env::get_temp_directory ()
+{
+  return (instance_ok ())
+         ? instance->do_get_temp_directory () : std::string ();
+}
+
+std::string
 octave_env::get_program_name (void)
 {
   return (instance_ok ())
@@ -184,6 +191,45 @@
          ? instance->do_get_host_name () : std::string ();
 }
 
+std::string
+octave_env::do_get_temp_directory (void) const
+{
+  std::string tempd;
+
+#if defined (__MINGW32__) || defined (_MSC_VER)
+
+  tempd = do_getenv ("TEMP");
+
+  if (tempd.empty ())
+    tempd = do_getenv ("TMP");
+
+  #if defined (P_tmpdir)
+  if (tempd.empty ())
+    tempd = P_tmpdir;
+  #endif
+
+  // Some versions of MinGW and MSVC either don't define P_tmpdir, or
+  // define it to a single backslash.  In such cases just use C:\temp.
+  if (tempd.empty () || tempd == "\\")
+    tempd = "c:\\temp";
+
+#else    // Unix-like OS
+
+  tempd = do_getenv ("TMP");
+
+  #if defined (P_tmpdir)
+  if (tempd.empty ())
+    tempd = P_tmpdir;
+  #else
+  if (tempd.empty ())
+    tempd = "/tmp";
+  #endif
+
+#endif
+
+  return tempd;
+}
+
 // FIXME: this leaves no way to distinguish between a
 // variable that is not set and one that is set to the empty string.
 // Is this a problem?
--- a/liboctave/system/oct-env.h	Fri Feb 06 08:31:09 2015 -0800
+++ b/liboctave/system/oct-env.h	Fri Feb 06 08:31:49 2015 -0800
@@ -51,6 +51,8 @@
 
   static std::string get_home_directory (void);
 
+  static std::string get_temp_directory (void);
+
   static std::string get_program_name (void);
 
   static std::string get_program_invocation_name (void);
@@ -88,6 +90,8 @@
 
   std::string do_get_home_directory (void) const;
 
+  std::string do_get_temp_directory (void) const;
+
   std::string do_get_user_name (void) const;
 
   std::string do_get_host_name (void) const;
--- a/liboctave/system/oct-time.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/liboctave/system/oct-time.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -235,7 +235,7 @@
 
   time_t t = ot.unix_time ();
 
-  octave_base_tm::init (localtime (&t));
+  octave_base_tm::init (gnulib::localtime (&t));
 }
 
 void
@@ -245,7 +245,7 @@
 
   time_t t = ot.unix_time ();
 
-  octave_base_tm::init (gmtime (&t));
+  octave_base_tm::init (gnulib::gmtime (&t));
 }
 
 void
--- a/liboctave/system/tempnam.c	Fri Feb 06 08:31:09 2015 -0800
+++ /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 Feb 06 08:31:09 2015 -0800
+++ /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 Feb 06 08:31:09 2015 -0800
+++ b/liboctave/util/base-list.h	Fri Feb 06 08:31:49 2015 -0800
@@ -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 Feb 06 08:31:09 2015 -0800
+++ b/liboctave/util/caseless-str.h	Fri Feb 06 08:31:49 2015 -0800
@@ -54,18 +54,19 @@
 
     while (p1 != end () && p2 != s.end ())
       {
-        char lp1 = std::tolower (*p1), lp2 = std::tolower (*p2);
+        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/cmd-edit.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/liboctave/util/cmd-edit.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -100,12 +100,16 @@
 
   void do_resize_terminal (void);
 
+  void do_set_screen_size (int ht, int wd);
+
   std::string newline_chars (void);
 
   void do_restore_terminal_state (void);
 
   void do_blink_matching_paren (bool flag);
 
+  bool do_erase_empty_line (bool flag);
+
   void do_set_basic_word_break_characters (const std::string& s);
 
   void do_set_completer_word_break_characters (const std::string& s);
@@ -179,6 +183,8 @@
 
   bool do_filename_quoting_desired (bool);
 
+  bool do_prefer_env_winsize (bool);
+
   void do_interrupt (bool);
 
   static int operate_and_get_next (int, int);
@@ -351,6 +357,12 @@
   ::octave_rl_resize_terminal ();
 }
 
+void
+gnu_readline::do_set_screen_size (int ht, int wd)
+{
+  ::octave_rl_set_screen_size (ht, wd);
+}
+
 std::string
 gnu_readline::newline_chars (void)
 {
@@ -369,6 +381,12 @@
   ::octave_rl_enable_paren_matching (flag ? 1 : 0);
 }
 
+bool
+gnu_readline::do_erase_empty_line (bool flag)
+{
+  return ::octave_rl_erase_empty_line (flag ? 1 : 0);
+}
+
 void
 gnu_readline::do_set_basic_word_break_characters (const std::string& s)
 {
@@ -651,6 +669,12 @@
   return ::octave_rl_filename_quoting_desired (arg);
 }
 
+bool
+gnu_readline::do_prefer_env_winsize (bool arg)
+{
+  return ::octave_rl_prefer_env_winsize (arg);
+}
+
 void
 gnu_readline::do_interrupt (bool arg)
 {
@@ -1112,6 +1136,13 @@
     instance->do_resize_terminal ();
 }
 
+void
+command_editor::set_screen_size (int ht, int wd)
+{
+  if (instance_ok ())
+    instance->do_set_screen_size (ht, wd);
+}
+
 std::string
 command_editor::decode_prompt_string (const std::string& s)
 {
@@ -1154,6 +1185,12 @@
     instance->do_blink_matching_paren (flag);
 }
 
+bool
+command_editor::erase_empty_line (bool flag)
+{
+  return instance_ok () ? instance->do_erase_empty_line (flag) : false;
+}
+
 void
 command_editor::set_basic_word_break_characters (const std::string& s)
 {
@@ -1447,6 +1484,13 @@
 }
 
 bool
+command_editor::prefer_env_winsize (bool arg)
+{
+  return (instance_ok ())
+         ? instance->do_prefer_env_winsize (arg) : false;
+}
+
+bool
 command_editor::interrupt (bool arg)
 {
   bool retval;
--- a/liboctave/util/cmd-edit.h	Fri Feb 06 08:31:09 2015 -0800
+++ b/liboctave/util/cmd-edit.h	Fri Feb 06 08:31:49 2015 -0800
@@ -83,12 +83,16 @@
 
   static void resize_terminal (void);
 
+  static void set_screen_size (int ht, int wd);
+
   static std::string decode_prompt_string (const std::string& s);
 
   static void restore_terminal_state (void);
 
   static void blink_matching_paren (bool flag);
 
+  static bool erase_empty_line (bool flag);
+
   static void set_basic_word_break_characters (const std::string& s);
 
   static void set_completer_word_break_characters (const std::string& s);
@@ -161,6 +165,8 @@
 
   static bool filename_quoting_desired (bool);
 
+  static bool prefer_env_winsize (bool);
+
   static bool interrupt (bool = true);
 
   static int current_command_number (void);
@@ -248,6 +254,8 @@
 
   virtual void do_resize_terminal (void) { }
 
+  virtual void do_set_screen_size (int, int) { }
+
   virtual std::string do_decode_prompt_string (const std::string&);
 
   virtual std::string newline_chars (void) { return "\n"; }
@@ -256,6 +264,8 @@
 
   virtual void do_blink_matching_paren (bool) { }
 
+  virtual bool do_erase_empty_line (bool) { return false; }
+
   virtual void do_set_basic_word_break_characters (const std::string&) { }
 
   virtual void do_set_completer_word_break_characters (const std::string&) { }
@@ -329,6 +339,8 @@
 
   virtual bool do_filename_quoting_desired (bool) { return false; }
 
+  virtual bool do_prefer_env_winsize (bool) { return false; }
+
   virtual void do_interrupt (bool) { }
 
   int do_insert_initial_input (void);
--- a/liboctave/util/cmd-hist.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/liboctave/util/cmd-hist.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -145,8 +145,9 @@
           else if (tmp == "ignorespace")
             history_control |= HC_IGNSPACE;
           else
-            (*current_liboctave_warning_handler)
-              ("unknown histcontrol directive %s", tmp.c_str ());
+            (*current_liboctave_warning_with_id_handler)
+              ("Octave:history-control",
+               "unknown histcontrol directive %s", tmp.c_str ());
 
           if (end != std::string::npos)
             beg = end + 1;
@@ -779,8 +780,9 @@
 void
 command_history::do_process_histcontrol (const std::string&)
 {
-  (*current_liboctave_warning_handler)
-    ("readline is not linked, so history control is not available");
+  (*current_liboctave_warning_with_id_handler)
+    ("Octave:history-control",
+     "readline is not linked, so history control is not available");
 }
 
 void
--- a/liboctave/util/data-conv.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/liboctave/util/data-conv.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -409,12 +409,11 @@
 
           if (input_is_output)
             {
-              input_is_output = false;
-
               s1 = s.substr (1, pos-1);
 
-              (*current_liboctave_warning_handler)
-                ("warning: ignoring leading * in fread precision");
+              (*current_liboctave_warning_with_id_handler)
+                ("Octave:fread-precision-syntax",
+                 "warning: ignoring leading * in fread precision");
             }
           else
             s1 = s.substr (0, pos);
@@ -587,7 +586,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 +609,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 +808,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 +866,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 +875,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 +973,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/kpse.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/liboctave/util/kpse.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -1549,8 +1549,9 @@
       /* What if there isn't a matching close brace? */
       if (! c)
         {
-          (*current_liboctave_warning_handler)
-            ("%s: Unmatched {", text.c_str ());
+          (*current_liboctave_warning_with_id_handler)
+            ("Octave:pathsearch-syntax",
+             "%s: Unmatched {", text.c_str ());
 
           result = string_vector (text);
         }
@@ -1612,7 +1613,10 @@
 static int
 brace_gobbler (const std::string& text, int& indx, int satisfy)
 {
-  int c = 0, level = 0, quoted = 0, pass_next = 0;
+  int c = 0;
+  int level = 0;
+  int quoted = 0;
+  int pass_next = 0;
 
   size_t text_len = text.length ();
 
@@ -2542,8 +2546,9 @@
 {
   if (expanding_p (var))
     {
-      (*current_liboctave_warning_handler)
-        ("kpathsea: variable '%s' references itself (eventually)",
+      (*current_liboctave_warning_with_id_handler)
+        ("Octave:pathsearch-syntax",
+         "kpathsea: variable '%s' references itself (eventually)",
          var.c_str ());
     }
   else
@@ -2620,8 +2625,9 @@
 
               if (var_end == src_len)
                 {
-                  (*current_liboctave_warning_handler)
-                    ("%s: No matching } for ${", src.c_str ());
+                  (*current_liboctave_warning_with_id_handler)
+                    ("Octave:pathsearch-syntax",
+                     "%s: No matching } for ${", src.c_str ());
                   i = var_end - 1; /* will incr to eos at top of loop */
                 }
               else
@@ -2633,8 +2639,9 @@
           else
             {
               /* $<something-else>: error.  */
-              (*current_liboctave_warning_handler)
-                ("%s: Unrecognized variable construct '$%c'",
+              (*current_liboctave_warning_with_id_handler)
+                ("Octave:pathsearch-syntax",
+                 "%s: Unrecognized variable construct '$%c'",
                  src.c_str (), src[i]);
 
               /* Just ignore those chars and keep going.  */
--- a/liboctave/util/lo-array-gripes.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/liboctave/util/lo-array-gripes.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -34,6 +34,10 @@
 
 const char *error_id_invalid_index = "Octave:invalid-index";
 
+const char *warning_id_nearly_singular_matrix = "Octave:nearly-singular-matrix";
+
+const char *warning_id_singular_matrix = "Octave:singular-matrix";
+
 void
 gripe_nan_to_logical_conversion (void)
 {
@@ -166,3 +170,19 @@
     ("A(I,J,...) = X: dimensions mismatch");
 }
 
+void
+gripe_singular_matrix (double rcond)
+{
+  if (rcond == 0.0)
+    {
+      (*current_liboctave_warning_with_id_handler)
+        (warning_id_singular_matrix,
+         "matrix singular to machine precision");
+    }
+  else
+    {
+      (*current_liboctave_warning_with_id_handler)
+        (warning_id_nearly_singular_matrix,
+         "matrix singular to machine precision, rcond = %g", rcond);
+    }
+}
--- a/liboctave/util/lo-array-gripes.h	Fri Feb 06 08:31:09 2015 -0800
+++ b/liboctave/util/lo-array-gripes.h	Fri Feb 06 08:31:49 2015 -0800
@@ -31,6 +31,10 @@
 
 extern OCTAVE_API const char *error_id_invalid_index;
 
+extern OCTAVE_API const char *warning_id_nearly_singular_matrix;
+
+extern OCTAVE_API const char *warning_id_singular_matrix;
+
 extern void OCTAVE_API
 gripe_nan_to_logical_conversion (void);
 
@@ -71,4 +75,7 @@
 extern void OCTAVE_API
 gripe_assignment_dimension_mismatch (void);
 
+extern void OCTAVE_API
+gripe_singular_matrix (double rcond = 0.0);
+
 #endif
--- a/liboctave/util/lo-cieee.c	Fri Feb 06 08:31:09 2015 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,279 +0,0 @@
-/*
-
-Copyright (C) 2002-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 <float.h>
-
-#if defined (HAVE_FLOATINGPOINT_H)
-#include <floatingpoint.h>
-#endif
-
-#if defined (HAVE_IEEEFP_H)
-#include <ieeefp.h>
-#endif
-
-#include "lo-ieee.h"
-#include "lo-math.h"
-
-#if ! defined (HAVE_ISNAN) && defined (HAVE__ISNAN)
-#define isnan _isnan
-#define HAVE_ISNAN 1
-#endif
-
-#if ! defined (HAVE_FINITE) && defined (HAVE__FINITE)
-#define finite _finite
-#define HAVE_FINITE 1
-#endif
-
-#if defined (_AIX) && defined (__GNUG__)
-#undef finite
-#define finite(x) ((x) < DBL_MAX && (x) > -DBL_MAX)
-#endif
-
-/* Octave's idea of infinity.  */
-double octave_Inf;
-float octave_Float_Inf;
-
-/* Octave's idea of a missing value.  */
-double octave_NA;
-float octave_Float_NA;
-
-/* Octave's idea of not a number.  */
-double octave_NaN;
-float octave_Float_NaN;
-
-int lo_ieee_hw;
-int lo_ieee_lw;
-
-int
-__lo_ieee_isnan (double x)
-{
-#if defined (HAVE_ISNAN)
-  return isnan (x);
-#else
-  return 0;
-#endif
-}
-
-int
-__lo_ieee_finite (double x)
-{
-#if defined (HAVE_FINITE)
-  return finite (x) != 0 && ! __lo_ieee_isnan (x);
-#elif defined (HAVE_ISINF)
-  return (! isinf (x) && ! __lo_ieee_isnan (x));
-#else
-  return ! __lo_ieee_isnan (x);
-#endif
-}
-
-int
-__lo_ieee_isinf (double x)
-{
-#if defined (HAVE_ISINF)
-  return isinf (x);
-#elif defined (HAVE_FINITE)
-  return (! (finite (x) || __lo_ieee_isnan (x)));
-#else
-  return 0;
-#endif
-}
-
-int
-__lo_ieee_is_NA (double x)
-{
-#if defined (HAVE_ISNAN)
-  lo_ieee_double t;
-  t.value = x;
-  return (isnan (x) && t.word[lo_ieee_hw] == LO_IEEE_NA_HW
-          && t.word[lo_ieee_lw] == LO_IEEE_NA_LW) ? 1 : 0;
-#else
-  return 0;
-#endif
-}
-
-int
-__lo_ieee_is_old_NA (double x)
-{
-#if defined (HAVE_ISNAN)
-  lo_ieee_double t;
-  t.value = x;
-  return (isnan (x) && t.word[lo_ieee_lw] == LO_IEEE_NA_LW_OLD
-          && t.word[lo_ieee_hw] == LO_IEEE_NA_HW_OLD) ? 1 : 0;
-#else
-  return 0;
-#endif
-}
-
-double
-__lo_ieee_replace_old_NA (double x)
-{
-  if (__lo_ieee_is_old_NA (x))
-    return lo_ieee_na_value ();
-  else
-    return x;
-}
-
-int
-__lo_ieee_is_NaN_or_NA (double x)
-{
-  return __lo_ieee_isnan (x);
-}
-
-double
-lo_ieee_inf_value (void)
-{
-  return octave_Inf;
-}
-
-double
-lo_ieee_na_value (void)
-{
-  return octave_NA;
-}
-
-double
-lo_ieee_nan_value (void)
-{
-  return octave_NaN;
-}
-
-#if ! (defined (signbit) || defined (HAVE_DECL_SIGNBIT)) && defined (HAVE_SIGNBIT)
-extern int signbit (double);
-#endif
-
-int
-__lo_ieee_signbit (double x)
-{
-  /* In the following definitions, only check x < 0 explicitly to avoid
-     a function call when it looks like signbit or copysign are actually
-     functions.  */
-
-#if defined (signbit)
-  return signbit (x);
-#elif defined (HAVE_SIGNBIT)
-  return (x < 0 || signbit (x));
-#elif defined (copysign)
-  return (copysign (1.0, x) < 0);
-#elif defined (HAVE_COPYSIGN)
-  return (x < 0 || copysign (1.0, x) < 0);
-#else
-  return x < 0;
-#endif
-}
-
-int
-__lo_ieee_float_isnan (float x)
-{
-#if defined (HAVE_ISNAN)
-  return isnan (x);
-#else
-  return 0;
-#endif
-}
-
-int
-__lo_ieee_float_finite (float x)
-{
-#if defined (HAVE_FINITE)
-  return finite (x) != 0 && ! __lo_ieee_float_isnan (x);
-#elif defined (HAVE_ISINF)
-  return (! isinf (x) && ! __lo_ieee_float_isnan (x));
-#else
-  return ! __lo_ieee_float_isnan (x);
-#endif
-}
-
-int
-__lo_ieee_float_isinf (float x)
-{
-#if defined (HAVE_ISINF)
-  return isinf (x);
-#elif defined (HAVE_FINITE)
-  return (! (finite (x) || __lo_ieee_float_isnan (x)));
-#else
-  return 0;
-#endif
-}
-
-int
-__lo_ieee_float_is_NA (float x)
-{
-#if defined (HAVE_ISNAN)
-  lo_ieee_float t;
-  t.value = x;
-  return (isnan (x) && (t.word == LO_IEEE_NA_FLOAT)) ? 1 : 0;
-#else
-  return 0;
-#endif
-}
-
-int
-__lo_ieee_float_is_NaN_or_NA (float x)
-{
-  return __lo_ieee_float_isnan (x);
-}
-
-float
-lo_ieee_float_inf_value (void)
-{
-  return octave_Float_Inf;
-}
-
-float
-lo_ieee_float_na_value (void)
-{
-  return octave_Float_NA;
-}
-
-float
-lo_ieee_float_nan_value (void)
-{
-  return octave_Float_NaN;
-}
-
-#if ! (defined (signbit) || defined (HAVE_DECL_SIGNBIT)) && defined (HAVE_SIGNBIT)
-extern int signbit (float);
-#endif
-
-int
-__lo_ieee_float_signbit (float x)
-{
-  /* In the following definitions, only check x < 0 explicitly to avoid
-     a function call when it looks like signbit or copysign are actually
-     functions.  */
-
-#if defined (signbit)
-  return signbit (x);
-#elif defined (HAVE_SIGNBIT)
-  return (x < 0 || signbit (x));
-#elif defined (copysign)
-  return (copysign (1.0, x) < 0);
-#elif defined (HAVE_COPYSIGN)
-  return (x < 0 || copysign (1.0, x) < 0);
-#else
-  return x < 0;
-#endif
-}
--- a/liboctave/util/lo-ieee.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/liboctave/util/lo-ieee.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -24,63 +24,256 @@
 #include <config.h>
 #endif
 
+#include <cfloat>
+#include <cmath>
 #include <cstdlib>
 
 #include <limits>
 
+static double lo_inf;
+static double lo_nan;
+static double lo_na;
+
+static float lo_float_inf;
+static float lo_float_nan;
+static float lo_float_na;
+
+static int lo_ieee_hw;
+static int lo_ieee_lw;
+
 #include "lo-error.h"
 #include "lo-ieee.h"
+#include "lo-math.h"
 #include "mach-info.h"
 
+int
+__lo_ieee_isnan (double x)
+{
+#if defined (HAVE_CMATH_ISNAN)
+  return std::isnan (x);
+#else
+  // Gnulib provides.
+  return isnan (x);
+#endif
+}
+
+int
+__lo_ieee_finite (double x)
+{
+#if defined (HAVE_CMATH_ISFINITE)
+  return std::isfinite (x);
+#else
+  // Gnulib provides.
+  return finite (x);
+#endif
+}
+
+int
+__lo_ieee_isinf (double x)
+{
+#if defined (HAVE_CMATH_ISINF)
+  return std::isinf (x);
+#else
+  // Gnulib provides.
+  return isinf (x);
+#endif
+}
+
+int
+__lo_ieee_is_NA (double x)
+{
+  lo_ieee_double t;
+  t.value = x;
+  return (__lo_ieee_isnan (x) && t.word[lo_ieee_hw] == LO_IEEE_NA_HW
+          && t.word[lo_ieee_lw] == LO_IEEE_NA_LW) ? 1 : 0;
+}
+
+int
+__lo_ieee_is_old_NA (double x)
+{
+  lo_ieee_double t;
+  t.value = x;
+  return (__lo_ieee_isnan (x) && t.word[lo_ieee_lw] == LO_IEEE_NA_LW_OLD
+          && t.word[lo_ieee_hw] == LO_IEEE_NA_HW_OLD) ? 1 : 0;
+}
+
+double
+__lo_ieee_replace_old_NA (double x)
+{
+  if (__lo_ieee_is_old_NA (x))
+    return lo_ieee_na_value ();
+  else
+    return x;
+}
+
+double
+lo_ieee_inf_value (void)
+{
+  octave_ieee_init ();
+
+  return lo_inf;
+}
+
+double
+lo_ieee_na_value (void)
+{
+  octave_ieee_init ();
+
+  return lo_na;
+}
+
+double
+lo_ieee_nan_value (void)
+{
+  octave_ieee_init ();
+
+  return lo_nan;
+}
+
+int
+__lo_ieee_signbit (double x)
+{
+#if defined (HAVE_CMATH_SIGNBIT)
+  return std::signbit (x);
+#else
+  // Gnulib provides.
+  return signbit (x);
+#endif
+}
+
+int
+__lo_ieee_float_isnan (float x)
+{
+#if defined (HAVE_CMATH_ISNAN)
+  return std::isnan (x);
+#else
+  // Gnulib provides.
+  return isnan (x);
+#endif
+}
+
+int
+__lo_ieee_float_finite (float x)
+{
+#if defined (HAVE_CMATH_ISFINITE)
+  return std::isfinite (x) != 0 && ! __lo_ieee_float_isnan (x);
+#else
+  // Gnulib provides.
+  return finite (x);
+#endif
+}
+
+int
+__lo_ieee_float_isinf (float x)
+{
+#if defined (HAVE_CMATH_ISINF)
+  return std::isinf (x);
+#else
+  // Gnulib provides.
+  return isinf (x);
+#endif
+}
+
+int
+__lo_ieee_float_is_NA (float x)
+{
+  lo_ieee_float t;
+  t.value = x;
+  return (__lo_ieee_float_isnan (x) && (t.word == LO_IEEE_NA_FLOAT)) ? 1 : 0;
+}
+
+float
+lo_ieee_float_inf_value (void)
+{
+  octave_ieee_init ();
+
+  return lo_float_inf;
+}
+
+float
+lo_ieee_float_na_value (void)
+{
+  octave_ieee_init ();
+
+  return lo_float_na;
+}
+
+float
+lo_ieee_float_nan_value (void)
+{
+  octave_ieee_init ();
+
+  return lo_float_nan;
+}
+
+int
+__lo_ieee_float_signbit (float x)
+{
+#if defined (HAVE_CMATH_SIGNBIT)
+  return std::signbit (x);
+#else
+  // Gnulib provides.
+  return signbit (x);
+#endif
+}
+
 void
 octave_ieee_init (void)
 {
-  oct_mach_info::float_format ff = oct_mach_info::native_float_format ();
-
-  switch (ff)
-    {
-    case oct_mach_info::flt_fmt_ieee_big_endian:
-    case oct_mach_info::flt_fmt_ieee_little_endian:
-      {
-        octave_NaN = std::numeric_limits<double>::quiet_NaN ();
-        octave_Inf = std::numeric_limits<double>::infinity ();
+  bool initialized = false;
 
-        octave_Float_NaN = std::numeric_limits<float>::quiet_NaN ();
-        octave_Float_Inf = std::numeric_limits<float>::infinity ();
-
-        // The following is patterned after code in R.
+  if (! initialized)
+    {
+      oct_mach_info::float_format ff = oct_mach_info::native_float_format ();
 
-        if (ff == oct_mach_info::flt_fmt_ieee_big_endian)
-          {
-            lo_ieee_hw = 0;
-            lo_ieee_lw = 1;
-          }
-        else
+      switch (ff)
+        {
+        case oct_mach_info::flt_fmt_ieee_big_endian:
+        case oct_mach_info::flt_fmt_ieee_little_endian:
           {
-            lo_ieee_hw = 1;
-            lo_ieee_lw = 0;
-          }
+            lo_nan = std::numeric_limits<double>::quiet_NaN ();
+            lo_inf = std::numeric_limits<double>::infinity ();
+
+            lo_float_nan = std::numeric_limits<float>::quiet_NaN ();
+            lo_float_inf = std::numeric_limits<float>::infinity ();
+
+            // The following is patterned after code in R.
 
-        lo_ieee_double t;
-        t.word[lo_ieee_hw] = LO_IEEE_NA_HW;
-        t.word[lo_ieee_lw] = LO_IEEE_NA_LW;
-
-        octave_NA = t.value;
+            if (ff == oct_mach_info::flt_fmt_ieee_big_endian)
+              {
+                lo_ieee_hw = 0;
+                lo_ieee_lw = 1;
+              }
+            else
+              {
+                lo_ieee_hw = 1;
+                lo_ieee_lw = 0;
+              }
 
-        lo_ieee_float tf;
-        tf.word = LO_IEEE_NA_FLOAT;
-        octave_Float_NA = tf.value;
-      }
-      break;
+            lo_ieee_double t;
+            t.word[lo_ieee_hw] = LO_IEEE_NA_HW;
+            t.word[lo_ieee_lw] = LO_IEEE_NA_LW;
+
+            lo_na = t.value;
+
+            lo_ieee_float tf;
+            tf.word = LO_IEEE_NA_FLOAT;
+
+            lo_float_na = tf.value;
+          }
+          break;
 
-    default:
-      // If the format is unknown, then you will probably not have a
-      // useful system, so we will abort here.  Anyone wishing to
-      // experiment with building Octave on a system without IEEE
-      // floating point should be capable of removing this check and
-      // the configure test.
-      (*current_liboctave_error_handler)
-        ("lo_ieee_init: floating point format is not IEEE!  Maybe DLAMCH is miscompiled, or you are using some strange system without IEEE floating point math?");
-      abort ();
+        default:
+          // If the format is unknown, then you will probably not have a
+          // useful system, so we will abort here.  Anyone wishing to
+          // experiment with building Octave on a system without IEEE
+          // floating point should be capable of removing this check and
+          // the configure test.
+          (*current_liboctave_error_handler)
+            ("lo_ieee_init: floating point format is not IEEE!  Maybe DLAMCH is miscompiled, or you are using some strange system without IEEE floating point math?");
+          abort ();
+        }
+
+      initialized = true;
     }
 }
--- a/liboctave/util/lo-ieee.h	Fri Feb 06 08:31:09 2015 -0800
+++ b/liboctave/util/lo-ieee.h	Fri Feb 06 08:31:49 2015 -0800
@@ -28,29 +28,26 @@
 #endif
 
 /*  Octave's idea of infinity.  */
-extern OCTAVE_API double octave_Inf;
+#define octave_Inf (lo_ieee_inf_value ())
 
 /* Octave's idea of a missing value.  */
-extern OCTAVE_API double octave_NA;
+#define octave_NA (lo_ieee_na_value ())
 
 /* Octave's idea of not a number.  */
-extern OCTAVE_API double octave_NaN;
+#define octave_NaN (lo_ieee_nan_value ())
 
 /*  Octave's idea of infinity.  */
-extern OCTAVE_API float octave_Float_Inf;
+#define octave_Float_Inf (lo_ieee_float_inf_value ())
 
 /* Octave's idea of a missing value.  */
-extern OCTAVE_API float octave_Float_NA;
+#define octave_Float_NA (lo_ieee_float_na_value ())
 
 /* Octave's idea of not a number.  */
-extern OCTAVE_API float octave_Float_NaN;
+#define octave_Float_NaN (lo_ieee_float_nan_value ())
 
 /* FIXME -- this code assumes that a double has twice the
    number of bits as an int */
 
-extern OCTAVE_API int lo_ieee_hw;
-extern OCTAVE_API int lo_ieee_lw;
-
 typedef union
 {
   double value;
@@ -77,7 +74,6 @@
 
 extern OCTAVE_API int __lo_ieee_is_NA (double);
 extern OCTAVE_API int __lo_ieee_is_old_NA (double);
-extern OCTAVE_API int __lo_ieee_is_NaN_or_NA (double) GCC_ATTR_DEPRECATED;
 extern OCTAVE_API double __lo_ieee_replace_old_NA (double);
 
 extern OCTAVE_API double lo_ieee_inf_value (void);
@@ -91,7 +87,6 @@
 extern OCTAVE_API int __lo_ieee_float_isinf (float x);
 
 extern OCTAVE_API int __lo_ieee_float_is_NA (float);
-extern OCTAVE_API int __lo_ieee_float_is_NaN_or_NA (float) GCC_ATTR_DEPRECATED;
 
 extern OCTAVE_API float lo_ieee_float_inf_value (void);
 extern OCTAVE_API float lo_ieee_float_na_value (void);
--- a/liboctave/util/lo-regexp.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/liboctave/util/lo-regexp.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -179,8 +179,9 @@
                   if (!lookbehind_warned)
                     {
                       lookbehind_warned = true;
-                      (*current_liboctave_warning_handler)
-                        ("%s: arbitrary length lookbehind patterns are only supported up to length %d",
+                      (*current_liboctave_warning_with_id_handler)
+                        ("Octave:regexp-lookbehind-limit",
+                         "%s: arbitrary length lookbehind patterns are only supported up to length %d",
                          who.c_str (), MAXLOOKBEHIND);
                     }
 
@@ -282,8 +283,9 @@
         {
           // Try harder; start with default value for MATCH_LIMIT
           // and increase it.
-          (*current_liboctave_warning_handler)
-            ("your pattern caused PCRE to hit its MATCH_LIMIT; trying harder now, but this will be slow");
+          (*current_liboctave_warning_with_id_handler)
+            ("Octave:regexp-match-limit",
+             "your pattern caused PCRE to hit its MATCH_LIMIT; trying harder now, but this will be slow");
 
           pcre_extra pe;
 
--- a/liboctave/util/lo-utils.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/liboctave/util/lo-utils.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -322,7 +322,8 @@
 std::complex<T>
 octave_read_cx_fp_value (std::istream& is)
 {
-  T re = 0.0, im = 0.0;
+  T re = 0.0;
+  T im = 0.0;
 
   std::complex<T> cx = 0.0;
 
--- a/liboctave/util/module.mk	Fri Feb 06 08:31:09 2015 -0800
+++ b/liboctave/util/module.mk	Fri Feb 06 08:31:49 2015 -0800
@@ -26,7 +26,6 @@
   util/oct-inttypes.h \
   util/oct-locbuf.h \
   util/oct-md5.h \
-  util/oct-mem.h \
   util/oct-mutex.h \
   util/oct-refcount.h \
   util/oct-rl-edit.h \
@@ -47,7 +46,6 @@
 
 UTIL_C_SRC = \
   util/f2c-main.c \
-  util/lo-cieee.c \
   util/lo-cutils.c \
   util/oct-rl-edit.c \
   util/oct-rl-hist.c
@@ -60,7 +58,6 @@
   util/lo-array-gripes.cc \
   util/lo-ieee.cc \
   util/lo-utils.cc \
-  util/oct-alloc.cc \
   util/oct-base64.cc \
   util/oct-glob.cc \
   util/oct-inttypes.cc \
@@ -89,6 +86,8 @@
 util_libutil_la_SOURCES = $(UTIL_SRC)
 util_libutil_la_CPPFLAGS = \
   $(liboctave_la_CPPFLAGS) \
+  $(CURL_CPPFLAGS) \
   $(PCRE_CPPFLAGS) \
   $(SPARSE_XCPPFLAGS)
 
+liboctave_la_LIBADD += util/libutil.la
--- a/liboctave/util/oct-alloc.cc	Fri Feb 06 08:31:09 2015 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,104 +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/>.
-
-*/
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <new>
-
-#include "oct-alloc.h"
-
-void *
-octave_allocator::alloc (size_t size)
-{
-  if (size != item_size)
-    return ::new char [size];
-
-  if (! head)
-    {
-      if (! grow ())
-        return 0;
-    }
-
-  link *tmp = head;
-  head = head->next;
-  return tmp;
-}
-
-// FIXME: if we free the last item on the list, shouldn't we
-// also free the underlying character array used for storage?
-
-void
-octave_allocator::free (void *p, size_t size)
-{
-  if (size != item_size)
-    ::delete [] (static_cast<char *> (p));
-  else
-    {
-      link *tmp = static_cast<link *> (p);
-      tmp->next = head;
-      head = tmp;
-    }
-}
-
-// Return TRUE for successful allocation, FALSE otherwise.
-
-bool
-octave_allocator::grow (void)
-{
-  bool retval = true;
-
-  char *start = new char [grow_size * item_size];
-
-  if (start)
-    {
-      char *last = &start[(grow_size - 1) * item_size];
-
-      char *p = start;
-      while (p < last)
-        {
-          char *next = p + item_size;
-          (reinterpret_cast<link *> (p)) -> next
-            = reinterpret_cast<link *> (next);
-          p = next;
-        }
-
-      (reinterpret_cast<link *> (last)) -> next = 0;
-
-      head = reinterpret_cast<link *> (start);
-    }
-  else
-    {
-      typedef void (*error_handler_function) (void);
-
-      error_handler_function f = std::set_new_handler (0);
-      std::set_new_handler (f);
-
-      if (f)
-        f ();
-
-      retval = false;
-    }
-
-  return retval;
-}
--- a/liboctave/util/oct-alloc.h	Fri Feb 06 08:31:09 2015 -0800
+++ b/liboctave/util/oct-alloc.h	Fri Feb 06 08:31:49 2015 -0800
@@ -23,79 +23,10 @@
 #if !defined (octave_oct_alloc_h)
 #define octave_oct_alloc_h 1
 
-#include <cstddef>
-
-class
-OCTAVE_API
-octave_allocator
-{
-public:
-
-  octave_allocator (size_t item_sz, int grow_sz = 256)
-    : head (0), grow_size (grow_sz),
-      item_size (item_sz > sizeof (link *) ? item_sz : sizeof (link *))
-  { }
-
-  // Get an object from the free list, possibly increasing the size of
-  // the free list.
-  void *alloc (size_t size);
-
-  // Put objects back on the free list.
-  void free (void *p, size_t size);
-
-private:
-
-  // Structure for internal free list management.
-  struct link { link *next; };
-
-  // Front of the free list.
-  link *head;
-
-  // How many objects to get each time we call the global operator new.
-  int grow_size;
-
-  // The size of each item on the list (or, if that is smaller than
-  // the size of list*, the size of list*.
-  size_t item_size;
-
-  // How to grow the free list.
-  bool grow (void);
-};
-
-#if defined (HAVE_PLACEMENT_DELETE)
-#define DECLARE_OCTAVE_ALLOCATOR_PLACEMENT_DELETE \
-    void operator delete (void *p, void *) \
-      { ::operator delete (p, static_cast<void*> (0)); }
-#else
-#define DECLARE_OCTAVE_ALLOCATOR_PLACEMENT_DELETE \
-    void operator delete (void *p, void *) \
-      { ::operator delete (p); }
-#endif
-
-#if defined (USE_OCTAVE_ALLOCATOR)
-
-#define DECLARE_OCTAVE_ALLOCATOR \
-  public: \
-    void *operator new (size_t size, void *p) \
-      { return ::operator new (size, p); } \
-    DECLARE_OCTAVE_ALLOCATOR_PLACEMENT_DELETE \
-    void *operator new (size_t size) { return allocator.alloc (size); } \
-    void operator delete (void *p, size_t size) { allocator.free (p, size); } \
-  private: \
-    static octave_allocator allocator;
-
-#define DEFINE_OCTAVE_ALLOCATOR(t) \
-  octave_allocator t::allocator (sizeof (t))
-
-#define DEFINE_OCTAVE_ALLOCATOR2(t, s) \
-  octave_allocator t::allocator (sizeof (t), s)
-
-#else
+#warning "the octave_allocator class has been deprecated and will be removed in a future release of Octave"
 
 #define DECLARE_OCTAVE_ALLOCATOR
 #define DEFINE_OCTAVE_ALLOCATOR(t)
 #define DEFINE_OCTAVE_ALLOCATOR2(t, s)
 
 #endif
-
-#endif
--- a/liboctave/util/oct-binmap.h	Fri Feb 06 08:31:09 2015 -0800
+++ b/liboctave/util/oct-binmap.h	Fri Feb 06 08:31:49 2015 -0800
@@ -167,7 +167,8 @@
 Array<U>
 binmap (const Array<T>& xa, const Array<R>& ya, F fcn, const char *name)
 {
-  dim_vector xad = xa.dims (), yad = ya.dims ();
+  dim_vector xad = xa.dims ();
+  dim_vector yad = ya.dims ();
   if (xa.numel () == 1)
     return binmap<U, T, R, F> (xa(0), ya, fcn);
   else if (ya.numel () == 1)
@@ -225,8 +226,8 @@
     {
       octave_idx_type nz = ys.nnz ();
       Sparse<U> retval (ys.rows (), ys.cols (), nz);
-      copy_or_memcpy (nz, ys.ridx (), retval.ridx ());
-      copy_or_memcpy (ys.cols () + 1, ys.cidx (), retval.cidx ());
+      std::copy (ys.ridx (), ys.ridx () + nz, retval.ridx ());
+      std::copy (ys.cidx (), ys.cidx () + ys.cols () + 1, retval.cidx ());
 
       for (octave_idx_type i = 0; i < nz; i++)
         {
@@ -256,8 +257,8 @@
     {
       octave_idx_type nz = xs.nnz ();
       Sparse<U> retval (xs.rows (), xs.cols (), nz);
-      copy_or_memcpy (nz, xs.ridx (), retval.ridx ());
-      copy_or_memcpy (xs.cols () + 1, xs.cidx (), retval.cidx ());
+      std::copy (xs.ridx (), xs.ridx () + nz, retval.ridx ());
+      std::copy (xs.cidx (), xs.cidx () + xs.cols () + 1, retval.cidx ());
 
       for (octave_idx_type i = 0; i < nz; i++)
         {
--- a/liboctave/util/oct-cmplx.h	Fri Feb 06 08:31:09 2015 -0800
+++ b/liboctave/util/oct-cmplx.h	Fri Feb 06 08:31:49 2015 -0800
@@ -36,14 +36,29 @@
 // The abs/arg comparison is definitely more useful (the other one is emulated
 // rather trivially), so let's be consistent and use that all over.
 
+// The standard C library function arg() returns [-pi,pi], which creates a
+// non-unique representation for numbers along the negative real axis branch
+// cut.  Change this to principal value (-pi,pi] by mapping -pi to pi.
+
 #define DEF_COMPLEXR_COMP(OP, OPS) \
 template <class T> \
 inline bool operator OP (const std::complex<T>& a, const std::complex<T>& b) \
 { \
-  FLOAT_TRUNCATE const T ax = std::abs (a), bx = std::abs (b); \
+  FLOAT_TRUNCATE const T ax = std::abs (a); \
+  FLOAT_TRUNCATE const T bx = std::abs (b); \
   if (ax == bx) \
     { \
-      FLOAT_TRUNCATE const T ay = std::arg (a), by = std::arg (b); \
+      FLOAT_TRUNCATE const T ay = std::arg (a); \
+      FLOAT_TRUNCATE const T by = std::arg (b); \
+      if (ay == -M_PI) \
+        { \
+          if (by != -M_PI) \
+            return M_PI OP by; \
+        } \
+      else if (by == -M_PI) \
+        { \
+          return ay OP M_PI; \
+        } \
       return ay OP by; \
     } \
   else \
@@ -52,10 +67,13 @@
 template <class T> \
 inline bool operator OP (const std::complex<T>& a, T b) \
 { \
-  FLOAT_TRUNCATE const T ax = std::abs (a), bx = std::abs (b); \
+  FLOAT_TRUNCATE const T ax = std::abs (a); \
+  FLOAT_TRUNCATE const T bx = std::abs (b); \
   if (ax == bx) \
     { \
       FLOAT_TRUNCATE const T ay = std::arg (a); \
+      if (ay == -M_PI) \
+        return M_PI OP 0; \
       return ay OP 0; \
     } \
   else \
@@ -64,10 +82,13 @@
 template <class T> \
 inline bool operator OP (T a, const std::complex<T>& b) \
 { \
-  FLOAT_TRUNCATE const T ax = std::abs (a), bx = std::abs (b); \
+  FLOAT_TRUNCATE const T ax = std::abs (a); \
+  FLOAT_TRUNCATE const T bx = std::abs (b); \
   if (ax == bx) \
     { \
       FLOAT_TRUNCATE const T by = std::arg (b); \
+      if (by == -M_PI) \
+        return 0 OP M_PI; \
       return 0 OP by; \
     } \
   else \
--- a/liboctave/util/oct-inttypes.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/liboctave/util/oct-inttypes.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -280,7 +280,8 @@
 octave_int_arith_base<uint64_t, false>::mul_internal (uint64_t x, uint64_t y)
 {
   // Get upper words
-  uint64_t ux = x >> 32, uy = y >> 32;
+  uint64_t ux = x >> 32;
+  uint64_t uy = y >> 32;
   uint64_t res;
   if (ux)
     {
@@ -288,21 +289,25 @@
         goto overflow;
       else
         {
-          uint64_t ly = static_cast<uint32_t> (y), uxly = ux*ly;
+          uint64_t ly = static_cast<uint32_t> (y);
+          uint64_t uxly = ux*ly;
           if (uxly >> 32)
             goto overflow;
           uxly <<= 32; // never overflows
-          uint64_t lx = static_cast<uint32_t> (x), lxly = lx*ly;
+          uint64_t lx = static_cast<uint32_t> (x);
+          uint64_t lxly = lx*ly;
           res = add (uxly, lxly);
         }
     }
   else if (uy)
     {
-      uint64_t lx = static_cast<uint32_t> (x), uylx = uy*lx;
+      uint64_t lx = static_cast<uint32_t> (x);
+      uint64_t uylx = uy*lx;
       if (uylx >> 32)
         goto overflow;
       uylx <<= 32; // never overflows
-      uint64_t ly = static_cast<uint32_t> (y), lylx = ly*lx;
+      uint64_t ly = static_cast<uint32_t> (y);
+      uint64_t lylx = ly*lx;
       res = add (uylx, lylx);
     }
   else
@@ -330,11 +335,13 @@
   // (as above) and impose the sign.
   // FIXME: can we do something faster if we HAVE_FAST_INT_OPS?
 
-  uint64_t usx = octave_int_abs (x), usy = octave_int_abs (y);
+  uint64_t usx = octave_int_abs (x);
+  uint64_t usy = octave_int_abs (y);
   bool positive = (x < 0) == (y < 0);
 
   // Get upper words
-  uint64_t ux = usx >> 32, uy = usy >> 32;
+  uint64_t ux = usx >> 32;
+  uint64_t uy = usy >> 32;
   uint64_t res;
   if (ux)
     {
@@ -342,11 +349,13 @@
         goto overflow;
       else
         {
-          uint64_t ly = static_cast<uint32_t> (usy), uxly = ux*ly;
+          uint64_t ly = static_cast<uint32_t> (usy);
+          uint64_t uxly = ux*ly;
           if (uxly >> 32)
             goto overflow;
           uxly <<= 32; // never overflows
-          uint64_t lx = static_cast<uint32_t> (usx), lxly = lx*ly;
+          uint64_t lx = static_cast<uint32_t> (usx);
+          uint64_t lxly = lx*ly;
           res = uxly + lxly;
           if (res < uxly)
             goto overflow;
@@ -354,11 +363,13 @@
     }
   else if (uy)
     {
-      uint64_t lx = static_cast<uint32_t> (usx), uylx = uy*lx;
+      uint64_t lx = static_cast<uint32_t> (usx);
+      uint64_t uylx = uy*lx;
       if (uylx >> 32)
         goto overflow;
       uylx <<= 32; // never overflows
-      uint64_t ly = static_cast<uint32_t> (usy), lylx = ly*lx;
+      uint64_t ly = static_cast<uint32_t> (usy);
+      uint64_t lylx = ly*lx;
       res = uylx + lylx;
       if (res < uylx)
         goto overflow;
@@ -496,11 +507,14 @@
 static void
 umul128 (uint64_t x, uint64_t y, uint32_t w[4])
 {
-  uint64_t lx = static_cast<uint32_t> (x), ux = x >> 32;
-  uint64_t ly = static_cast<uint32_t> (y), uy = y >> 32;
+  uint64_t lx = static_cast<uint32_t> (x);
+  uint64_t ux = x >> 32;
+  uint64_t ly = static_cast<uint32_t> (y);
+  uint64_t uy = y >> 32;
   uint64_t a = lx * ly;
   w[0] = a; a >>= 32;
-  uint64_t uxly = ux*ly, uylx = uy*lx;
+  uint64_t uxly = ux*ly;
+  uint64_t uylx = uy*lx;
   a += static_cast<uint32_t> (uxly); uxly >>= 32;
   a += static_cast<uint32_t> (uylx); uylx >>= 32;
   w[1] = a; a >>= 32;
--- a/liboctave/util/oct-inttypes.h	Fri Feb 06 08:31:09 2015 -0800
+++ b/liboctave/util/oct-inttypes.h	Fri Feb 06 08:31:49 2015 -0800
@@ -81,7 +81,8 @@
   class NM \
     { \
     public: \
-      static const bool ltval = (0 OP 1), gtval = (1 OP 0); \
+      static const bool ltval = (0 OP 1); \
+      static const bool gtval = (1 OP 0); \
       template <class T> \
       static bool op (T x, T y) { return x OP y; } \
     }
@@ -92,7 +93,8 @@
   class NM \
     { \
     public: \
-      static const bool ltval = value, gtval = value; \
+      static const bool ltval = value; \
+      static const bool gtval = value; \
       template <class T> \
       static bool op (T, T) { return value; } \
     }
@@ -268,7 +270,9 @@
     // An exhaustive test whether the max and/or min check can be omitted.
     static const bool t_is_signed = std::numeric_limits<T>::is_signed;
     static const bool s_is_signed = std::numeric_limits<S>::is_signed;
-    static const int t_size = sizeof (T), s_size = sizeof (S);
+    static const int t_size = sizeof (T);
+    static const int s_size = sizeof (S);
+
     static const bool omit_chk_min =
       (! s_is_signed || (t_is_signed && t_size >= s_size));
     static const bool omit_chk_max =
@@ -420,7 +424,8 @@
   {
     if (y != 0)
       {
-        T z = x / y, w = x % y;
+        T z = x / y;
+        T w = x % y;
         if (w >= y-w) z += 1;
         return z;
       }
@@ -610,7 +615,8 @@
     // compiler from interfering. Also, the signed operations on small types
     // actually return int.
     T u = static_cast<UT> (x) + static_cast<UT> (y);
-    T ux = u ^ x, uy = u ^ y;
+    T ux = u ^ x;
+    T uy = u ^ y;
     if ((ux & uy) < 0)
       {
         u = octave_int_base<T>::max_val () + __signbit (~u);
@@ -651,7 +657,8 @@
     // compiler from interfering. Also, the signed operations on small types
     // actually return int.
     T u = static_cast<UT> (x) - static_cast<UT> (y);
-    T ux = u ^ x, uy = u ^ ~y;
+    T ux = u ^ x;
+    T uy = u ^ ~y;
     if ((ux & uy) < 0)
       {
         u = octave_int_base<T>::max_val () + __signbit (~u);
@@ -1286,7 +1293,8 @@
 octave_int<T>
 xmax (const octave_int<T>& x, const octave_int<T>& y)
 {
-  const T xv = x.value (), yv = y.value ();
+  const T xv = x.value ();
+  const T yv = y.value ();
   return octave_int<T> (xv >= yv ? xv : yv);
 }
 
@@ -1294,7 +1302,8 @@
 octave_int<T>
 xmin (const octave_int<T>& x, const octave_int<T>& y)
 {
-  const T xv = x.value (), yv = y.value ();
+  const T xv = x.value ();
+  const T yv = y.value ();
   return octave_int<T> (xv <= yv ? xv : yv);
 }
 
--- a/liboctave/util/oct-locbuf.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/liboctave/util/oct-locbuf.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -140,8 +140,12 @@
     }
   else
     {
-      (*current_liboctave_warning_handler)
-        ("octave_chunk_buffer::clear: %d active allocations remain!",
+      // FIXME: Doesn't this situation represent a programming error of
+      // some kind?  If so, maybe this should be a fatal error?
+
+      (*current_liboctave_warning_with_id_handler)
+        ("Octave:local-buffer-inconsistency",
+         "octave_chunk_buffer::clear: %d active allocations remain!",
          active);
     }
 }
--- a/liboctave/util/oct-mem.h	Fri Feb 06 08:31:09 2015 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,160 +0,0 @@
-/*
-
-Copyright (C) 2009-2013 VZLU Prague
-
-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_oct_mem_h)
-#define octave_oct_mem_h 1
-
-#include <cstddef>
-#include <cstring>
-#include <algorithm>
-
-#include "oct-cmplx.h"
-#include "oct-inttypes.h"
-
-// NOTE: These functions are used to optimize stuff where performance is a
-// priority. They assume that the std::complex and octave_int can be
-// manipulated as plain memory, an assumption that is always true in practice
-// but not theoretically guaranteed by the C++ standard. In the future, C++ may
-// provide a better way to accomplish these tasks.
-
-inline size_t safe_size_comp (size_t n, size_t size)
-{
-  if (n > static_cast<size_t> (-1) / size)
-    throw std::bad_alloc ();
-  return n * size;
-}
-
-// Unaliased copy. This boils down to memcpy, even for octave_int and
-// complex types.
-
-template <class T>
-inline void copy_or_memcpy (size_t n, const T *src, T *dest)
-{ std::copy (src, src + n, dest); }
-
-#define DEFINE_POD_UCOPY(T) \
-inline void copy_or_memcpy (size_t n, const T *src, T *dest) \
-{ std::memcpy (dest, src, n * sizeof (T)); }
-
-DEFINE_POD_UCOPY (double)
-DEFINE_POD_UCOPY (float)
-DEFINE_POD_UCOPY (char)
-DEFINE_POD_UCOPY (short)
-DEFINE_POD_UCOPY (int)
-DEFINE_POD_UCOPY (long)
-DEFINE_POD_UCOPY (unsigned char)
-DEFINE_POD_UCOPY (unsigned short)
-DEFINE_POD_UCOPY (unsigned int)
-DEFINE_POD_UCOPY (unsigned long)
-
-DEFINE_POD_UCOPY (Complex)
-DEFINE_POD_UCOPY (FloatComplex)
-
-template <class T>
-DEFINE_POD_UCOPY (octave_int<T>)
-
-// Fill by value, with a check for zero. This boils down to memset if value is
-// a POD zero.
-template <class T>
-inline void fill_or_memset (size_t n, const T& value, T *dest)
-{ std::fill_n (dest, n, value); }
-
-template <class T>
-inline bool helper_is_zero_mem (const T& value)
-{
-  // get integer type of the same size.
-  typedef typename query_integer_type<sizeof (T), false>::type IT;
-  return *(reinterpret_cast<const IT *>(&value)) == 0;
-}
-
-template <class T>
-inline bool helper_is_zero_mem (const std::complex<T>& value)
-{
-  return (helper_is_zero_mem (value.real ())
-          && helper_is_zero_mem (value.imag ()));
-}
-
-template <class T>
-inline bool helper_is_zero_mem (const octave_int<T>& value)
-{ return value.value () == T (); }
-
-#define DEFINE_POD_FILL(T) \
-inline void fill_or_memset (size_t n, const T& value, T *dest) \
-{ \
-  if (helper_is_zero_mem (value)) \
-    std::memset (dest, 0, n * sizeof (T)); \
-  else \
-    std::fill_n (dest, n, value); \
-}
-
-DEFINE_POD_FILL (double)
-DEFINE_POD_FILL (float)
-DEFINE_POD_FILL (char)
-DEFINE_POD_FILL (short)
-DEFINE_POD_FILL (int)
-DEFINE_POD_FILL (long)
-DEFINE_POD_FILL (unsigned char)
-DEFINE_POD_FILL (unsigned short)
-DEFINE_POD_FILL (unsigned int)
-DEFINE_POD_FILL (unsigned long)
-
-DEFINE_POD_FILL (Complex)
-DEFINE_POD_FILL (FloatComplex)
-
-template <class T>
-DEFINE_POD_FILL (octave_int<T>)
-
-// Uninitialized allocation.
-// Will not initialize memory for complex and octave_int.
-// Memory allocated by octave_new should be freed by octave_delete.
-template <class T>
-inline T *no_ctor_new (size_t n)
-{
-  // Some systems let us allocate > 2GB memory even though size_t, which is
-  // either buggy or completely cuckoo, so let's check here to stay safe.
-  safe_size_comp (n, sizeof (T));
-  return new T [n];
-}
-template <class T>
-inline void no_ctor_delete (T *ptr)
-{ delete [] ptr; }
-
-#define DEFINE_POD_NEW_DELETE(T) \
-template <> \
-inline T *no_ctor_new<T > (size_t n) \
-{ return reinterpret_cast<T *> (new char [safe_size_comp (n, sizeof (T))]); } \
-template <> \
-inline void no_ctor_delete<T > (T *ptr) \
-{ delete [] reinterpret_cast<char *> (ptr); }
-
-DEFINE_POD_NEW_DELETE (Complex)
-DEFINE_POD_NEW_DELETE (FloatComplex)
-
-DEFINE_POD_NEW_DELETE (octave_int8)
-DEFINE_POD_NEW_DELETE (octave_int16)
-DEFINE_POD_NEW_DELETE (octave_int32)
-DEFINE_POD_NEW_DELETE (octave_int64)
-DEFINE_POD_NEW_DELETE (octave_uint8)
-DEFINE_POD_NEW_DELETE (octave_uint16)
-DEFINE_POD_NEW_DELETE (octave_uint32)
-DEFINE_POD_NEW_DELETE (octave_uint64)
-
-#endif /* octave_oct_mem_h */
--- a/liboctave/util/oct-rl-edit.c	Fri Feb 06 08:31:09 2015 -0800
+++ b/liboctave/util/oct-rl-edit.c	Fri Feb 06 08:31:49 2015 -0800
@@ -74,6 +74,14 @@
   rl_variable_bind ("blink-matching-paren", val ? "1" : "0");
 }
 
+int
+octave_rl_erase_empty_line (int val)
+{
+  int retval = rl_erase_empty_line;
+  rl_erase_empty_line = val;
+  return retval;
+}
+
 /* It would be much simpler if we could just call _rl_clear_screen to
    only clear the screen, but it is not a public function, and on some
    systems, it is not exported from shared library versions of
@@ -117,6 +125,12 @@
 }
 
 void
+octave_rl_set_screen_size (int ht, int wd)
+{
+  rl_set_screen_size (ht, wd);
+}
+
+void
 octave_rl_restore_terminal_state ()
 {
   if (rl_deprep_term_function)
@@ -242,6 +256,14 @@
   return retval;
 }
 
+int
+octave_rl_prefer_env_winsize (int arg)
+{
+  int retval = rl_prefer_env_winsize;
+  rl_prefer_env_winsize = arg;
+  return retval;
+}
+
 void
 octave_rl_done (int arg)
 {
--- a/liboctave/util/oct-rl-edit.h	Fri Feb 06 08:31:09 2015 -0800
+++ b/liboctave/util/oct-rl-edit.h	Fri Feb 06 08:31:49 2015 -0800
@@ -56,12 +56,18 @@
 
 extern void octave_rl_enable_paren_matching (int);
 
+extern int octave_rl_erase_empty_line (int);
+
 extern void octave_rl_init (void);
 
 extern void octave_rl_clear_screen (int skip_redisplay);
 
 extern void octave_rl_resize_terminal (void);
 
+extern void octave_rl_resize_terminal (void);
+
+extern void octave_rl_set_screen_size (int ht, int wd);
+
 extern void octave_rl_restore_terminal_state (void);
 
 extern char *octave_rl_copy_line (void);
@@ -98,6 +104,8 @@
 
 extern int octave_rl_filename_quoting_desired (int);
 
+extern int octave_rl_prefer_env_winsize (int);
+
 extern void octave_rl_done (int);
 
 extern char *octave_rl_filename_completion_function (const char *, int);
--- a/liboctave/util/oct-shlib.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/liboctave/util/oct-shlib.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -87,8 +87,9 @@
     {
       tm_loaded = fs.mtime ();
 
-      (*current_liboctave_warning_handler)
-        ("library %s not reloaded due to existing references", file.c_str ());
+      (*current_liboctave_warning_with_id_handler)
+        ("Octave:library-reload",
+         "library %s not reloaded due to existing references", file.c_str ());
     }
 }
 
--- a/liboctave/util/oct-sort.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/liboctave/util/oct-sort.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -158,7 +158,8 @@
   for (; start < nel; ++start)
     {
       /* set l to where *start belongs */
-      octave_idx_type l = 0, r = start;
+      octave_idx_type l = 0;
+      octave_idx_type r = start;
       T pivot = data[start];
       /* Invariants:
        * pivot >= all in [lo, l).
@@ -202,7 +203,8 @@
   for (; start < nel; ++start)
     {
       /* set l to where *start belongs */
-      octave_idx_type l = 0, r = start;
+      octave_idx_type l = 0;
+      octave_idx_type r = start;
       T pivot = data[start];
       /* Invariants:
        * pivot >= all in [lo, l).
@@ -1694,7 +1696,8 @@
         {
           // Not the final column.
           assert (n > 1);
-          const T *hi = lo + n, *lst = lo;
+          const T *hi = lo + n;
+          const T *lst = lo;
           for (lo++; lo < hi; lo++)
             {
               if (comp (*lst, *lo))
@@ -1756,7 +1759,8 @@
 octave_sort<T>::lookup (const T *data, octave_idx_type nel,
                         const T& value, Comp comp)
 {
-  octave_idx_type lo = 0, hi = nel;
+  octave_idx_type lo = 0;
+  octave_idx_type hi = nel;
 
   while (lo < hi)
     {
@@ -1834,7 +1838,8 @@
 {
   if (rev)
     {
-      octave_idx_type i = 0, j = nvalues - 1;
+      octave_idx_type i = 0;
+      octave_idx_type j = nvalues - 1;
 
       if (nvalues > 0 && nel > 0)
         {
@@ -1856,7 +1861,8 @@
     }
   else
     {
-      octave_idx_type i = 0, j = 0;
+      octave_idx_type i = 0;
+      octave_idx_type j = 0;
 
       if (nvalues > 0 && nel > 0)
         {
--- a/liboctave/util/oct-sparse.h	Fri Feb 06 08:31:09 2015 -0800
+++ b/liboctave/util/oct-sparse.h	Fri Feb 06 08:31:49 2015 -0800
@@ -94,4 +94,16 @@
 #endif
 #endif
 
+// Cope with new suitesparse versions
+//
+#if defined (SUITESPARSE_VERSION)
+# if SUITESPARSE_VERSION >= SUITESPARSE_VER_CODE (4, 3)
+#  define SUITESPARSE_ASSIGN_FPTR(f_name, f_var, f_assign) (SuiteSparse_config.f_name = f_assign)
+#  define SUITESPARSE_ASSIGN_FPTR2(f_name, f_var, f_assign) (SuiteSparse_config.f_name = CHOLMOD_NAME (f_assign))
+# else
+#  define SUITESPARSE_ASSIGN_FPTR(f_name, f_var, f_assign) (f_var = f_assign)
+#  define SUITESPARSE_ASSIGN_FPTR2(f_name, f_var, f_assign) (f_var = CHOLMOD_NAME (f_assign))
+# endif
 #endif
+
+#endif
--- a/liboctave/util/sparse-util.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/liboctave/util/sparse-util.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -48,12 +48,9 @@
   // Ignore CHOLMOD_NOT_POSDEF, since we handle that in Fchol as an
   // error or exit status.
   if (status != CHOLMOD_NOT_POSDEF)
-    {
-      (*current_liboctave_warning_handler)("warning %i, at line %i in file %s",
-                                           status, line, file);
-
-      (*current_liboctave_warning_handler)(message);
-    }
+    (*current_liboctave_warning_with_id_handler)
+      ("Octave:cholmod-message", "warning %i, at line %i in file %s: %s",
+       status, line, file, message);
 }
 
 int
--- a/liboctave/util/str-vec.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/liboctave/util/str-vec.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -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 Feb 06 08:31:09 2015 -0800
+++ b/m4/acinclude.m4	Fri Feb 06 08:31:49 2015 -0800
@@ -478,6 +478,69 @@
   fi
 ])
 dnl
+dnl Check whether the Qt QTabWidget::setMovable() function exists.
+dnl This function was added in Qt 4.5.
+dnl
+AC_DEFUN([OCTAVE_CHECK_FUNC_QTABWIDGET_SETMOVABLE], [
+  AC_CACHE_CHECK([whether Qt has the QTabWidget::setMovable() function],
+    [octave_cv_func_qtabwidget_setmovable],
+    [AC_LANG_PUSH(C++)
+    ac_octave_save_CPPFLAGS="$CPPFLAGS"
+    CPPFLAGS="$QT_CPPFLAGS $CPPFLAGS"
+    AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
+        #include <QTabWidget>
+        class tab_widget : public QTabWidget
+        {
+        public:
+          tab_widget (QWidget *parent = 0) : QTabWidget (parent) { this->setMovable (true); }
+          ~tab_widget () {}
+        };
+        ]], [[
+        tab_widget tw;
+        ]])],
+      octave_cv_func_qtabwidget_setmovable=yes,
+      octave_cv_func_qtabwidget_setmovable=no)
+    CPPFLAGS="$ac_octave_save_CPPFLAGS"
+    AC_LANG_POP(C++)
+  ])
+  if test $octave_cv_func_qtabwidget_setmovable = yes; then
+    AC_DEFINE(HAVE_QTABWIDGET_SETMOVABLE, 1,
+      [Define to 1 if Qt has the QTabWidget::setMovable() function.])
+  fi
+])
+dnl
+dnl Check whether the QsciScintilla::findFirstInSelection () function exists.
+dnl This function was added in QScintilla 2.7.
+dnl
+AC_DEFUN([OCTAVE_CHECK_FUNC_QSCI_FINDSELECTION], [
+  AC_CACHE_CHECK([whether QSci has the QsciScintilla::findFirstInSelection () function],
+    [octave_cv_func_qsci_findfirstinselection],
+    [AC_LANG_PUSH(C++)
+    ac_octave_save_CPPFLAGS="$CPPFLAGS"
+    CPPFLAGS="$QT_CPPFLAGS $CPPFLAGS"
+    AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
+        #include <Qsci/qsciscintilla.h>
+        class qsci : public QsciScintilla
+        {
+        public:
+          qsci (QWidget *parent = 0) : QsciScintilla (parent)
+          { this->findFirstInSelection (QString ("x"),true,true,true,true,true); }
+          ~qsci () {}
+        };
+        ]], [[
+        qsci edit;
+        ]])],
+      octave_cv_func_qsci_findfirstinselection=yes,
+      octave_cv_func_qsci_findfirstinselection=no)
+    CPPFLAGS="$ac_octave_save_CPPFLAGS"
+    AC_LANG_POP(C++)
+  ])
+  if test $octave_cv_func_qsci_findfirstinselection = yes; then
+    AC_DEFINE(HAVE_QSCI_FINDSELECTION, 1,
+      [Define to 1 if Qsci has the QsciScintilla::findFirstInSelection () function.])
+  fi
+])
+dnl
 dnl Check whether HDF5 library has version 1.6 API functions.
 dnl
 AC_DEFUN([OCTAVE_CHECK_HDF5_HAS_VER_16_API], [
@@ -535,7 +598,6 @@
     ;;
   esac
 
-  [TEXINFO_]m4_toupper([$1])=
   warn_$1="$3"
   m4_set_add([summary_warning_list], [warn_$1])
 
@@ -560,8 +622,7 @@
         m4_ifblank([$8], [
           warn_$1=
           AC_DEFINE([HAVE_]m4_toupper([$1]), 1,
-            [Define to 1 if $2 is available.])
-          [TEXINFO_]m4_toupper([$1])="@set [HAVE_]m4_toupper([$1])"], [$8])
+            [Define to 1 if $2 is available.])], [$8])
       fi
     fi
     m4_ifnblank([$6], [AC_LANG_POP($6)])
@@ -571,7 +632,6 @@
   fi
 
   AC_SUBST(m4_toupper([$1])_LIBS)
-  AC_SUBST([TEXINFO_]m4_toupper([$1]))
   if test -n "$warn_$1"; then
     AC_MSG_WARN([$warn_$1])
     m4_toupper([$1])_LIBS=
@@ -898,6 +958,16 @@
     ])
 
     if test $have_opengl_incs = yes; then
+      AC_CHECK_HEADERS([GL/glext.h OpenGL/glext.h], [], [], [
+#ifdef HAVE_WINDOWS_H
+# include <windows.h>
+#endif
+#if defined (HAVE_GL_GL_H)
+# include <GL/gl.h>
+#elif defined (HAVE_OPENGL_GL_H)
+# include <OpenGL/gl.h>
+#endif
+      ])
       case $canonical_host_type in
         *-*-mingw32* | *-*-msdosmsvc)
           save_LIBS="$LIBS"
@@ -1737,6 +1807,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], [
--- a/m4/ax_blas.m4	Fri Feb 06 08:31:09 2015 -0800
+++ b/m4/ax_blas.m4	Fri Feb 06 08:31:49 2015 -0800
@@ -63,12 +63,13 @@
 #   modified version of the Autoconf Macro, you may extend this special
 #   exception to the GPL to apply to your modified version as well.
 
-#serial 12
+#serial 14
 
 AU_ALIAS([ACX_BLAS], [AX_BLAS])
 AC_DEFUN([AX_BLAS], [
 AC_PREREQ(2.50)
 AC_REQUIRE([AC_F77_LIBRARY_LDFLAGS])
+AC_REQUIRE([AC_CANONICAL_HOST])
 ax_blas_ok=no
 
 AC_ARG_WITH(blas,
@@ -107,6 +108,12 @@
 	LIBS="$save_LIBS"
 fi
 
+# BLAS in OpenBLAS library? (http://xianyi.github.com/OpenBLAS/)
+if test $ax_blas_ok = no; then
+	AC_CHECK_LIB(openblas, $sgemm, [ax_blas_ok=yes
+			                BLAS_LIBS="-lopenblas"])
+fi
+
 # BLAS in ATLAS library? (http://math-atlas.sourceforge.net/)
 if test $ax_blas_ok = no; then
 	AC_CHECK_LIB(atlas, ATL_xerbla,
@@ -130,6 +137,36 @@
 
 # BLAS in Intel MKL library?
 if test $ax_blas_ok = no; then
+	# MKL for gfortran
+	if test x"$ac_cv_fc_compiler_gnu" = xyes; then
+		# 64 bit
+		if test $host_cpu = x86_64; then
+			AC_CHECK_LIB(mkl_gf_lp64, $sgemm,
+			[ax_blas_ok=yes;BLAS_LIBS="-lmkl_gf_lp64 -lmkl_sequential -lmkl_core -lpthread"],,
+			[-lmkl_gf_lp64 -lmkl_sequential -lmkl_core -lpthread])
+		# 32 bit
+		elif test $host_cpu = i686; then
+			AC_CHECK_LIB(mkl_gf, $sgemm,
+				[ax_blas_ok=yes;BLAS_LIBS="-lmkl_gf -lmkl_sequential -lmkl_core -lpthread"],,
+				[-lmkl_gf -lmkl_sequential -lmkl_core -lpthread])
+		fi
+	# MKL for other compilers (Intel, PGI, ...?)
+	else
+		# 64-bit
+		if test $host_cpu = x86_64; then
+			AC_CHECK_LIB(mkl_intel_lp64, $sgemm,
+				[ax_blas_ok=yes;BLAS_LIBS="-lmkl_intel_lp64 -lmkl_sequential -lmkl_core -lpthread"],,
+				[-lmkl_intel_lp64 -lmkl_sequential -lmkl_core -lpthread])
+		# 32-bit
+		elif test $host_cpu = i686; then
+			AC_CHECK_LIB(mkl_intel, $sgemm,
+				[ax_blas_ok=yes;BLAS_LIBS="-lmkl_intel -lmkl_sequential -lmkl_core -lpthread"],,
+				[-lmkl_intel -lmkl_sequential -lmkl_core -lpthread])
+		fi
+	fi
+fi
+# Old versions of MKL
+if test $ax_blas_ok = no; then
 	AC_CHECK_LIB(mkl, $sgemm, [ax_blas_ok=yes;BLAS_LIBS="-lmkl -lguide -lpthread"],,[-lguide -lpthread])
 fi
 
--- a/m4/ax_blas_f77_func.m4	Fri Feb 06 08:31:09 2015 -0800
+++ b/m4/ax_blas_f77_func.m4	Fri Feb 06 08:31:49 2015 -0800
@@ -55,21 +55,20 @@
 #serial 8
 
 AU_ALIAS([ACX_BLAS_F77_FUNC], [AX_BLAS_F77_FUNC])
-
 AC_DEFUN([AX_BLAS_F77_FUNC], [
-  AC_PREREQ(2.50)
-  AC_REQUIRE([AX_BLAS])
+AC_PREREQ(2.50)
+AC_REQUIRE([AX_BLAS])
 
-  ## F77 call-compatibility checks
-  if test "$cross_compiling" = yes ; then
-    ifelse($3, ,$1,$3)
-  elif test x"$ax_blas_ok" = xyes; then
-    save_ax_blas_f77_func_LIBS="$LIBS"
-    LIBS="$BLAS_LIBS $LIBS"
-    AC_LANG_PUSH(Fortran 77)
-    ## LSAME check (LOGICAL return values)
-    AC_MSG_CHECKING([whether LSAME is called correctly from Fortran])
-    AC_RUN_IFELSE([AC_LANG_PROGRAM([], [[
+# F77 call-compatibility checks
+if test "$cross_compiling" = yes ; then
+	ifelse($3, ,$1,$3)
+elif test x"$ax_blas_ok" = xyes; then
+	save_ax_blas_f77_func_LIBS="$LIBS"
+	LIBS="$BLAS_LIBS $LIBS"
+	AC_LANG_PUSH(Fortran 77)
+# LSAME check (LOGICAL return values)
+	AC_MSG_CHECKING([whether LSAME is called correctly from Fortran])
+	AC_RUN_IFELSE(AC_LANG_PROGRAM(,[[
       logical lsame,w
       external lsame
       character c1,c2
@@ -79,13 +78,12 @@
       if (w) stop 1
       w = lsame(c1,c1)
       if (.not. w) stop 1
-      ]])],
-      [ax_blas_lsame_fcall_ok=yes],
-      [ax_blas_lsame_fcall_ok=no])
-    AC_MSG_RESULT([$ax_blas_lsame_fcall_ok])
-    ## ISAMAX check (INTEGER return values)
-    AC_MSG_CHECKING([whether ISAMAX is called correctly from Fortran])
-    AC_RUN_IFELSE([AC_LANG_PROGRAM([], [[
+      ]]),[ax_blas_lsame_fcall_ok=yes],
+	[ax_blas_lsame_fcall_ok=no])
+	AC_MSG_RESULT([$ax_blas_lsame_fcall_ok])
+# ISAMAX check (INTEGER return values)
+	AC_MSG_CHECKING([whether ISAMAX is called correctly from Fortran])
+	AC_RUN_IFELSE(AC_LANG_PROGRAM(,[[
       integer isamax,i
       external isamax
       real a(2)
@@ -93,73 +91,68 @@
       a(2) = -2e0
       i = isamax(2,a,1)
       if (i.ne.2) stop 1
-      ]])],
-      [ax_blas_isamax_fcall_ok=yes],
-      [ax_blas_isamax_fcall_ok=no])
-    AC_MSG_RESULT([$ax_blas_isamax_fcall_ok])
-    ## SDOT check (REAL return values)
-    AC_MSG_CHECKING([whether SDOT is called correctly from Fortran])
-    AC_RUN_IFELSE([AC_LANG_PROGRAM([], [[
+      ]]),[ax_blas_isamax_fcall_ok=yes],
+	[ax_blas_isamax_fcall_ok=no])
+	AC_MSG_RESULT([$ax_blas_isamax_fcall_ok])
+# SDOT check (REAL return values)
+	AC_MSG_CHECKING([whether SDOT is called correctly from Fortran])
+	AC_RUN_IFELSE(AC_LANG_PROGRAM(,[[
       real sdot,a(1),b(1),w
       external sdot
       a(1) = 1e0
       b(1) = 2e0
       w = sdot(1,a,1,b,1)
       if (w .ne. a(1)*b(1)) stop 1
-      ]])],
-      [ax_blas_sdot_fcall_ok=yes],
-      [ax_blas_sdot_fcall_ok=no])
-    AC_MSG_RESULT([$ax_blas_sdot_fcall_ok])
-    ## DDOT check (DOUBLE return values)
-    AC_MSG_CHECKING([whether DDOT is called correctly from Fortran])
-    AC_RUN_IFELSE([AC_LANG_PROGRAM([], [[
+      ]]),[ax_blas_sdot_fcall_ok=yes],
+	[ax_blas_sdot_fcall_ok=no])
+	AC_MSG_RESULT([$ax_blas_sdot_fcall_ok])
+# DDOT check (DOUBLE return values)
+	AC_MSG_CHECKING([whether DDOT is called correctly from Fortran])
+	AC_RUN_IFELSE(AC_LANG_PROGRAM(,[[
       double precision ddot,a(1),b(1),w
       external ddot
       a(1) = 1d0
       b(1) = 2d0
       w = ddot(1,a,1,b,1)
       if (w .ne. a(1)*b(1)) stop 1
-      ]])],
-      [ax_blas_ddot_fcall_ok=yes],
-      [ax_blas_ddot_fcall_ok=no])
-    AC_MSG_RESULT([$ax_blas_ddot_fcall_ok])
-    ## CDOTU check (COMPLEX return values)
-    AC_MSG_CHECKING([whether CDOTU is called correctly from Fortran])
-    AC_RUN_IFELSE([AC_LANG_PROGRAM([], [[
+      ]]),[ax_blas_ddot_fcall_ok=yes],
+	[ax_blas_ddot_fcall_ok=no])
+	AC_MSG_RESULT([$ax_blas_ddot_fcall_ok])
+# CDOTU check (COMPLEX return values)
+	AC_MSG_CHECKING([whether CDOTU is called correctly from Fortran])
+	AC_RUN_IFELSE(AC_LANG_PROGRAM(,[[
       complex cdotu,a(1),b(1),w
       external cdotu
       a(1) = cmplx(1e0,1e0)
       b(1) = cmplx(1e0,2e0)
       w = cdotu(1,a,1,b,1)
       if (w .ne. a(1)*b(1)) stop 1
-      ]])],
-      [ax_blas_cdotu_fcall_ok=yes],
-      [ax_blas_cdotu_fcall_ok=no])
-    AC_MSG_RESULT([$ax_blas_cdotu_fcall_ok])
-    ## ZDOTU check (DOUBLE COMPLEX return values)
-    AC_MSG_CHECKING([whether ZDOTU is called correctly from Fortran])
-    AC_RUN_IFELSE([AC_LANG_PROGRAM([], [[
+      ]]),[ax_blas_cdotu_fcall_ok=yes],
+	[ax_blas_cdotu_fcall_ok=no])
+	AC_MSG_RESULT([$ax_blas_cdotu_fcall_ok])
+# ZDOTU check (DOUBLE COMPLEX return values)
+	AC_MSG_CHECKING([whether ZDOTU is called correctly from Fortran])
+	AC_RUN_IFELSE(AC_LANG_PROGRAM(,[[
       double complex zdotu,a(1),b(1),w
       external zdotu
       a(1) = dcmplx(1d0,1d0)
       b(1) = dcmplx(1d0,2d0)
       w = zdotu(1,a,1,b,1)
       if (w .ne. a(1)*b(1)) stop 1
-      ]])],
-      [ax_blas_zdotu_fcall_ok=yes],
-      [ax_blas_zdotu_fcall_ok=no])
-    AC_MSG_RESULT([$ax_blas_zdotu_fcall_ok])
-    ## Check for correct integer size
-    ## FIXME: this may fail with things like -ftrapping-math.
-    AC_MSG_CHECKING([whether the integer size is correct])
-    AC_RUN_IFELSE([AC_LANG_PROGRAM([], [[
+      ]]),[ax_blas_zdotu_fcall_ok=yes],
+	[ax_blas_zdotu_fcall_ok=no])
+	AC_MSG_RESULT([$ax_blas_zdotu_fcall_ok])
+# Check for correct integer size
+# FIXME: this may fail with things like -ftrapping-math.
+        AC_MSG_CHECKING([whether the integer size is correct])
+        AC_RUN_IFELSE(AC_LANG_PROGRAM(,[[
       integer n,nn(3)
       real s,a(1),b(1),sdot
       a(1) = 1.0
       b(1) = 1.0
-c Generate -2**32 + 1, if possible
+c Generate -2**33 + 1, if possible
       n = 2
-      n = -4 ** (n ** 30)
+      n = -4 * (n ** 30)
       n = n + 1
       if (n >= 0) goto 1
 c This means we're on 64-bit integers. Check whether the BLAS is, too.
@@ -173,40 +166,39 @@
       nn(3) = -1
       s = sdot(nn(2),a,1,b,1)
       if (s .ne. 1.0) stop 1
-      ]])],
-      [ax_blas_integer_size_ok=yes],
-      [ax_blas_integer_size_ok=no])
-    AC_MSG_RESULT([$ax_blas_integer_size_ok])
+       ]]),[ax_blas_integer_size_ok=yes],
+	[ax_blas_integer_size_ok=no])
+	AC_MSG_RESULT([$ax_blas_integer_size_ok])
 
-    AC_LANG_POP(Fortran 77)
+	AC_LANG_POP(Fortran 77)
 
-    ## if any of the tests failed, reject the BLAS library
-    if test $ax_blas_lsame_fcall_ok = yes \
-      -a $ax_blas_sdot_fcall_ok = yes \
-      -a $ax_blas_ddot_fcall_ok = yes \
-      -a $ax_blas_cdotu_fcall_ok = yes \
-      -a $ax_blas_zdotu_fcall_ok = yes \
-      -a $ax_blas_integer_size_ok = yes; then
-      ax_blas_f77_func_ok=yes;
-      $1
-    else
-      ax_blas_f77_func_ok=no;
-      $2
-    fi
-    LIBS="$save_ax_blas_f77_func_LIBS"
-  fi
+# if any of the tests failed, reject the BLAS library
+	if test $ax_blas_lsame_fcall_ok = yes \
+		-a $ax_blas_sdot_fcall_ok = yes \
+		-a $ax_blas_ddot_fcall_ok = yes \
+		-a $ax_blas_cdotu_fcall_ok = yes \
+		-a $ax_blas_zdotu_fcall_ok = yes \
+		-a $ax_blas_integer_size_ok = yes; then
+		ax_blas_f77_func_ok=yes;
+		$1
+	else
+		ax_blas_f77_func_ok=no;
+		$2
+	fi
+	LIBS="$save_ax_blas_f77_func_LIBS"
+fi
+
 ])dnl AX_BLAS_F77_FUNC
 
 AC_DEFUN([AX_BLAS_WITH_F77_FUNC], [
-  AC_PREREQ(2.50)
-  AX_BLAS([# disable special action], [])
-  if test x$ax_blas_ok = xyes ; then
-    AX_BLAS_F77_FUNC(
-    [ifelse([$1],,AC_DEFINE(HAVE_BLAS,1,[Define if you have a BLAS library.]),[$1])],
-    [ax_blas_ok=no; BLAS_LIBS=],
-    [$3])
-  fi
-  if test x$ax_blas_ok = xno ; then
-    $2
-  fi
+AC_PREREQ(2.50)
+AX_BLAS([# disable special action], [])
+if test x$ax_blas_ok = xyes ; then
+	AX_BLAS_F77_FUNC(
+	[ifelse([$1],,AC_DEFINE(HAVE_BLAS,1,[Define if you have a BLAS library.]),[$1])],
+	[ax_blas_ok=no; BLAS_LIBS=])
+fi
+if test x$ax_blas_ok = xno ; then
+	$2
+fi
 ])dnl AX_BLAS_WITH_F77_FUNC
--- a/m4/ax_pthread.m4	Fri Feb 06 08:31:09 2015 -0800
+++ b/m4/ax_pthread.m4	Fri Feb 06 08:31:49 2015 -0800
@@ -82,7 +82,7 @@
 #   modified version of the Autoconf Macro, you may extend this special
 #   exception to the GPL to apply to your modified version as well.
 
-#serial 18
+#serial 21
 
 AU_ALIAS([ACX_PTHREAD], [AX_PTHREAD])
 AC_DEFUN([AX_PTHREAD], [
@@ -103,8 +103,8 @@
         save_LIBS="$LIBS"
         LIBS="$PTHREAD_LIBS $LIBS"
         AC_MSG_CHECKING([for pthread_join in LIBS=$PTHREAD_LIBS with CFLAGS=$PTHREAD_CFLAGS])
-        AC_TRY_LINK_FUNC(pthread_join, ax_pthread_ok=yes)
-        AC_MSG_RESULT($ax_pthread_ok)
+        AC_TRY_LINK_FUNC([pthread_join], [ax_pthread_ok=yes])
+        AC_MSG_RESULT([$ax_pthread_ok])
         if test x"$ax_pthread_ok" = xno; then
                 PTHREAD_LIBS=""
                 PTHREAD_CFLAGS=""
@@ -164,6 +164,20 @@
         ;;
 esac
 
+# Clang doesn't consider unrecognized options an error unless we specify
+# -Werror. We throw in some extra Clang-specific options to ensure that
+# this doesn't happen for GCC, which also accepts -Werror.
+
+AC_MSG_CHECKING([if compiler needs -Werror to reject unknown flags])
+save_CFLAGS="$CFLAGS"
+ax_pthread_extra_flags="-Werror"
+CFLAGS="$CFLAGS $ax_pthread_extra_flags -Wunknown-warning-option -Wsizeof-array-argument"
+AC_COMPILE_IFELSE([AC_LANG_PROGRAM([int foo(void);],[foo()])],
+                  [AC_MSG_RESULT([yes])],
+                  [ax_pthread_extra_flags=
+                   AC_MSG_RESULT([no])])
+CFLAGS="$save_CFLAGS"
+
 if test x"$ax_pthread_ok" = xno; then
 for flag in $ax_pthread_flags; do
 
@@ -178,7 +192,7 @@
                 ;;
 
                 pthread-config)
-                AC_CHECK_PROG(ax_pthread_config, pthread-config, yes, no)
+                AC_CHECK_PROG([ax_pthread_config], [pthread-config], [yes], [no])
                 if test x"$ax_pthread_config" = xno; then continue; fi
                 PTHREAD_CFLAGS="`pthread-config --cflags`"
                 PTHREAD_LIBS="`pthread-config --ldflags` `pthread-config --libs`"
@@ -193,7 +207,7 @@
         save_LIBS="$LIBS"
         save_CFLAGS="$CFLAGS"
         LIBS="$PTHREAD_LIBS $LIBS"
-        CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
+        CFLAGS="$CFLAGS $PTHREAD_CFLAGS $ax_pthread_extra_flags"
 
         # Check for various functions.  We must include pthread.h,
         # since some functions may be macros.  (On the Sequent, we
@@ -219,7 +233,7 @@
         LIBS="$save_LIBS"
         CFLAGS="$save_CFLAGS"
 
-        AC_MSG_RESULT($ax_pthread_ok)
+        AC_MSG_RESULT([$ax_pthread_ok])
         if test "x$ax_pthread_ok" = xyes; then
                 break;
         fi
@@ -245,9 +259,9 @@
                 [attr_name=$attr; break],
                 [])
         done
-        AC_MSG_RESULT($attr_name)
+        AC_MSG_RESULT([$attr_name])
         if test "$attr_name" != PTHREAD_CREATE_JOINABLE; then
-            AC_DEFINE_UNQUOTED(PTHREAD_CREATE_JOINABLE, $attr_name,
+            AC_DEFINE_UNQUOTED([PTHREAD_CREATE_JOINABLE], [$attr_name],
                                [Define to necessary symbol if this constant
                                 uses a non-standard name on your system.])
         fi
@@ -261,45 +275,54 @@
             if test "$GCC" = "yes"; then
                 flag="-D_REENTRANT"
             else
+                # TODO: What about Clang on Solaris?
                 flag="-mt -D_REENTRANT"
             fi
             ;;
         esac
-        AC_MSG_RESULT(${flag})
+        AC_MSG_RESULT([$flag])
         if test "x$flag" != xno; then
             PTHREAD_CFLAGS="$flag $PTHREAD_CFLAGS"
         fi
 
         AC_CACHE_CHECK([for PTHREAD_PRIO_INHERIT],
-            ax_cv_PTHREAD_PRIO_INHERIT, [
-                AC_LINK_IFELSE([
-                    AC_LANG_PROGRAM([[#include <pthread.h>]], [[int i = PTHREAD_PRIO_INHERIT;]])],
+            [ax_cv_PTHREAD_PRIO_INHERIT], [
+                AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include <pthread.h>]],
+                                                [[int i = PTHREAD_PRIO_INHERIT;]])],
                     [ax_cv_PTHREAD_PRIO_INHERIT=yes],
                     [ax_cv_PTHREAD_PRIO_INHERIT=no])
             ])
         AS_IF([test "x$ax_cv_PTHREAD_PRIO_INHERIT" = "xyes"],
-            AC_DEFINE([HAVE_PTHREAD_PRIO_INHERIT], 1, [Have PTHREAD_PRIO_INHERIT.]))
+            [AC_DEFINE([HAVE_PTHREAD_PRIO_INHERIT], [1], [Have PTHREAD_PRIO_INHERIT.])])
 
         LIBS="$save_LIBS"
         CFLAGS="$save_CFLAGS"
 
-        # More AIX lossage: must compile with xlc_r or cc_r
-        if test x"$GCC" != xyes; then
-          AC_CHECK_PROGS(PTHREAD_CC, xlc_r cc_r, ${CC})
-        else
-          PTHREAD_CC=$CC
+        # More AIX lossage: compile with *_r variant
+        if test "x$GCC" != xyes; then
+            case $host_os in
+                aix*)
+                AS_CASE(["x/$CC"],
+                  [x*/c89|x*/c89_128|x*/c99|x*/c99_128|x*/cc|x*/cc128|x*/xlc|x*/xlc_v6|x*/xlc128|x*/xlc128_v6],
+                  [#handle absolute path differently from PATH based program lookup
+                   AS_CASE(["x$CC"],
+                     [x/*],
+                     [AS_IF([AS_EXECUTABLE_P([${CC}_r])],[PTHREAD_CC="${CC}_r"])],
+                     [AC_CHECK_PROGS([PTHREAD_CC],[${CC}_r],[$CC])])])
+                ;;
+            esac
         fi
-else
-        PTHREAD_CC="$CC"
 fi
 
-AC_SUBST(PTHREAD_LIBS)
-AC_SUBST(PTHREAD_CFLAGS)
-AC_SUBST(PTHREAD_CC)
+test -n "$PTHREAD_CC" || PTHREAD_CC="$CC"
+
+AC_SUBST([PTHREAD_LIBS])
+AC_SUBST([PTHREAD_CFLAGS])
+AC_SUBST([PTHREAD_CC])
 
 # Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND:
 if test x"$ax_pthread_ok" = xyes; then
-        ifelse([$1],,AC_DEFINE(HAVE_PTHREAD,1,[Define if you have POSIX threads libraries and header files.]),[$1])
+        ifelse([$1],,[AC_DEFINE([HAVE_PTHREAD],[1],[Define if you have POSIX threads libraries and header files.])],[$1])
         :
 else
         ax_pthread_ok=no
--- a/run-octave.in	Fri Feb 06 08:31:09 2015 -0800
+++ b/run-octave.in	Fri Feb 06 08:31:49 2015 -0800
@@ -33,18 +33,21 @@
 d1="$top_srcdir/scripts"
 d2="$builddir/scripts"
 d3="$builddir/libinterp"
+d4="$top_srcdir/examples/data"
 
 d1_list=`$FIND "$d1" -type d -a ! \( \( -name private -o -name '@*' \) -a -prune \) -exec echo '{}' ';' | $SED 's/$/:/'`
 d2_list=`$FIND "$d2" -type d -a ! \( \( -name private -o -name '@*' \) -a -prune \) -exec echo '{}' ';' | $SED 's/$/:/'`
 d3_list=`$FIND "$d3" -type d -a ! \( \( -name private -o -name '@*' \) -a -prune \) -exec echo '{}' ';' | $SED 's/$/:/'`
+d4_list=`$FIND "$d4" -type d -exec echo '{}' ';' | $SED 's/$/:/'`
 
 d1_path=`echo "$d1_list" | $AWK '{ t = (s $0); s = t; } END { sub (/:$/, "", s); print s; }'`
 d2_path=`echo "$d2_list" | $AWK '{ t = (s $0); s = t; } END { sub (/:$/, "", s); print s; }'`
 d3_path=`echo "$d3_list" | $AWK '{ t = (s $0); s = t; } END { sub (/:$/, "", s); print s; }'`
+d4_path=`echo "$d4_list" | $AWK '{ t = (s $0); s = t; } END { sub (/:$/, "", s); print s; }'`
 
 octave_executable="$builddir/src/octave"
 
-LOADPATH="$d1_path:$d2_path:$d3_path"
+LOADPATH="$d1_path:$d2_path:$d3_path:$d4_path"
 IMAGEPATH="$top_srcdir/scripts/image"
 DOCFILE="$builddir/doc/interpreter/doc-cache"
 BUILT_IN_DOCSTRINGS_FILE="$builddir/libinterp/DOCSTRINGS"
@@ -69,6 +72,9 @@
   elif [ "x$1" = "x-valgrind" ]; then
     driver="valgrind --tool=memcheck"
     shift
+  elif [ "x$1" = "x-callgrind" ]; then
+    driver="valgrind --tool=callgrind"
+    shift
   elif [ "x$1" = "x-strace" ]; then
     driver="strace -o octave.trace"
     shift
--- a/scripts/@ftp/ascii.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/@ftp/ascii.m	Fri Feb 06 08:31:49 2015 -0800
@@ -30,3 +30,7 @@
   __ftp_ascii__ (f.curlhandle);
 endfunction
 
+
+## No test possible for interactive function.
+%!assert (1)
+
--- a/scripts/@ftp/binary.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/@ftp/binary.m	Fri Feb 06 08:31:49 2015 -0800
@@ -29,3 +29,7 @@
   __ftp_binary__ (f.curlhandle);
 endfunction
 
+
+## No test possible for interactive function.
+%!assert (1)
+
--- a/scripts/@ftp/cd.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/@ftp/cd.m	Fri Feb 06 08:31:49 2015 -0800
@@ -42,3 +42,7 @@
   path = __ftp_pwd__ (f.curlhandle);
 endfunction
 
+
+## No test possible for interactive function.
+%!assert (1)
+
--- a/scripts/@ftp/close.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/@ftp/close.m	Fri Feb 06 08:31:49 2015 -0800
@@ -27,3 +27,7 @@
   __ftp_close__ (f.curlhandle);
 endfunction
 
+
+## No test possible for interactive function.
+%!assert (1)
+
--- a/scripts/@ftp/delete.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/@ftp/delete.m	Fri Feb 06 08:31:49 2015 -0800
@@ -27,3 +27,7 @@
   __ftp_delete__ (f.curlhandle, file);
 endfunction
 
+
+## No test possible for interactive function.
+%!assert (1)
+
--- a/scripts/@ftp/dir.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/@ftp/dir.m	Fri Feb 06 08:31:49 2015 -0800
@@ -32,3 +32,7 @@
   endif
 endfunction
 
+
+## No test possible for interactive function.
+%!assert (1)
+
--- a/scripts/@ftp/display.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/@ftp/display.m	Fri Feb 06 08:31:49 2015 -0800
@@ -24,3 +24,7 @@
   printf (" mode: %s\n", __ftp_mode__ (obj.curlhandle));
 endfunction
 
+
+## No test possible for interactive function.
+%!assert (1)
+
--- a/scripts/@ftp/ftp.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/@ftp/ftp.m	Fri Feb 06 08:31:49 2015 -0800
@@ -51,7 +51,7 @@
     p.host = host;
     p.username = username;
     p.password = password;
-    p.curlhandle = tmpnam ("ftp-");
+    p.curlhandle = tempname ("ftp-");
     if (nargin > 0)
       p.curlhandle = __ftp__ (host, username, password);
     endif
@@ -59,3 +59,7 @@
   endif
 endfunction
 
+
+## No test possible for interactive function.
+%!assert (1)
+
--- a/scripts/@ftp/loadobj.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/@ftp/loadobj.m	Fri Feb 06 08:31:49 2015 -0800
@@ -34,3 +34,7 @@
   endif
 endfunction
 
+
+## No test possible for interactive function.
+%!assert (1)
+
--- a/scripts/@ftp/mget.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/@ftp/mget.m	Fri Feb 06 08:31:49 2015 -0800
@@ -36,3 +36,7 @@
   __ftp_mget__ (f.curlhandle, file);
 endfunction
 
+
+## No test possible for interactive function.
+%!assert (1)
+
--- a/scripts/@ftp/mkdir.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/@ftp/mkdir.m	Fri Feb 06 08:31:49 2015 -0800
@@ -27,3 +27,7 @@
   __ftp_mkdir__ (f.curlhandle, path);
 endfunction
 
+
+## No test possible for interactive function.
+%!assert (1)
+
--- a/scripts/@ftp/mput.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/@ftp/mput.m	Fri Feb 06 08:31:49 2015 -0800
@@ -34,3 +34,7 @@
   endif
 endfunction
 
+
+## No test possible for interactive function.
+%!assert (1)
+
--- a/scripts/@ftp/rename.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/@ftp/rename.m	Fri Feb 06 08:31:49 2015 -0800
@@ -28,3 +28,7 @@
   __ftp_rename__ (f.curlhandle, oldname, newname);
 endfunction
 
+
+## No test possible for interactive function.
+%!assert (1)
+
--- a/scripts/@ftp/rmdir.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/@ftp/rmdir.m	Fri Feb 06 08:31:49 2015 -0800
@@ -27,3 +27,7 @@
   __ftp_rmdir__ (f.curlhandle, path);
 endfunction
 
+
+## No test possible for interactive function.
+%!assert (1)
+
--- a/scripts/@ftp/saveobj.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/@ftp/saveobj.m	Fri Feb 06 08:31:49 2015 -0800
@@ -22,3 +22,7 @@
   b.dir = __ftp_pwd__ (a.curlhandle);
 endfunction
 
+
+## No test possible for interactive function.
+%!assert (1)
+
--- a/scripts/Makefile.am	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/Makefile.am	Fri Feb 06 08:31:49 2015 -0800
@@ -495,5 +495,5 @@
 
 distclean-local:
 	if [ "x$(srcdir)" != "x." ]; then \
-	  rm $(java_JAVA_IMAGES); \
+	  rm -f $(java_JAVA_IMAGES); \
 	fi
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/audio/@audioplayer/__get_properties__.m	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,67 @@
+## Copyright (C) 2013 Vytautas Jančauskas
+##
+## 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{properties} =} __get_properties__ (@var{player})
+## Return a struct containing all named properties of the audioplayer
+## object @var{player}.
+## @end deftypefn
+
+function props = __get_properties__ (player)
+
+  if (nargin != 1)
+    print_usage ();
+  endif
+
+  if (__player_isplaying__ (struct (player).player))
+    running = "on";
+  else
+    running = "off";
+  endif
+
+  props = struct ("BitsPerSample",
+                  __player_get_nbits__ (struct (player).player),
+
+                  "CurrentSample",
+                  __player_get_sample_number__ (struct (player).player),
+
+                  "DeviceID",
+                  __player_get_id__ (struct (player).player),
+
+                  "NumberOfChannels",
+                  __player_get_channels__ (struct (player).player),
+
+                  "Running",
+                  running,
+
+                  "SampleRate",
+                  __player_get_fs__ (struct (player).player),
+
+                  "TotalSamples",
+                  __player_get_total_samples__ (struct (player).player),
+
+                  "Tag",
+                  __player_get_tag__ (struct (player).player),
+
+                  "Type",
+                  "audioplayer",
+
+                  "UserData",
+                  __player_get_userdata__ (struct (player).player));
+
+endfunction
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/audio/@audioplayer/audioplayer.m	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,202 @@
+## Copyright (C) 2013 Vytautas Jančauskas
+##
+## 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{player} =} audioplayer (@var{y}, @var{fs})
+## @deftypefnx {Function File} {@var{player} =} audioplayer (@var{y}, @var{fs}, @var{nbits})
+## @deftypefnx {Function File} {@var{player} =} audioplayer (@var{y}, @var{fs}, @var{nbits}, @var{id})
+## @deftypefnx {Function File} {@var{player} =} audioplayer (@var{recorder})
+## @deftypefnx {Function File} {@var{player} =} audioplayer (@var{recorder}, @var{id})
+## Create an audioplayer object that will play back data @var{y} at sample
+## rate @var{fs}.  The optional arguments @var{nbits}, and @var{id}
+## specify the bit depth and player device id, respectively.  Device IDs
+## may be found using the audiodevinfo function.
+## Given an audioplayer object, use the data from the object to
+## initialize the player.
+##
+## The signal @var{y} can be a vector or a two-dimensional array.
+##
+## The following example will create an audioplayer object that will play
+## back one second of white noise at 44100 sample rate using 8 bits per
+## sample.
+##
+## @example
+## @group
+## y = randn (2, 44100) - 0.5;
+## player = audioplayer (y, 44100, 8);
+## play (player);
+## @end group
+## @end example
+## @end deftypefn
+
+## FIXME: callbacks don't work properly, apparently because portaudio
+## will execute the callbacks in a separate thread, and calling Octave
+## functions in a separate thread which is likely to cause trouble with
+## all of Octave's global data...
+##
+## @deftypefnx {Function File} {@var{player} =} audioplayer (@var{function}, @dots{})
+##
+## Given a function handle, use that function to process the audio.
+#
+## The following example will create and register a callback that generates
+## a sine wave on both channels.
+##
+## @example
+## @group
+## function [ sound, status ] = callback_sine (frames)
+##   global lphase = 0.0;
+##   global rphase = 0.0;
+##   incl = 440.0 / 44100.0;
+##   incr = 443.0 / 44100.0;
+##   nl = incl * frames;
+##   nr = incr * frames;
+##   left = sin (2.0 * pi * [lphase:incl:lphase+nl]);
+##   right = sin (2.0 * pi * [rphase:incr:rphase+nr]);
+##   sound = [left', right'];
+##   status = 0;
+##   lphase = lphase + nl;
+##   rphase = rphase + nr;
+## endfunction
+## player = audioplayer (@@callback_sine, 44100);
+## play (player);
+## # play for as long as you want
+## stop (player);
+## @end group
+
+function player = audioplayer (varargin)
+
+  if (nargin < 1 || nargin > 4
+      || (nargin < 2 && (isa (varargin{1}, "function_handle")
+                         || ischar (varargin{1}))))
+    print_usage ();
+  endif
+
+  if (isa (varargin{1}, "audiorecorder"))
+    if (nargin == 1)
+      player = getplayer (varargin{1});
+    elseif (nargin == 2)
+      recorder = varargin{1};
+      data = getaudiodata (recorder);
+      player = audioplayer (data, get (recorder, "SampleRate"),
+                            get (recorder, "BitsPerSample"), varargin{2});
+    else
+      print_usage ();
+    endif
+  else
+    if (ischar (varargin{1}))
+      varargin{1} = str2func (varargin{1});
+    endif
+    player.player = __player_audioplayer__ (varargin{:});
+    player = class (player, "audioplayer");
+  endif
+
+endfunction
+
+%!testif HAVE_PORTAUDIO
+%! mono = randn (1, 44100) - 0.5;
+%! stereo = randn (2, 44100) - 0.5;
+%! fs = 44100;
+%! player1 = audioplayer (mono, fs);
+%! player2 = audioplayer (stereo, fs);
+%! assert (player1.NumberOfChannels, 1);
+%! assert (player2.NumberOfChannels, 2);
+%! assert (player1.SampleRate, 44100);
+%! assert (player2.SampleRate, 44100);
+%! assert (player1.TotalSamples, 44100);
+%! assert (player2.TotalSamples, 44100);
+%! playblocking (player1);
+%! playblocking (player2);
+
+%!testif HAVE_PORTAUDIO
+%! audio = randn (2, 88200) - 0.5;
+%! fs = 44100;
+%! player = audioplayer (audio, fs);
+%! assert (!isplaying (player));
+%! play (player);
+%! assert (isplaying (player));
+%! sleep (1);
+%! pause (player);
+%! assert (!isplaying (player));
+%! sleep (1);
+%! resume (player);
+%! assert (isplaying (player));
+%! sleep (1);
+
+%!testif HAVE_PORTAUDIO
+%! audio = randn (2, 88200) - 0.5;
+%! fs = 44100;
+%! player = audioplayer (audio, fs);
+%! assert (!isplaying (player));
+%! play (player);
+%! assert (isplaying (player));
+%! sleep (1);
+%! stop (player);
+%! sleep (1);
+%! assert (!isplaying (player));
+%! assert (player.CurrentSample, 0);
+
+%!testif HAVE_PORTAUDIO
+%! audio = randn (2, 44100) - 0.5;
+%! fs = 44100;
+%! player = audioplayer (audio, fs);
+%! set (player, {"SampleRate", "Tag", "UserData"}, {8000, "tag", [1, 2; 3, 4]});
+%! assert (player.SampleRate, 8000);
+%! assert (player.Tag, "tag");
+%! assert (player.UserData, [1, 2; 3, 4]);
+
+%!testif HAVE_PORTAUDIO
+%! audio = randn (2, 44100) - 0.5;
+%! fs = 44100;
+%! player = audioplayer (audio, fs);
+%! settable = set (player);
+%! settable.SampleRate = 8000;
+%! settable.Tag = "tag";
+%! settable.UserData = [1, 2; 3, 4];
+%! set (player, settable);
+%! assert (player.SampleRate, 8000);
+%! assert (player.Tag, "tag");
+%! assert (player.UserData, [1, 2; 3, 4]);
+
+%!testif HAVE_PORTAUDIO
+%! audio = randn (2, 44100) - 0.5;
+%! fs = 44100;
+%! player = audioplayer (audio, fs);
+%! player.SampleRate = 8000;
+%! player.Tag = "tag";
+%! player.UserData = [1, 2; 3, 4];
+%! properties = get (player, {"SampleRate", "Tag", "UserData"});
+%! assert (properties, {8000, "tag", [1, 2; 3, 4]});
+
+#%!function [sound, status] = callback (samples)
+#%!  sound = rand (samples, 2) - 0.5;
+#%!  status = 0;
+#%!endfunction
+
+#%!testif HAVE_PORTAUDIO
+#%! player = audioplayer (@callback, 44100);
+#%! play (player);
+#%! sleep (2);
+#%! stop (player);
+#%! assert (1);
+
+#%!testif HAVE_PORTAUDIO
+#%! player = audioplayer ("callback", 44100, 16);
+#%! play (player);
+#%! sleep (2);
+#%! stop (player);
+#%! assert (1);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/audio/@audioplayer/display.m	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,32 @@
+## Copyright (C) 2013 Vytautas Jančauskas
+##
+## 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} {} display (@var{player})
+## Display the properties of the audioplayer object @var{player}.
+## @end deftypefn
+
+function display (player)
+
+  if (nargin != 1)
+    print_usage ();
+  endif
+
+  disp (__get_properties__ (player));
+
+endfunction
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/audio/@audioplayer/get.m	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,54 @@
+## Copyright (C) 2013 Vytautas Jančauskas
+##
+## 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{value} =} get (@var{player}, @var{name})
+## @deftypefnx {Function File} {@var{values} =} get (@var{player})
+## Return the @var{value} of the property identified by @var{name}.
+## If @var{name} is a cell array return the values of the properties
+## identified by the elements of the cell array.  Given only the
+## player object, return a scalar structure with values of all
+## properties of @var{player}.  The field names of the structure
+## correspond to property names.
+## @end deftypefn
+
+function retval = get (varargin)
+
+  if (nargin < 1 || nargin > 2)
+    print_usage ();
+  endif
+
+  properties = __get_properties__ (varargin{1});
+
+  if (nargin == 1)
+    retval = properties;
+  elseif (nargin == 2)
+    pnames = varargin{2};
+    if (ischar (pnames))
+      retval = getfield (properties, pnames);
+    elseif (iscellstr (pnames))
+      retval = cell (size (pnames));
+      for i = 1:numel (pnames)
+        retval{i} = getfield (properties, pnames{i});
+      endfor
+    else
+      error ("@audioplayer/get: invalid name argument");
+    endif
+  endif
+
+endfunction
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/audio/@audioplayer/isplaying.m	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,33 @@
+## Copyright (C) 2013 Vytautas Jančauskas
+##
+## 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} {} isplaying (@var{player})
+## Return 1 if the audioplayer object @var{player}is currently playing
+## back audio and 0 otherwise.
+## @end deftypefn
+
+function result = isplaying (player)
+
+  if (nargin != 1)
+    print_usage ();
+  endif
+
+  result = __player_isplaying__ (struct (player).player);
+
+endfunction
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/audio/@audioplayer/pause.m	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,32 @@
+## Copyright (C) 2013 Vytautas Jančauskas
+##
+## 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} {} pause (@var{player})
+## Pause the audioplayer @var{player}.
+## @end deftypefn
+
+function pause (player)
+
+  if (nargin != 1)
+    print_usage ();
+  endif
+
+  __player_pause__ (struct (player).player);
+
+endfunction
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/audio/@audioplayer/play.m	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,38 @@
+## Copyright (C) 2013 Vytautas Jančauskas
+##
+## 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} {} play (@var{player})
+## @deftypefnx {Function File} {} play (@var{player}, @var{start})
+## @deftypefnx {Function File} {} play (@var{player}, @var{limits})
+## Play audio stored in the audioplayer object @var{player} without blocking.
+## Given optional argument start, begin playing at @var{start} seconds
+## in the recording.  Given a two-element vector @var{limits}, begin and
+## end playing at the number of seconds specified by the elements of the
+## vector.
+## @end deftypefn
+
+function play (varargin)
+
+  if (nargin < 1 || nargin > 2)
+    print_usage ();
+  endif
+
+  __player_play__ (struct (varargin{1}).player, varargin{2:end});
+
+endfunction
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/audio/@audioplayer/playblocking.m	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,38 @@
+## Copyright (C) 2013 Vytautas Jančauskas
+##
+## 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} {} playblocking (@var{player})
+## @deftypefnx {Function File} {} playblocking (@var{player}, @var{start})
+## @deftypefnx {Function File} {} playblocking (@var{player}, @var{limits})
+## Play audio stored in the audioplayer object @var{player} with blocking.
+## Given optional argument start, begin playing at @var{start} seconds
+## in the recording.  Given a two-element vector @var{limits}, begin and
+## end playing at the number of seconds specified by the elements of the
+## vector.
+## @end deftypefn
+
+function playblocking (varargin)
+
+  if (nargin < 1 || nargin > 2)
+    print_usage ();
+  endif
+
+  __player_playblocking__ (struct (varargin{1}).player, varargin{2:end});
+
+endfunction
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/audio/@audioplayer/resume.m	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,32 @@
+## Copyright (C) 2013 Vytautas Jančauskas
+##
+## 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} {} resume (@var{player})
+## Resume playback for the paused audioplayer object @var{player}.
+## @end deftypefn
+
+function resume (player)
+
+  if (nargin != 1)
+    print_usage ();
+  endif
+
+  __player_resume__ (struct (player).player);
+
+endfunction
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/audio/@audioplayer/set.m	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,74 @@
+## Copyright (C) 2013 Vytautas Jančauskas
+##
+## 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} {} set (@var{player}, @var{name}, @var{value})
+## @deftypefnx {Function File} {} set (@var{player}, @var{properties})
+## @deftypefnx {Function File} {@var{properties} =} set (@var{player})
+## Set the value of property specified by @var{name} to a given @var{value}.
+## If @var{name} and @var{value} are cell arrays, set each property to the
+## corresponding value.  Given a structure of @var{properties} with
+## fields corresponding to property names, set the value of those
+## properties to the field values.  Given only the audioplayer object,
+## return a structure of settable properties.
+## @end deftypefn
+
+function settable = set (varargin)
+
+  if (nargin < 1 || nargin > 3)
+    print_usage ();
+  endif
+
+  player = struct (varargin{1}).player;
+
+  if (nargin == 1)
+    settable.SampleRate = {};
+    settable.Tag = {};
+    settable.UserData = {};
+  elseif (nargin == 2)
+    for [value, property] = varargin{2}
+      setproperty (player, property, value);
+    endfor
+  elseif (nargin == 3)
+    if (iscell (varargin{2}))
+      index = 1;
+      for property = varargin{2}
+        setproperty (player, char (property), varargin{3}{index});
+        index = index + 1;
+      endfor
+    else
+      setproperty (player, varargin{2}, varargin{3});
+    endif
+  else
+    error ("@audioplayer/set: wrong number of arguments to the set method");
+  endif
+
+endfunction
+
+function setproperty (player, property, value)
+  switch (property)
+    case "SampleRate"
+      __player_set_fs__ (player, value);
+    case "Tag"
+      __player_set_tag__ (player, value);
+    case "UserData"
+      __player_set_userdata__ (player, value);
+    otherwise
+      error ("audioplayer: no such property or the property specified is read-only");
+  endswitch
+endfunction
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/audio/@audioplayer/stop.m	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,33 @@
+## Copyright (C) 2013 Vytautas Jančauskas
+##
+## 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} {} stop (@var{player})
+## Stop the playback for the audioplayer @var{player} and reset the
+## relevant variables to their starting values.
+## @end deftypefn
+
+function stop (player)
+
+  if (nargin != 1)
+    print_usage ();
+  endif
+
+  __player_stop__ (struct (player).player);
+
+endfunction
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/audio/@audioplayer/subsasgn.m	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,39 @@
+## Copyright (C) 2013 Vytautas Jančauskas
+##
+## 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{value} =} subsasgn (@var{player}, @var{idx}, @var{rhs})
+## Perform subscripted assignment on the audio player object @var{player}.
+## Assign the value of @var{rhs} to the player property named by @var{idx}.
+## @end deftypefn
+
+function value = subsasgn (player, idx, rhs)
+
+  if (isempty (idx))
+    error ("audioplayer: missing index");
+  endif
+
+  if (strcmp (idx(1).type, "."))
+    field = idx.subs;
+    set (player, field, rhs);
+    value = player;
+  else
+    error ("@audioplayer/subsasgn: invalid subscript type");
+  endif
+
+endfunction
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/audio/@audioplayer/subsref.m	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,41 @@
+## Copyright (C) 2013 Vytautas Jančauskas
+##
+## 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{value} =} subsref (@var{player}, @var{idx})
+## Perform subscripted selection on the audio player object @var{player}.
+## Return the player property value named by @var{idx}.
+## @end deftypefn
+
+function value = subsref (player, idx)
+  if (nargin != 2)
+    print_usage ();
+  endif
+
+  if (isempty (idx))
+    error ("@audioplayer/subsref: missing index");
+  endif
+
+  if (strcmp (idx(1).type, "."))
+    field = idx.subs;
+    value = get (player, field);
+  else
+    error ("@audioplayer/subsref: invalid subscript type")
+  endif
+
+endfunction
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/audio/@audiorecorder/__get_properties__.m	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,67 @@
+## Copyright (C) 2013 Vytautas Jančauskas
+##
+## 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{properties} =} __get_properties__ (@var{recorder})
+## Return a struct containing all named properties of the recorder object
+## @var{recorder}.
+## @end deftypefn
+
+function props = __get_properties__ (recorder)
+
+  if (nargin != 1)
+    print_usage ();
+  endif
+
+  if (__recorder_isrecording__ (struct (recorder).recorder))
+    running = "on";
+  else
+    running = "off";
+  endif
+
+  props = struct ("BitsPerSample",
+                  __recorder_get_nbits__ (struct (recorder).recorder),
+
+                  "CurrentSample",
+                  __recorder_get_sample_number__ (struct (recorder).recorder),
+
+                  "DeviceID",
+                  __recorder_get_id__ (struct (recorder).recorder),
+
+                  "NumberOfChannels",
+                  __recorder_get_channels__ (struct (recorder).recorder),
+
+                  "Running",
+                  running,
+
+                  "SampleRate",
+                  __recorder_get_fs__ (struct (recorder).recorder),
+
+                  "TotalSamples",
+                  __recorder_get_total_samples__ (struct (recorder).recorder),
+
+                  "Tag",
+                  __recorder_get_tag__ (struct (recorder).recorder),
+
+                  "Type",
+                  "audiorecorder",
+
+                  "UserData",
+                  __recorder_get_userdata__ (struct (recorder).recorder));
+
+endfunction
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/audio/@audiorecorder/audiorecorder.m	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,140 @@
+## Copyright (C) 2013 Vytautas Jančauskas
+##
+## 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{recorder} =} audiorecorder ()
+## @deftypefnx {Function File} {@var{recorder} =} audiorecorder (@var{fs}, @var{nbits}, @var{channels})
+## @deftypefnx {Function File} {@var{recorder} =} audiorecorder (@var{fs}, @var{nbits}, @var{channels}, @var{id})
+## Create an audiorecorder object recording 8 bit mono audio at 8000 Hz
+## sample rate.  The optional arguments @var{fs}, @var{nbits},
+## @var{channels}, and @var{id} specify the sample rate, bit depth,
+## number of channels and recording device id, respectively.  Device IDs
+## may be found using the audiodevinfo function.
+## @end deftypefn
+
+## FIXME: callbacks don't work properly, apparently because portaudio
+## will execute the callbacks in a separate thread, and calling Octave
+## functions in a separate thread which is likely to cause trouble with
+## all of Octave's global data...
+##
+## @deftypefnx {Function File} {@var{recorder} =} audiorecorder (@var{function}, @dots{})
+##
+## Given a function handle, use that function to process the audio.
+
+function recorder = audiorecorder (varargin)
+
+  if (nargin > 5)
+    print_usage ();
+  endif
+
+  if (nargin > 0 && ischar (varargin{1}))
+    varargin{1} = str2func (varargin{1});
+  endif
+
+  recorder.recorder = __recorder_audiorecorder__ (varargin{:});
+  recorder = class (recorder, "audiorecorder");
+
+endfunction
+
+%!testif HAVE_PORTAUDIO
+%! recorder = audiorecorder (44100, 16, 2);
+%! recordblocking (recorder, 1);
+%! data = getaudiodata (recorder, "int16");
+%! assert (strcmp (class (data), "int16"));
+%! data = getaudiodata (recorder, "int8");
+%! assert (strcmp (class (data), "int8"));
+%! data = getaudiodata (recorder, "uint8");
+%! assert (strcmp (class (data), "uint8"));
+%! assert (size (data)(1), recorder.TotalSamples);
+%! assert (size (data)(2), 2);
+%! assert (size (data)(1) != 0);
+
+%!testif HAVE_PORTAUDIO
+%! recorder = audiorecorder (44100, 16, 2);
+%! record (recorder, 1)
+%! sleep (2);
+%! record (recorder, 1);
+%! sleep (2);
+%! data = getaudiodata (recorder);
+%! assert (size (data)(1) < 44100 * 2);
+
+%!testif HAVE_PORTAUDIO
+%! recorder = audiorecorder (44100, 16, 2);
+%! record (recorder, 1);
+%! sleep (2);
+%! player1 = audioplayer (recorder);
+%! player2 = getplayer (recorder);
+%! play (player1);
+%! sleep (2);
+%! play (player2);
+%! sleep (2);
+%! assert (player1.TotalSamples, recorder.TotalSamples);
+%! assert (player2.TotalSamples, recorder.TotalSamples);
+
+%!testif HAVE_PORTAUDIO
+%! recorder = audiorecorder;
+%! set (recorder, {"SampleRate", "Tag", "UserData"}, {8000, "tag", [1, 2; 3, 4]});
+%! assert (recorder.SampleRate, 8000);
+%! assert (recorder.Tag, "tag");
+%! assert (recorder.UserData, [1, 2; 3, 4]);
+
+%!testif HAVE_PORTAUDIO
+%! recorder = audiorecorder;
+%! settable = set (recorder);
+%! settable.SampleRate = 8000;
+%! settable.Tag = "tag";
+%! settable.UserData = [1, 2; 3, 4];
+%! set (recorder, settable);
+%! assert (recorder.SampleRate, 8000);
+%! assert (recorder.Tag, "tag");
+%! assert (recorder.UserData, [1, 2; 3, 4]);
+
+%!testif HAVE_PORTAUDIO
+%! recorder = audiorecorder;
+%! recorder.SampleRate = 8000;
+%! recorder.Tag = "tag";
+%! recorder.UserData = [1, 2; 3, 4];
+%! properties = get (recorder, {"SampleRate", "Tag", "UserData"});
+%! assert (properties, {8000, "tag", [1, 2; 3, 4]});
+
+#%!function status = callback_record (sound)
+#%!  fid = fopen ("record.txt", "at");
+#%!  for index = 1:rows(sound)
+#%!    fprintf (fid, "%.4f, %.4f\n", sound(index, 1), sound(index, 2));
+#%!  endfor
+#%!  fclose (fid);
+#%!  status = 0;
+#%!endfunction
+
+#%!testif HAVE_PORTAUDIO
+#%! recorder = audiorecorder (@callback_record, 44100);
+#%! unlink ("record.txt")
+#%! record (recorder);
+#%! sleep (2);
+#%! stop (recorder);
+#%! s = stat ("record.txt");
+#%! assert (s.size > 0);
+
+#%!testif HAVE_PORTAUDIO
+#%! recorder = audiorecorder (@callback_record, 44100);
+#%! unlink ("record.txt")
+#%! record (recorder);
+#%! sleep (2);
+#%! stop (recorder);
+#%! s = stat ("record.txt");
+#%! assert (s.size > 0);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/audio/@audiorecorder/display.m	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,32 @@
+## Copyright (C) 2013 Vytautas Jančauskas
+##
+## 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} {} display (@var{recorder})
+## Display the properties of the audiorecorder object @var{recorder}.
+## @end deftypefn
+
+function display (recorder)
+
+  if (nargin != 1)
+    print_usage ();
+  endif
+
+  disp (__get_properties__ (recorder));
+
+endfunction
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/audio/@audiorecorder/get.m	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,54 @@
+## Copyright (C) 2013 Vytautas Jančauskas
+##
+## 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{value} =} get (@var{recorder}, @var{name})
+## @deftypefnx {Function File} {@var{values} =} get (@var{recorder})
+## Return the @var{value} of the property identified by @var{name}.
+## If @var{name} is a cell array, return the values of the properties
+## corresponding to the elements of the cell array.  Given only the
+## recorder object, return a scalar structure with values of all
+## properties of @var{recorder}.  The field names of the structure
+## correspond to property names.
+## @end deftypefn
+
+function retval = get (varargin)
+
+  if (nargin < 1 || nargin > 2)
+    print_usage ();
+  endif
+
+  properties = __get_properties__ (varargin{1});
+
+  if (nargin == 1)
+    retval = properties;
+  elseif (nargin == 2)
+    pnames = varargin{2};
+    if (ischar (pnames))
+      retval = getfield (properties, pnames);
+    elseif (iscellstr (pnames))
+      retval = cell (size (pnames));
+      for i = 1:numel (pnames)
+        retval{i} = getfield (properties, pnames{i});
+      endfor
+    else
+      error ("@audiorecorder/get: invalid name argument");
+    endif
+  endif
+
+endfunction
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/audio/@audiorecorder/getaudiodata.m	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,58 @@
+## Copyright (C) 2013 Vytautas Jančauskas
+##
+## 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{data} =} getaudiodata (@var{recorder})
+## @deftypefnx {Function File} {@var{data} =} getaudiodata (@var{recorder}, @var{datatype})
+## Return recorder audio data as a matrix with values between -1.0 and 1.0
+## and with as many columns as there are channels in the recorder.
+## Given the optional argument @var{datatype}, convert the recorded data
+## to the specified type, which may be one of @qcode{"double"},
+## @qcode{"single"}, @qcode{"int16"}, @qcode{"int8"} or @qcode{"uint8"}.
+## @end deftypefn
+
+function data = getaudiodata (varargin)
+
+  if (nargin < 1 || nargin > 2)
+    print_usage ();
+  endif
+
+  recorder = varargin{1};
+
+  if (nargin == 1)
+    data = __recorder_getaudiodata__ (struct (recorder).recorder);
+  else
+    data = __recorder_getaudiodata__ (struct (recorder).recorder);
+    type = varargin{2};
+    switch (type)
+      case "int16"
+        data = int16 (data * (2.0 ^ 15));
+      case "int8"
+        data = int8 (data * (2.0 ^ 7));
+      case "uint8"
+        data = uint8 ((data + 1.0) * 0.5 * (2.0 ^ 8 - 1));
+    endswitch
+  endif
+
+  if (get (recorder, "NumberOfChannels") == 2)
+    data = data';
+  else
+    data = data(1,:)';
+  endif
+
+endfunction
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/audio/@audiorecorder/getplayer.m	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,36 @@
+## Copyright (C) 2013 Vytautas Jančauskas
+##
+## 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{player} =} getplayer (@var{recorder})
+## Return an audioplayer object with data recorded by the audiorecorder
+## object @var{recorder}.
+## @end deftypefn
+
+function player = getplayer (varargin)
+
+  if (nargin < 1 || nargin > 2)
+    print_usage ();
+  endif
+
+  recorder = varargin{1};
+  data = getaudiodata (recorder);
+  player = audioplayer (data, get (recorder, "SampleRate"),
+                        get (recorder, "BitsPerSample"));
+
+endfunction
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/audio/@audiorecorder/isrecording.m	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,33 @@
+## Copyright (C) 2013 Vytautas Jančauskas
+##
+## 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} {} isrecording (@var{recorder})
+## Return 1 if the audiorecorder object @var{recorder} is currently
+## recording audio and 0 otherwise.
+## @end deftypefn
+
+function result = isrecording (recorder)
+
+  if (nargin != 1)
+    print_usage ();
+  endif
+
+  result = __recorder_isrecording__ (struct (recorder).recorder);
+
+endfunction
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/audio/@audiorecorder/pause.m	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,32 @@
+## Copyright (C) 2013 Vytautas Jančauskas
+##
+## 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} {} pause (@var{recorder})
+## Pause recording with audiorecorder object @var{recorder}.
+## @end deftypefn
+
+function pause (recorder)
+
+  if (nargin != 1)
+    print_usage ();
+  endif
+
+  __recorder_pause__ (struct (recorder).recorder);
+
+endfunction
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/audio/@audiorecorder/play.m	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,46 @@
+## Copyright (C) 2013 Vytautas Jančauskas
+##
+## 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{player} =} play (@var{recorder})
+## @deftypefnx {Function File} {@var{player} =} play (@var{recorder}, @var{start})
+## @deftypefnx {Function File} {@var{player} =} play (@var{recorder}, [@var{start}, @var{end}])
+## Play the audio recorded in @var{recorder} and return a corresponding
+## audioplayer object.  If the optional argument @var{start} is
+## provided, begin playing @var{start} seconds in to the recording.
+## If the optional argument @var{end} is provided, stop playing at
+## @var{end} seconds in the recording.
+## @end deftypefn
+
+function player = play (varargin)
+
+  if (nargin < 1 || nargin > 2)
+    print_usage ();
+  endif
+
+  recorder = varargin{1};
+  data = getaudiodata (recorder);
+  player = audioplayer (data, get (recorder, "SampleRate"),
+                        get (recorder, "BitsPerSample"));
+  if (nargin == 1)
+    play (player);
+  else
+    play (player, varargin{2});
+  endif
+
+endfunction
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/audio/@audiorecorder/record.m	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,36 @@
+## Copyright (C) 2013 Vytautas Jančauskas
+##
+## 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} {} record (@var{recorder})
+## @deftypefnx {Function File} {} record (@var{recorder}, @var{length})
+## Record audio without blocking using the audiorecorder object
+## @var{recorder} until stopped or paused by the @var{stop} or
+## @var{pause} method.  Given the optional argument @var{length}, record
+## for @var{length} seconds.
+## @end deftypefn
+
+function record (varargin)
+
+  if (nargin < 1 || nargin > 2)
+    print_usage ();
+  endif
+
+  __recorder_record__ (struct (varargin{1}).recorder, varargin{2:end});
+
+endfunction
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/audio/@audiorecorder/recordblocking.m	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,33 @@
+## Copyright (C) 2013 Vytautas Jančauskas
+##
+## 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} {} recordblocking (@var{recorder}, @var{length})
+## Record audio with blocking (synchronous I/O).  You must specify the
+## length of the recording in seconds.
+## @end deftypefn
+
+function recordblocking (varargin)
+
+  if (nargin != 2)
+    print_usage ();
+  endif
+
+  __recorder_recordblocking__ (struct (varargin{1}).recorder, varargin{2});
+
+endfunction
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/audio/@audiorecorder/resume.m	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,32 @@
+## Copyright (C) 2013 Vytautas Jančauskas
+##
+## 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} {} resume (@var{recorder})
+## Resume recording with the paused audiorecorder object @var{recorder}.
+## @end deftypefn
+
+function resume (recorder)
+
+  if (nargin != 1)
+    print_usage ();
+  endif
+
+  __recorder_resume__ (struct (recorder).recorder);
+
+endfunction
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/audio/@audiorecorder/set.m	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,75 @@
+## Copyright (C) 2013 Vytautas Jančauskas
+##
+## 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} {} set (@var{recorder}, @var{name}, @var{value})
+## @deftypefnx {Function File} {} set (@var{recorder}, @var{properties})
+## @deftypefnx {Function File} {@var{properties} =} set (@var{recorder})
+## Set the value of property specified by @var{name} to a given @var{value}.
+## If @var{name} and @var{value} are cell arrays of the same size,
+## set each property to a corresponding value.
+## Given a structure with fields corresponding to property names, set
+## the value of those properties to the corresponding field values.
+## Given only the recorder object, return a structure of settable
+## properties.
+## @end deftypefn
+
+function settable = set (varargin)
+
+  if (nargin < 1 || nargin > 3)
+    print_usage ();
+  endif
+
+  recorder = struct (varargin{1}).recorder;
+
+  if (nargin == 1)
+    settable.SampleRate = {};
+    settable.Tag = {};
+    settable.UserData = {};
+  elseif (nargin == 2)
+    for [value, property] = varargin{2}
+      setproperty (recorder, property, value);
+    endfor
+  elseif (nargin == 3)
+    if (iscell (varargin{2}))
+      index = 1;
+      for property = varargin{2}
+        setproperty (recorder, char (property), varargin{3}{index});
+        index = index + 1;
+      endfor
+    else
+      setproperty (recorder, varargin{2}, varargin{3});
+    endif
+  endif
+
+endfunction
+
+function setproperty (recorder, property, value)
+
+  switch (property)
+    case "SampleRate"
+      __recorder_set_fs__ (recorder, value);
+    case "Tag"
+      __recorder_set_tag__ (recorder, value);
+    case "UserData"
+      __recorder_set_userdata__ (recorder, value);
+    otherwise
+      error ("@audiorecorder/set: no such property or the property specified is read-only");
+  endswitch
+
+endfunction
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/audio/@audiorecorder/stop.m	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,33 @@
+## Copyright (C) 2013 Vytautas Jančauskas
+##
+## 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} {} stop (@var{recorder})
+## Stop the audiorecorder object @var{recorder} and clean up any audio
+## streams.
+## @end deftypefn
+
+function stop (recorder)
+
+  if (nargin != 1)
+    print_usage ();
+  endif
+
+  __recorder_stop__ (struct (recorder).recorder);
+
+endfunction
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/audio/@audiorecorder/subsasgn.m	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,42 @@
+## Copyright (C) 2013 Vytautas Jančauskas
+##
+## 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{value} =} subsasgn (@var{recorder}, @var{idx}, @var{rhs})
+## Perform subscripted assignment on the audio recorder object @var{recorder}.
+## Assign the value of @var{rhs} to the recorder property named by @var{idx}.
+## @end deftypefn
+
+function value = subsasgn (recorder, idx, rhs)
+  if (nargin != 3)
+    print_usage ();
+  endif
+
+  if (isempty (idx))
+    error ("@audiorecorder/subsasgn: missing index");
+  endif
+
+  if (strcmp (idx(1).type, "."))
+    field = idx.subs;
+    set (recorder, field, rhs);
+    value = recorder;
+  else
+    error ("@audiorecorder/subsasgn: invalid subscript type");
+  endif
+
+endfunction
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/audio/@audiorecorder/subsref.m	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,42 @@
+## Copyright (C) 2013 Vytautas Jančauskas
+##
+## 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{value} =} subsref (@var{recorder}, @var{idx})
+## Perform subscripted selection on the audio recorder object @var{recorder}.
+## Return the recorder property value named by @var{idx}.
+## @end deftypefn
+
+function value = subsref (recorder, idx)
+
+  if (nargin != 2)
+    print_usage ();
+  endif
+
+  if (isempty (idx))
+    error ("@audiorecorder/subsref: missing index");
+  endif
+
+  if (strcmp (idx(1).type, "."))
+    field = idx.subs;
+    value = get (recorder, field);
+  else
+    error ("@audiorecorder/subsref: invalid subscript type")
+  endif
+
+endfunction
--- a/scripts/audio/lin2mu.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/audio/lin2mu.m	Fri Feb 06 08:31:49 2015 -0800
@@ -25,7 +25,7 @@
 ##
 ## If @var{n} is not specified it defaults to 0, 8, or 16 depending on
 ## the range of values in @var{x}.
-## @seealso{mu2lin, loadaudio, saveaudio}
+## @seealso{mu2lin}
 ## @end deftypefn
 
 
--- a/scripts/audio/loadaudio.m	Fri Feb 06 08:31:09 2015 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,82 +0,0 @@
-## Copyright (C) 1995-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} {} loadaudio (@var{name}, @var{ext}, @var{bps})
-## Load audio data from the file @file{@var{name}.@var{ext}} into the
-## vector @var{x}.
-##
-## The extension @var{ext} determines how the data in the audio file is
-## interpreted; the extensions @file{lin} (default) and @file{raw}
-## correspond to linear, the extensions @file{au}, @file{mu}, or @file{snd}
-## to mu-law encoding.
-##
-## The argument @var{bps} can be either 8 (default) or 16, and specifies
-## the number of bits per sample used in the audio file.
-## @seealso{lin2mu, mu2lin, saveaudio, playaudio, setaudio, record}
-## @end deftypefn
-
-
-## Author: AW <Andreas.Weingessel@ci.tuwien.ac.at>
-## Created: 10 April 1994
-## Adapted-By: jwe
-
-function X = loadaudio (name, ext, bps)
-
-  if (nargin == 0 || nargin > 3)
-    print_usage ();
-  endif
-
-  if (nargin == 1)
-    ext = "lin";
-  endif
-
-  if (nargin < 3)
-    bps = 8;
-  elseif (bps != 8 && bps != 16)
-    error ("loadaudio: BPS must be either 8 or 16");
-  endif
-
-  name = [name, ".", ext];
-  num = fopen (name, "rb");
-
-  if (strcmp (ext, "lin") || strcmp (ext, "raw") || strcmp (ext, "pcm"))
-    if (bps == 8)
-      [Y, c] = fread (num, inf, "uchar");
-      X = Y - 127;
-    else
-      [X, c] = fread (num, inf, "short");
-    endif
-  elseif (strcmp (ext, "mu") || strcmp (ext, "au")
-          || strcmp (ext, "snd") || strcmp (ext, "ul"))
-    [Y, c] = fread (num, inf, "uchar");
-    ## remove file header
-    m = find (Y(1:64) == 0, 1, "last");
-    if (! isempty (m))
-      Y(1:m) = [];
-    endif
-    X = mu2lin (Y, bps);
-  else
-    fclose (num);
-    error ("loadaudio: unsupported extension");
-  endif
-
-  fclose (num);
-
-endfunction
-
--- a/scripts/audio/module.mk	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/audio/module.mk	Fri Feb 06 08:31:49 2015 -0800
@@ -2,14 +2,39 @@
 
 audio_FCN_FILES = \
   audio/lin2mu.m \
-  audio/loadaudio.m \
   audio/mu2lin.m \
-  audio/playaudio.m \
   audio/record.m \
-  audio/saveaudio.m \
-  audio/setaudio.m \
   audio/wavread.m \
-  audio/wavwrite.m
+  audio/wavwrite.m \
+  audio/@audioplayer/__get_properties__.m \
+  audio/@audioplayer/audioplayer.m \
+  audio/@audioplayer/display.m \
+  audio/@audioplayer/get.m \
+  audio/@audioplayer/isplaying.m \
+  audio/@audioplayer/pause.m  \
+  audio/@audioplayer/play.m \
+  audio/@audioplayer/playblocking.m \
+  audio/@audioplayer/resume.m \
+  audio/@audioplayer/set.m \
+  audio/@audioplayer/stop.m \
+  audio/@audioplayer/subsasgn.m \
+  audio/@audioplayer/subsref.m \
+  audio/@audiorecorder/__get_properties__.m \
+  audio/@audiorecorder/audiorecorder.m \
+  audio/@audiorecorder/display.m \
+  audio/@audiorecorder/get.m \
+  audio/@audiorecorder/getaudiodata.m \
+  audio/@audiorecorder/getplayer.m \
+  audio/@audiorecorder/isrecording.m \
+  audio/@audiorecorder/pause.m \
+  audio/@audiorecorder/play.m \
+  audio/@audiorecorder/record.m \
+  audio/@audiorecorder/recordblocking.m \
+  audio/@audiorecorder/resume.m \
+  audio/@audiorecorder/set.m \
+  audio/@audiorecorder/stop.m \
+  audio/@audiorecorder/subsasgn.m \
+  audio/@audiorecorder/subsref.m
 
 FCN_FILES += $(audio_FCN_FILES)
 
--- a/scripts/audio/mu2lin.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/audio/mu2lin.m	Fri Feb 06 08:31:49 2015 -0800
@@ -24,7 +24,7 @@
 ## is 0.
 ##
 ## If @var{n} is not specified it defaults to 0.
-## @seealso{lin2mu, loadaudio, saveaudio}
+## @seealso{lin2mu}
 ## @end deftypefn
 
 ## Author:  Andreas Weingessel <Andreas.Weingessel@ci.tuwien.ac.at>
--- a/scripts/audio/playaudio.m	Fri Feb 06 08:31:09 2015 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,88 +0,0 @@
-## Copyright (C) 1995-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} {} playaudio (@var{name}, @var{ext})
-## @deftypefnx {Function File} {} playaudio (@var{x})
-## Play the audio file @file{@var{name}.@var{ext}} or the audio data
-## stored in the vector @var{x}.
-## @seealso{lin2mu, mu2lin, loadaudio, saveaudio, setaudio, record}
-## @end deftypefn
-
-## Author: AW <Andreas.Weingessel@ci.tuwien.ac.at>
-## Created: 11 April 1994
-## Adapted-By: jwe
-
-function playaudio (name, ext)
-
-  if (nargin < 1 || nargin > 2)
-    print_usage ();
-  endif
-
-  if (nargin == 1 && isnumeric (name))
-    ## play a vector
-    if (! isvector (name))
-      error ("playaudio: X must be a vector");
-    endif
-    X = name(:) + 127;
-    unwind_protect
-      file = tmpnam ();
-      fid = fopen (file, "wb");
-      fwrite (fid, X, "uchar");
-      fclose (fid);
-      [status, out] = system (sprintf ('cat "%s" > /dev/dsp', file));
-      if (status != 0)
-        system (sprintf ("paplay --raw \"%s\"", file));
-      endif
-    unwind_protect_cleanup
-      unlink (file);
-    end_unwind_protect
-  elseif (nargin >= 1 && ischar (name))
-    ## play a file
-    if (nargin == 1)
-      name = [name ".lin"];
-    elseif (nargin == 2)
-      name = [name "." ext];
-    endif
-    if (any (strcmp (ext, {"lin", "raw"})))
-      [status, out] = system (sprintf ('cat "%s" > /dev/dsp', name));
-      if (status != 0)
-        system (sprintf ('paplay --raw "%s"', name));
-      endif
-    elseif (any (strcmp (ext, {"mu", "au" "snd", "ul"})))
-      [status, out] = system (sprintf ('cat "%s" > /dev/audio', name));
-      if (status != 0)
-        system (sprintf ('paplay "%s"', name));
-      endif
-    else
-      error ("playaudio: unsupported extension '%s'", ext);
-    endif
-  else
-    print_usage ();
-  endif
-
-endfunction
-
-
-%% Test input validation
-%!error playaudio ()
-%!error playaudio (1,2,3)
-%!error <X must be a vector> playaudio (magic (3))
-%!error <unsupported extension> playaudio ("file", "abc")
-%!error playaudio ({"abc"})
-
--- a/scripts/audio/record.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/audio/record.m	Fri Feb 06 08:31:49 2015 -0800
@@ -22,7 +22,7 @@
 ## default value for @var{sampling_rate} is 8000 samples per second, or
 ## 8kHz.  The program waits until the user types @key{RET} and then
 ## immediately starts to record.
-## @seealso{lin2mu, mu2lin, loadaudio, saveaudio, playaudio, setaudio}
+## @seealso{lin2mu, mu2lin}
 ## @end deftypefn
 
 ## Author: AW <Andreas.Weingessel@ci.tuwien.ac.at>
@@ -39,7 +39,7 @@
 
   unwind_protect
 
-    file = tmpnam ();
+    file = tempname ();
 
     input ("Please hit ENTER and speak afterwards!\n", 1);
 
--- a/scripts/audio/saveaudio.m	Fri Feb 06 08:31:09 2015 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,89 +0,0 @@
-## Copyright (C) 1995-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} {} saveaudio (@var{name}, @var{x}, @var{ext}, @var{bps})
-## Save a vector @var{x} of audio data to the file
-## @file{@var{name}.@var{ext}}.  The optional parameters @var{ext} and
-## @var{bps} determine the encoding and the number of bits per sample used
-## in the audio file (see @code{loadaudio}); defaults are @file{lin} and
-## 8, respectively.
-## @seealso{lin2mu, mu2lin, loadaudio, playaudio, setaudio, record}
-## @end deftypefn
-
-## Author: AW <Andreas.Weingessel@ci.tuwien.ac.at>
-## Created: 5 September 1994
-## Adapted-By: jwe
-
-function saveaudio (name, x, ext, bps)
-
-  if (nargin < 2 || nargin > 4)
-    print_usage ();
-  endif
-
-  if (nargin == 2)
-    ext = "lin";
-  endif
-
-  if (nargin < 4)
-    bps = 8;
-  elseif (bps != 8 && bps != 16)
-    error ("saveaudio: BPS must be either 8 or 16");
-  endif
-
-  [nr, nc] = size (x);
-  if (nc != 1)
-    if (nr == 1)
-      x = x';
-      nr = nc;
-    else
-      error ("saveaudio: X must be a vector");
-    endif
-  endif
-
-  num = fopen ([name, ".", ext], "wb");
-
-  if (strcmp (ext, "lin") || strcmp (ext, "raw"))
-    if (bps == 8)
-      ld = max (abs (x));
-      if (ld > 127)   # convert 16 to 8 bit
-        if (ld < 16384)
-          sc = 64 / ld;
-        else
-          sc = 1 / 256;
-        endif
-        x = fix (x * sc);
-      endif
-      x = x + 127;
-      c = fwrite (num, x, "uchar");
-    else
-      c = fwrite (num, x, "short");
-    endif
-  elseif (strcmp (ext, "mu") || strcmp (ext, "au")
-          || strcmp (ext, "snd") || strcmp (ext, "ul"))
-    y = lin2mu (x);
-    c = fwrite (num, y, "uchar");
-  else
-    fclose (num);
-    error ("saveaudio: unsupported extension");
-  endif
-
-  fclose (num);
-
-endfunction
-
--- a/scripts/audio/setaudio.m	Fri Feb 06 08:31:09 2015 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,44 +0,0 @@
-## Copyright (C) 1995-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} {} setaudio ()
-## @deftypefnx {Function File} {} setaudio (@var{w_type})
-## @deftypefnx {Function File} {} setaudio (@var{w_type}, @var{value})
-## Execute the shell command @samp{mixer}, possibly with optional
-## arguments @var{w_type} and @var{value}.
-## @end deftypefn
-
-## Author: AW <Andreas.Weingessel@ci.tuwien.ac.at>
-## Created: 5 October 1994
-## Adapted-By: jwe
-
-function setaudio (w_type, value)
-
-  if (nargin == 0)
-    system ("mixer");
-  elseif (nargin == 1)
-    system (sprintf ("mixer %s", w_type));
-  elseif (nargin == 2)
-    system (sprintf ("mixer %s %d", w_type, value));
-  else
-    print_usage ();
-  endif
-
-endfunction
-
--- a/scripts/audio/wavwrite.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/audio/wavwrite.m	Fri Feb 06 08:31:49 2015 -0800
@@ -151,7 +151,7 @@
 
 
 %!shared fname
-%! fname = tmpnam ();
+%! fname = tempname ();
 
 %!test
 %! A = [-1:0.1:1; -1:0.1:1]';
--- a/scripts/deprecated/__error_text__.m	Fri Feb 06 08:31:09 2015 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,37 +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 {Built-in Function} {[@var{msg}, @var{msgid}] =} __error_text__ (@var{msg}, @var{msgid})
-## This function has been deprecated.  Use @code{lasterr} instead.
-## @seealso{lasterr}
-## @end deftypefn
-
-function [msg, msgid] = __error_text__ (varargin)
-
-  persistent warned = false;
-  if (! warned)
-    warned = true;
-    warning ("Octave:deprecated-function",
-             "__error_text__ is obsolete and will be removed from a future version of Octave, please use lasterr instead");
-  endif
-
-  [msg, msgid] = lasterr (varargin{:});
-
-endfunction
-
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/deprecated/bicubic.m	Fri Feb 06 08:31:49 2015 -0800
@@ -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.4.
+## 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.0
+
+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/cor.m	Fri Feb 06 08:31:09 2015 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,54 +0,0 @@
-## Copyright (C) 1995-2013 Kurt Hornik
-##
-## 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} {} cor (@var{x})
-## @deftypefnx {Function File} {} cor (@var{x}, @var{y})
-## Compute matrix of correlation coefficients.
-##
-## This is an alias for @code{corrcoef}.
-## @seealso{corrcoef}
-## @end deftypefn
-
-function retval = cor (x, y = x)
-
-  persistent warned = false;
-  if (! warned)
-    warned = true;
-    warning ("Octave:deprecated-function",
-             "cor is obsolete and will be removed from a future version of Octave; please use corr instead");
-  endif
-
-  if (nargin < 1 || nargin > 2)
-    print_usage ();
-  endif
-
-  retval = corrcoef (x, y);
-
-endfunction
-
-
-%!test
-%! x = rand (10, 2);
-%! assert (cor (x), corrcoef (x), 5*eps);
-%! assert (cor (x(:,1), x(:,2)) == corrcoef (x(:,1), x(:,2)));
-
-%% Test input validation
-%!error corrcoef ();
-%!error corrcoef (1, 2, 3);
-
--- a/scripts/deprecated/corrcoef.m	Fri Feb 06 08:31:09 2015 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,119 +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} {} corrcoef (@var{x})
-## @deftypefnx {Function File} {} corrcoef (@var{x}, @var{y})
-## Compute matrix of correlation coefficients.
-##
-## If each row of @var{x} and @var{y} is an observation and each column is
-## a variable, then the @w{(@var{i}, @var{j})-th} entry of
-## @code{corrcoef (@var{x}, @var{y})} is the correlation between the
-## @var{i}-th variable in @var{x} and the @var{j}-th variable in @var{y}.
-## @tex
-## $$
-## {\rm corrcoef}(x,y) = {{\rm cov}(x,y) \over {\rm std}(x) {\rm std}(y)}
-## $$
-## @end tex
-## @ifnottex
-##
-## @example
-## corrcoef(x,y) = cov(x,y)/(std(x)*std(y))
-## @end example
-##
-## @end ifnottex
-## If called with one argument, compute @code{corrcoef (@var{x}, @var{x})},
-## the correlation between the columns of @var{x}.
-## @seealso{cov}
-## @end deftypefn
-
-## Author: Kurt Hornik <hornik@wu-wien.ac.at>
-## Created: March 1993
-## Adapted-By: jwe
-
-function retval = corrcoef (x, y = [])
-
-  persistent warned = false;
-  if (! warned)
-    warned = true;
-    warning ("Octave:deprecated-function",
-             "corrcoef is not equivalent to Matlab and will be removed from a future version of Octave; for similar functionality see corr");
-  endif
-
-  if (nargin < 1 || nargin > 2)
-    print_usage ();
-  endif
-
-  ## Input validation is done by cov.m.  Don't repeat tests here
-
-  ## Special case, scalar is always 100% correlated with itself
-  if (isscalar (x))
-    if (isa (x, 'single'))
-      retval = single (1);
-    else
-      retval = 1;
-    endif
-    return;
-  endif
-
-  ## No check for division by zero error, which happens only when
-  ## there is a constant vector and should be rare.
-  if (nargin == 2)
-    c = cov (x, y);
-    s = std (x)' * std (y);
-    retval = c ./ s;
-  else
-    c = cov (x);
-    s = sqrt (diag (c));
-    retval = c ./ (s * s');
-  endif
-
-endfunction
-
-
-%!test
-%! x = rand (10);
-%! cc1 = corrcoef (x);
-%! cc2 = corrcoef (x, x);
-%! assert (size (cc1) == [10, 10] && size (cc2) == [10, 10]);
-%! assert (cc1, cc2, sqrt (eps));
-
-%!test
-%! x = [1:3]';
-%! y = [3:-1:1]';
-%! assert (corrcoef (x,y), -1, 5*eps)
-%! assert (corrcoef (x,flipud (y)), 1, 5*eps)
-%! assert (corrcoef ([x, y]), [1 -1; -1 1], 5*eps)
-
-%!test
-%! x = single ([1:3]');
-%! y = single ([3:-1:1]');
-%! assert (corrcoef (x,y), single (-1), 5*eps)
-%! assert (corrcoef (x,flipud (y)), single (1), 5*eps)
-%! assert (corrcoef ([x, y]), single ([1 -1; -1 1]), 5*eps)
-
-%!assert (corrcoef (5), 1);
-%!assert (corrcoef (single(5)), single(1));
-
-%% Test input validation
-%!error corrcoef ();
-%!error corrcoef (1, 2, 3);
-%!error corrcoef ([1; 2], ["A", "B"]);
-%!error corrcoef (ones (2,2,2));
-%!error corrcoef (ones (2,2), ones (2,2,2));
-
--- a/scripts/deprecated/cut.m	Fri Feb 06 08:31:09 2015 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,72 +0,0 @@
-## Copyright (C) 1996-2013 Kurt Hornik
-##
-## 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} {} cut (@var{x}, @var{breaks})
-## Create categorical data from numerical or continuous data by
-## cutting into intervals.
-##
-## If @var{breaks} is a scalar, the data is cut into that many
-## equal-width intervals.  If @var{breaks} is a vector of break points,
-## the category has @code{length (@var{breaks}) - 1} groups.
-##
-## The returned value is a vector of the same size as @var{x} telling
-## which group each point in @var{x} belongs to.  Groups are labelled
-## from 1 to the number of groups; points outside the range of
-## @var{breaks} are labelled by @code{NaN}.
-## @seealso{histc}
-## @end deftypefn
-
-## Author: KH <Kurt.Hornik@wu-wien.ac.at>
-## Description: Cut data into intervals
-
-function group = cut (x, breaks)
-
-  persistent warned = false;
-  if (! warned)
-    warned = true;
-    warning ("Octave:deprecated-function",
-             "cut is obsolete and will be removed from a future version of Octave; please use histc instead");
-  endif
-
-  if (nargin != 2)
-    print_usage ();
-  endif
-
-  if (!isvector (x))
-    error ("cut: X must be a vector");
-  endif
-  if (isscalar (breaks))
-    breaks = linspace (min (x), max (x), breaks + 1);
-    breaks(1) = breaks(1) - 1;
-  elseif (isvector (breaks))
-    breaks = sort (breaks);
-  else
-    error ("cut: BREAKS must be a scalar or vector");
-  endif
-
-  group = NaN (size (x));
-  m = length (breaks);
-  if (any (k = find ((x >= min (breaks)) & (x < max (breaks)))))
-    n = length (k);
-    group(k) = sum ((ones (m, 1) * reshape (x(k), 1, n))
-                    >= (reshape (breaks, m, 1) * ones (1, n)));
-  endif
-
-endfunction
-
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/deprecated/delaunay3.m	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,90 @@
+## Copyright (C) 1999-2013 Kai Habel
+##
+## 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{tetr} =} delaunay3 (@var{x}, @var{y}, @var{z})
+## @deftypefnx {Function File} {@var{tetr} =} delaunay3 (@var{x}, @var{y}, @var{z}, @var{options})
+##
+## @code{delaunay3} is deprecated and will be removed in Octave version 4.4.
+## Please use @code{delaunay} in all new code.
+##
+## Compute the Delaunay triangulation for a 3-D set of points.
+## The return value @var{tetr} is a set of tetrahedrons which satisfies the
+## Delaunay circum-circle criterion, i.e., only a single data point from
+## [@var{x}, @var{y}, @var{z}] is within the circum-circle of the defining
+## tetrahedron.
+##
+## The set of tetrahedrons @var{tetr} is a matrix of size [n, 4].  Each
+## row defines a tetrahedron and the four columns are the four vertices
+## of the tetrahedron.  The value of @code{@var{tetr}(i,j)} is an index into
+## @var{x}, @var{y}, @var{z} for the location of the j-th vertex of the i-th
+## tetrahedron.
+##
+## An optional fourth argument, which must be a string or cell array of strings,
+## contains options passed to the underlying qhull command.
+## See the documentation for the Qhull library for details
+## @url{http://www.qhull.org/html/qh-quick.htm#options}.
+## The default options are @code{@{"Qt", "Qbb", "Qc", "Qz"@}}.
+##
+## If @var{options} is not present or @code{[]} then the default arguments are
+## used.  Otherwise, @var{options} replaces the default argument list.
+## To append user options to the defaults it is necessary to repeat the
+## default arguments in @var{options}.  Use a null string to pass no arguments.
+##
+## @seealso{delaunay, delaunayn, convhull, voronoi, tetramesh}
+## @end deftypefn
+
+## Author: Kai Habel <kai.habel@gmx.de>
+
+## Deprecated in 4.0
+
+function tetr = delaunay3 (x, y, z, options)
+
+  persistent warned = false;
+  if (! warned)
+    warned = true;
+    warning ("Octave:deprecated-function",
+             "delaunay3 is obsolete and will be removed from a future version of Octave, please use delaunay instead");
+  endif
+
+  if (nargin < 3 || nargin > 4)
+    print_usage ();
+  endif
+
+  if (! (isvector (x) && isvector (y) && isvector (z)
+         && length (x) == length (y) && length (x) == length (z)))
+    error ("delaunay: X, Y, and Z must be the same size");
+  elseif (nargin == 4 && ! (ischar (options) || iscellstr (options)))
+    error ("delaunay3: OPTIONS must be a string or cell array of strings");
+  endif
+
+  if (nargin == 3)
+    tetr = delaunayn ([x(:), y(:), z(:)]);
+  else
+    tetr = delaunayn ([x(:), y(:), z(:)], options);
+  endif
+
+endfunction
+
+
+%!testif HAVE_QHULL
+%! x = [-1, -1, 1, 0, -1]; y = [-1, 1, 1, 0, -1]; z = [0, 0, 0, 1, 1];
+%! assert (sortrows (sort (delaunay3 (x, y, z), 2)), [1,2,3,4;1,2,4,5])
+
+%% FIXME: Need input validation tests
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/deprecated/dump_prefs.m	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,122 @@
+## Copyright (C) 1994-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} {} dump_prefs ()
+## @deftypefnx {Function File} {} dump_prefs (@var{fid})
+##
+## @code{dump_prefs} is deprecated and will be removed in Octave version 4.4.
+## Please use individual preference get/set routines in all new code.
+##
+## Dump the current settings of all user preferences to stdout in a format that
+## can be parsed by Octave later.
+##
+## If the optional argument @var{fid} is given then the results are written to
+## the file specified by file descriptor @var{fid}.
+## @seealso{octave_config_info}
+## @end deftypefn
+
+## Author: jwe
+
+## Deprecated in 4.0
+
+function dump_prefs (fid)
+
+  persistent warned = false;
+  if (! warned)
+    warned = true;
+    warning ("Octave:deprecated-function",
+             "dump_prefs is obsolete and will be removed from a future version of Octave, recode using individual preference get/set routines");
+  endif
+
+  if (nargin > 1)
+    print_usage ();
+  endif
+
+  if (nargin == 0)
+    fid = stdout;
+  endif
+
+  ## 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
+
+  ## FIXME: Update this list for 4.2.0 release
+  ##        Example, 'gnuplot_command_end' is no longer valid.
+
+  pref_list = {"EDITOR"
+              "EXEC_PATH"
+              "IMAGE_PATH"
+              "PAGER"
+              "PS1"
+              "PS2"
+              "PS4"
+              "beep_on_error"
+              "completion_append_char"
+              "crash_dumps_octave_core"
+              "echo_executing_commands"
+              "fixed_point_format"
+              "gnuplot_binary"
+              "gnuplot_command_end"
+              "gnuplot_command_plot"
+              "gnuplot_command_replot"
+              "gnuplot_command_splot"
+              "gnuplot_command_title"
+              "gnuplot_command_using"
+              "gnuplot_command_with"
+              "history_file"
+              "history_size"
+              "ignore_function_time_stamp"
+              "info_file"
+              "info_program"
+              "makeinfo_program"
+              "max_recursion_depth"
+              "output_max_field_width"
+              "output_precision"
+              "page_output_immediately"
+              "page_screen_output"
+              "print_answer_id_name"
+              "print_empty_dimensions"
+              "save_precision"
+              "saving_history"
+              "sighup_dumps_octave_core"
+              "sigterm_dumps_octave_core"
+              "silent_functions"
+              "split_long_rows"
+              "string_fill_char"
+              "struct_levels_to_print"
+              "suppress_verbose_help_message"};
+
+  for i = 1:rows (pref_list)
+    pref = pref_list{i};
+    try
+      val = feval (pref);
+      if (isnumeric (val))
+        val = sprintf ("%g", val);
+      endif
+      fprintf (fid, "  %s = %s\n", pref, val);
+    catch
+      fprintf (fid, "# %s = <no value or error in displaying it>\n", pref);
+    end_try_catch
+  endfor
+
+endfunction
+
+
+%!error dump_prefs (1,2)
+
--- a/scripts/deprecated/error_text.m	Fri Feb 06 08:31:09 2015 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,37 +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 {Built-in Function} {[@var{msg}, @var{msgid}] =} error_text (@var{msg}, @var{msgid})
-## This function has been deprecated.  Use @code{lasterr} instead.
-## @seealso{lasterr}
-## @end deftypefn
-
-function [msg, msgid] = error_text (varargin)
-
-  persistent warned = false;
-  if (! warned)
-    warned = true;
-    warning ("Octave:deprecated-function",
-             "error_text is obsolete and will be removed from a future version of Octave, please use lasterr instead");
-  endif
-
-  [msg, msgid] = lasterr (varargin{:});
-
-endfunction
-
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/deprecated/find_dir_in_path.m	Fri Feb 06 08:31:49 2015 -0800
@@ -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.0
+
+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
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/deprecated/finite.m	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,52 @@
+## 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/>.
+
+## -*- texinfo -*-
+## @deftypefn {Mapping Function} {} finite (@var{x})
+##
+## @code{finite} is deprecated and will be removed in Octave version 4.4.
+## Please use @code{isfinite} in all new code.
+##
+## Return a logical array which is true where the elements of @var{x} are
+## finite values and false where they are not.
+## For example:
+##
+## @example
+## @group
+## finite ([13, Inf, NA, NaN])
+##      @result{} [ 1, 0, 0, 0 ]
+## @end group
+## @end example
+## @seealso{isfinite, isinf, isnan, isna}
+## @end deftypefn
+
+## Deprecated in version 4.0
+
+function retval = finite (varargin)
+
+  persistent warned = false;
+  if (! warned)
+    warned = true;
+    warning ("Octave:deprecated-function",
+             "finite is obsolete and will be removed from a future version of Octave, please use isfinite instead");
+  endif
+
+  retval = isfinite (varargin{:});
+
+endfunction
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/deprecated/fmod.m	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,51 @@
+## 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/>.
+
+## -*- texinfo -*-
+## @deftypefn {Mapping Function} {} fmod (@var{x}, @var{y})
+##
+## @code{fmod} is deprecated and will be removed in Octave version 4.4.
+## Please use @code{rem} in all new code.
+##
+## Return the remainder of the division @code{@var{x} / @var{y}}, computed
+## using the expression
+##
+## @example
+## x - y .* fix (x ./ y)
+## @end example
+##
+## An error message is printed if the dimensions of the arguments do not
+## agree, or if either of the arguments is complex.
+## @seealso{rem, mod}
+## @end deftypefn
+
+## Deprecated in version 4.0
+
+function retval = fmod (varargin)
+
+  persistent warned = false;
+  if (! warned)
+    warned = true;
+    warning ("Octave:deprecated-function",
+             "fmod is obsolete and will be removed from a future version of Octave, please use rem instead");
+  endif
+
+  retval = rem (varargin{:});
+
+endfunction
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/deprecated/fnmatch.m	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,52 @@
+## 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/>.
+
+## -*- texinfo -*-
+## @deftypefn {Built-in Function} {} fnmatch (@var{pattern}, @var{string})
+##
+## @code{fnmatch} is deprecated and will be removed in Octave version 4.4.
+## Please use @code{glob} or @code{regexp} in all new code.
+##
+## Return true or false for each element of @var{string} that matches any of
+## the elements of the string array @var{pattern}, using the rules of
+## filename pattern matching.  For example:
+##
+## @example
+## @group
+## fnmatch (\"a*b\", @{\"ab\"; \"axyzb\"; \"xyzab\"@})
+##      @result{} [ 1; 1; 0 ]
+## @end group
+## @end example
+## @seealso{glob, regexp}
+## @end deftypefn
+
+## Deprecated in version 4.0
+
+function retval = fnmatch (varargin)
+
+  persistent warned = false;
+  if (! warned)
+    warned = true;
+    warning ("Octave:deprecated-function",
+             "fnmatch is obsolete and will be removed from a future version of Octave, please use glob or regexp instead");
+  endif
+
+  retval = __fnmatch__ (varargin{:});
+
+endfunction
+
--- a/scripts/deprecated/java_convert_matrix.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/deprecated/java_convert_matrix.m	Fri Feb 06 08:31:49 2015 -0800
@@ -22,7 +22,7 @@
 ## @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.
--- a/scripts/deprecated/java_debug.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/deprecated/java_debug.m	Fri Feb 06 08:31:49 2015 -0800
@@ -23,7 +23,7 @@
 ## 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.
--- a/scripts/deprecated/java_invoke.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/deprecated/java_invoke.m	Fri Feb 06 08:31:49 2015 -0800
@@ -21,20 +21,20 @@
 ## @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.
+## 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
 
@@ -46,7 +46,7 @@
     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
--- a/scripts/deprecated/java_new.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/deprecated/java_new.m	Fri Feb 06 08:31:49 2015 -0800
@@ -21,14 +21,14 @@
 ## @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
 
--- a/scripts/deprecated/java_unsigned_conversion.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/deprecated/java_unsigned_conversion.m	Fri Feb 06 08:31:49 2015 -0800
@@ -24,7 +24,7 @@
 ## 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.
--- a/scripts/deprecated/javafields.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/deprecated/javafields.m	Fri Feb 06 08:31:49 2015 -0800
@@ -20,7 +20,7 @@
 ## @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
+## 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}
@@ -34,11 +34,11 @@
     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, ';');
 
--- a/scripts/deprecated/javamethods.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/deprecated/javamethods.m	Fri Feb 06 08:31:49 2015 -0800
@@ -20,7 +20,7 @@
 ## @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
+## 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}
@@ -34,7 +34,7 @@
     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
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/deprecated/loadaudio.m	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,93 @@
+## Copyright (C) 1995-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} {} loadaudio (@var{name}, @var{ext}, @var{bps})
+##
+## @code{loadaudio} is deprecated and will be removed in Octave version 4.4.
+## Please use @code{audioread} in all new code.
+##
+## Load audio data from the file @file{@var{name}.@var{ext}} into the
+## vector @var{x}.
+##
+## The extension @var{ext} determines how the data in the audio file is
+## interpreted; the extensions @file{lin} (default) and @file{raw}
+## correspond to linear, the extensions @file{au}, @file{mu}, or @file{snd}
+## to mu-law encoding.
+##
+## The argument @var{bps} can be either 8 (default) or 16, and specifies
+## the number of bits per sample used in the audio file.
+## @seealso{lin2mu, mu2lin, saveaudio, playaudio, setaudio, record}
+## @end deftypefn
+
+
+## Author: AW <Andreas.Weingessel@ci.tuwien.ac.at>
+## Created: 10 April 1994
+## Adapted-By: jwe
+
+function X = loadaudio (name, ext, bps)
+
+  persistent warned = false;
+  if (! warned)
+    warned = true;
+    warning ("Octave:deprecated-function",
+             "loadaudio is obsolete and will be removed from a future version of Octave, please use audioread instead");
+  endif
+
+  if (nargin == 0 || nargin > 3)
+    print_usage ();
+  endif
+
+  if (nargin == 1)
+    ext = "lin";
+  endif
+
+  if (nargin < 3)
+    bps = 8;
+  elseif (bps != 8 && bps != 16)
+    error ("loadaudio: BPS must be either 8 or 16");
+  endif
+
+  name = [name, ".", ext];
+  num = fopen (name, "rb");
+
+  if (strcmp (ext, "lin") || strcmp (ext, "raw") || strcmp (ext, "pcm"))
+    if (bps == 8)
+      [Y, c] = fread (num, inf, "uchar");
+      X = Y - 127;
+    else
+      [X, c] = fread (num, inf, "short");
+    endif
+  elseif (strcmp (ext, "mu") || strcmp (ext, "au")
+          || strcmp (ext, "snd") || strcmp (ext, "ul"))
+    [Y, c] = fread (num, inf, "uchar");
+    ## remove file header
+    m = find (Y(1:64) == 0, 1, "last");
+    if (! isempty (m))
+      Y(1:m) = [];
+    endif
+    X = mu2lin (Y, bps);
+  else
+    fclose (num);
+    error ("loadaudio: unsupported extension");
+  endif
+
+  fclose (num);
+
+endfunction
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/deprecated/luinc.m	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,93 @@
+## 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/>.
+
+## @deftypefn  {Built-in Function} {[@var{L}, @var{U}, @var{P}, @var{Q}] =} luinc (@var{A}, '0')
+## @deftypefnx {Built-in Function} {[@var{L}, @var{U}, @var{P}, @var{Q}] =} luinc (@var{A}, @var{droptol})
+## @deftypefnx {Built-in Function} {[@var{L}, @var{U}, @var{P}, @var{Q}] =} luinc (@var{A}, @var{opts})
+##
+## @code{luinc} is deprecated and will be removed in Octave version 4.4.
+## Please use @code{ilu} or @code{ichol} in all new code.
+##
+## Produce the incomplete LU@tie{}factorization of the sparse matrix @var{A}.
+## Two types of incomplete factorization are possible, and the type
+## is determined by the second argument to @code{luinc}.
+##
+## Called with a second argument of @qcode{'0'}, the zero-level incomplete
+## LU@tie{}factorization is produced.  This creates a factorization of @var{A}
+## where the position of the nonzero arguments correspond to the same
+## positions as in the matrix @var{A}.
+##
+## Alternatively, the fill-in of the incomplete LU@tie{}factorization can
+## be controlled through the variable @var{droptol} or the structure
+## @var{opts}.  The @sc{umfpack} multifrontal factorization code by Tim A.
+## Davis is used for the incomplete LU@tie{}factorization, (availability
+## @url{http://www.cise.ufl.edu/research/sparse/umfpack/})
+##
+## @var{droptol} determines the values below which the values in the
+## LU@tie{} factorization are dropped and replaced by zero.  It must be a
+## positive scalar, and any values in the factorization whose absolute value
+## are less than this value are dropped, expect if leaving them increase the
+## sparsity of the matrix.  Setting @var{droptol} to zero results in a complete
+## LU@tie{}factorization which is the default.
+##
+## @var{opts} is a structure containing one or more of the fields
+##
+## @table @code
+## @item droptol
+## The drop tolerance as above.  If @var{opts} only contains @code{droptol}
+## then this is equivalent to using the variable @var{droptol}.
+##
+## @item milu
+## A logical variable flagging whether to use the modified incomplete
+## LU@tie{} factorization.  In the case that @code{milu} is true, the dropped
+## values are subtracted from the diagonal of the matrix @var{U} of the
+## factorization.  The default is @code{false}.
+##
+## @item udiag
+## A logical variable that flags whether zero elements on the diagonal of
+## @var{U} should be replaced with @var{droptol} to attempt to avoid singular
+## factors.  The default is @code{false}.
+##
+## @item thresh
+## Defines the pivot threshold in the interval [0,1].  Values outside that
+## range are ignored.
+## @end table
+##
+## All other fields in @var{opts} are ignored.  The outputs from @code{luinc}
+## are the same as for @code{lu}.
+##
+## Given the string argument @qcode{\"vector\"}, @code{luinc} returns the
+## values of @var{p} @var{q} as vector values.
+## @seealso{ilu, ichol, lu, sparse}
+## @end deftypefn
+
+## Deprecated in version 4.0
+
+function [L, U, P, Q] = luinc (varargin)
+
+  persistent warned = false;
+  if (! warned)
+    warned = true;
+    warning ("Octave:deprecated-function",
+             "luinc is obsolete and will be removed from a future version of Octave, please use ilu or ichol instead");
+  endif
+
+  [L, U, P, Q] = __luinc__ (varargin{:});
+
+endfunction
+
--- a/scripts/deprecated/module.mk	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/deprecated/module.mk	Fri Feb 06 08:31:49 2015 -0800
@@ -1,12 +1,14 @@
 FCN_FILE_DIRS += deprecated
 
 deprecated_FCN_FILES = \
-  deprecated/__error_text__.m \
-  deprecated/cor.m \
-  deprecated/corrcoef.m \
-  deprecated/cut.m \
+  deprecated/bicubic.m \
   deprecated/default_save_options.m \
-  deprecated/error_text.m \
+  deprecated/delaunay3.m \
+  deprecated/dump_prefs.m \
+  deprecated/find_dir_in_path.m \
+  deprecated/finite.m \
+  deprecated/fmod.m \
+  deprecated/fnmatch.m \
   deprecated/gen_doc_cache.m \
   deprecated/interp1q.m \
   deprecated/isequalwithequalnans.m \
@@ -18,13 +20,19 @@
   deprecated/java_unsigned_conversion.m \
   deprecated/javafields.m \
   deprecated/javamethods.m \
-  deprecated/polyderiv.m \
+  deprecated/loadaudio.m \
+  deprecated/luinc.m \
+  deprecated/nfields.m \
+  deprecated/octave_tmp_file_name.m \
+  deprecated/playaudio.m \
   deprecated/re_read_readline_init_file.m \
   deprecated/read_readline_init_file.m \
+  deprecated/saveaudio.m \
   deprecated/saving_history.m \
-  deprecated/shell_cmd.m \
-  deprecated/studentize.m \
-  deprecated/sylvester_matrix.m
+  deprecated/setaudio.m \
+  deprecated/strmatch.m \
+  deprecated/syl.m \
+  deprecated/usage.m
 
 FCN_FILES += $(deprecated_FCN_FILES)
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/deprecated/nfields.m	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,46 @@
+## 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.4.
+## Use @code{numfields} instead.
+## @seealso{numfields, fieldnames}
+## @end deftypefn
+
+## Deprecated in 4.0
+
+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
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/deprecated/octave_tmp_file_name.m	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,53 @@
+## 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/>.
+
+## -*- texinfo -*-
+## @deftypefn  {Built-in Function} {@var{fname} =} octave_tmp_file_name ()
+## @deftypefnx {Built-in Function} {@var{fname} =} octave_tmp_file_name (@var{dir})
+## @deftypefnx {Built-in Function} {@var{fname} =} octave_tmp_file_name (@var{dir}, @var{prefix})
+##
+## @code{octave_tmp_file_name} is deprecated and will be removed in Octave
+## version 4.4.  Use @code{tempname} for equivalent functionality.
+##
+## Return a unique temporary file name as a string.
+##
+## If @var{prefix} is omitted, a value of @qcode{"oct-"} is used.
+## If @var{dir} is also omitted, the default directory for temporary files
+## (@code{P_tmpdir} is used.  If @var{dir} is provided, it must exist,
+## otherwise the default directory for temporary files is used.
+## @seealso{tempname, tmpnam, mkstemp, tempdir, P_tmpdir, tmpfile}
+## @end deftypefn
+
+## Deprecated in version 4.0
+
+function filename = octave_tmp_file_name (varargin)
+
+  persistent warned = false;
+  if (! warned)
+    warned = true;
+    warning ("Octave:deprecated-function",
+             "octave_tmp_file_name is obsolete and will be removed from a future version of Octave, please use tempname instead");
+  endif
+
+  filename = tmpnam (varargin{:});
+
+endfunction
+
+
+%!assert (1)
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/deprecated/playaudio.m	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,99 @@
+## Copyright (C) 1995-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} {} playaudio (@var{name}, @var{ext})
+## @deftypefnx {Function File} {} playaudio (@var{x})
+##
+## @code{playaudio} is deprecated and will be removed in Octave version 4.4.
+## Please use @code{audioplayer} in all new code.
+##
+## Play the audio file @file{@var{name}.@var{ext}} or the audio data
+## stored in the vector @var{x}.
+## @seealso{lin2mu, mu2lin, loadaudio, saveaudio, setaudio, record}
+## @end deftypefn
+
+## Author: AW <Andreas.Weingessel@ci.tuwien.ac.at>
+## Created: 11 April 1994
+## Adapted-By: jwe
+
+function playaudio (name, ext)
+
+  persistent warned = false;
+  if (! warned)
+    warned = true;
+    warning ("Octave:deprecated-function",
+             "playaudio is obsolete and will be removed from a future version of Octave, please use audioplayer instead");
+  endif
+
+  if (nargin < 1 || nargin > 2)
+    print_usage ();
+  endif
+
+  if (nargin == 1 && isnumeric (name))
+    ## play a vector
+    if (! isvector (name))
+      error ("playaudio: X must be a vector");
+    endif
+    X = name(:) + 127;
+    unwind_protect
+      file = tempname ();
+      fid = fopen (file, "wb");
+      fwrite (fid, X, "uchar");
+      fclose (fid);
+      [status, out] = system (sprintf ('cat "%s" > /dev/dsp', file));
+      if (status != 0)
+        system (sprintf ("paplay --raw \"%s\"", file));
+      endif
+    unwind_protect_cleanup
+      unlink (file);
+    end_unwind_protect
+  elseif (nargin >= 1 && ischar (name))
+    ## play a file
+    if (nargin == 1)
+      name = [name ".lin"];
+    elseif (nargin == 2)
+      name = [name "." ext];
+    endif
+    if (any (strcmp (ext, {"lin", "raw"})))
+      [status, out] = system (sprintf ('cat "%s" > /dev/dsp', name));
+      if (status != 0)
+        system (sprintf ('paplay --raw "%s"', name));
+      endif
+    elseif (any (strcmp (ext, {"mu", "au" "snd", "ul"})))
+      [status, out] = system (sprintf ('cat "%s" > /dev/audio', name));
+      if (status != 0)
+        system (sprintf ('paplay "%s"', name));
+      endif
+    else
+      error ("playaudio: unsupported extension '%s'", ext);
+    endif
+  else
+    print_usage ();
+  endif
+
+endfunction
+
+
+%% Test input validation
+%!error playaudio ()
+%!error playaudio (1,2,3)
+%!error <X must be a vector> playaudio (magic (3))
+%!error <unsupported extension> playaudio ("file", "abc")
+%!error playaudio ({"abc"})
+
--- a/scripts/deprecated/polyderiv.m	Fri Feb 06 08:31:09 2015 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,109 +0,0 @@
-## Copyright (C) 1994-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} {} polyderiv (@var{p})
-## @deftypefnx {Function File} {[@var{k}] =} polyderiv (@var{a}, @var{b})
-## @deftypefnx {Function File} {[@var{q}, @var{d}] =} polyderiv (@var{b}, @var{a})
-## Return the coefficients of the derivative of the polynomial whose
-## coefficients are given by the vector @var{p}.  If a pair of polynomials
-## is given, return the derivative of the product @math{@var{a}*@var{b}}.
-## If two inputs and two outputs are given, return the derivative of the
-## polynomial quotient @math{@var{b}/@var{a}}.  The quotient numerator is
-## in @var{q} and the denominator in @var{d}.
-## @seealso{poly, polyint, polyreduce, roots, conv, deconv, residue,
-## filter, polygcd, polyval, polyvalm}
-## @end deftypefn
-
-## Author: Tony Richardson <arichard@stark.cc.oh.us>
-## Created: June 1994
-## Adapted-By: jwe
-
-function [q, d] = polyderiv (p, a)
-
-  persistent warned = false;
-  if (! warned)
-    warned = true;
-    warning ("Octave:deprecated-function",
-             "polyderiv is obsolete and will be removed from a future version of Octave; please use polyder instead");
-  endif
-
-  if (nargin == 1 || nargin == 2)
-    if (! isvector (p))
-      error ("polyderiv: argument must be a vector");
-    endif
-    if (nargin == 2)
-      if (! isvector (a))
-        error ("polyderiv: argument must be a vector");
-      endif
-      if (nargout == 1)
-        ## derivative of p*a returns a single polynomial
-        q = polyderiv (conv (p, a));
-      else
-        ## derivative of p/a returns numerator and denominator
-        d = conv (a, a);
-        if (numel (p) == 1)
-          q = -p * polyderiv (a);
-        elseif (numel (a) == 1)
-          q = a * polyderiv (p);
-        else
-          q = conv (polyderiv (p), a) - conv (p, polyderiv (a));
-          q = polyreduce (q);
-        endif
-
-        ## remove common factors from numerator and denominator
-        x = polygcd (q, d);
-        if (length(x) != 1)
-          q = deconv (q, x);
-          d = deconv (d, x);
-        endif
-
-        ## move all the gain into the numerator
-        q = q/d(1);
-        d = d/d(1);
-      endif
-    else
-      lp = numel (p);
-      if (lp == 1)
-        q = 0;
-        return;
-      elseif (lp == 0)
-        q = [];
-        return;
-      endif
-
-      ## Force P to be a row vector.
-      p = p(:).';
-
-      q = p(1:(lp-1)) .* [(lp-1):-1:1];
-    endif
-  else
-    print_usage ();
-  endif
-
-endfunction
-
-
-%!assert(all (all (polyderiv ([1, 2, 3]) == [2, 2])));
-
-%!assert(polyderiv (13) == 0);
-
-%!error polyderiv ([]);
-
-%!error polyderiv ([1, 2; 3, 4]);
-
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/deprecated/saveaudio.m	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,100 @@
+## Copyright (C) 1995-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} {} saveaudio (@var{name}, @var{x}, @var{ext}, @var{bps})
+##
+## @code{saveaudio} is deprecated and will be removed in Octave version 4.4.
+## Please use @code{audiowrite} in all new code.
+##
+## Save a vector @var{x} of audio data to the file
+## @file{@var{name}.@var{ext}}.  The optional parameters @var{ext} and
+## @var{bps} determine the encoding and the number of bits per sample used
+## in the audio file (see @code{loadaudio}); defaults are @file{lin} and
+## 8, respectively.
+## @seealso{lin2mu, mu2lin, loadaudio, playaudio, setaudio, record}
+## @end deftypefn
+
+## Author: AW <Andreas.Weingessel@ci.tuwien.ac.at>
+## Created: 5 September 1994
+## Adapted-By: jwe
+
+function saveaudio (name, x, ext, bps)
+
+  persistent warned = false;
+  if (! warned)
+    warned = true;
+    warning ("Octave:deprecated-function",
+             "saveaudio is obsolete and will be removed from a future version of Octave, please use audiowrite instead");
+  endif
+
+  if (nargin < 2 || nargin > 4)
+    print_usage ();
+  endif
+
+  if (nargin == 2)
+    ext = "lin";
+  endif
+
+  if (nargin < 4)
+    bps = 8;
+  elseif (bps != 8 && bps != 16)
+    error ("saveaudio: BPS must be either 8 or 16");
+  endif
+
+  [nr, nc] = size (x);
+  if (nc != 1)
+    if (nr == 1)
+      x = x';
+      nr = nc;
+    else
+      error ("saveaudio: X must be a vector");
+    endif
+  endif
+
+  num = fopen ([name, ".", ext], "wb");
+
+  if (strcmp (ext, "lin") || strcmp (ext, "raw"))
+    if (bps == 8)
+      ld = max (abs (x));
+      if (ld > 127)   # convert 16 to 8 bit
+        if (ld < 16384)
+          sc = 64 / ld;
+        else
+          sc = 1 / 256;
+        endif
+        x = fix (x * sc);
+      endif
+      x = x + 127;
+      c = fwrite (num, x, "uchar");
+    else
+      c = fwrite (num, x, "short");
+    endif
+  elseif (strcmp (ext, "mu") || strcmp (ext, "au")
+          || strcmp (ext, "snd") || strcmp (ext, "ul"))
+    y = lin2mu (x);
+    c = fwrite (num, y, "uchar");
+  else
+    fclose (num);
+    error ("saveaudio: unsupported extension");
+  endif
+
+  fclose (num);
+
+endfunction
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/deprecated/setaudio.m	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,56 @@
+## Copyright (C) 1995-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} {} setaudio ()
+## @deftypefnx {Function File} {} setaudio (@var{w_type})
+## @deftypefnx {Function File} {} setaudio (@var{w_type}, @var{value})
+##
+## @code{setaudio} is deprecated and will be removed in Octave version 4.4.
+## Please scale the audio signal in all new code or use the operating system's
+## native tools to adjust audio input and output levels.
+##
+## Execute the shell command @samp{mixer}, possibly with optional
+## arguments @var{w_type} and @var{value}.
+## @end deftypefn
+
+## Author: AW <Andreas.Weingessel@ci.tuwien.ac.at>
+## Created: 5 October 1994
+## Adapted-By: jwe
+
+function setaudio (w_type, value)
+
+  persistent warned = false;
+  if (! warned)
+    warned = true;
+    warning ("Octave:deprecated-function",
+             "setaudio is obsolete and will be removed from a future version of Octave, please scale the audio signal instead");
+  endif
+
+  if (nargin == 0)
+    system ("mixer");
+  elseif (nargin == 1)
+    system (sprintf ("mixer %s", w_type));
+  elseif (nargin == 2)
+    system (sprintf ("mixer %s %d", w_type, value));
+  else
+    print_usage ();
+  endif
+
+endfunction
+
--- a/scripts/deprecated/shell_cmd.m	Fri Feb 06 08:31:09 2015 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,68 +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} {} shell_cmd (@var{string})
-## @deftypefnx {Built-in Function} {} shell_cmd (@var{string}, @var{return_output})
-## @deftypefnx {Built-in Function} {} shell_cmd (@var{string}, @var{return_output}, @var{type})
-## @deftypefnx {Built-in Function} {[@var{status}, @var{output}] =} shell_cmd (@dots{})
-## @deftypefnx {Built-in Function} {[@var{status}, @var{output}] =} shell_cmd (@var{string}, @var{return_output}, @var{type})
-## Execute a shell command specified by @var{string}.
-## If the optional argument @var{type} is @qcode{"async"}, the process
-## is started in the background and the process id of the child process
-## is returned immediately.  Otherwise, the process is started and
-## Octave waits until it exits.  If the @var{type} argument is omitted, it
-## defaults to a value of @qcode{"sync"}.
-##
-## If the optional argument @var{return_output} is true and the subprocess
-## is started synchronously, or if @var{shell_cmd} is called with one input
-## argument and one or more output arguments, then the output from the command
-## is returned.  Otherwise, if the subprocess is executed synchronously, its
-## output is sent to the standard output.
-##
-## The @code{shell_cmd} function can return two values.  The first is the
-## exit status of the command and the second is any output from the
-## command that was written to the standard output stream.  For example,
-##
-## @example
-## [status, output] = shell_cmd ("echo foo; exit 2");
-## @end example
-##
-## @noindent
-## will set the variable @code{output} to the string @samp{foo}, and the
-## variable @code{status} to the integer @samp{2}.
-##
-## For commands run asynchronously, @var{status} is the process id of the
-## command shell that is started to run the command.
-## @seealso{system, unix, dos}
-## @end deftypefn
-
-## Deprecated in version 3.6
-
-function [status, output] = shell_cmd (varargin)
-  persistent warned = false;
-  if (! warned)
-    warned = true;
-    warning ("Octave:deprecated-function",
-             "shell_cmd is obsolete and will be removed from a future version of Octave; please use system instead");
-  endif
-
-  [status, output] = system (varargin{:});
-
-endfunction
-
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/deprecated/strmatch.m	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,130 @@
+## Copyright (C) 2000-2013 Paul Kienzle
+## Copyright (C) 2003 Alois Schloegl
+## Copyright (C) 2010 VZLU Prague
+##
+## 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} {} strmatch (@var{s}, @var{A})
+## @deftypefnx {Function File} {} strmatch (@var{s}, @var{A}, "exact")
+##
+## @code{strmatch} is deprecated and will be removed in Octave version 4.4.
+## Use @code{strncmp} (normal case), or @code{strcmp} (@qcode{"exact"} case),
+## or @code{regexp} in all new code.
+##
+## Return indices of entries of @var{A} which begin with the string @var{s}.
+## The second argument @var{A} must be a string, character matrix, or a cell
+## array of strings.  If the third argument @qcode{"exact"} is not given, then
+## @var{s} only needs to match @var{A} up to the length of @var{s}.
+## Trailing spaces and nulls in @var{s} and @var{A} are ignored when matching.
+##
+## For example:
+##
+## @example
+## @group
+## strmatch ("apple", "apple juice")
+##      @result{} 1
+##
+## strmatch ("apple", ["apple  "; "apple juice"; "an apple"])
+##      @result{} [1; 2]
+##
+## strmatch ("apple", ["apple  "; "apple juice"; "an apple"], "exact")
+##      @result{} [1]
+## @end group
+## @end example
+##
+## @seealso{strfind, findstr, strcmp, strncmp, strcmpi, strncmpi, find}
+## @end deftypefn
+
+## Author: Paul Kienzle, Alois Schloegl
+## Adapted-by: jwe
+
+## Deprecated in version 4.0
+
+function idx = strmatch (s, A, exact)
+
+  persistent warned = false;
+  if (! warned)
+    warned = true;
+    warning ("Octave:deprecated-function",
+             "strmatch is obsolete and will be removed from a future version of Octave, please use strncmp, strcmp, or regexp instead");
+  endif
+
+  if (nargin < 2 || nargin > 3)
+    print_usage ();
+  endif
+
+  if (! ischar (s) || (! isempty (s) && ! isvector (s)))
+    error ("strmatch: S must be a string");
+  elseif (! (ischar (A) || iscellstr (A)))
+    error ("strmatch: A must be a string or cell array of strings");
+  endif
+
+  ## Trim blanks and nulls from search string
+  s = regexprep (s, "[ \\0]+$", '');
+  len = length (s);
+
+  exact = nargin == 3 && ischar (exact) && strcmp (exact, "exact");
+
+  if (ischar (A))
+    [nr, nc] = size (A);
+    if (len > nc)
+      idx = [];
+    else
+      match = all (bsxfun (@eq, A(:,1:len), s), 2);
+      if (exact)
+        AA = A(:,len+1:nc);
+        match &= all (AA == " " | AA == "\0", 2);
+      endif
+      idx = find (match);
+    endif
+  else
+    if (len > 0)
+      idx = find (strncmp (s, A, len));
+    else
+      idx = find (strcmp (s, A));
+    endif
+    if (exact)
+      ## We can't just use strcmp, because we need to ignore spaces at end.
+      B = regexprep (A(idx), "[ \\0]+$", '');
+      idx = idx(strcmp (s, B));
+    endif
+  endif
+
+endfunction
+
+
+%!assert (strmatch ("a", {"aaa", "bab", "bbb"}), 1)
+%!assert (strmatch ("apple", "apple juice"), 1)
+%!assert (strmatch ("apple", ["apple pie"; "apple juice"; "an apple"]), [1; 2])
+%!assert (strmatch ("apple", {"apple pie"; "apple juice"; "tomato"}), [1; 2])
+%!assert (strmatch ("apple pie", "apple"), [])
+%!assert (strmatch ("a ", "a"), 1)
+%!assert (strmatch ("a", "a \0", "exact"), 1)
+%!assert (strmatch ("a b", {"a b", "a c", "c d"}), 1)
+%!assert (strmatch ("", {"", "foo", "bar", ""}), [1, 4])
+%!assert (strmatch ('', { '', '% comment', 'var a = 5', ''}, 'exact'), [1,4])
+
+%% Test input validation
+%!error <Invalid call to strmatch> strmatch ()
+%!error <Invalid call to strmatch> strmatch ("a")
+%!error <Invalid call to strmatch> strmatch ("a", "aaa", "exact", 1)
+%!error <S must be a string> strmatch (1, "aaa")
+%!error <S must be a string> strmatch (char ("a", "bb"), "aaa")
+%!error <A must be a string> strmatch ("a", 1)
+%!error <A must be a string> strmatch ("a", {"hello", [1]})
+
--- a/scripts/deprecated/studentize.m	Fri Feb 06 08:31:09 2015 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,95 +0,0 @@
-## Copyright (C) 1995-2013 Kurt Hornik
-##
-## 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} {} studentize (@var{x})
-## @deftypefnx {Function File} {} studentize (@var{x}, @var{dim})
-## If @var{x} is a vector, subtract its mean and divide by its standard
-## deviation.
-##
-## If @var{x} is a matrix, do the above along the first non-singleton
-## dimension.
-## If the optional argument @var{dim} is given, operate along this dimension.
-## @seealso{center}
-## @end deftypefn
-
-## Author: KH <Kurt.Hornik@wu-wien.ac.at>
-## Description: Subtract mean and divide by standard deviation
-
-function t = studentize (x, dim)
-  persistent warned = false;
-  if (! warned)
-    warned = true;
-    warning ("Octave:deprecated-function",
-             "studentize is obsolete and will be removed from a future version of Octave; please use zscore instead");
-  endif
-
-  if (nargin != 1 && nargin != 2)
-    print_usage ();
-  endif
-
-  if (! isnumeric(x))
-    error ("studentize: X must be a numeric vector or matrix");
-  endif
-
-  if (isinteger (x))
-    x = double (x);
-  endif
-
-  nd = ndims (x);
-  sz = size (x);
-  if (nargin != 2)
-    ## Find the first non-singleton dimension.
-    dim = find (sz > 1, 1);
-    if (isempty (dim))
-      dim = 1;
-    endif
-  else
-    if (!(isscalar (dim) && dim == fix (dim))
-        || !(1 <= dim && dim <= nd))
-      error ("studentize: DIM must be an integer and a valid dimension");
-    endif
-  endif
-
-  c = sz(dim);
-  if (c == 0)
-    t = x;
-  else
-    idx = ones (1, nd);
-    idx(dim) = c;
-    t = x - repmat (mean (x, dim), idx);
-    t = t ./ repmat (max (cat (dim, std(t, [], dim), ! any (t, dim)), [], dim), idx);
-  endif
-
-endfunction
-
-
-%!assert(studentize ([1,2,3]), [-1,0,1])
-%!assert(studentize (int8 ([1,2,3])), [-1,0,1])
-#%!assert(studentize (ones (3,2,0,2)), zeros (3,2,0,2))
-%!assert(studentize ([2,0,-2;0,2,0;-2,-2,2]), [1,0,-1;0,1,0;-1,-1,1])
-
-%% Test input validation
-%!error studentize ()
-%!error studentize (1, 2, 3)
-%!error studentize ([true true])
-%!error studentize (1, ones(2,2))
-%!error studentize (1, 1.5)
-%!error studentize (1, 0)
-%!error studentize (1, 3)
-
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/deprecated/syl.m	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,66 @@
+## 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/>.
+
+## -*- texinfo -*-
+## @deftypefn {Built-in Function} {@var{x} =} syl (@var{A}, @var{B}, @var{C})
+##
+## @code{syl} is deprecated and will be removed in Octave version 4.4.
+## Use @code{sylvester} for the equivalent functionality.
+##
+## Solve the Sylvester equation
+## @tex
+## $$
+##  A X + X B + C = 0
+## $$
+## @end tex
+## @ifnottex
+##
+## @example
+## A X + X B + C = 0
+## @end example
+##
+## @end ifnottex
+## using standard @sc{lapack} subroutines.  For example:
+##
+## @example
+## @group
+## syl ([1, 2; 3, 4], [5, 6; 7, 8], [9, 10; 11, 12])
+##    @result{} [ -0.50000, -0.66667; -0.66667, -0.50000 ]
+## @end group
+## @end example
+## @end deftypefn
+
+## Deprecated in version 4.0
+
+function x = syl (A, B, C)
+
+  persistent warned = false;
+  if (! warned)
+    warned = true;
+    warning ("Octave:deprecated-function",
+             "syl is obsolete and will be removed from a future version of Octave, please use sylvester instead");
+  endif
+
+  if (nargin != 3 || nargout > 1)
+    print_usage ();
+  endif
+
+  x = -sylvester (A, B, C);
+
+endfunction
+
--- a/scripts/deprecated/sylvester_matrix.m	Fri Feb 06 08:31:09 2015 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,70 +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} {} sylvester_matrix (@var{k})
-## Return the Sylvester matrix of order
-## @tex
-## $n = 2^k$.
-## @end tex
-## @ifnottex
-## n = 2^@var{k}.
-## @end ifnottex
-##
-## @seealso{toeplitz, hankel}
-## @end deftypefn
-
-## Author: jwe
-
-function retval = sylvester_matrix (k)
-
-  persistent warned = false;
-  if (! warned)
-    warned = true;
-    warning ("Octave:deprecated-function",
-             "sylvester_matrix is obsolete and will be removed from a future version of Octave; please use hadamard(2^k) instead");
-  endif
-
-  if (nargin != 1)
-    print_usage ();
-  endif
-
-  if (isscalar (k))
-    if (k < 1)
-      retval = 1;
-    else
-      tmp = sylvester_matrix (k-1);
-      retval = [tmp, tmp; tmp, -tmp];
-    endif
-  else
-    error ("sylvester_matrix: expecting scalar argument");
-  endif
-
-endfunction
-
-
-%!assert((sylvester_matrix (1) == [1, 1; 1, -1]
-%! && (sylvester_matrix (2)
-%! == [1, 1, 1, 1; 1, -1, 1, -1; 1, 1, -1, -1; 1, -1, -1, 1])));
-
-%!error sylvester_matrix ([1, 2; 3, 4]);
-
-%!error sylvester_matrix ();
-
-%!error sylvester_matrix (1, 2);
-
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/deprecated/usage.m	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,66 @@
+## 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/>.
+
+## -*- texinfo -*-
+## @deftypefn {Built-in Function} {} usage (@var{msg})
+##
+## @code{usage} is deprecated and will be removed in Octave version 4.4.
+## Please use @code{print_usage} in all new code.
+##
+## Print the message @var{msg}, prefixed by the string @samp{usage: }, and
+## set Octave's internal error state such that control will return to the
+## top level without evaluating any more commands.  This is useful for
+## aborting from functions.
+##
+## After @code{usage} is evaluated, Octave will print a traceback of all
+## the function calls leading to the usage message.
+##
+## You should use this function for reporting problems errors that result
+## from an improper call to a function, such as calling a function with an
+## incorrect number of arguments, or with arguments of the wrong type.  For
+## example, most functions distributed with Octave begin with code like
+## this
+##
+## @example
+## @group
+## if (nargin != 2)
+##   usage (\"foo (a, b)\");
+## endif
+## @end group
+## @end example
+##
+## @noindent
+## to check for the proper number of arguments.
+## @seealso{print_usage}
+## @end deftypefn
+
+## Deprecated in version 4.0
+
+function retval = usage (varargin)
+
+  persistent warned = false;
+  if (! warned)
+    warned = true;
+    warning ("Octave:deprecated-function",
+             "usage is obsolete and will be removed from a future version of Octave, please use print_usage instead");
+  endif
+
+  retval = __usage__ (varargin{:});
+
+endfunction
+
--- a/scripts/elfun/cosd.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/elfun/cosd.m	Fri Feb 06 08:31:49 2015 -0800
@@ -34,7 +34,7 @@
   I = x / 180;
   y = cos (I .* pi);
   I = I + 0.5;
-  y(I == fix (I) & finite (I)) = 0;
+  y(I == fix (I) & isfinite (I)) = 0;
 
 endfunction
 
--- a/scripts/elfun/sind.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/elfun/sind.m	Fri Feb 06 08:31:49 2015 -0800
@@ -33,7 +33,7 @@
 
   I = x / 180;
   y = sin (I .* pi);
-  y(I == fix (I) & finite (I)) = 0;
+  y(I == fix (I) & isfinite (I)) = 0;
 
 endfunction
 
--- a/scripts/elfun/tand.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/elfun/tand.m	Fri Feb 06 08:31:49 2015 -0800
@@ -35,8 +35,8 @@
   I0 = x / 180;
   I90 = (x-90) / 180;
   y = tan (I0 .* pi);
-  y(I0 == fix (I0) & finite (I0)) = 0;
-  y(I90 == fix (I90) & finite (I90)) = Inf;
+  y(I0 == fix (I0) & isfinite (I0)) = 0;
+  y(I90 == fix (I90) & isfinite (I90)) = Inf;
 
 endfunction
 
--- a/scripts/general/bicubic.m	Fri Feb 06 08:31:09 2015 -0800
+++ /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/bitcmp.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/general/bitcmp.m	Fri Feb 06 08:31:49 2015 -0800
@@ -31,6 +31,7 @@
 ##   @result{} 110100
 ## @end group
 ## @end example
+##
 ## @seealso{bitand, bitor, bitxor, bitset, bitget, bitcmp, bitshift, bitmax}
 ## @end deftypefn
 
@@ -52,27 +53,11 @@
   elseif (isa (A, "single"))
     bmax = bitmax ("single");
     amax = ceil (log2 (bmax));
+  elseif (isinteger (A))
+    amax = sizeof (ones (1, class (A))) * 8;
+    bmax = bitpack (true (amax, 1), class (A));
   else
-    if (isa (A, "uint8"))
-      amax = 8;
-    elseif (isa (A, "uint16"))
-      amax = 16;
-    elseif (isa (A, "uint32"))
-      amax = 32;
-    elseif (isa (A, "uint64"))
-      amax = 64;
-    elseif (isa (A, "int8"))
-      amax = 8;
-    elseif (isa (A, "int16"))
-      amax = 16;
-    elseif (isa (A, "int32"))
-      amax = 32;
-    elseif (isa (A, "int64"))
-      amax = 64;
-    else
-      error ("bitcmp: invalid class %s", class (A));
-    endif
-    bmax = intmax (class (A));
+    error ("bitcmp: invalid class %s", class (A));
   endif
 
   if (nargin == 1 || k == amax)
@@ -131,3 +116,9 @@
 %! assert (bitcmp (A,Amax-1), bitshift (uint64 (1),Amax-2));
 %! assert (bitcmp (A,Amax-2), uint64 (0));
 
+## Do not forget signed integers
+%!assert (bitcmp (int8 (127)), int8 (-128)) # [1 1 1 1 1 1 1 0]
+%!assert (bitcmp (int8 (1)), int8 (-2))     # [1 0 0 0 0 0 0 0]
+%!assert (bitcmp (int8 (0)), int8 (-1))     # [0 0 0 0 0 0 0 0]
+%!assert (bitcmp (int8 (8)), int8 (-9))     # [0 0 0 1 0 0 0 0]
+
--- a/scripts/general/cell2mat.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/general/cell2mat.m	Fri Feb 06 08:31:49 2015 -0800
@@ -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/chop.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/general/chop.m	Fri Feb 06 08:31:49 2015 -0800
@@ -55,7 +55,7 @@
     ## unless base was explicitly provided.
 
     inflate = 10 .^ (ndigits - tmp);
-    deflate = 10 .^ (tmp - ndigits);
+    deflate = 1 ./ inflate;
     if (nargin == 2)
       retval = deflate .* round (x .* inflate);
     else
--- a/scripts/general/cplxpair.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/general/cplxpair.m	Fri Feb 06 08:31:49 2015 -0800
@@ -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/deal.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/general/deal.m	Fri Feb 06 08:31:49 2015 -0800
@@ -54,6 +54,26 @@
 ## @example
 ## a = b = c = x;
 ## @end example
+##
+## Programming Note: @code{deal} is often used with comma separated lists
+## derived from cell arrays or structures.  This is unnecessary as the
+## interpreter can perform the same action without the overhead of a function
+## call.  For example:
+##
+## @example
+## @group
+## c = @{[1 2], "Three", 4@};
+## [x, y, z ] = c@{:@}
+## @result{}
+##    x =
+##
+##       1   2
+##
+##    y = Three
+##    z =  4
+## @end group
+## @end example
+## @seealso{cell2struct, struct2cell, repmat}
 ## @end deftypefn
 
 ## Author: Ariel Tankus
@@ -83,3 +103,6 @@
 %! assert (a, 1);
 %! assert (b, 1);
 
+%!error deal ()
+%!error <nargin . 1 and nargin != nargout> y = deal (1, 2)
+
--- a/scripts/general/del2.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/general/del2.m	Fri Feb 06 08:31:49 2015 -0800
@@ -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, flip (b,1));
+%! assert (b, flip (b,2));
+%! assert (b, flip (b,3));
+
--- a/scripts/general/fieldnames.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/general/fieldnames.m	Fri Feb 06 08:31:49 2015 -0800
@@ -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
+## 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")));
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/general/flip.m	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,106 @@
+## Copyright (C) 2004-2013 David Bateman
+## Copyright (C) 2009 VZLU Prague
+##
+## 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} {} flip (@var{x})
+## @deftypefnx {Function File} {} flip (@var{x}, @var{dim})
+## Flip array across specific dimension.
+##
+## Return a copy of @var{x} flipped about the dimension @var{dim}.
+## @var{dim} defaults to the first non-singleton dimension.
+## For example:
+##
+## @example
+## @group
+## flip ([1  2  3  4])
+##       @result{}  4  3  2  1
+##
+## flip ([1; 2; 3; 4])
+##       @result{}  4
+##           3
+##           2
+##           1
+##
+## flip ([1 2; 3 4])
+##       @result{}  3  4
+##           1  2
+##
+## flip ([1 2; 3 4], 2)
+##       @result{}  2  1
+##           4  3
+## @end group
+## @end example
+##
+## @seealso{fliplr, flipud, rot90, rotdim, permute, transpose}
+## @end deftypefn
+
+## Author: David Bateman, Jaroslav Hajek
+
+function y = flip (x, dim)
+
+  if (nargin < 1 || nargin > 2)
+    print_usage ();
+  endif
+
+  nd = ndims (x);
+  sz = size (x);
+  if (nargin == 1)
+    ## Find the first non-singleton dimension.
+    (dim = find (sz > 1, 1)) || (dim = 1);
+  elseif (! (isscalar (dim) && isindex (dim)))
+    error ("flip: DIM must be a positive integer");
+  endif
+
+  idx(1:max(nd, dim)) = {':'};
+  idx{dim} = size (x, dim):-1:1;
+  y = x(idx{:});
+
+endfunction
+
+
+%!assert (flip ([1 2; 3 4], 2), [2 1; 4 3])
+%!assert (flip ([1 2; 3 4], 3), [1 2; 3 4])
+
+## Test defaults
+%!assert (flip ([1 2 3 4]), [4 3 2 1])
+%!assert (flip ([1 2 3 4].'), [4 3 2 1].')
+%!assert (flip ([1 2; 3 4]), flip ([1 2 ; 3 4], 1))
+
+## Test NDArrays
+%!test
+%! a(1:2,1:2,1) = [1 2; 3 4];
+%! a(1:2,1:2,2) = [5 6; 7 8];
+%! b(1:2,1:2,1) = [5 6; 7 8];
+%! b(1:2,1:2,2) = [1 2; 3 4];
+%! assert (flip (a, 3), b)
+
+%!test
+%! a = b = zeros (2, 2, 1, 2);
+%! a(1:2,1:2,:,1) = [1 2; 3 4];
+%! a(1:2,1:2,:,2) = [5 6; 7 8];
+%! b(1:2,1:2,:,1) = [5 6; 7 8];
+%! b(1:2,1:2,:,2) = [1 2; 3 4];
+%! assert (flip (a, 3), a)
+%! assert (flip (a, 4), b)
+%! assert (flip (a, 5), a)
+
+%!error flip ()
+%!error flip (1, 2, 3)
+%!error <DIM must be a positive integer> flip (magic (3), -1)
+
--- a/scripts/general/flipdim.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/general/flipdim.m	Fri Feb 06 08:31:49 2015 -0800
@@ -20,50 +20,22 @@
 ## -*- texinfo -*-
 ## @deftypefn  {Function File} {} flipdim (@var{x})
 ## @deftypefnx {Function File} {} flipdim (@var{x}, @var{dim})
-## Return a copy of @var{x} flipped about the dimension @var{dim}.
-## @var{dim} defaults to the first non-singleton dimension.
-## For example:
+## Flip array across specific dimension.
 ##
-## @example
-## @group
-## flipdim ([1, 2; 3, 4], 2)
-##       @result{}  2  1
-##           4  3
-## @end group
-## @end example
-## @seealso{fliplr, flipud, rot90, rotdim}
+## This function is an alias for @code{flip} and exists for backwards
+## and @sc{matlab} compatibility.  See further details about its usage
+## on @code{flip} help text.
+##
+## @seealso{flip, fliplr, flipud, rot90, rotdim}
 ## @end deftypefn
 
 ## Author: David Bateman, Jaroslav Hajek
 
-function y = flipdim (x, dim)
-
-  if (nargin != 1 && nargin != 2)
-    print_usage ();
-  endif
-
-  nd = ndims (x);
-  sz = size (x);
-  if (nargin == 1)
-    ## Find the first non-singleton dimension.
-    (dim = find (sz > 1, 1)) || (dim = 1);
-  elseif (! (isscalar (dim) && isindex (dim)))
-    error ("flipdim: DIM must be a positive integer");
-  endif
-
-  idx(1:max(nd, dim)) = {':'};
-  idx{dim} = size (x, dim):-1:1;
-  y = x(idx{:});
-
+function y = flipdim (varargin)
+  y = flip (varargin{:});
 endfunction
 
 
-%!assert (flipdim ([1,2;3,4]), flipdim ([1,2 ; 3,4], 1))
-%!assert (flipdim ([1,2;3,4], 2), [2,1;4,3])
-%!assert (flipdim ([1,2;3,4], 3), [1,2;3,4])
+## No tests needed for alias.  All tests for functionality are in flip.m
+%!assert (1)
 
-## FIXME -- we need tests for multidimensional arrays.
-
-%!error flipdim ()
-%!error flipdim (1, 2, 3)
-
--- a/scripts/general/fliplr.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/general/fliplr.m	Fri Feb 06 08:31:49 2015 -0800
@@ -18,6 +18,8 @@
 
 ## -*- texinfo -*-
 ## @deftypefn {Function File} {} fliplr (@var{x})
+## Flip array left to right.
+##
 ## Return a copy of @var{x} with the order of the columns reversed.  In
 ## other words, @var{x} is flipped left-to-right about a vertical axis.  For
 ## example:
@@ -30,9 +32,7 @@
 ## @end group
 ## @end example
 ##
-## Note that @code{fliplr} only works with 2-D arrays.  To flip N-D arrays
-## use @code{flipdim} instead.
-## @seealso{flipud, flipdim, rot90, rotdim}
+## @seealso{flipud, flip, rot90, rotdim}
 ## @end deftypefn
 
 ## Author: jwe
@@ -42,13 +42,7 @@
   if (nargin != 1)
     print_usage ();
   endif
-
-  if (ndims (x) > 2)
-    error ("fliplr: Only works with 2-D arrays");
-  endif
-
-  nc = columns (x);
-  y = x (:, nc:-1:1);
+  y = flip (x, 2);
 
 endfunction
 
@@ -56,6 +50,29 @@
 %!assert (fliplr ([1, 2; 3, 4]), [2, 1; 4, 3])
 %!assert (fliplr ([1, 2; 3, 4; 5, 6]), [2, 1; 4, 3; 6, 5])
 %!assert (fliplr ([1, 2, 3; 4, 5, 6]), [3, 2, 1; 6, 5, 4])
+%!assert (fliplr ([1 2 3].'), [1 2 3].')
+
+## Test NDArrays
+%!test
+%! a(:,:,1) = [ 1  2;  3  4;  5  6];
+%! a(:,:,2) = [ 7  8;  9 10; 11 12];
+%! b(:,:,1) = [ 2  1;  4  3;  6  5];
+%! b(:,:,2) = [ 8  7; 10  9; 12 11];
+%! assert (fliplr (a), b)
+
+## Test NDArray with singleton dimensions
+%!test
+%! a(:,:,:,1) = [ 1  2;  3  4;  5  6];
+%! a(:,:,:,2) = [ 7  8;  9 10; 11 12];
+%! b(:,:,:,1) = [ 2  1;  4  3;  6  5];
+%! b(:,:,:,2) = [ 8  7; 10  9; 12 11];
+%! assert (fliplr (a), b)
+
+## Test for 1 row, i.e., returns the same
+%!test
+%! a(:,1,:,1) = [ 1  2  3  4];
+%! a(:,1,:,2) = [ 5  6  7  8];
+%! assert (fliplr (a), a)
 
 %!error fliplr()
 %!error fliplr (1, 2)
--- a/scripts/general/flipud.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/general/flipud.m	Fri Feb 06 08:31:49 2015 -0800
@@ -18,6 +18,8 @@
 
 ## -*- texinfo -*-
 ## @deftypefn {Function File} {} flipud (@var{x})
+## Flip array upside down.
+##
 ## Return a copy of @var{x} with the order of the rows reversed.  In
 ## other words, @var{x} is flipped upside-down about a horizontal axis.  For
 ## example:
@@ -30,9 +32,7 @@
 ## @end group
 ## @end example
 ##
-## Note that @code{flipud} only works with 2-D arrays.  To flip N-D arrays
-## use @code{flipdim} instead.
-## @seealso{fliplr, flipdim, rot90, rotdim}
+## @seealso{fliplr, flip, rot90, rotdim}
 ## @end deftypefn
 
 ## Author: jwe
@@ -42,13 +42,7 @@
   if (nargin != 1)
     print_usage ();
   endif
-
-  if (ndims (x) > 2)
-    error ("flipud: Only works with 2-d arrays");
-  endif
-
-  nr = rows (x);
-  y = x (nr:-1:1, :);
+  y = flip (x, 1);
 
 endfunction
 
@@ -56,6 +50,29 @@
 %!assert (flipud ([1, 2; 3, 4]), [3, 4; 1, 2])
 %!assert (flipud ([1, 2; 3, 4; 5, 6]), [5, 6; 3, 4; 1, 2])
 %!assert (flipud ([1, 2, 3; 4, 5, 6]), [4, 5, 6; 1, 2, 3])
+%!assert (flipud ([1 2 3]), [1 2 3])
+
+## Test NDArrays
+%!test
+%! a(:,:,1) = [ 1  2  3;  4  5  6];
+%! a(:,:,2) = [ 7  8  9; 10 11 12];
+%! b(:,:,1) = [ 4  5  6;  1  2  3];
+%! b(:,:,2) = [10 11 12;  7  8  9];
+%! assert (flipud (a), b)
+
+## Test NDArray with singleton dimensions
+%!test
+%! a(:,:,:,1) = [ 1  2  3;  4  5  6];
+%! a(:,:,:,2) = [ 7  8  9; 10 11 12];
+%! b(:,:,:,1) = [ 4  5  6;  1  2  3];
+%! b(:,:,:,2) = [10 11 12;  7  8  9];
+%! assert (flipud (a), b)
+
+## Test for 1 row, i.e., returns the same
+%!test
+%! a(1,:,:,1) = [ 1  2  3  4];
+%! a(1,:,:,2) = [ 5  6  7  8];
+%! assert (flipud (a), a)
 
 %!error flipud ()
 %!error flipud (1, 2)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/general/inputParser.m	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,590 @@
+## Copyright (C) 2011-2014 Carnë Draug
+##
+## 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{p} =} inputParser ()
+## Create object @var{p} of the inputParser class.
+##
+## This class is designed to allow easy parsing of function arguments.  The
+## class supports four types of arguments:
+##
+## @enumerate
+## @item mandatory (see @command{addRequired});
+##
+## @item optional (see @command{addOptional});
+##
+## @item named (see @command{addParamValue});
+##
+## @item switch (see @command{addSwitch}).
+## @end enumerate
+##
+## After defining the function API with these methods, the supplied arguments
+## can be parsed with the @command{parse} method and the parsing results
+## accessed with the @command{Results} accessor.
+##
+## @end deftypefn
+## @deftypefn {Accessor method} {} inputParser.Parameters
+## Return list of parameter names already defined.
+##
+## @end deftypefn
+## @deftypefn {Accessor method} {} inputParser.Results
+## Return structure with argument names as fieldnames and corresponding values.
+##
+## @end deftypefn
+## @deftypefn {Accessor method} {} inputParser.Unmatched
+## Return structure similar to @command{Results}, but for unmatched parameters.
+## See the @command{KeepUnmatched} property.
+##
+## @end deftypefn
+## @deftypefn {Accessor method} {} inputParser.UsingDefaults
+## Return cell array with the names of arguments that are using default values.
+##
+## @end deftypefn
+## @deftypefn {Class property} {} inputParser.CaseSensitive = @var{boolean}
+## Set whether matching of argument names should be case sensitive.  Defaults
+## to false.
+##
+## @end deftypefn
+## @deftypefn {Class property} {} inputParser.FunctionName = @var{name}
+## Set function name to be used in error messages; Defaults to empty string.
+##
+## @end deftypefn
+## @deftypefn {Class property} {} inputParser.KeepUnmatched = @var{boolean}
+## Set whether an error should be given for non-defined arguments.  Defaults to
+## false.  If set to true, the extra arguments can be accessed through
+## @code{Unmatched} after the @code{parse} method.  Note that since
+## @command{Switch} and @command{ParamValue} arguments can be mixed, it is
+## not possible to know the unmatched type.  If argument is found unmatched
+## it is assumed to be of the @command{ParamValue} type and it is expected to
+## be followed by a value.
+##
+## @end deftypefn
+## @deftypefn {Class property} {} inputParser.StructExpand = @var{boolean}
+## Set whether a structure can be passed to the function instead of
+## parameter/value pairs.  Defaults to true.  Not implemented yet.
+##
+## The following example shows how to use this class:
+##
+## @example
+## @group
+## function check (varargin)
+## @c The next two comments need to be indented by one for alignment
+##   p = inputParser ();                      # create object
+##   p.FunctionName = "check";                # set function name
+##   p.addRequired ("pack", @@ischar);         # mandatory argument
+##   p.addOptional ("path", pwd(), @@ischar);  # optional argument
+##
+##   ## create a function handle to anonymous functions for validators
+##   val_mat = @@(x) isvector (x) && all (x <= 1) && all (x >= 0);
+##   p.addOptional ("mat", [0 0], val_mat);
+##
+##   ## create two arguments of type "ParamValue"
+##   val_type = @@(x) any (strcmp (x, @{"linear", "quadratic"@}));
+##   p.addParamValue ("type", "linear", val_type);
+##   val_verb = @@(x) any (strcmp (x, @{"low", "medium", "high"@}));
+##   p.addParamValue ("tolerance", "low", val_verb);
+##
+##   ## create a switch type of argument
+##   p.addSwitch ("verbose");
+##
+##   p.parse (varargin@{:@});  # Run created parser on inputs
+##
+##   ## the rest of the function can access inputs by using p.Results.
+##   ## for example, get the tolerance input with p.Results.tolerance
+## endfunction
+## @end group
+##
+## check ("mech");           # valid, use defaults for other arguments
+## check ();                 # error, one argument is mandatory
+## check (1);                # error, since !ischar
+## check ("mech", "~/dev");  # valid, use defaults for other arguments
+##
+## check ("mech", "~/dev", [0 1 0 0], "type", "linear");  # valid
+##
+## ## following is also valid.  Note how the Switch argument type can
+## ## be mixed into or before the ParamValue argument type (but it
+## ## must still appear after any Optional argument).
+## check ("mech", "~/dev", [0 1 0 0], "verbose", "tolerance", "high");
+##
+## ## following returns an error since not all optional arguments,
+## ## `path' and `mat', were given before the named argument `type'.
+## check ("mech", "~/dev", "type", "linear");
+## @end example
+##
+## @emph{Note 1}: A function can have any mixture of the four API types but
+## they must appear in a specific order.  @command{Required} arguments must be
+## first and can be followed by any @command{Optional} arguments.  Only
+## the @command{ParamValue} and @command{Switch} arguments may be mixed
+## together and they must appear at the end.
+##
+## @emph{Note 2}: If both @command{Optional} and @command{ParamValue} arguments
+## are mixed in a function API then once a string Optional argument fails to
+## validate it will be considered the end of the @command{Optional}
+## arguments.  The remaining arguments will be compared against any
+## @command{ParamValue} or @command{Switch} arguments.
+##
+## @seealso{nargin, validateattributes, validatestring, varargin}
+## @end deftypefn
+
+## -*- texinfo -*-
+## @deftypefn  {Function File} {} addOptional (@var{argname}, @var{default})
+## @deftypefnx {Function File} {} addOptional (@var{argname}, @var{default}, @var{validator})
+## Add new optional argument to the object @var{parser} of the class inputParser
+## to implement an ordered arguments type of API
+##
+## @var{argname} must be a string with the name of the new argument.  The order
+## in which new arguments are added with @command{addOptional}, represents the
+## expected order of arguments.
+##
+## @var{default} will be the value used when the argument is not specified.
+##
+## @var{validator} is an optional anonymous function to validate the given
+## values for the argument with name @var{argname}.  Alternatively, a
+## function name can be used.
+##
+## See @command{help inputParser} for examples.
+##
+## @emph{Note}: if a string argument does not validate, it will be considered a
+## ParamValue key.  If an optional argument is not given a validator, anything
+## will be valid, and so any string will be considered will be the value of the
+## optional argument (in @sc{matlab}, if no validator is given and argument is
+## a string it will also be considered a ParamValue key).
+##
+## @end deftypefn
+
+## -*- texinfo -*-
+## @deftypefn  {Function File} {} addParamValue (@var{argname}, @var{default})
+## @deftypefnx {Function File} {} addParamValue (@var{argname}, @var{default}, @var{validator})
+## Add new parameter to the object @var{parser} of the class inputParser to
+## implement a name/value pair type of API.
+##
+## @var{argname} must be a string with the name of the new parameter.
+##
+## @var{default} will be the value used when the parameter is not specified.
+##
+## @var{validator} is an optional function handle to validate the given values
+## for the parameter with name @var{argname}.  Alternatively, a function name
+## can be used.
+##
+## See @command{help inputParser} for examples.
+##
+## @end deftypefn
+
+## -*- texinfo -*-
+## @deftypefn  {Function File} {} addRequired (@var{argname})
+## @deftypefnx {Function File} {} addRequired (@var{argname}, @var{validator})
+## Add new mandatory argument to the object @var{parser} of inputParser class.
+##
+## This method belongs to the inputParser class and implements an ordered
+## arguments type of API.
+##
+## @var{argname} must be a string with the name of the new argument.  The order
+## in which new arguments are added with @command{addrequired}, represents the
+## expected order of arguments.
+##
+## @var{validator} is an optional function handle to validate the given values
+## for the argument with name @var{argname}.  Alternatively, a function name
+## can be used.
+##
+## See @command{help inputParser} for examples.
+##
+## @emph{Note}: this can be used together with the other type of arguments but
+## it must be the first (see @command{@@inputParser}).
+##
+## @end deftypefn
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} addSwitch (@var{argname})
+## Add new switch type of argument to the object @var{parser} of inputParser
+## class.
+##
+## This method belongs to the inputParser class and implements a switch
+## arguments type of API.
+##
+## @var{argname} must be a string with the name of the new argument.  Arguments
+## of this type can be specified at the end, after @code{Required} and
+## @code{Optional}, and mixed between the @code{ParamValue}.  They default to
+## false.  If one of the arguments supplied is a string like @var{argname},
+## then after parsing the value of @var{parse}.Results.@var{argname} will be
+## true.
+##
+## See @command{help inputParser} for examples.
+##
+## @end deftypefn
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} parse (@var{varargin})
+## Parses and validates list of arguments according to object @var{parser} of
+## the class inputParser.
+##
+## After parsing, the results can be accessed with the @command{Results}
+## accessor.  See @command{help inputParser} for a more complete description.
+##
+## @end deftypefn
+
+## Author: Carnë Draug <carandraug@octave.org>
+
+classdef inputParser < handle
+  properties
+    ## TODO set input checking for this properties
+    CaseSensitive   = false;
+    FunctionName    = "";
+    KeepUnmatched   = false;
+#    PartialMatching = true;   # TODO unimplemented
+#    StructExpand    = true;   # TODO unimplemented
+  endproperties
+
+  properties (SetAccess = protected)
+    Parameters      = cell ();
+    Results         = struct ();
+    Unmatched       = struct ();
+    UsingDefaults   = cell ();
+  endproperties
+
+  properties (Access = protected)
+    ## Since Required and Optional are ordered, they get a cell array of
+    ## structs with the fields "name", "def" (default), and "val" (validator).
+    Required    = cell ();
+    Optional    = cell ();
+    ## ParamValue and Swicth are unordered so we have a struct whose fieldnames
+    ## are the argname, and values are a struct with fields "def" and "val"
+    ParamValue  = struct ();
+    Switch      = struct ();
+
+    ## List of ParamValues and Switch names to ease searches
+    ParamValueNames = cell ();
+    SwitchNames     = cell ();
+
+    ## When checking for fieldnames in a Case Insensitive way, this variable
+    ## holds the correct identifier for the last searched named using the
+    ## is_argname method.
+    last_name = "";
+  endproperties
+
+  properties (Access = protected, Constant = true)
+    ## Default validator, always returns scalar true.
+    def_val = @() true;
+  endproperties
+
+  methods
+    function addRequired (this, name, val = inputParser.def_val)
+      if (nargin < 2 || nargin > 3)
+        print_usage ();
+      elseif (numel (this.Optional) || numel (fieldnames (this.ParamValue))
+              || numel (fieldnames (this.Switch)))
+        error (["inputParser.addRequired: can't have a Required argument " ...
+                "after Optional, ParamValue, or Switch"]);
+      endif
+      this.validate_name ("Required", name);
+      this.Required{end+1} = struct ("name", name, "val", val);
+    endfunction
+
+    function addOptional (this, name, def, val = inputParser.def_val)
+      if (nargin < 3 || nargin > 4)
+        print_usage ();
+      elseif (numel (fieldnames (this.ParamValue))
+              || numel (fieldnames (this.Switch)))
+        error (["inputParser.Optional: can't have Optional arguments " ...
+                "after ParamValue or Switch"]);
+      endif
+      this.validate_name ("Optional", name);
+      this.validate_default ("Optional", name, def, val);
+      this.Optional{end+1} = struct ("name", name, "def", def, "val", val);
+    endfunction
+
+    function addParamValue (this, name, def, val = inputParser.def_val)
+      if (nargin < 3 || nargin > 4)
+        print_usage ();
+      endif
+      this.validate_name ("ParamValue", name);
+      this.validate_default ("ParamValue", name, def, val);
+      this.ParamValue.(name).def = def;
+      this.ParamValue.(name).val = val;
+    endfunction
+
+    function addSwitch (this, name)
+      if (nargin != 2)
+        print_usage ();
+      endif
+      this.validate_name ("Switch", name);
+      this.Switch.(name).def = false;
+    endfunction
+
+    function parse (this, varargin)
+      if (numel (varargin) < numel (this.Required))
+        if (this.FunctionName)
+          print_usage (this.FunctionName);
+        else
+          this.error ("not enough input arguments");
+        endif
+      endif
+      pnargin = numel (varargin);
+
+      this.ParamValueNames = fieldnames (this.ParamValue);
+      this.SwitchNames     = fieldnames (this.Switch);
+
+      ## Evaluate the Required arguments first
+      nReq = numel (this.Required);
+      for idx = 1:nReq
+        req = this.Required{idx};
+        this.validate_arg (req.name, req.val, varargin{idx});
+      endfor
+
+      vidx = nReq;  # current index in varargin
+
+      ## Search for a list of Optional arguments
+      idx  = 0;     # current index on the array of Optional
+      nOpt = numel (this.Optional);
+      while (vidx < pnargin && idx < nOpt)
+        opt = this.Optional{++idx};
+        in  = varargin{++vidx};
+        if (! opt.val (in))
+          ## If it does not match there's two options:
+          ##    1) input is actually wrong and we should error;
+          ##    2) it's a ParamValue or Switch name and we should use the
+          ##       the default for the rest.
+          if (ischar (in))
+            idx--;
+            vidx--;
+            break
+          else
+            this.error (sprintf ("failed validation of %s",
+                                 toupper (opt.name)));
+          endif
+        endif
+        this.Results.(opt.name) = in;
+      endwhile
+
+      ## Fill in with defaults of missing Optional
+      while (idx++ < nOpt)
+        opt = this.Optional{idx};
+        this.UsingDefaults{end+1} = opt.name;
+        this.Results.(opt.name) = opt.def;
+      endwhile
+
+      ## Search unordered Options (Switch and ParamValue)
+      while (vidx++ < pnargin)
+        name = varargin{vidx};
+        if (this.is_argname ("ParamValue", name))
+          if (vidx++ > pnargin)
+            this.error (sprintf ("no matching value for option '%s'",
+                                 toupper (name)));
+          endif
+          this.validate_arg (this.last_name, this.ParamValue.(this.last_name).val,
+                             varargin{vidx});
+        elseif (this.is_argname ("Switch", name))
+          this.Results.(this.last_name) = true;
+        else
+          if (vidx++ < pnargin && this.KeepUnmatched)
+            this.Unmatched.(name) = varargin{vidx};
+          else
+            this.error (sprintf ("argument '%s' is not a valid parameter",
+                                  toupper (name)));
+          endif
+        endif
+      endwhile
+      ## Add them to the UsingDeafults list
+      this.add_missing ("ParamValue");
+      this.add_missing ("Switch");
+
+    endfunction
+
+    function display (this)
+      if (nargin > 1)
+        print_usage ();
+      endif
+      printf ("inputParser object with properties:\n\n");
+      b2s = @(x) ifelse (any (x), "true", "false");
+      printf (["   CaseSensitive   : %s\n   FunctionName    : %s\n" ...
+               "   KeepUnmatched   : %s\n   PartialMatching : %s\n" ...
+               "   StructExpand    : %s\n\n"],
+               b2s (this.CaseSensitive), b2s (this.FunctionName),
+               b2s (this.KeepUnmatched), b2s (this.PartialMatching),
+               b2s (this.StructExpand));
+      printf ("Defined parameters:\n\n   {%s}\n",
+              strjoin (this.Parameters, ", "));
+    endfunction
+  endmethods
+
+  methods (Access = private)
+    function validate_name (this, type, name)
+      if (! isvarname (name))
+        error ("inputParser.add%s: NAME is an invalid identifier", method);
+      elseif (any (strcmpi (this.Parameters, name)))
+        ## Even if CaseSensitive is "on", we still shouldn't allow
+        ## two args with the same name.
+        error ("inputParser.add%s: argname '%s' has already been specified",
+               type, name);
+      endif
+      this.Parameters{end+1} = name;
+    endfunction
+
+    function validate_default (this, type, name, def, val)
+      if (! feval (val, def))
+        error ("inputParser.add%s: failed validation for '%s' default value",
+               type, name);
+      endif
+    endfunction
+
+    function validate_arg (this, name, val, in)
+        if (! val (in))
+          this.error (sprintf ("failed validation of %s", toupper (name)));
+        endif
+        this.Results.(name) = in;
+    endfunction
+
+    function r = is_argname (this, type, name)
+      if (this.CaseSensitive)
+        r = isfield (this.(type), name);
+        this.last_name = name;
+      else
+        fnames = this.([type "Names"]);
+        l = strcmpi (name, fnames);
+        r = any (l(:));
+        if (r)
+          this.last_name = fnames{l};
+        endif
+      endif
+    endfunction
+
+    function add_missing (this, type)
+      unmatched = setdiff (fieldnames (this.(type)), fieldnames (this.Results));
+      for namec = unmatched(:)'
+        name = namec{1};
+        this.UsingDefaults{end+1} = name;
+        this.Results.(name) = this.(type).(name).def;
+      endfor
+    endfunction
+
+    function error (this, msg)
+      where = "";
+      if (this.FunctionName)
+        where = [this.FunctionName ": "];
+      endif
+      error ("%s%s", where, msg);
+    endfunction
+  endmethods
+
+endclassdef
+
+%!function p = create_p ()
+%!  p = inputParser ();
+%!  p.CaseSensitive = true;
+%!  p.addRequired ("req1", @(x) ischar (x));
+%!  p.addOptional ("op1", "val", @(x) any (strcmp (x, {"val", "foo"})));
+%!  p.addOptional ("op2", 78, @(x) x > 50);
+%!  p.addSwitch ("verbose");
+%!  p.addParamValue ("line", "tree", @(x) any (strcmp (x, {"tree", "circle"})));
+%!endfunction
+
+## check normal use, only required are given
+%!test
+%! p = create_p ();
+%! p.parse ("file");
+%! r = p.Results;
+%! assert (r.req1, "file");
+%! assert (sort (p.UsingDefaults), sort ({"op1", "op2", "verbose", "line"}));
+%! assert ({r.req1, r.op1, r.op2, r.verbose, r.line},
+%!        {"file", "val", 78,    false,     "tree"});
+
+## check normal use, but give values different than defaults
+%!test
+%! p = create_p ();
+%! p.parse ("file", "foo", 80, "line", "circle", "verbose");
+%! r = p.Results;
+%! assert ({r.req1, r.op1, r.op2, r.verbose, r.line},
+%!         {"file", "foo", 80,    true,      "circle"});
+
+## check optional is skipped and considered ParamValue if unvalidated string
+%!test
+%! p = create_p ();
+%! p.parse ("file", "line", "circle");
+%! r = p.Results;
+%! assert ({r.req1, r.op1, r.op2, r.verbose, r.line},
+%!         {"file", "val", 78,    false,     "circle"});
+
+## check case insensitivity
+%!test
+%! p = create_p ();
+%!  p.CaseSensitive = false;
+%! p.parse ("file", "foo", 80, "LiNE", "circle", "vERbOSe");
+%! r = p.Results;
+%! assert ({r.req1, r.op1, r.op2, r.verbose, r.line},
+%!         {"file", "foo", 80,    true,      "circle"});
+
+## check KeepUnmatched
+%!test
+%! p = create_p ();
+%! p.KeepUnmatched = true;
+%! p.parse ("file", "foo", 80, "line", "circle", "verbose", "extra", 50);
+%! assert (p.Unmatched.extra, 50)
+
+## check error when missing required
+%!error <not enough input arguments>
+%! p = create_p ();
+%! p.parse ();
+
+## check error when given required does not validate
+%!error <failed validation of >
+%! p = create_p ();
+%! p.parse (50);
+
+## check error when given optional does not validate
+%!error <is not a valid parameter>
+%! p = create_p ();
+%! p.parse ("file", "no-val");
+
+## check error when given ParamValue does not validate
+%!error <failed validation of >
+%! p = create_p ();
+%! p.parse ("file", "foo", 51, "line", "round");
+
+## check alternative method (obj, ...) API
+%!function p2 = create_p2 ();
+%!  p2 = inputParser;
+%!  addRequired (p2, "req1", @(x) ischar (x));
+%!  addOptional (p2, "op1", "val", @(x) any (strcmp (x, {"val", "foo"})));
+%!  addOptional (p2, "op2", 78, @(x) x > 50);
+%!  addSwitch (p2, "verbose");
+%!  addParamValue (p2, "line", "tree", @(x) any (strcmp (x, {"tree", "circle"})));
+%!endfunction
+
+## check normal use, only required are given
+%!test
+%! p2 = create_p2 ();
+%! parse (p2, "file");
+%! r = p2.Results;
+%! assert ({r.req1, r.op1, r.op2, r.verbose, r.line},
+%!         {"file", "val", 78,    false,     "tree"});
+%! assert (sort (p2.UsingDefaults), sort ({"op1", "op2", "verbose", "line"}));
+
+## check normal use, but give values different than defaults
+%!test
+%! p2 = create_p2 ();
+%! parse (p2, "file", "foo", 80, "line", "circle", "verbose");
+%! r = p2.Results;
+%! assert ({r.req1, r.op1, r.op2, r.verbose, r.line},
+%!         {"file", "foo", 80,    true,      "circle"});
+
+## FIXME: This somehow works in Matlab
+#%!test
+#%! p = inputParser;
+#%! p.addOptional ("op1", "val");
+#%! p.addParamValue ("line", "tree");
+#%! p.parse ("line", "circle");
+#%! assert (p.Results, struct ("op1", "val", "line", "circle"));
--- a/scripts/general/interp1.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/general/interp1.m	Fri Feb 06 08:31:49 2015 -0800
@@ -1,3 +1,4 @@
+## Copyright (C) 2014 Nir Krakauer
 ## Copyright (C) 2000-2013 Paul Kienzle
 ## Copyright (C) 2009 VZLU Prague
 ##
@@ -29,28 +30,35 @@
 ## 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{"previous"}
+## Return the previous neighbor.
 ##
-## @item @qcode{"linear"}
-## Linear interpolation from nearest neighbors
+## @item @qcode{"next"}
+## Return the next neighbor.
+##
+## @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 +69,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
@@ -76,7 +84,7 @@
 ## right-continuous.  If @var{x} is decreasing, the default discontinuous
 ## interpolant is left-continuous.
 ## The continuity condition of the interpolant may be specified by using
-## the options, @qcode{"left"} or @qcode{"right"}, to select a left-continuous
+## the options @qcode{"left"} or @qcode{"right"} to select a left-continuous
 ## or right-continuous interpolant, respectively.
 ## Discontinuous interpolation is only allowed for @qcode{"nearest"} and
 ## @qcode{"linear"} methods; in all other cases, the @var{x}-values must be
@@ -91,16 +99,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 +138,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 +186,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.
@@ -186,6 +195,10 @@
     y = y(p,:);
   endif
 
+  if (any (strcmp (method, {"previous", "*previous", "next", "*next"})))
+    rightcontinuous = NaN; # needed for these methods to work
+  endif
+
   if (isnan (rightcontinuous))
     ## If not specified, set the continuity condition
     if (x(end) < x(1))
@@ -193,15 +206,25 @@
     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);
   endif
 
+  ## Because of the way mkpp works, it's easiest to implement "next"
+  ## by running "previous" with vectors flipped.
+  if (strcmp (method, "next"))
+    x = flipud (x);
+    y = flipud (y);
+    method = "previous";
+  elseif (strcmp (method, "*next"))
+    x = flipud (x);
+    y = flipud (y);
+    method = "*previous";
+  endif
+
   starmethod = method(1) == "*";
 
   if (starmethod)
@@ -215,7 +238,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 +262,29 @@
       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
+        yi = ppval (pp, reshape (xi, szx));
+      endif
+
+    case "previous"
+      pp = mkpp ([x(1:nx); 2*x(nx)-x(nx-1)],
+                 shiftdim (y, 1), szy(2:end));
+      pp.orient = "first";
+
+      if (ispp)
+        yi = pp;
+      else
+        yi = ppval (pp, reshape (xi, szx));
+      endif
+
+    case "*previous"
+      pp = mkpp (x(1)+[0:nx]*dx,
+                 shiftdim (y, 1), szy(2:end));
+      pp.orient = "first";
+
       if (ispp)
         yi = pp;
       else
@@ -323,7 +370,7 @@
 
   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));
@@ -349,12 +396,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
 
@@ -362,36 +410,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
 
@@ -412,7 +474,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
@@ -425,7 +487,7 @@
 %! xi = [-1, 0, 2.2, 4, 6.6, 10, 11];
 
 ## The following BLOCK/ENDBLOCK section is repeated for each style
-##    nearest, linear, cubic, spline, pchip
+##    nearest, previous, next, linear, cubic, spline, pchip
 ## The test for ppval of cubic has looser tolerance, but otherwise
 ## the tests are identical.
 ## Note that the block checks style and *style; if you add more tests
@@ -468,6 +530,78 @@
 %!error interp1 (1,1,1, style)
 ## ENDBLOCK
 
+%!test style = "previous";
+## BLOCK
+%!assert (interp1 (xp, yp, [min(xp)-1, max(xp)+1],style), [NA, NA])
+%!assert (interp1 (xp,yp,xp,style), yp, 100*eps)
+%!assert (interp1 (xp,yp,xp',style), yp', 100*eps)
+%!assert (interp1 (xp',yp',xp',style), yp', 100*eps)
+%!assert (interp1 (xp',yp',xp,style), yp, 100*eps)
+%!assert (isempty (interp1 (xp',yp',[],style)))
+%!assert (isempty (interp1 (xp,yp,[],style)))
+%!assert (interp1 (xp,[yp',yp'],xi(:),style),...
+%!        [interp1(xp,yp,xi(:),style),interp1(xp,yp,xi(:),style)])
+## This test is expected to fail, so commented out.
+## "previous" and "next" options are not symmetric w.r.t to flipping xp,yp
+#%!assert (interp1 (xp,yp,xi,style),...
+#%!        interp1 (fliplr (xp),fliplr (yp),xi,style),100*eps)
+%!assert (ppval (interp1 (xp,yp,style,"pp"),xi),
+%!        interp1 (xp,yp,xi,style,"extrap"),10*eps)
+%!error interp1 (1,1,1, style)
+%!assert (interp1 (xp,[yp',yp'],xi,style),
+%!        interp1 (xp,[yp',yp'],xi,["*",style]),100*eps)
+%!test style = ["*",style];
+%!assert (interp1 (xp, yp, [min(xp)-1, max(xp)+1],style), [NA, NA])
+%!assert (interp1 (xp,yp,xp,style), yp, 100*eps)
+%!assert (interp1 (xp,yp,xp',style), yp', 100*eps)
+%!assert (interp1 (xp',yp',xp',style), yp', 100*eps)
+%!assert (interp1 (xp',yp',xp,style), yp, 100*eps)
+%!assert (isempty (interp1 (xp',yp',[],style)))
+%!assert (isempty (interp1 (xp,yp,[],style)))
+%!assert (interp1 (xp,[yp',yp'],xi(:),style),...
+%!        [interp1(xp,yp,xi(:),style),interp1(xp,yp,xi(:),style)])
+# %!assert (interp1 (xp,yp,xi,style),...
+# %!        interp1 (fliplr (xp),fliplr (yp),xi,style),100*eps)
+%!assert (ppval (interp1 (xp,yp,style,"pp"),xi),
+%!        interp1 (xp,yp,xi,style,"extrap"),10*eps)
+%!error interp1 (1,1,1, style)
+## ENDBLOCK
+
+%!test style = "next";
+## BLOCK
+%!assert (interp1 (xp, yp, [min(xp)-1, max(xp)+1],style), [NA, NA])
+%!assert (interp1 (xp,yp,xp,style), yp, 100*eps)
+%!assert (interp1 (xp,yp,xp',style), yp', 100*eps)
+%!assert (interp1 (xp',yp',xp',style), yp', 100*eps)
+%!assert (interp1 (xp',yp',xp,style), yp, 100*eps)
+%!assert (isempty (interp1 (xp',yp',[],style)))
+%!assert (isempty (interp1 (xp,yp,[],style)))
+%!assert (interp1 (xp,[yp',yp'],xi(:),style),...
+%!        [interp1(xp,yp,xi(:),style),interp1(xp,yp,xi(:),style)])
+# %!assert (interp1 (xp,yp,xi,style),...
+# %!        interp1 (fliplr (xp),fliplr (yp),xi,style),100*eps)
+%!assert (ppval (interp1 (xp,yp,style,"pp"),xi),
+%!        interp1 (xp,yp,xi,style,"extrap"),10*eps)
+%!error interp1 (1,1,1, style)
+%!assert (interp1 (xp,[yp',yp'],xi,style),
+%!        interp1 (xp,[yp',yp'],xi,["*",style]),100*eps)
+%!test style = ["*",style];
+%!assert (interp1 (xp, yp, [min(xp)-1, max(xp)+1],style), [NA, NA])
+%!assert (interp1 (xp,yp,xp,style), yp, 100*eps)
+%!assert (interp1 (xp,yp,xp',style), yp', 100*eps)
+%!assert (interp1 (xp',yp',xp',style), yp', 100*eps)
+%!assert (interp1 (xp',yp',xp,style), yp, 100*eps)
+%!assert (isempty (interp1 (xp',yp',[],style)))
+%!assert (isempty (interp1 (xp,yp,[],style)))
+%!assert (interp1 (xp,[yp',yp'],xi(:),style),...
+%!        [interp1(xp,yp,xi(:),style),interp1(xp,yp,xi(:),style)])
+# %!assert (interp1 (xp,yp,xi,style),...
+# %!        interp1 (fliplr (xp),fliplr (yp),xi,style),100*eps)
+%!assert (ppval (interp1 (xp,yp,style,"pp"),xi),
+%!        interp1 (xp,yp,xi,style,"extrap"),10*eps)
+%!error interp1 (1,1,1, style)
+## ENDBLOCK
+
 %!test style = "linear";
 ## BLOCK
 %!assert (interp1 (xp, yp, [min(xp)-1, max(xp)+1],style), [NA, NA])
@@ -611,20 +745,27 @@
 ## ENDBLOCK
 ## ENDBLOCKTEST
 
-## test extrapolation (linear)
+## test extrapolation
 %!assert (interp1 ([1:5],[3:2:11],[0,6],"linear","extrap"), [1, 13], eps)
+%!assert (interp1 ([1:5],[3:2:11],[0,6],"nearest","extrap"), [3, 11], eps)
+%!assert (interp1 ([1:5],[3:2:11],[0,6],"previous","extrap"), [3, 11], eps)
+%!assert (interp1 ([1:5],[3:2:11],[0,6],"next","extrap"), [3, 11], eps)
 %!assert (interp1 (xp, yp, [-1, max(xp)+1],"linear",5), [5, 5])
 %!assert (interp1 ([0,1],[1,0],[0.1,0.9;0.2,1.1]), [0.9 0.1; 0.8 NA], eps)
 %!assert (interp1 ([0,1],[1,0],[0.1,0.9;0.2,1]), [0.9 0.1; 0.8 0], eps)
 
 ## Basic sanity checks
 %!assert (interp1 (1:2,1:2,1.4,"nearest"), 1)
+%!assert (interp1 (1:2,1:2,1.6,"previous"), 1)
+%!assert (interp1 (1:2,1:2,1.4,"next"), 2)
 %!assert (interp1 (1:2,1:2,1.4,"linear"), 1.4)
 %!assert (interp1 (1:4,1:4,1.4,"cubic"), 1.4)
 %!assert (interp1 (1:2,1:2,1.1,"spline"), 1.1)
 %!assert (interp1 (1:3,1:3,1.4,"spline"), 1.4)
 
 %!assert (interp1 (1:2:4,1:2:4,1.4,"*nearest"), 1)
+%!assert (interp1 (1:2:4,1:2:4,2.2,"*previous"), 1)
+%!assert (interp1 (1:2:4,1:2:4,1.4,"*next"), 3)
 %!assert (interp1 (1:2:4,1:2:4,[0,1,1.4,3,4],"*linear"), [NA,1,1.4,3,NA])
 %!assert (interp1 (1:2:8,1:2:8,1.4,"*cubic"), 1.4)
 %!assert (interp1 (1:2,1:2,1.3, "*spline"), 1.3)
@@ -642,12 +783,15 @@
 %% 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")
+%!error <minimum of 2 points required> interp1 (1,1,1, "previous")
+%!error <minimum of 2 points required> interp1 (1,1,1, "*previous")
 %!warning <multiple discontinuities> interp1 ([1 1 1 2], [1 2 3 4], 1);
+%!error <discontinuities not supported> interp1 ([1 1],[1 2],1, "next")
 %!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 Feb 06 08:31:09 2015 -0800
+++ b/scripts/general/interp2.m	Fri Feb 06 08:31:49 2015 -0800
@@ -19,137 +19,115 @@
 
 ## -*- 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}
+## @var{extrap} is a scalar number. It replaces values beyond the endpoints
+## with @var{extrap}.  Note that if @var{extrapval} is used, @var{method} must
+## be specified as well.  If @var{extrap} is omitted and the @var{method} is
+## @qcode{"spline"}, then the extrapolated values of the @qcode{"spline"} are
+## used.  Otherwise the default @var{extrap} value for any other @var{method}
+## is @qcode{"NA"}.
+## @seealso{interp1, interp3, interpn, meshgrid}
 ## @end deftypefn
 
-## Author:      Kai Habel <kai.habel@gmx.de>
-## 2005-03-02 Thomas Weber <weber@num.uni-sb.de>
-##     * Add test cases
-## 2005-03-02 Paul Kienzle <pkienzle@users.sf.net>
-##     * Simplify
-## 2005-04-23 Dmitri A. Sergatskov <dasergatskov@gmail.com>
-##     * Modified demo and test for new gnuplot interface
-## 2005-09-07 Hoxide <hoxide_dirac@yahoo.com.cn>
-##     * Add bicubic interpolation method
-##     * Fix the eat line bug when the last element of XI or YI is
-##       negative or zero.
-## 2005-11-26 Pierre Baldensperger <balden@libertysurf.fr>
-##     * Rather big modification (XI,YI no longer need to be
-##       "meshgridded") to be consistent with the help message
-##       above and for compatibility.
+function ZI = interp2 (varargin)
 
-function ZI = interp2 (varargin)
+  narginchk (1, 7);
+  nargs = nargin;
+
   Z = X = Y = XI = YI = n = [];
   method = "linear";
-  extrapval = NA;
+  extrap = [];
 
-  switch (nargin)
+  ## Check for method and extrap
+  if (nargs > 1 && ischar (varargin{end-1}))
+    if (! isnumeric (varargin{end}) || ! isscalar (varargin{end}))
+      error ("interp2: EXTRAP must be a numeric scalar");
+    endif
+    extrap = varargin{end};
+    method = varargin{end-1};
+    nargs -= 2;
+  elseif (ischar (varargin{end}))
+    method = varargin{end};
+    nargs--;
+  endif
+  if (method(1) == "*")
+    warning ("interp2: ignoring unsupported '*' flag to METHOD");
+    method(1) = [];
+  endif
+  method = validatestring (method, ...
+    {"nearest", "linear", "pchip", "cubic", "spline"});
+
+  ## Read numeric input
+  switch (nargs)
     case 1
       Z = varargin{1};
       n = 1;
     case 2
-      if (ischar (varargin{2}))
-        [Z, method] = deal (varargin{:});
-        n = 1;
-      else
-        [Z, n] = deal (varargin{:});
-      endif
+      [Z, n] = deal (varargin{1:nargs});
     case 3
-      if (ischar (varargin{3}))
-        [Z, n, method] = deal (varargin{:});
-      else
-        [Z, XI, YI] = deal (varargin{:});
-      endif
-    case 4
-      if (ischar (varargin{4}))
-        [Z, XI, YI, method] = deal (varargin{:});
-      else
-        [Z, n, method, extrapval] = deal (varargin{:});
-      endif
+      [Z, XI, YI] = deal (varargin{1:nargs});
     case 5
-      if (ischar (varargin{4}))
-        [Z, XI, YI, method, extrapval] = 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] = deal (varargin{1:nargs});
     otherwise
       print_usage ();
   endswitch
 
-  ## Type checking.
-  if (!ismatrix (Z))
-    error ("interp2: Z must be a matrix");
-  endif
-  if (!isempty (n) && !isscalar (n))
-    error ("interp2: N must be a scalar");
+  ## Type checking
+  if (! isnumeric (Z) || isscalar (Z) || ! ismatrix (Z) || ndims (Z) != 2)
+    error ("interp2: Z must be a 2-D matrix");
   endif
-  if (!ischar (method))
-    error ("interp2: METHOD must be a string");
-  endif
-  if (ischar (extrapval) || strcmp (extrapval, "extrap"))
-    extrapval = [];
-  elseif (!isscalar (extrapval))
-    error ("interp2: EXTRAPVAL must be a scalar");
+  if (! isempty (n) && ! (isscalar (n) && n >= 0 && n == fix (n)))
+    error ("interp2: N must be an integer >= 0");
   endif
 
   ## Define X, Y, XI, YI if needed
@@ -171,21 +149,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 +233,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 +293,51 @@
 
     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;
-        else
-          ZI (XI < X(1) | XI > X(end) | YI < Y(end) | YI > Y(1)) = ...
-                  extrapval;
-        endif
-      else
-        if (Y (1) < Y (end))
-          ZI (XI < X(end) | XI > X(1) | YI < Y(1) | YI > Y(end)) = ...
-                  extrapval;
-        else
-          ZI (XI < X(1,end) | XI > X(1) | YI < Y(end) | YI > Y(1)) = ...
-                  extrapval;
-        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
 
-    if (strcmp (method, "cubic"))
+    if (strcmp (method, "spline"))
       if (isgriddata (XI) && isgriddata (YI'))
-        ZI = bicubic (X, Y, Z, XI (1, :), YI (:, 1), extrapval);
-      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));
-
-        ## 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;
-
-        ## 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));
-
-        ## 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 = __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
-
-    elseif (strcmp (method, "spline"))
-      if (isgriddata (XI) && isgriddata (YI'))
-        ZI = __splinen__ ({Y(:,1).', X(1,:)}, Z, {YI(:,1), XI(1,:)}, extrapval,
-                        "spline");
-      else
-        error ("interp2: input data must have 'meshgrid' format");
-      endif
-    else
-      error ("interp2: interpolation METHOD not recognized");
     endif
 
+    return; # spline doesn't need NA extrapolation value (MATLAB compatibility)
+
   endif
+
+  ## extrapolation 'extrap' 
+  if (isempty (extrap))
+    extrap = NA;
+  endif
+  
+  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)) = extrap;
+    endif
+  else
+    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)) = extrap;
+    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 +352,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 +375,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 +386,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 +397,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 +408,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 +420,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 +432,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 +443,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 +454,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 +465,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 +476,78 @@
 %! 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", 2), [2,2;2,2]);
+%! assert (interp2 (x,y,orig, xi, yi,"spline", 2), [2,2;2,2]);
+%! assert (interp2 (x,y,orig, xi, yi,"linear", 0+1i), [0+1i,0+1i;0+1i,0+1i]);
+%! assert (interp2 (x,y,orig, xi, yi,"spline"), [27,43;512,528]);
 
-%!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 +562,33 @@
 %!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 interp2 (1, 1, 1, 1, 1, 2)    #only 5 numeric inputs
+%!error interp2 (1, 1, 1, 1, 1, 2, 2) #only 5 numeric inputs
+%!error <Z must be a 2-D matrix> interp2 ({1})
+%!error <Z must be a 2-D matrix> interp2 (1,1,1)
+%!error <Z must be a 2-D matrix> interp2 (ones (2,2,2))
+%!error <N must be an integer .= 0> interp2 (ones (2), ones (2))
+%!error <N must be an integer .= 0> interp2 (ones (2), -1)
+%!error <N must be an integer .= 0> interp2 (ones (2), 1.5)
+%!warning <ignoring unsupported '\*' flag> interp2 (rand (3,3), 1, "*linear");
+%!error <EXTRAP must be a numeric scalar> interp2 (1, 1, 1, 1, 1, 'linear', {1})
+%!error <EXTRAP must be a numeric scalar> interp2 (1, 1, 1, 1, 1, 'linear', ones (2,2))
+%!error <EXTRAP must be a numeric scalar> interp2 (1, 1, 1, 1, 1, 'linear', "abc")
+%!error <EXTRAP must be a numeric scalar> interp2 (1, 1, 1, 1, 1, 'linear', "extrap")
+%!error <X, Y must be numeric matrices> interp2 ({1}, 1, ones (2), 1, 1)
+%!error <X, Y must be numeric matrices> interp2 (1, {1}, ones (2), 1, 1)
+%!error <XI, YI must be numeric> interp2 (1, 1, ones (2), {1}, 1)
+%!error <XI, YI must be numeric> interp2 (1, 1, ones (2), 1, {1})
+%!error <X and Y must be matrices of equal size> interp2 (ones(2,2), 1, ones (2), 1, 1)
+%!error <X and Y must be matrices of equal size> interp2 (ones(2,2), ones(2,3), ones (2), 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:2, 1:2, ones (2), ones(2,2), 1)
+%!error <XI and YI must be matrices of equal size> interp2 (1:2, 1:2, ones (2), 1, ones(2,2))
+%!error <XI, YI must have uniform spacing> interp2 (1:2, 1:2, ones (2), [1 2 4], [1 2 3], "spline")
+%!error <XI, YI must have uniform spacing> interp2 (1:2, 1:2, ones (2), [1 2 3], [1 2 4], "spline")
+%!error interp2 (1, 1, 1, 1, 1, "foobar")
+
--- a/scripts/general/interp3.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/general/interp3.m	Fri Feb 06 08:31:49 2015 -0800
@@ -19,168 +19,248 @@
 ## -*- 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{"cubic"}
-## Cubic interpolation from four nearest neighbors (not implemented yet).
+## Piecewise cubic Hermite interpolating polynomial---shape-preserving
+## interpolation with smooth first derivative (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}
+## @var{extrapval} is a scalar number. It replaces values beyond the endpoints
+## with @var{extrapval}.  Note that if @var{extrapval} is used, @var{method}
+## must be specified as well.  If @var{extrapval} is omitted and the
+## @var{method} is @qcode{"spline"}, then the extrapolated values of the
+## @qcode{"spline"} are used.  Otherwise the default @var{extrapval} value for
+## any other @var{method} is @qcode{"NA"}.
+## @seealso{interp1, interp2, interpn, meshgrid}
 ## @end deftypefn
 
+## FIXME: Need to add support for 'cubic' method (maybe change interpn).
+
 function vi = interp3 (varargin)
+
+  narginchk (1,9);
+
   method = "linear";
-  extrapval = NA;
+  extrapval = [];
   nargs = nargin;
 
   if (nargin < 1 || ! isnumeric (varargin{1}))
     print_usage ();
   endif
 
-  if (ischar (varargin{end}))
-    method = varargin{end};
-    nargs = nargs - 1;
-  elseif (nargs > 1 && ischar (varargin{end - 1}))
+  if (nargs > 1 && ischar (varargin{end-1}))
     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;
+  elseif (ischar (varargin{end}))
+    method = varargin{end};
+    nargs--;
   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
+  method = validatestring (method, ...
+    {"nearest", "linear", "cubic", "spline"});
+
+  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
+    n = varargin(2:nargs);
+    v = permute (v, [2, 1, 3]);
+    if (isempty (extrapval))
+      vi = interpn (v, n{:}, method);
+    else
+      vi = interpn (v, n{:}, method, extrapval);
     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]);
+    vi = ipermute (vi, [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)
+    if (isempty (extrapval))
+      vi = interpn (v, xi{:}, method);
+    else
+      vi = interpn (v, xi{:}, method, extrapval);
+    endif
+    vi = ipermute (vi, [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]);
+    if (isempty (extrapval))
+      vi = interpn (x{:}, v, xi{:}, method);
+    else
+      vi = interpn (x{:}, v, xi{:}, method, extrapval);
+    endif
+    vi = ipermute (vi, [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);
+
+%!test # extrapolation
+%! X=[0,0.5,1]; Y=X; Z=X;
+%! V = zeros (3,3,3);
+%! V(:,:,1) = [1 3 5; 3 5 7; 5 7 9];
+%! V(:,:,2) = V(:,:,1) + 2;
+%! V(:,:,3) = V(:,:,2) + 2;
+%! tol = 10 * eps;
+%! x=[-0.1,0,0.1]; y=x; z=x; 
+%! assert(interp3(X,Y,Z,V,x,y,z,"spline"), [-0.2, 1.0, 2.2]',tol);
+%! assert(interp3(X,Y,Z,V,x,y,z,"linear"), [NA, 1.0, 2.2]',tol);
+%! assert(interp3(X,Y,Z,V,x,y,z,"spline", 0), [0, 1.0, 2.2]',tol);
+%! assert(interp3(X,Y,Z,V,x,y,z,"linear", 0), [0, 1.0, 2.2]',tol);
+
 %!shared z, zout, tol
 %! z = zeros (3, 3, 3);
 %! zout = zeros (5, 5, 5);
@@ -195,7 +275,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 Feb 06 08:31:09 2015 -0800
+++ b/scripts/general/interpn.m	Fri Feb 06 08:31:49 2015 -0800
@@ -39,17 +39,21 @@
 ## points.  This process is performed @var{m} times.  If only @var{v} is
 ## specified, then @var{m} is assumed to be @code{1}.
 ##
-## Method is one of:
+## 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
@@ -58,34 +62,44 @@
 ##
 ## The default method is @qcode{"linear"}.
 ##
-## If @var{extrapval} is the scalar value, use it to replace the values
-## beyond the endpoints with that number.  If @var{extrapval} is missing,
-## assume NA.
-## @seealso{interp1, interp2, spline, ndgrid}
+## @var{extrapval} is a scalar number. It replaces values beyond the endpoints
+## with @var{extrapval}.  Note that if @var{extrapval} is used, @var{method}
+## must be specified as well.  If @var{extrapval} is omitted and the
+## @var{method} is @qcode{"spline"}, then the extrapolated values of the
+## @qcode{"spline"} are used.  Otherwise the default @var{extrapval} value for
+## any other @var{method} is @qcode{"NA"}.
+## @seealso{interp1, interp2, interp3, spline, ndgrid}
 ## @end deftypefn
 
 function vi = interpn (varargin)
 
   method = "linear";
-  extrapval = NA;
+  extrapval = [];
   nargs = nargin;
 
   if (nargin < 1 || ! isnumeric (varargin{1}))
     print_usage ();
   endif
 
-  if (ischar (varargin{end}))
-    method = varargin{end};
-    nargs -= 1;
-  elseif (nargs > 1 && ischar (varargin{end - 1}))
+  if (nargs > 1 && ischar (varargin{end-1}))
     if (! isnumeric (varargin{end}) || ! isscalar (varargin{end}))
-      error ("interpn: extrapal is expected to be a numeric scalar");
+      error ("interpn: EXTRAPVAL must be a numeric scalar");
     endif
-    method = varargin{end - 1};
     extrapval = varargin{end};
+    method = varargin{end-1};
     nargs -= 2;
+  elseif (ischar (varargin{end}))
+    method = varargin{end};
+    nargs--;
   endif
 
+  if (method(1) == "*")
+    warning ("interpn: ignoring unsupported '*' flag to METHOD");
+    method(1) = [];
+  endif
+  method = validatestring (method, ...
+    {"nearest", "linear", "pchip", "cubic", "spline"});
+
   if (nargs < 3)
     v = varargin{1};
     m = 1;
@@ -154,6 +168,9 @@
 
   if (strcmp (method, "linear"))
     vi = __lin_interpn__ (x{:}, v, y{:});
+    if (isempty (extrapval))
+      extrapval = NA;
+    endif
     vi(isna (vi)) = extrapval;
   elseif (strcmp (method, "nearest"))
     yshape = size (y{1});
@@ -171,6 +188,9 @@
     for i = 1 : nd
       idx |= y{i} < min (x{i}(:)) | y{i} > max (x{i}(:));
     endfor
+    if (isempty (extrapval))
+      extrapval = NA;
+    endif
     vi(idx) = extrapval;
     vi = reshape (vi, yshape);
   elseif (strcmp (method, "spline"))
@@ -318,3 +338,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/isa.m	Fri Feb 06 08:31:09 2015 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,110 +0,0 @@
-## Copyright (C) 2004-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} {} isa (@var{obj}, @var{classname})
-## Return true if @var{obj} is an object from the class @var{classname}.
-##
-## @var{classname} may also be one of the following class categories:
-##
-## @table @asis
-## @item @qcode{"float"}
-## Floating point value comprising classes @qcode{"double"} and
-## @qcode{"single"}.
-##
-## @item @qcode{"integer"}
-## Integer value comprising classes (u)int8, (u)int16, (u)int32, (u)int64.
-##
-## @item @qcode{"numeric"}
-## Numeric value comprising either a floating point or integer value.
-## @end table
-## @seealso{class, typeinfo}
-## @end deftypefn
-
-## Author: Paul Kienzle <pkienzle@users.sf.net>
-## Adapted-by: jwe
-
-function retval = isa (obj, classname)
-
-  if (nargin != 2)
-    print_usage ();
-  endif
-
-  if (strcmp (classname, "float"))
-    retval = isfloat (obj);
-  elseif (strcmp (classname, "integer"))
-    retval = isinteger (obj);
-  elseif (strcmp (classname, "numeric"))
-    retval = isnumeric (obj);
-  else
-    class_of_obj = class (obj);
-    retval = strcmp (class_of_obj, classname);
-    if (! retval && isobject (obj))
-      retval = __isa_parent__ (obj, classname);
-    endif
-  endif
-
-endfunction
-
-
-%!assert (isa ("char", "float"), false)
-%!assert (isa (logical (1), "float"), false)
-%!assert (isa (double (13), "float"), true)
-%!assert (isa (single (13), "float"), true)
-%!assert (isa (int8 (13), "float"), false)
-%!assert (isa (int16 (13), "float"), false)
-%!assert (isa (int32 (13), "float"), false)
-%!assert (isa (int64 (13), "float"), false)
-%!assert (isa (uint8 (13), "float"), false)
-%!assert (isa (uint16 (13), "float"), false)
-%!assert (isa (uint32 (13), "float"), false)
-%!assert (isa (uint64 (13), "float"), false)
-%!assert (isa ("char", "numeric"), false)
-%!assert (isa (logical (1), "numeric"), false)
-%!assert (isa (double (13), "numeric"), true)
-%!assert (isa (single (13), "numeric"), true)
-%!assert (isa (int8 (13), "numeric"), true)
-%!assert (isa (int16 (13), "numeric"), true)
-%!assert (isa (int32 (13), "numeric"), true)
-%!assert (isa (int64 (13), "numeric"), true)
-%!assert (isa (uint8 (13), "numeric"), true)
-%!assert (isa (uint16 (13), "numeric"), true)
-%!assert (isa (uint32 (13), "numeric"), true)
-%!assert (isa (uint64 (13), "numeric"), true)
-%!assert (isa (uint8 (13), "integer"), true)
-%!assert (isa (double (13), "integer"), false)
-%!assert (isa (single (13), "integer"), false)
-
-%!assert (isa (double (13), "double"))
-%!assert (isa (single (13), "single"))
-%!assert (isa (int8 (13), "int8"))
-%!assert (isa (int16 (13), "int16"))
-%!assert (isa (int32 (13), "int32"))
-%!assert (isa (int64 (13), "int64"))
-%!assert (isa (uint8 (13), "uint8"))
-%!assert (isa (uint16 (13), "uint16"))
-%!assert (isa (uint32 (13), "uint32"))
-%!assert (isa (uint64 (13), "uint64"))
-%!assert (isa ("string", "char"))
-%!assert (isa (true, "logical"))
-%!assert (isa (false, "logical"))
-%!assert (isa ({1, 2}, "cell"))
-%!test
-%! a.b = 1;
-%! assert (isa (a, "struct"));
-
--- a/scripts/general/iscolumn.m	Fri Feb 06 08:31:09 2015 -0800
+++ /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 Feb 06 08:31:09 2015 -0800
+++ b/scripts/general/isequal.m	Fri Feb 06 08:31:49 2015 -0800
@@ -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 Feb 06 08:31:09 2015 -0800
+++ b/scripts/general/isequaln.m	Fri Feb 06 08:31:49 2015 -0800
@@ -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 Feb 06 08:31:09 2015 -0800
+++ /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 Feb 06 08:31:09 2015 -0800
+++ /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 Feb 06 08:31:09 2015 -0800
+++ /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 Feb 06 08:31:09 2015 -0800
+++ /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 Feb 06 08:31:09 2015 -0800
+++ b/scripts/general/module.mk	Fri Feb 06 08:31:49 2015 -0800
@@ -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 \
@@ -29,34 +28,30 @@
   general/display.m \
   general/divergence.m \
   general/fieldnames.m \
+  general/flip.m \
   general/flipdim.m \
   general/fliplr.m \
   general/flipud.m \
   general/gradient.m \
   general/idivide.m \
+  general/inputParser.m \
   general/int2str.m \
   general/interp1.m \
   general/interp2.m \
   general/interp3.m \
+  general/interpft.m \
   general/interpn.m \
-  general/interpft.m \
-  general/isa.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 \
   general/nargchk.m \
   general/narginchk.m \
   general/nargoutchk.m \
+  general/nextpow2.m \
   general/nthargout.m \
-  general/nextpow2.m \
   general/num2str.m \
   general/pol2cart.m \
   general/polyarea.m \
@@ -80,8 +75,9 @@
   general/sph2cart.m \
   general/structfun.m \
   general/subsindex.m \
+  general/trapz.m \
   general/triplequad.m \
-  general/trapz.m \
+  general/validateattributes.m \
   $(general_PRIVATE_FCN_FILES)
 
 FCN_FILES += $(general_FCN_FILES)
--- a/scripts/general/nargchk.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/general/nargchk.m	Fri Feb 06 08:31:49 2015 -0800
@@ -25,6 +25,9 @@
 ##
 ## This is useful for checking to see that the number of input arguments
 ## supplied to a function is within an acceptable range.
+##
+## @strong{Caution}: @code{nargchk} is scheduled for deprecation.  Use
+## @code{narginchk} in all new code.
 ## @seealso{nargoutchk, narginchk, error, nargin, nargout}
 ## @end deftypefn
 
--- a/scripts/general/narginchk.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/general/narginchk.m	Fri Feb 06 08:31:49 2015 -0800
@@ -28,7 +28,7 @@
 ##
 ## Note that this function evaluates @code{nargin} on the caller.
 ##
-## @seealso{nargchk, nargoutchk, error, nargout, nargin}
+## @seealso{nargoutchk, error, nargout, nargin}
 ## @end deftypefn
 
 ## Author: Carnë Draug <carandraug+dev@gmail.com>
--- a/scripts/general/nargoutchk.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/general/nargoutchk.m	Fri Feb 06 08:31:49 2015 -0800
@@ -38,7 +38,7 @@
 ##
 ## This is useful for checking to see that the number of output
 ## arguments supplied to a function is within an acceptable range.
-## @seealso{nargchk, narginchk, error, nargout, nargin}
+## @seealso{narginchk, error, nargout, nargin}
 ## @end deftypefn
 
 ## Author: Bill Denney <bill@denney.ws>
@@ -76,7 +76,7 @@
     if (strcmpi (outtype, "string"))
       msg = msg.message;
     elseif (isempty (msg.message))
-      ## Compatability: Matlab returns a 0x1 empty struct when nargchk passes
+      ## Compatibility: Matlab returns a 0x1 empty struct when nargoutchk passes
       msg = resize (msg, 0, 1);
     endif
 
--- a/scripts/general/postpad.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/general/postpad.m	Fri Feb 06 08:31:49 2015 -0800
@@ -30,6 +30,9 @@
 ##
 ## If the optional argument @var{dim} is given, operate along this
 ## dimension.
+##
+## If @var{dim} is larger than the dimensions of @var{x}, the result will
+## have @var{dim} dimensions.
 ## @seealso{prepad, cat, resize}
 ## @end deftypefn
 
@@ -56,8 +59,7 @@
     ## Find the first non-singleton dimension.
     (dim = find (sz > 1, 1)) || (dim = 1);
   else
-    if (!(isscalar (dim) && dim == fix (dim))
-        || !(1 <= dim && dim <= nd))
+    if (!(isscalar (dim) && dim == fix (dim) && dim >= 1))
       error ("postpad: DIM must be an integer and a valid dimension");
     endif
   endif
@@ -89,9 +91,14 @@
 %!assert (postpad ([1,2], 4, 2), [1,2,2,2])
 %!assert (postpad ([1;2], 4, 2), [1;2;2;2])
 %!assert (postpad ([1,2], 2, 2, 1), [1,2;2,2])
+%!assert (postpad ([1;2], 2, 2, 3), reshape ([1;2;2;2], 2, 1, 2))
+%!assert (postpad ([1,2], 2, 2, 3), reshape ([1,2,2,2], 1, 2, 2))
+
+%! ## Test with string concatenation (bug #44162)
+%!assert (postpad ("Octave", 16, "x"), "Octavexxxxxxxxxx")
+%!assert (postpad ("Octave", 4), "Octa")
 
 %!error postpad ()
 %!error postpad (1)
 %!error postpad (1,2,3,4,5)
-%!error postpad ([1,2], 2, 2,3)
 
--- a/scripts/general/prepad.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/general/prepad.m	Fri Feb 06 08:31:49 2015 -0800
@@ -30,6 +30,9 @@
 ##
 ## If the optional argument @var{dim} is given, operate along this
 ## dimension.
+##
+## If @var{dim} is larger than the dimensions of @var{x}, the result will
+## have @var{dim} dimensions.
 ## @seealso{postpad, cat, resize}
 ## @end deftypefn
 
@@ -56,8 +59,7 @@
     ## Find the first non-singleton dimension.
     (dim = find (sz > 1, 1)) || (dim = 1);
   else
-    if (!(isscalar (dim) && dim == fix (dim))
-        || !(1 <= dim && dim <= nd))
+    if (!(isscalar (dim) && dim == fix (dim) && dim >= 1))
       error ("prepad: DIM must be an integer and a valid dimension");
     endif
   endif
@@ -78,7 +80,7 @@
     y = x(idx{:});
   else
     sz (dim) = l - d;
-    y = cat (dim, c * ones (sz), x);
+    y = cat (dim, c(ones (sz)), x);
   endif
 
 endfunction
@@ -92,7 +94,14 @@
 
 %!assert (prepad ([1,2], 2, 2, 1), [2,2;1,2])
 
-## FIXME -- we need tests for multidimensional arrays.
+%!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))
+
+%! ## Test with string concatenation (bug #44162)
+%!assert (prepad ("Octave", 16, "x"), "xxxxxxxxxxOctave")
+%!assert (prepad ("Octave", 4), "tave")
+
+## FIXME: We need tests for multidimensional arrays.
 
 %!error prepad ()
 %!error prepad (1)
@@ -100,7 +109,6 @@
 %!error <C must be empty or a scalar> prepad ([1,2], 2, ones (2))
 %!error <DIM must be an integer> prepad ([1,2], 2, 2, ones (3))
 %!error <DIM must be an integer> prepad ([1,2], 2, 2, 1.1)
-%!error <DIM must be an integer> prepad ([1,2], 2, 2, 3)
 %!error <L must be a positive scalar> prepad ([1,2], ones (2))
 %!error <L must be a positive scalar> prepad ([1,2], -1)
 
--- a/scripts/general/private/__isequal__.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/general/private/__isequal__.m	Fri Feb 06 08:31:49 2015 -0800
@@ -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/private/__splinen__.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/general/private/__splinen__.m	Fri Feb 06 08:31:49 2015 -0800
@@ -38,10 +38,12 @@
   endfor
 
   [xi{:}] = ndgrid (cellfun (@(x) x(:), xi, "uniformoutput", false){:});
-  idx = zeros (size (xi{1}));
-  for i = 1 : length (x)
-    idx |= xi{i} < min (x{i}(:)) | xi{i} > max (x{i}(:));
-  endfor
-  yi(idx) = extrapval;
+  if (!isempty (extrapval))
+    idx = zeros (size (xi{1}));
+    for i = 1 : length (x)
+      idx |= xi{i} < min (x{i}(:)) | xi{i} > max (x{i}(:));
+    endfor
+    yi(idx) = extrapval;
+  endif
 endfunction
 
--- a/scripts/general/profshow.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/general/profshow.m	Fri Feb 06 08:31:49 2015 -0800
@@ -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/quadgk.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/general/quadgk.m	Fri Feb 06 08:31:49 2015 -0800
@@ -27,7 +27,7 @@
 ## using adaptive Gauss-Konrod quadrature.
 ## @var{f} is a function handle, inline function, or string
 ## containing the name of the function to evaluate.
-## The formulation is based on a proposal by L.F. Shampine,
+## The formulation is based on a proposal by @nospell{L.F. Shampine},
 ## @cite{"Vectorized adaptive quadrature in @sc{matlab}", Journal of
 ## Computational and Applied Mathematics, pp131-140, Vol 211, Issue 2,
 ## Feb 2008} where all function evaluations at an iteration are
--- a/scripts/general/quadl.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/general/quadl.m	Fri Feb 06 08:31:49 2015 -0800
@@ -45,7 +45,7 @@
 ## @var{f}.  To use default values for @var{tol} and @var{trace}, one may pass
 ## empty matrices ([]).
 ##
-## Reference: W. Gander and W. Gautschi, @cite{Adaptive Quadrature -
+## Reference: @nospell{W. Gander and W. Gautschi}, @cite{Adaptive Quadrature -
 ## Revisited}, BIT Vol. 40, No. 1, March 2000, pp. 84--101.
 ## @url{http://www.inf.ethz.ch/personal/gander/}
 ## @seealso{quad, quadv, quadgk, quadcc, trapz, dblquad, triplequad}
--- a/scripts/general/rat.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/general/rat.m	Fri Feb 06 08:31:49 2015 -0800
@@ -142,7 +142,7 @@
       s_nc = columns (s);
       if (n_nc > s_nc)
         s(:,s_nc+1:n_nc) = " ";
-      elseif (s_nc > n_nc)
+      elseif (s_nc > n_nc && n_nc != 0)
         n(:,n_nc+1:s_nc) = " ";
       endif
       n = cat (1, n, s);
@@ -157,6 +157,9 @@
 %! assert (n, [1, 3, 1]);
 %! assert (d, [2, 10, 3]);
 
+## bug #43374
+%!assert (eval (rat (0.75)), [0.75])
+
 %!error rat ();
 %!error rat (1, 2, 3);
 
--- a/scripts/general/repmat.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/general/repmat.m	Fri Feb 06 08:31:49 2015 -0800
@@ -1,3 +1,4 @@
+## Copyright (C) 2014 Markus Bergholz
 ## Copyright (C) 2000-2013 Paul Kienzle
 ## Copyright (C) 2008 Jaroslav Hajek
 ##
@@ -20,6 +21,7 @@
 ## -*- texinfo -*-
 ## @deftypefn  {Function File} {} repmat (@var{A}, @var{m})
 ## @deftypefnx {Function File} {} repmat (@var{A}, @var{m}, @var{n})
+## @deftypefnx {Function File} {} repmat (@var{A}, @var{m}, @var{n}, @var{p} @dots{})
 ## @deftypefnx {Function File} {} repmat (@var{A}, [@var{m} @var{n}])
 ## @deftypefnx {Function File} {} repmat (@var{A}, [@var{m} @var{n} @var{p} @dots{}])
 ## Form a block matrix of size @var{m} by @var{n}, with a copy of matrix
@@ -33,13 +35,14 @@
 ## Author: Paul Kienzle <pkienzle@kienzle.powernet.co.uk>
 ## Created: July 2000
 
-function x = repmat (A, m, n)
+function x = repmat (A, m, varargin)
 
-  if (nargin < 2 || nargin > 3)
+  if (nargin < 2)
     print_usage ();
   endif
 
   if (nargin == 3)
+    n = varargin{1};
     if (! isempty (m) && isempty (n))
       m = m(:).';
       n = 1;
@@ -64,12 +67,20 @@
       n = n(:).';
     endif
   else
-    if (isempty (m))
+    if (nargin > 3)
+      # input check for m and varargin
+      if (isscalar (m) && all (cellfun ("numel", varargin) == 1))
+        m = [m varargin{:}];
+        n = [];
+      else
+        error ("repmat: all input arguments must be scalar");
+      end
+    elseif (isempty (m))
       m = n = 1;
     elseif (isscalar (m))
       n = m;
     elseif (ndims (m) > 2)
-      error ("repmat: M has more than 2 dimensions")
+      error ("repmat: M has more than 2 dimensions");
     elseif (all (size (m) > 1))
       m = m(:,1).';
       n = [];
@@ -81,7 +92,7 @@
   idx = [m, n];
 
   if (all (idx < 0))
-    error ("repmat: invalid dimensions")
+    error ("repmat: invalid dimensions");
   else
     idx = max (idx, 0);
   endif
@@ -150,6 +161,7 @@
 %!assert (repmat (x, [1 3]), repmat (x, 1, 3))
 %!assert (repmat (x, [3 1]), repmat (x, 3, 1))
 %!assert (repmat (x, [3 3]), repmat (x, 3, 3))
+%!assert (repmat (pi, [1,2,3,4]), repmat (pi, 1,2,3,4))
 
 # Tests for numel==1 case:
 %!shared x, r
--- a/scripts/general/rot90.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/general/rot90.m	Fri Feb 06 08:31:49 2015 -0800
@@ -19,6 +19,8 @@
 ## -*- texinfo -*-
 ## @deftypefn  {Function File} {} rot90 (@var{A})
 ## @deftypefnx {Function File} {} rot90 (@var{A}, @var{k})
+## Rotate array by 90 degree increments.
+##
 ## Return a copy of @var{A} with the elements rotated counterclockwise in
 ## 90-degree increments.  The second argument is optional, and specifies
 ## how many 90-degree rotations are to be applied (the default value is 1).
@@ -45,9 +47,11 @@
 ## @end group
 ## @end example
 ##
-## Note that @code{rot90} only works with 2-D arrays.  To rotate N-D arrays
-## use @code{rotdim} instead.
-## @seealso{rotdim, flipud, fliplr, flipdim}
+## The rotation is always performed on the plane of the first two dimensions,
+## i.e., rows and columns.  To perform a rotation on any other plane, use
+## @code{rotdim}.
+##
+## @seealso{rotdim, fliplr, flipud, flip}
 ## @end deftypefn
 
 ## Author: jwe
@@ -58,22 +62,24 @@
     print_usage ();
   endif
 
-  if (ndims (A) > 2)
-    error ("rot90: A must be a 2-D array");
-  elseif (! (isscalar (k) && isreal (k) && k == fix (k)))
+  if (! (isscalar (k) && isreal (k) && k == fix (k)))
     error ("rot90: K must be a single real integer");
   endif
 
   k = mod (k, 4);
+  nd = ndims (A);
 
   if (k == 0)
     B = A;
   elseif (k == 1)
-    B = flipud (A.');
+    B = flipud (permute (A, [2 1 3:1:nd]));
   elseif (k == 2)
-    B = flipud (fliplr (A));
+    idx(1:nd) = {':'};
+    idx{1} = rows (A):-1:1;
+    idx{2} = columns (A):-1:1;
+    B = A(idx{:});
   elseif (k == 3)
-    B = (flipud (A)).';
+    B = permute (flipud (A), [2 1 3:1:nd]);
   else
     error ("rot90: internal error!");
   endif
@@ -94,6 +100,38 @@
 %! assert (rot90 (x1, 5), x2);
 %! assert (rot90 (x1, -1), x4);
 
+## Test NDArrays
+%!test
+%! a(1:2,1:2,1) = [1 2; 3 4];
+%! a(1:2,1:2,2) = [5 6; 7 8];
+%! b(1:2,1:2,1) = [2 4; 1 3];
+%! b(1:2,1:2,2) = [6 8; 5 7];
+%! assert (rot90 (a, 1), b)
+%! assert (rot90 (a, 2), rot90 (b, 1))
+%! assert (rot90 (a, 3), rot90 (b, 2))
+
+%!test
+%! a = b = zeros (2, 2, 1, 2);
+%! a(1:2,1:2,:,1) = [1 2; 3 4];
+%! a(1:2,1:2,:,2) = [5 6; 7 8];
+%! b(1:2,1:2,:,1) = [2 4; 1 3];
+%! b(1:2,1:2,:,2) = [6 8; 5 7];
+%! assert (rot90 (a, 1), b)
+%! assert (rot90 (a, 2), rot90 (b, 1))
+%! assert (rot90 (a, 3), rot90 (b, 2))
+
+## With non-square matrices
+%!test
+%! a = zeros (3, 2, 1, 2);
+%! b = zeros (2, 3, 1, 2);
+%! a(1:2,1:3,:,1) = [ 1  2  3;  4  5  6];
+%! a(1:2,1:3,:,2) = [ 7  8  9; 10 11 12];
+%! b(1:3,1:2,:,1) = [ 3  6;  2  5;  1  4];
+%! b(1:3,1:2,:,2) = [ 9 12;  8 11;  7 10];
+%! assert (rot90 (a, 1), b)
+%! assert (rot90 (a, 2), rot90 (b, 1))
+%! assert (rot90 (a, 3), rot90 (b, 2))
+
 %% Test input validation
 %!error rot90 ()
 %!error rot90 (1, 2, 3)
--- a/scripts/general/rotdim.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/general/rotdim.m	Fri Feb 06 08:31:49 2015 -0800
@@ -51,7 +51,7 @@
 ## rotdim ([1, 2; 3, 4], 7, [1, 2])
 ## @end group
 ## @end example
-## @seealso{rot90, flipud, fliplr, flipdim}
+## @seealso{rot90, fliplr, flipud, flip}
 ## @end deftypefn
 
 function y = rotdim (x, n, plane)
@@ -107,16 +107,16 @@
   if (n == 0)
     y = x;
   elseif (n == 2)
-    y = flipdim (flipdim (x, plane(1)), plane(2));
+    y = flip (flip (x, plane(1)), plane(2));
   elseif (n == 1 || n == 3)
     perm = 1:nd;
     perm(plane(1)) = plane(2);
     perm(plane(2)) = plane(1);
     y = permute (x, perm);
     if (n == 1)
-      y = flipdim (y, min (plane));
+      y = flip (y, min (plane));
     else
-      y = flipdim (y, max (plane));
+      y = flip (y, max (plane));
     endif
   else
     error ("rotdim: internal error!");
@@ -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)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/general/validateattributes.m	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,432 @@
+## Copyright (C) 2013 Carnë Draug
+##
+## 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} {} validateattributes (@var{A}, @var{classes}, @var{attributes})
+## @deftypefnx {Function File} {} validateattributes (@var{A}, @var{classes}, @var{attributes}, @var{arg_idx})
+## @deftypefnx {Function File} {} validateattributes (@var{A}, @var{classes}, @var{attributes}, @var{func_name})
+## @deftypefnx {Function File} {} validateattributes (@var{A}, @var{classes}, @var{attributes}, @var{func_name}, @var{arg_name})
+## @deftypefnx {Function File} {} validateattributes (@var{A}, @var{classes}, @var{attributes}, @var{func_name}, @var{arg_name}, @var{arg_idx})
+## Check validity of input argument.
+##
+## Confirms that the argument @var{A} is valid by belonging to one of
+## @var{classes}, and holding all of the @var{attributes}.  If it does not,
+## an error is thrown, with a message formatted accordingly.  The error
+## message can be made further complete by the function name @var{fun_name},
+## the argument name @var{arg_name}, and its position in the input
+## @var{arg_idx}.
+##
+## @var{classes} must be a cell array of strings (an empty cell array is
+## allowed) with the name of classes (remember that a class name is case
+## sensitive).  In addition to the class name, the following categories
+## names are also valid:
+##
+## @table @asis
+## @item @qcode{"float"}
+## Floating point value comprising classes @qcode{"double"} and
+## @qcode{"single"}.
+##
+## @item @qcode{"integer"}
+## Integer value comprising classes (u)int8, (u)int16, (u)int32, (u)int64.
+##
+## @item @qcode{"numeric"}
+## Numeric value comprising either a floating point or integer value.
+##
+## @end table
+##
+## @var{attributes} must be a cell array with names of checks for @var{A}.
+## Some of them require an additional value to be supplied right after the
+## name (see details for each below).
+##
+## @table @asis
+## @item @qcode{"<="}
+## All values are less than or equal to the following value in @var{attributes}.
+##
+## @item @qcode{"<"}
+## All values are less than the following value in @var{attributes}.
+##
+## @item @qcode{">="}
+## All values are greater than or equal to the following value in
+## @var{attributes}.
+##
+## @item @qcode{">"}
+## All values are greater than the following value in @var{attributes}.
+##
+## @item @qcode{"2d"}
+## A 2-dimensional matrix.  Note that vectors and empty matrices have
+## 2 dimensions, one of them being of length 1, or both length 0.
+##
+## @item @qcode{"3d"}
+## Has no more than 3 dimensions.  A 2-dimensional matrix is a 3-D matrix
+## whose 3rd dimension is of length 1.
+##
+## @item @qcode{"binary"}
+## All values are either 1 or 0.
+##
+## @item @qcode{"column"}
+## Values are arranged in a single column.
+##
+## @item @qcode{"decreasing"}
+## No value is @var{NaN}, and each is less than the preceding one.
+##
+## @item @qcode{"even"}
+## All values are even numbers.
+##
+## @item @qcode{"finite"}
+## All values are finite.
+##
+## @item @qcode{"increasing"}
+## No value is @var{NaN}, and each is greater than the preceding one.
+##
+## @item @qcode{"integer"}
+## All values are integer.  This is different than using @code{isinteger}
+## which only checks its an integer type.  This checks that each value in
+## @var{A} is an integer value, i.e., it has no decimal part.
+##
+## @item @qcode{"ncols"}
+## Has exactly as many columns as the next value in @var{attributes}.
+##
+## @item @qcode{"ndims"}
+## Has exactly as many dimensions as the next value in @var{attributes}.
+##
+## @item @qcode{"nondecreasing"}
+## No value is @var{NaN}, and each is greater than or equal to the preceding
+## one.
+##
+## @item @qcode{"nonempty"}
+## It is not empty.
+##
+## @item @qcode{"nonincreasing"}
+## No value is @var{NaN}, and each is less than or equal to the preceding one.
+##
+## @item @qcode{"nonnan"}
+## No value is a @code{NaN}.
+##
+## @item @qcode{"non-negative"}
+## All values are non negative.
+##
+## @item @qcode{"nonsparse"}
+## It is not a sparse matrix.
+##
+## @item @qcode{"nonzero"}
+## No value is zero.
+##
+## @item @qcode{"nrows"}
+## Has exactly as many rows as the next value in @var{attributes}.
+##
+## @item @qcode{"numel"}
+## Has exactly as many elements as the next value in @var{attributes}.
+##
+## @item @qcode{"odd"}
+## All values are odd numbers.
+##
+## @item @qcode{"positive"}
+## All values are positive.
+##
+## @item @qcode{"real"}
+## It is a non-complex matrix.
+##
+## @item @qcode{"row"}
+## Values are arranged in a single row.
+##
+## @item @qcode{"scalar"}
+## It is a scalar.
+##
+## @item @qcode{"size"}
+## Its size has length equal to the values of the next in @var{attributes}.
+## The next value must is an array with the length for each dimension.  To
+## ignore the check for a certain dimension, the value of @code{NaN} can be
+## used.
+##
+## @item @qcode{"square"}
+## Is a square matrix.
+##
+## @item @qcode{"vector"}
+## Values are arranged in a single vector (column or vector).
+##
+## @end table
+##
+## @seealso{isa, validatestring, inputParser}
+## @end deftypefn
+
+function validateattributes (A, cls, attr, varargin)
+  if (nargin < 3 || nargin > 6)
+    print_usage ();
+  elseif (! iscellstr (cls))
+    error ("validateattributes: CLASSES must be a cell array of strings");
+  elseif (! iscell (attr))
+    error ("validateattributes: ATTRIBUTES must be a cell array");
+  endif
+
+  ## Built start of error message from the extra optional arguments
+  func_name = "";
+  var_name  = "input";
+  if (nargin > 3)
+    fourth = varargin{1};
+    if (ischar (fourth))
+      func_name = [fourth ": "];
+    elseif (nargin == 4 && valid_arg_idx (fourth))
+      var_name = sprintf ("input %d", fourth);
+    else
+      error ("validateattributes: 4th input argument must be ARG_IDX or FUNC_NAME");
+    endif
+
+    if (nargin > 4)
+      var_name = varargin{2};
+      if (! ischar (var_name))
+        error ("validateattributes: VAR_NAME must be a string");
+      endif
+
+      if (nargin > 5)
+        arg_idx = varargin{3};
+        if (! valid_arg_idx (arg_idx))
+          error ("validateattributes: ARG_IDX must be a positive integer");
+        endif
+        var_name = sprintf ("%s (argument #%i)", var_name, arg_idx);
+      endif
+    endif
+  endif
+  err_ini = [func_name var_name];
+
+  check_cl = isa (A, cls);
+  if (! isempty (check_cl) && ! any (check_cl))
+    ## Allowing for an empty list of classes is Matlab incompatible but
+    ## that should count as a just a Matlab bug, not an incompatibility.
+
+    ## Replace the category names with the classes that belong to it.
+    integer = { "int8"  "int16"  "int32"  "int64" ...
+               "uint8" "uint16" "uint32" "uint64"};
+    float   = {"single" "double"};
+    numeric = {integer{:} float{:}};
+    cls = replace_cl_group (cls, "integer", integer);
+    cls = replace_cl_group (cls, "float",   float  );
+    cls = replace_cl_group (cls, "numeric", numeric);
+    cls = unique (cls);
+
+    classes = sprintf (" %s", cls{:});
+    error ("%s must be of class:\n\n %s\n\nbut was of class %s",
+           err_ini, classes, class (A));
+  endif
+
+  ## We use a while loop because some attributes require the following value
+  ## in the cell array. Also, we can't just get the boolean value for the
+  ## test and check at the end the error message since some of the tests
+  ## require some more complex error message.
+
+  ## It may look like that we don't perform enough input check in this
+  ## function (e.g., we don't check if there's a value after the size
+  ## attribute). The reasoning is that this will be a function mostly used
+  ## by developers with fairly static input so any problem would be caught
+  ## immediately during that functino development, it's no dependent on the
+  ## final user input. In addition, it can be called so many times at the
+  ## start of every function, we want it to run specially fast.
+  idx = 1;
+  problem = false; # becomes true when one of the tests fails
+  while (idx <= numel (attr))
+    ## TODO: once we use this in Octave core, it might be worthy to find
+    ## which attributes are checked more often, and place them in that
+    ## order inside the switch block.
+    switch (tolower (attr{idx++}))
+      case "2d",            problem = ndims (A) != 2;
+      case "3d",            problem = ndims (A) > 3;
+      case "column",        problem = ! iscolumn (A);
+      case "row",           problem = ! isrow (A);
+      case "scalar",        problem = ! isscalar (A);
+      case "vector",        problem = ! isvector (A);
+      case "square",        problem = ! issquare (A);
+      case "nonempty",      problem = isempty (A);
+      case "nonsparse",     problem = issparse (A);
+      case "binary",        problem = ! islogical (A) && ...
+                                      any ((A(:) != 1) & (A(:) != 0));
+      case "even",          problem = any (rem (A(:), 2) != 0);
+      case "odd",           problem = any (mod (A(:), 2) != 1);
+      case "integer",       problem = ! isinteger (A) && ...
+                                      any (ceil (A(:)) != A(:));
+      case "real",          problem = ! isreal (A);
+      case "finite",        problem = ! isinteger (A) && ...
+                                      ! all (isfinite (A(:)));
+      case "nonnan",        problem = ! isinteger (A) && ...
+                                      any (isnan (A(:)));
+      case "nonnegative",   problem = any (A(:) < 0);
+      case "nonzero",       problem = any (A(:) == 0);
+      case "positive",      problem = any (A(:) <= 0);
+      case "decreasing",    problem = (any (isnan (A(:))) ||
+                                       any (diff (A(:)) >= 0));
+      case "increasing",    problem = (any (isnan (A(:))) ||
+                                       any (diff (A(:)) <= 0));
+      case "nondecreasing", problem = (any (isnan (A(:))) ||
+                                       any (diff (A(:)) <  0));
+      case "nonincreasing", problem = (any (isnan (A(:))) ||
+                                       any (diff (A(:)) >  0));
+      case "size",
+        A_size = size (A);
+        w_size = attr{idx++};
+        A_size(isnan (w_size)) = NaN;
+        if (! isequaln (A_size, w_size))
+          A_size_str = sprintf ("%dx", size (A))(1:end-1);
+          w_size_str = sprintf ("%ix", w_size)(1:end-1);
+          w_size_str = strrep (w_size_str, "NaN", "N");
+          error ("%s must be of size %s but was %s", err_ini, w_size_str, A_size_str);
+        endif
+      case "numel",
+        if (numel (A) != attr{idx++})
+          error ("%s must have %d elements", err_ini, attr{idx-1});
+        endif
+      case "ncols",
+        if (columns (A) != attr{idx++})
+          error ("%s must have %d columns", err_ini, attr{idx-1});
+        endif
+      case "nrows",
+        if (rows (A) != attr{idx++})
+          error ("%s must have %d rows", err_ini, attr{idx-1});
+        endif
+      case "ndims",
+        ## Note that a [4 5 1] matrix is not considered to have ndims == 3
+        ## but is ok for "3d". This is not a bug.
+        if (ndims (A) != attr{idx++})
+          error ("%s must have %d dimensions", err_ini, attr{idx-1});
+        endif
+      case ">"
+        if (! all (A(:) > attr{idx++}))
+          error ("%s must be greater than %f", err_ini, attr{idx-1});
+        endif
+      case ">="
+        if (! all (A(:) >= attr{idx++}))
+          error ("%s must be greater than or equal to %f", err_ini, attr{idx-1});
+        endif
+      case "<"
+        if (! all (A(:) < attr{idx++}))
+          error ("%s must be less than %f", err_ini, attr{idx-1});
+        endif
+      case "<="
+        if (! all (A(:) <= attr{idx++}))
+          error ("%s must be less than or equal to %f", err_ini, attr{idx-1});
+        endif
+      otherwise
+        error ("validateattributes: unknown ATTRIBUTE %s", attr{idx-1});
+    endswitch
+    if (problem)
+      error ("%s must be %s", err_ini, attr{idx-1});
+    endif
+  endwhile
+endfunction
+
+function retval = valid_arg_idx (arg)
+  retval = isnumeric (arg) && isscalar (arg) && arg > 0 && ceil (arg) == arg;
+endfunction
+
+function cls = replace_cl_group (cls, name, group)
+  num_pos = strcmpi (cls, name);
+  if (any (num_pos))
+    cls(num_pos) = [];
+    cls(end+1:end+numel(group)) = group;
+  endif
+endfunction
+
+%!error <double> validateattributes (rand (5), {"uint8"}, {})
+%!error <single> validateattributes (uint8 (rand (5)), {"float"}, {})
+%!error <2d> validateattributes (rand (5, 5, 5), {}, {"2d"})
+%!error <3d> validateattributes (rand (5, 5, 5, 7), {}, {"3d"})
+%!error <column> validateattributes (rand (5, 5), {}, {"column"})
+%!error <column> validateattributes (rand (1, 5), {}, {"column"})
+%!error <row> validateattributes (rand (5, 5), {}, {"row"})
+%!error <row> validateattributes (rand (5, 1), {}, {"row"})
+%!error <scalar> validateattributes (rand (1, 5), {}, {"scalar"})
+%!error <vector> validateattributes (rand (5), {}, {"vector"})
+%!error <square> validateattributes (rand (5, 6), {}, {"square"})
+%!error <nonempty> validateattributes ([], {}, {"nonempty"})
+%!error <nonsparse> validateattributes (sparse(rand(5)), {}, {"nonsparse"})
+%!error <binary> validateattributes ("text", {}, {"binary"})
+%!error <binary> validateattributes ([0 1 0 3 0], {}, {"binary"})
+%!error <even> validateattributes ([2 3 6 8], {}, {"even"})
+%!error <even> validateattributes ([2 NaN], {}, {"even"})
+%!error <odd> validateattributes ([3 4 7 5], {}, {"odd"})
+%!error <odd> validateattributes ([5 NaN], {}, {"odd"})
+%!error <integer> validateattributes ([5 5.2 5.7], {}, {"integer"})
+%!error <real> validateattributes ([5i 8 9], {}, {"real"})
+%!error <finite> validateattributes ([5i Inf 8], {}, {"finite"})
+%!error <nonnan> validateattributes ([NaN Inf 8], {}, {"nonnan"})
+%!error <nonnegative> validateattributes ([7 8 -9], {}, {"nonnegative"})
+%!error <nonzero> validateattributes ([7 8 0], {}, {"nonzero"})
+%!error <positive> validateattributes ([7 0 8], {}, {"positive"})
+%!error <decreasing> validateattributes ([7 8 4 3 -5], {}, {"decreasing"})
+%!error <decreasing> validateattributes ([7 NaN 4 3 -5], {}, {"decreasing"})
+%!error <increasing> validateattributes ([7 8 4 9 20], {}, {"increasing"})
+%!error <increasing> validateattributes ([7 8 NaN 9 20], {}, {"increasing"})
+%!error <nonincreasing> validateattributes ([7 8 4 9 20], {}, {"nonincreasing"})
+%!error <nonincreasing> validateattributes ([7 8 NaN 9 20], {}, {"nonincreasing"})
+%!error <nondecreasing> validateattributes ([7 8 4 3 -5], {}, {"nondecreasing"})
+%!error <nondecreasing> validateattributes ([7 NaN 4 3 -5], {}, {"nondecreasing"})
+%!error <size> validateattributes (ones (5, 3, 6), {}, {"size", [5 4 7]})
+%!error <size> validateattributes (ones (5, 3, 6), {}, {"size", [5 NaN 7]})
+%!error <size> validateattributes (ones (5, 3, 6), {}, {"size", [5 3 6 2]})
+%!error <elements> validateattributes (ones (6, 3), {}, {"numel", 12})
+%!error <columns> validateattributes (ones (6, 2), {}, {"ncols", 3})
+%!error <rows> validateattributes (ones (6, 2), {}, {"nrows", 3})
+%!error <dimensions> validateattributes (ones (6, 2, 6, 3), {}, {"ndims", 3})
+%!error <greater than> validateattributes ([6 7 8 5], {}, {">", 5})
+%!error <greater than> validateattributes ([6 7 8 5], {}, {">=", 6})
+%!error <less than> validateattributes ([6 7 8 5], {}, {"<", 8})
+%!error <less than> validateattributes ([6 7 8 5], {}, {"<=", 7})
+
+%!test
+%! validateattributes (rand (5), {"numeric"}, {})
+%! validateattributes (rand (5), {"float"}, {})
+%! validateattributes (rand (5), {"double"}, {})
+%! validateattributes ("text", {"char"}, {})
+%! validateattributes (rand (5), {}, {"2d"})
+%! validateattributes (rand (5), {}, {"3d"})
+%! validateattributes (rand (5, 5, 5), {}, {"3d"})
+%! validateattributes (rand (5, 1), {}, {"column"})
+%! validateattributes (rand (1, 5), {}, {"row"})
+%! validateattributes ("a", {}, {"scalar"})
+%! validateattributes (5, {}, {"scalar"})
+%! validateattributes (rand (1, 5), {}, {"vector"})
+%! validateattributes (rand (5, 1), {}, {"vector"})
+%! validateattributes (rand (5), {}, {"square"})
+%! validateattributes (rand (5), {}, {"nonempty"})
+%! validateattributes (rand (5), {}, {"nonsparse"})
+%! validateattributes ([0 1 0 1 0], {}, {"binary"})
+%! validateattributes (rand (5) > 0.5, {}, {"binary"})
+%! validateattributes ([8 4 0 6], {}, {"even"})
+%! validateattributes ([-1 3 5], {}, {"odd"})
+%! validateattributes ([8 4 0 6], {}, {"real"})
+%! validateattributes ([8 4i 0 6], {}, {"finite"})
+%! validateattributes (uint8 ([8 4]), {}, {"finite"})
+%! validateattributes ([8 Inf], {}, {"nonnan"})
+%! validateattributes ([0 7 4], {}, {"nonnegative"})
+%! validateattributes ([-8 7 4], {}, {"nonzero"})
+%! validateattributes ([8 7 4], {}, {"positive"})
+%! validateattributes ([8 7 4 -5], {}, {"decreasing"})
+%! validateattributes ([-8 -7 4 5], {}, {"increasing"})
+%! validateattributes ([8 4 4 -5], {}, {"nonincreasing"})
+%! validateattributes ([-8 -8 4 5], {}, {"nondecreasing"})
+%! validateattributes (rand (4, 6, 7, 2), {}, {"size", [4 6 7 2]})
+%! validateattributes (rand (4, 6, 7, 2), {}, {"size", [4 NaN 7 2]})
+%! validateattributes (rand (4, 6, 7, 2), {}, {"size", [4 6 NaN 2 NaN]})
+%! validateattributes (rand (6, 2), {}, {"numel", 12})
+%! validateattributes (rand (6, 2), {}, {"ncols", 2})
+%! validateattributes (rand (6, 2), {}, {"nrows", 6})
+%! validateattributes (rand (6, 2, 4, 5), {}, {"ndims", 4})
+%! validateattributes ([4 5 6 7], {}, {">", 3})
+%! validateattributes ([4 5 6 7], {}, {">=", 4})
+%! validateattributes ([4 5 6 7], {}, {"<", 8})
+%! validateattributes ([4 5 6 7], {}, {"<=", 7})
+
+%!test
+%! validateattributes ([0 1 0 1], {"double", "uint8"}, {"binary", "size", [NaN 4], "nonnan"})
--- a/scripts/geometry/delaunay.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/geometry/delaunay.m	Fri Feb 06 08:31:49 2015 -0800
@@ -17,22 +17,32 @@
 ## <http://www.gnu.org/licenses/>.
 
 ## -*- texinfo -*-
-## @deftypefn  {Function File} {} delaunay (@var{x}, @var{y})
-## @deftypefnx {Function File} {} delaunay (@var{x})
-## @deftypefnx {Function File} {} delaunay (@dots{}, @var{options})
-## @deftypefnx {Function File} {@var{tri} =} delaunay (@dots{})
-## Compute the Delaunay triangulation for a 2-D set of points.
-## The return value @var{tri} is a set of triangles which satisfies the
-## Delaunay circum-circle criterion, i.e., only a single data point from
-## [@var{x}, @var{y}] is within the circum-circle of the defining triangle.
-## The input @var{x} may also be a matrix with two columns where the first
-## column contains x-data and the second y-data.
+## @deftypefn  {Function File} {@var{tri} =} delaunay (@var{x}, @var{y})
+## @deftypefnx {Function File} {@var{tetr} =} delaunay (@var{x}, @var{y}, @var{z})
+## @deftypefnx {Function File} {@var{tri} =} delaunay (@var{x})
+## @deftypefnx {Function File} {@var{tri} =} delaunay (@dots{}, @var{options})
+## Compute the Delaunay triangulation for a 2-D or 3-D set of points.
 ##
-## The set of triangles @var{tri} is a matrix of size [n, 3].  Each
-## row defines a triangle and the three columns are the three vertices
-## of the triangle.  The value of @code{@var{tri}(i,j)} is an index into
-## @var{x} and @var{y} for the location of the j-th vertex of the i-th
-## triangle.
+## For 2-D sets, the return value @var{tri} is a set of triangles which
+## satisfies the Delaunay circum-circle criterion, i.e., only a single data
+## point from [@var{x}, @var{y}] is within the circum-circle of the defining
+## triangle.  The set of triangles @var{tri} is a matrix of size [n, 3].  Each
+## row defines a triangle and the three columns are the three vertices of the
+## triangle.  The value of @code{@var{tri}(i,j)} is an index into @var{x} and
+## @var{y} for the location of the j-th vertex of the i-th triangle.
+##
+## For 3-D sets, the return value @var{tetr} is a set of tetrahedrons which
+## satisfies the Delaunay circum-circle criterion, i.e., only a single data
+## point from [@var{x}, @var{y}, @var{z}] is within the circum-circle of the
+## defining tetrahedron.  The set of tetrahedrons is a matrix of size [n, 4].
+## Each row defines a tetrahedron and the four columns are the four vertices of
+## the tetrahedron.  The value of @code{@var{tetr}(i,j)} is an index into
+## @var{x}, @var{y}, @var{z} for the location of the j-th vertex of the i-th
+## tetrahedron.
+##
+## The input @var{x} may also be a matrix with two or three columns where the
+## first column contains x-data, the second y-data, and the optional third
+## column contains z-data.
 ##
 ## The optional last argument, which must be a string or cell array of strings,
 ## contains options passed to the underlying qhull command.
@@ -45,63 +55,84 @@
 ## To append user options to the defaults it is necessary to repeat the
 ## default arguments in @var{options}.  Use a null string to pass no arguments.
 ##
-## If no output argument is specified the resulting Delaunay triangulation
-## is plotted along with the original set of points.
-##
 ## @example
 ## @group
 ## x = rand (1, 10);
 ## y = rand (1, 10);
-## T = delaunay (x, y);
-## VX = [ x(T(:,1)); x(T(:,2)); x(T(:,3)); x(T(:,1)) ];
-## VY = [ y(T(:,1)); y(T(:,2)); y(T(:,3)); y(T(:,1)) ];
+## tri = delaunay (x, y);
+## triplot (tri, x, y);
+## hold on;
+## plot (x, y, "r*");
 ## axis ([0,1,0,1]);
-## plot (VX, VY, "b", x, y, "r*");
 ## @end group
 ## @end example
-## @seealso{delaunay3, delaunayn, convhull, voronoi, triplot, trimesh, trisurf}
+## @seealso{delaunayn, convhull, voronoi, triplot, trimesh, tetramesh, trisurf}
 ## @end deftypefn
 
 ## Author: Kai Habel <kai.habel@gmx.de>
 
 function tri = delaunay (varargin)
 
-  if (nargin < 1 || nargin > 3)
+  if (nargin < 1 || nargin > 4)
     print_usage ();
   endif
 
+  z = [];
   options = [];
 
   switch (nargin)
 
     case 1
-      if (! ismatrix (varargin{1}) || columns (varargin{1}) != 2)
-          error ("delaunay: X must be a matrix with 2 columns");
+      if (! ismatrix (varargin{1})
+          || (columns (varargin{1}) != 2 && columns (varargin{1}) != 3))
+          error ("delaunay: X must be a matrix with 2 or 3 columns");
       else
         x = varargin{1}(:,1);
         y = varargin{1}(:,2);
+        if (columns (varargin{1}) == 3)
+          z = varargin{1}(:,3);
+        endif
       endif
 
     case 2
       if (isnumeric (varargin{2}))
         x = varargin{1};
         y = varargin{2};
-      elseif (ischar (varargin{2}) || iscellstr (varargin{2}))
+      elseif (! (ischar (varargin{2}) || iscellstr (varargin{2})))
+        error ("delaunay: OPTIONS must be a string or cell array of strings");
+      else
         options = varargin{2};
-        if (! ismatrix (varargin{1}) && columns (varargin{1}) != 2)
-            error ("delaunay: X must be a matrix with 2 columns");
+        ncols = columns (varargin{1});
+
+        if (! ismatrix (varargin{1}) || (ncols != 2 && ncols != 3))
+          error ("delaunay: X must be a matrix with 2 or 3 columns");
         else
           x = varargin{1}(:,1);
           y = varargin{1}(:,2);
+          if (ncols == 3)
+            z = varargin{1}(:,3);
+          endif
         endif
-      else
-        error ("delaunay: OPTIONS must be a string or cell array of strings");
       endif
 
     case 3
+      if (isnumeric (varargin{3}))
+        x = varargin{1};
+        y = varargin{2};
+        z = varargin{3};
+      elseif (! (ischar (varargin{3}) || iscellstr (varargin{3})))
+        error ("delaunay: OPTIONS must be a string or cell array of strings");
+      else
+        x = varargin{1};
+        y = varargin{2};
+        options = varargin{3};
+      endif
+
+    case 4
       x = varargin{1};
       y = varargin{2};
-      options = varargin{3};
+      z = varargin{3};
+      options = varargin{4};
 
       if (! (ischar (options) || iscellstr (options)))
         error ("delaunay: OPTIONS must be a string or cell array of strings");
@@ -109,20 +140,16 @@
 
   endswitch
 
-  if (! (isequal(size(x),size(y))))
-    error ("delaunay: X and Y must be the same size");
-  endif
-
-  T = delaunayn ([x(:), y(:)], options);
-
-  if (nargout == 0)
-    x = x(:).';
-    y = y(:).';
-    VX = [ x(T(:,1)); x(T(:,2)); x(T(:,3)); x(T(:,1)) ];
-    VY = [ y(T(:,1)); y(T(:,2)); y(T(:,3)); y(T(:,1)) ];
-    plot (VX, VY, "b", x, y, "r*");
+  if (isempty (z))
+    if (! size_equal (x, y))
+      error ("delaunay: X and Y must be the same size");
+    endif
+    tri = delaunayn ([x(:), y(:)], options);
   else
-    tri = T;
+    if (! size_equal (x, y, z))
+      error ("delaunay: X, Y, and Z must be the same size");
+    endif
+    tri = delaunayn ([x(:), y(:), z(:)], options);
   endif
 
 endfunction
@@ -134,11 +161,11 @@
 %! rand ("state", 1);
 %! x = rand (1,10);
 %! y = rand (1,10);
-%! T = delaunay (x,y);
-%! VX = [ x(T(:,1)); x(T(:,2)); x(T(:,3)); x(T(:,1)) ];
-%! VY = [ y(T(:,1)); y(T(:,2)); y(T(:,3)); y(T(:,1)) ];
+%! tri = delaunay (x,y);
 %! clf;
-%! plot (VX,VY,"b", x,y,"r*");
+%! triplot (tri, x, y);
+%! hold on;
+%! plot (x, y, "r*");
 %! axis ([0,1,0,1]);
 
 %!testif HAVE_QHULL
@@ -165,5 +192,19 @@
 %! y = [5 7 8; 1 2 3];
 %! assert (sortrows (sort (delaunay (x, y), 2)), [1,2,4;1,3,4;1,3,5;3,4,6]);
 
-%% FIXME: Need input validation tests
+## Test 3-D input
+%!testif HAVE_QHULL
+%! x = [-1, -1, 1, 0, -1]; y = [-1, 1, 1, 0, -1]; z = [0, 0, 0, 1, 1];
+%! assert (sortrows (sort (delaunay (x, y, z), 2)), [1,2,3,4;1,2,4,5])
 
+%% Input validation tests
+%!error delaunay ()
+%!error delaunay (1,2,3,4,5)
+%!error <X must be a matrix with 2 or 3 columns> delaunay (ones (2,4))
+%!error <OPTIONS must be a string or cell array> delaunay (ones (2,2), struct())
+%!error <X must be a matrix with 2 or 3 columns> delaunay (ones (2,4), "")
+%!error <OPTIONS must be a string or cell array> delaunay (ones (2,2), ones (2,2), struct())
+%!error <OPTIONS must be a string or cell array> delaunay (ones (2,2), ones (2,2), ones (2,2), struct())
+%!error <X and Y must be the same size> delaunay (1, [1 2])
+%!error <X, Y, and Z must be the same size> delaunay (1, [1 2], [1 2])
+
--- a/scripts/geometry/delaunay3.m	Fri Feb 06 08:31:09 2015 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,77 +0,0 @@
-## Copyright (C) 1999-2013 Kai Habel
-##
-## 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{tetr} =} delaunay3 (@var{x}, @var{y}, @var{z})
-## @deftypefnx {Function File} {@var{tetr} =} delaunay3 (@var{x}, @var{y}, @var{z}, @var{options})
-## Compute the Delaunay triangulation for a 3-D set of points.
-## The return value @var{tetr} is a set of tetrahedrons which satisfies the
-## Delaunay circum-circle criterion, i.e., only a single data point from
-## [@var{x}, @var{y}, @var{z}] is within the circum-circle of the defining
-## tetrahedron.
-##
-## The set of tetrahedrons @var{tetr} is a matrix of size [n, 4].  Each
-## row defines a tetrahedron and the four columns are the four vertices
-## of the tetrahedron.  The value of @code{@var{tetr}(i,j)} is an index into
-## @var{x}, @var{y}, @var{z} for the location of the j-th vertex of the i-th
-## tetrahedron.
-##
-## An optional fourth argument, which must be a string or cell array of strings,
-## contains options passed to the underlying qhull command.
-## See the documentation for the Qhull library for details
-## @url{http://www.qhull.org/html/qh-quick.htm#options}.
-## The default options are @code{@{"Qt", "Qbb", "Qc", "Qz"@}}.
-##
-## If @var{options} is not present or @code{[]} then the default arguments are
-## used.  Otherwise, @var{options} replaces the default argument list.
-## To append user options to the defaults it is necessary to repeat the
-## default arguments in @var{options}.  Use a null string to pass no arguments.
-##
-## @seealso{delaunay, delaunayn, convhull, voronoi, tetramesh}
-## @end deftypefn
-
-## Author: Kai Habel <kai.habel@gmx.de>
-
-function tetr = delaunay3 (x, y, z, options)
-
-  if (nargin < 3 || nargin > 4)
-    print_usage ();
-  endif
-
-  if (! (isvector (x) && isvector (y) && isvector (z)
-         && length (x) == length (y) && length (x) == length (z)))
-    error ("delaunay: X, Y, and Z must be the same size");
-  elseif (nargin == 4 && ! (ischar (options) || iscellstr (options)))
-    error ("delaunay3: OPTIONS must be a string or cell array of strings");
-  endif
-
-  if (nargin == 3)
-    tetr = delaunayn ([x(:), y(:), z(:)]);
-  else
-    tetr = delaunayn ([x(:), y(:), z(:)], options);
-  endif
-
-endfunction
-
-
-%!testif HAVE_QHULL
-%! x = [-1, -1, 1, 0, -1]; y = [-1, 1, 1, 0, -1]; z = [0, 0, 0, 1, 1];
-%! assert (sortrows (sort (delaunay3 (x, y, z), 2)), [1,2,3,4;1,2,4,5])
-
-%% FIXME: Need input validation tests
-
--- a/scripts/geometry/delaunayn.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/geometry/delaunayn.m	Fri Feb 06 08:31:49 2015 -0800
@@ -47,7 +47,7 @@
 ## To append user options to the defaults it is necessary to repeat the
 ## default arguments in @var{options}.  Use a null string to pass no arguments.
 ##
-## @seealso{delaunay, delaunay3, convhulln, voronoin, trimesh, tetramesh}
+## @seealso{delaunay, convhulln, voronoin, trimesh, tetramesh}
 ## @end deftypefn
 
 function T = delaunayn (pts, varargin)
@@ -59,9 +59,9 @@
   T = __delaunayn__ (pts, varargin{:});
 
   if (isa (pts, "single"))
-    myeps = eps ("single");
+    tol = 1e3 * eps ("single");
   else
-    myeps = eps;
+    tol = 1e3 * eps;
   endif
 
   ## Try to remove the zero volume simplices.  The volume of the i-th simplex is
@@ -75,10 +75,10 @@
   ## prod(1:n) is dropped.
   idx = [];
   [nt, n] = size (T);
-  ## FIXME: Vectorize this for loop or convert to delaunayn to .oct function
+  ## FIXME: Vectorize this for loop or convert delaunayn to .oct function
   for i = 1:nt
     X = pts(T(i,1:end-1),:) - pts(T(i,2:end),:);
-    if (abs (det (X)) / sqrt (sum (X .^ 2, 2)) < 1e3 * myeps)
+    if (abs (det (X)) / sqrt (sumsq (X, 2)) < tol)
       idx(end+1) = i;
     endif
   endfor
@@ -87,7 +87,17 @@
 endfunction
 
 
+%!testif HAVE_QHULL
+%! x = [-1, 0; 0, 1; 1, 0; 0, -1; 0, 0];
+%! assert (sortrows (sort (delaunayn (x), 2)), [1,2,5;1,4,5;2,3,5;3,4,5]);
+
+## Test 3-D input
+%!testif HAVE_QHULL
+%! x = [-1, -1, 1, 0, -1]; y = [-1, 1, 1, 0, -1]; z = [0, 0, 0, 1, 1];
+%! assert (sortrows (sort (delaunayn ([x(:) y(:) z(:)]), 2)), [1,2,3,4;1,2,4,5])
+
 %% FIXME: Need tests for delaunayn
 
-%% FIXME: Need input validation tests
+%% Input validation tests
+%!error delaunayn ()
 
--- a/scripts/geometry/module.mk	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/geometry/module.mk	Fri Feb 06 08:31:49 2015 -0800
@@ -2,7 +2,6 @@
 
 geometry_FCN_FILES = \
   geometry/convhull.m \
-  geometry/delaunay3.m \
   geometry/delaunayn.m \
   geometry/delaunay.m \
   geometry/dsearch.m \
--- a/scripts/geometry/voronoi.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/geometry/voronoi.m	Fri Feb 06 08:31:49 2015 -0800
@@ -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 Feb 06 08:31:09 2015 -0800
+++ b/scripts/gui/module.mk	Fri Feb 06 08:31:49 2015 -0800
@@ -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 \
--- a/scripts/gui/private/__file_filter__.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/gui/private/__file_filter__.m	Fri Feb 06 08:31:49 2015 -0800
@@ -53,7 +53,7 @@
     if (! strcmp (fname, "*"))
       defname = strcat (fname, fext);
     endif
-    if (length (fext) > 0)
+    if ((length (fext) > 0) && (! strcmp(fext, '.*')))
       fext = strcat ("*", fext);
       retval = {fext, __default_filtername__(fext)};
     endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/gui/private/__get_funcname__.m	Fri Feb 06 08:31:49 2015 -0800
@@ -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 Feb 06 08:31:09 2015 -0800
+++ b/scripts/gui/private/__is_function__.m	Fri Feb 06 08:31:49 2015 -0800
@@ -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 Feb 06 08:31:09 2015 -0800
+++ b/scripts/gui/uigetdir.m	Fri Feb 06 08:31:49 2015 -0800
@@ -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 Feb 06 08:31:09 2015 -0800
+++ b/scripts/gui/uigetfile.m	Fri Feb 06 08:31:49 2015 -0800
@@ -66,20 +66,7 @@
 
 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");
--- a/scripts/gui/uiputfile.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/gui/uiputfile.m	Fri Feb 06 08:31:49 2015 -0800
@@ -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 ();
@@ -125,6 +112,19 @@
     [retfile, retpath, retindex] = feval (funcname, outargs{:});
   endif
 
+  # add extension to the name it isnt already added
+
+  if ischar (retfile)
+    ext = outargs{1}{retindex};
+    ext = strrep (ext, '*', '');
+
+    if length (retfile) >= length (ext)
+      if ! strcmp (retfile(end-length (ext)+1:end), ext)
+        retfile = [retfile ext];
+      endif
+    endif
+  endif
+
 endfunction
 
 
--- a/scripts/gui/waitbar.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/gui/waitbar.m	Fri Feb 06 08:31:49 2015 -0800
@@ -106,7 +106,8 @@
     ## Save and restore current figure
     cf = get (0, "currentfigure");
 
-    hf = figure ("position", [250, 500, 400, 100],
+    hf = figure ("units", "pixels",
+                 "position", [250, 500, 400, 100],
                  "numbertitle", "off",
                  "menubar", "none", "toolbar", "none",
                  "integerhandle", "off",
--- a/scripts/help/__gripe_missing_component__.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/help/__gripe_missing_component__.m	Fri Feb 06 08:31:49 2015 -0800
@@ -17,7 +17,7 @@
 ## <http://www.gnu.org/licenses/>.
 
 ## -*- texinfo -*-
-## @deftypefn {Function File} __gripe_missing_component__ (@var{caller}, @var{component})
+## @deftypefn {Function File} {} __gripe_missing_component__ (@var{caller}, @var{component})
 ## Undocumented internal function.
 ## @end deftypefn
 
@@ -46,7 +46,7 @@
       case "octave-config"
         msg = "unable to find the octave-config command, Octave installation is incomplete";
       otherwise
-        msg = ["unable to find required Octave component \"" component "\""];
+        msg = ['unable to find required Octave component "' component '"'];
     endswitch
   endif
 
@@ -54,3 +54,14 @@
 
 endfunction
 
+
+## Some trivial testing
+%!error <abc: unable to find the Octave info manual> __gripe_missing_component__ ("abc", "info-file")
+%!error <abc: unable to find the octave executable> __gripe_missing_component__ ("abc", "octave")
+%!error <abc: unable to find the octave-config command> __gripe_missing_component__ ("abc", "octave-config")
+%!error <abc: unable to find required Octave component "xyz"> __gripe_missing_component__ ("abc", "xyz")
+
+%!error __gripe_missing_component__ ()
+%!error __gripe_missing_component__ ("fcn")
+%!error __gripe_missing_component__ ("fcn", 1 , 2)
+
--- a/scripts/help/__unimplemented__.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/help/__unimplemented__.m	Fri Feb 06 08:31:49 2015 -0800
@@ -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", ...
@@ -534,17 +534,14 @@
   "Tiff",
   "VideoReader",
   "VideoWriter",
+  "addCause",
+  "addcats",
   "align",
   "alim",
   "alpha",
   "alphamap",
   "annotation",
-  "audiodevinfo",
-  "audioinfo",
-  "audioplayer",
-  "audioread",
-  "audiorecorder",
-  "audiowrite",
+  "array2table",
   "bar3",
   "bar3h",
   "bench",
@@ -572,16 +569,19 @@
   "camup",
   "camva",
   "camzoom",
+  "categorical",
+  "categories",
   "cdf2rdf",
   "cdfepoch",
   "cdfinfo",
+  "cdflib",
   "cdfread",
   "cdfwrite",
+  "cell2table",
   "cellplot",
-  "checkin",
   "checkcode",
+  "checkin",
   "checkout",
-  "cholinc",
   "clearvars",
   "clipboard",
   "cmopts",
@@ -593,6 +593,8 @@
   "coneplot",
   "containers.Map",
   "contourslice",
+  "corrcoef",
+  "countcats",
   "createClassFromWsdl",
   "createSoapMessage",
   "customverctrl",
@@ -607,6 +609,7 @@
   "delaunayTriangulation",
   "depdir",
   "depfun",
+  "details",
   "deval",
   "dialog",
   "dither",
@@ -614,20 +617,24 @@
   "dragrect",
   "dynamicprops",
   "echodemo",
+  "empty",
+  "enumeration",
   "evalc",
+  "events",
   "export2wsdlg",
   "figurepalette",
   "filebrowser",
   "fill3",
+  "findprop",
   "fitsdisp",
   "fitsinfo",
   "fitsread",
   "fitswrite",
   "flow",
-  "frame2im",
   "freqspace",
   "funm",
   "gammaincinv",
+  "getReport",
   "getframe",
   "getpixelposition",
   "gobjects",
@@ -635,10 +642,7 @@
   "graymon",
   "griddedInterpolant",
   "gsvd",
-  "guidata",
   "guide",
-  "guihandles",
-  "handle",
   "h5create",
   "h5disp",
   "h5info",
@@ -646,35 +650,39 @@
   "h5readatt",
   "h5write",
   "h5writeatt",
+  "handle",
   "hdfinfo",
   "hdfread",
+  "height",
   "hgexport",
-  "hgload",
-  "hgsave",
   "hgsetget",
   "hgtransform",
-  "ichol",
-  "ilu",
-  "im2frame",
   "im2java",
   "imapprox",
   "import",
   "inmem",
-  "inputParser",
+  "innerjoin",
   "inspect",
-  "instrcallback",
-  "instrfind",
-  "instrfindall",
   "integral",
   "integral2",
   "integral3",
   "interpstreamspeed",
-  "iscom",
-  "isinterface",
-  "isjava",
+  "isKey",
+  "iscategorical",
+  "iscategory",
+  "ismissing",
   "isocaps",
+  "isordinal",
+  "isprotected",
   "isstudent",
-  "javachk",
+  "istable",
+  "isundefined",
+  "isvalid",
+  "javaMethodEDT",
+  "javaObjectEDT",
+  "join",
+  "keys",
+  "last",
   "ldl",
   "libfunctions",
   "libfunctionsview",
@@ -684,11 +692,10 @@
   "light",
   "lightangle",
   "lighting",
-  "linkaxes",
   "linkdata",
   "listfonts",
   "loadlibrary",
-  "lscov",
+  "localfunctions",
   "lsqr",
   "makehgtform",
   "material",
@@ -696,7 +703,7 @@
   "matlabrc",
   "memmapfile",
   "memory",
-  "metaclass",
+  "mergecats",
   "methodsview",
   "minres",
   "mlintrpt",
@@ -715,8 +722,10 @@
   "ncwrite",
   "ncwriteatt",
   "ncwriteschema",
+  "netcdf",
   "noanimate",
   "notebook",
+  "notify",
   "ode113",
   "ode15i",
   "ode15s",
@@ -728,15 +737,14 @@
   "odeget",
   "odeset",
   "odextend",
-  "open",
   "openfig",
   "opengl",
   "openvar",
   "ordeig",
   "ordqz",
   "ordschur",
+  "outerjoin",
   "padecoef",
-  "pan",
   "parseSoapResponse",
   "pathtool",
   "pcode",
@@ -750,23 +758,26 @@
   "printpreview",
   "profsave",
   "propedit",
+  "properties",
   "propertyeditor",
   "psi",
   "publish",
-  "qmr",
   "quad2d",
   "rbbox",
+  "readtable",
   "reducepatch",
   "reducevolume",
-  "readasync",
+  "remove",
+  "removecats",
+  "renamecats",
+  "reordercats",
   "rng",
-  "rotate",
-  "rotate3d",
+  "rowfun",
+  "savefig",
   "scatteredInterpolant",
   "selectmoveresize",
   "sendmail",
   "serial",
-  "serialbreak",
   "setpixelposition",
   "showplottool",
   "smooth3",
@@ -774,8 +785,9 @@
   "sound",
   "soundsc",
   "ss2tf",
+  "stack",
+  "standardizeMissing",
   "startup",
-  "stopasync",
   "stream2",
   "stream3",
   "streamline",
@@ -783,30 +795,32 @@
   "streamribbon",
   "streamslice",
   "streamtube",
-  "strings",
+  "struct2table",
   "subvolume",
+  "summary",
   "superclasses",
   "surf2patch",
+  "sylvester",
   "symmlq",
-  "syntax",
+  "table2array",
+  "table2cell",
+  "table2struct",
   "texlabel",
   "textwrap",
   "tfqmr",
+  "throw",
+  "throwAsCaller",
+  "timeit",
   "timer",
   "timeseries",
   "todatenum",
   "toolboxdir",
   "triangulation",
   "tscollection",
-  "tstool",
   "uibuttongroup",
-  "uicontextmenu",
-  "uicontrol",
   "uigetpref",
   "uiimport",
   "uiopen",
-  "uipanel",
-  "uipushtool",
   "uiresume",
   "uisave",
   "uisetcolor",
@@ -821,22 +835,27 @@
   "unicode2native",
   "unloadlibrary",
   "unmesh",
+  "unstack",
   "userpath",
-  "validateattributes",
+  "values",
+  "varfun",
+  "verLessThan",
   "verctrl",
-  "verLessThan",
   "viewmtx",
   "visdiff",
   "volumebounds",
   "web",
-  "whatsnew",
+  "width",
   "winopen",
   "winqueryreg",
   "workspace",
+  "writetable",
+  "xlsfinfo",
+  "xlsread",
+  "xlswrite",
   "xmlread",
   "xmlwrite",
   "xslt",
-  "zoom",
   };
 endfunction
 
--- a/scripts/help/doc.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/help/doc.m	Fri Feb 06 08:31:49 2015 -0800
@@ -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);
@@ -81,12 +81,13 @@
         info_file_name = info_file ();
 
         if (! exist (info_file_name, "file")
-            && ! exist ([info_file_name ".gz"], "file"))
+            && ! exist ([info_file_name ".gz"], "file")
+            && ! exist ([info_file_name ".bz2"], "file"))
           __gripe_missing_component__ ("doc", "info-file");
         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/doc_cache_create.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/help/doc_cache_create.m	Fri Feb 06 08:31:49 2015 -0800
@@ -55,6 +55,7 @@
 
   ## Save cache
   if (! isempty (cache))
+     save_header_format_string (["# doc-cache created by Octave " OCTAVE_VERSION], "local");
      save ("-text", out_file, "cache");
   endif
 
--- a/scripts/help/get_first_help_sentence.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/help/get_first_help_sentence.m	Fri Feb 06 08:31:49 2015 -0800
@@ -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 Feb 06 08:31:09 2015 -0800
+++ b/scripts/help/help.m	Fri Feb 06 08:31:49 2015 -0800
@@ -20,9 +20,11 @@
 ## @deftypefn  {Command} {} help @var{name}
 ## @deftypefnx {Command} {} help @code{--list}
 ## @deftypefnx {Command} {} help @code{.}
-## Display the help text for @var{name}.  For example, the command
-## @kbd{help help} prints a short message describing the @code{help}
-## command.
+## @deftypefnx {Command} {} help
+## Display the help text for @var{name}.
+##
+## For example, the command @kbd{help help} prints a short message describing
+## the @code{help} command.
 ##
 ## Given the single argument @code{--list}, list all operators,
 ## keywords, built-in functions, and loadable functions available
@@ -34,10 +36,11 @@
 ## If invoked without any arguments, @code{help} display instructions
 ## on how to access help from the command line.
 ##
-## The help command can give you information about operators, but not the
-## comma and semicolons that are used as command separators.  To get help
-## for those, you must type @kbd{help comma} or @kbd{help semicolon}.
-## @seealso{doc, lookfor, which}
+## The help command can provide information about most operators, for example
+## @code{help +}, but not the comma and semicolon characters which are used
+## by the Octave interpreter as command separators.  For help on either of
+## these type @kbd{help comma} or @kbd{help semicolon}.
+## @seealso{doc, lookfor, which, info}
 ## @end deftypefn
 
 function retval = help (name)
@@ -69,21 +72,21 @@
   elseif (nargin == 1 && ischar (name))
 
     if (strcmp (name, "--list"))
-      tmp = do_list_functions ();
+      list = do_list_functions ();
       if (nargout == 0)
-        printf ("%s", tmp);
+        printf ("%s", list);
       else
-        retval = tmp;
+        retval = list;
       endif
       return;
     endif
 
     if (strcmp (name, "."))
-      tmp = do_list_operators ();
+      list = do_list_operators ();
       if (nargout == 0)
-        printf ("%s", tmp);
+        printf ("%s", list);
       else
-        retval = tmp;
+        retval = list;
       endif
       return;
     endif
@@ -129,7 +132,7 @@
 function retval = do_list_operators ()
 
   retval = sprintf ("*** operators:\n\n%s\n\n",
-                       list_in_columns (__operators__ ()));
+                    list_in_columns (__operators__ ()));
 endfunction
 
 function retval = do_list_functions ()
@@ -163,7 +166,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"));
@@ -207,5 +210,10 @@
 
 
 %!assert (! isempty (strfind (help ("ls"), "List directory contents")))
+%!assert (! isempty (strfind (help ("."), "||")))
+
+## Test input validation
 %!error <invalid input> help (42)
+%!error <invalid input> help ("abc", "def")
+%!error <'_!UNLIKELY_FCN!_' not found> help ("_!UNLIKELY_FCN!_")
 
--- a/scripts/help/which.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/help/which.m	Fri Feb 06 08:31:49 2015 -0800
@@ -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/autumn.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/image/autumn.m	Fri Feb 06 08:31:49 2015 -0800
@@ -31,17 +31,14 @@
 ## PKG_ADD: colormap ("register", "autumn");
 ## PKG_DEL: colormap ("unregister", "autumn");
 
-function map = autumn (n)
+function map = autumn (n = rows (colormap ()))
 
-  if (nargin == 0)
-    n = rows (colormap);
-  elseif (nargin == 1)
-    if (! isscalar (n))
-      error ("autumn: N must be a scalar");
-    endif
-  else
+  if (nargin > 1)
     print_usage ();
+  elseif (! isscalar (n))
+    error ("autumn: N must be a scalar");
   endif
+  n = double (n);
 
   if (n == 1)
     map = [1, 0, 0];
@@ -56,7 +53,6 @@
 
 endfunction
 
-
 %!demo
 %! ## Show the 'autumn' colormap as an image
 %! image (1:64, linspace (0, 1, 64), repmat ((1:64)', 1, 64));
--- a/scripts/image/bone.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/image/bone.m	Fri Feb 06 08:31:49 2015 -0800
@@ -31,17 +31,14 @@
 ## PKG_ADD: colormap ("register", "bone");
 ## PKG_DEL: colormap ("unregister", "bone");
 
-function map = bone (n)
+function map = bone (n = rows (colormap ()))
 
-  if (nargin == 0)
-    n = rows (colormap);
-  elseif (nargin == 1)
-    if (! isscalar (n))
-      error ("bone: N must be a scalar");
-    endif
-  else
+  if (nargin > 1)
     print_usage ();
+  elseif (! isscalar (n))
+    error ("bone: N must be a scalar");
   endif
+  n = double (n);
 
   if (n == 1)
     map = [1/8 1/8 1/8];
@@ -83,7 +80,6 @@
 
 endfunction
 
-
 %!demo
 %! ## Show the 'bone' colormap as an image
 %! image (1:64, linspace (0, 1, 64), repmat ((1:64)', 1, 64));
--- a/scripts/image/colormap.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/image/colormap.m	Fri Feb 06 08:31:49 2015 -0800
@@ -60,6 +60,7 @@
 ## Adapted-By: jwe
 
 function cmap = colormap (varargin)
+  mlock; # prevent map_list to be cleared by "clear all"
   persistent map_list = cell ();
 
   [hax, varargin, nargin] = __plt_get_axis_arg__ ("colormap", varargin{:});
--- a/scripts/image/cool.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/image/cool.m	Fri Feb 06 08:31:49 2015 -0800
@@ -30,17 +30,14 @@
 ## PKG_ADD: colormap ("register", "cool");
 ## PKG_DEL: colormap ("unregister", "cool");
 
-function map = cool (n)
+function map = cool (n = rows (colormap ()))
 
-  if (nargin == 0)
-    n = rows (colormap);
-  elseif (nargin == 1)
-    if (! isscalar (n))
-      error ("cool: N must be a scalar");
-    endif
-  else
+  if (nargin > 1)
     print_usage ();
+  elseif (! isscalar (n))
+    error ("cool: N must be a scalar");
   endif
+  n = double (n);
 
   if (n == 1)
     map = [0, 1, 1];
@@ -55,7 +52,6 @@
 
 endfunction
 
-
 %!demo
 %! ## Show the 'cool' colormap as an image
 %! image (1:64, linspace (0, 1, 64), repmat ((1:64)', 1, 64));
--- a/scripts/image/copper.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/image/copper.m	Fri Feb 06 08:31:49 2015 -0800
@@ -31,17 +31,14 @@
 ## PKG_ADD: colormap ("register", "copper");
 ## PKG_DEL: colormap ("unregister", "copper");
 
-function map = copper (n)
+function map = copper (n = rows (colormap ()))
 
-  if (nargin == 0)
-    n = rows (colormap);
-  elseif (nargin == 1)
-    if (! isscalar (n))
-      error ("copper: N must be a scalar");
-    endif
-  else
+  if (nargin > 1)
     print_usage ();
+  elseif (! isscalar (n))
+    error ("copper: N must be a scalar");
   endif
+  n = double (n);
 
   if (n == 1)
     map = [0, 0, 0];
@@ -58,7 +55,6 @@
 
 endfunction
 
-
 %!demo
 %! ## Show the 'copper' colormap as an image
 %! image (1:64, linspace (0, 1, 64), repmat ((1:64)', 1, 64));
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/image/cubehelix.m	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,87 @@
+## Copyright (C) 2014 Carnë Draug
+##
+## 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{map} =} cubehelix ()
+## @deftypefnx {Function File} {@var{map} =} cubehelix (@var{n})
+## Create cubehelix colormap.
+##
+## This colormap varies from black to white going though blue, green, and red
+## tones while maintaining a monotonically increasing perception of intensity.
+## This is achieved by transversing a color cube from black to white through
+## a helix, hence the name cubehelix, while taking into account the perceived
+## brightness of each channel according to the NTSC specifications from 1953.
+##
+## @example
+## rgbplot (cubehelix (256))
+## @end example
+##
+## The argument @var{n} must be a scalar and corresponds to the lenght of the
+## colormap.  Defaults to the length of the current colormap.
+##
+## Development of this colormap is described in @cite{Green, D. A., 2011,
+## "A colour scheme for the display of astronomical intensity images",
+## Bulletin of the Astronomical Society of India, 39, 289.}.
+##
+## @seealso{colormap}
+## @end deftypefn
+
+## Author: Carnë Draug <carandraug@octave.org>
+
+## PKG_ADD: colormap ("register", "cubehelix");
+## PKG_DEL: colormap ("unregister", "cubehelix");
+
+function map = cubehelix (n = rows (colormap ()), start = 0.5,
+                          rots = -1.5, hue = 1, gamma = 1)
+
+  if (nargin > 5)
+    print_usage ()
+  elseif (! isscalar (n))
+    error ("cubehelix: N must be a scalar");
+  endif
+  n = double (n);
+
+  if (n > 1)
+    coeff = [ -0.14861  -0.29227   1.97294
+               1.78277  -0.90649   0.00000];
+
+    fract = ((0:n-1) / (n-1))';
+    angle = 2 * pi * (start/3 + 1 + rots*fract);
+    fract = fract .^ gamma;
+    amp   = hue * fract .* (1-fract) /2;
+    warning ("off", "Octave:broadcast", "local");
+    map   = fract + amp .* ([cos(angle) sin(angle)] * coeff);
+
+    ## Clip values (only in case users have changed values of hue or gamma)
+    map(map < 0) = 0;
+    map(map > 1) = 1;
+
+  elseif (n > 0)
+    map = [0, 0, 0];
+  else
+    map = zeros (0, 3);
+  endif
+
+endfunction
+
+%!demo
+%! subplot (1, 2, 1)
+%! rgbplot (cubehelix (256), "composite")
+%! subplot (1, 2, 2)
+%! rgbplot (cubehelix (256))
+
--- a/scripts/image/flag.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/image/flag.m	Fri Feb 06 08:31:49 2015 -0800
@@ -31,16 +31,12 @@
 ## PKG_ADD: colormap ("register", "flag");
 ## PKG_DEL: colormap ("unregister", "flag");
 
-function map = flag (n)
+function map = flag (n = rows (colormap ()))
 
-  if (nargin == 0)
-    n = rows (colormap);
-  elseif (nargin == 1)
-    if (! isscalar (n))
-      error ("flag: N must be a scalar");
-    endif
-  else
+  if (nargin > 1)
     print_usage ();
+  elseif (! isscalar (n))
+    error ("flag: N must be a scalar");
   endif
 
   if (n == 1)
@@ -54,7 +50,6 @@
 
 endfunction
 
-
 %!demo
 %! ## Show the 'flag' colormap as an image
 %! image (1:64, linspace (0, 1, 64), repmat ((1:64)', 1, 64));
--- a/scripts/image/gmap40.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/image/gmap40.m	Fri Feb 06 08:31:49 2015 -0800
@@ -31,19 +31,15 @@
 ## PKG_ADD: colormap ("register", "gmap40");
 ## PKG_DEL: colormap ("unregister", "gmap40");
 
-function map = gmap40 (n)
+function map = gmap40 (n = rows (colormap ()))
 
-  if (nargin == 0)
-    n = 6;
-  elseif (nargin == 1)
-    if (! isscalar (n))
-      error ("gmap40: N must be a scalar");
-    endif
-  else
+  if (nargin > 1)
     print_usage ();
+  elseif (! isscalar (n))
+    error ("gmap40: N must be a scalar");
   endif
 
-  if (n > 1)
+  if (n > 0)
     C = [1, 0, 0; 0, 1, 0; 0, 0, 1; 1, 1, 0; 1, 0, 1; 0, 1, 1];
     map = C(rem (0:(n-1), 6) + 1, :);
   else
@@ -52,7 +48,6 @@
 
 endfunction
 
-
 %!demo
 %! ## Show the 'gmap40' colormap as an image
 %! image (1:6, linspace (0, 1, 6), repmat ((1:6)', 1, 6));
--- a/scripts/image/gray.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/image/gray.m	Fri Feb 06 08:31:49 2015 -0800
@@ -33,17 +33,14 @@
 ## PKG_ADD: colormap ("register", "gray");
 ## PKG_DEL: colormap ("unregister", "gray");
 
-function map = gray (n)
+function map = gray (n = rows (colormap ()))
 
-  if (nargin == 0)
-    n = rows (colormap);
-  elseif (nargin == 1)
-    if (! isscalar (n))
-      error ("gray: N must be a scalar");
-    endif
-  else
+  if (nargin > 1)
     print_usage ();
+  elseif (! isscalar (n))
+    error ("gray: N must be a scalar");
   endif
+  n = double (n);
 
   if (n == 1)
     map = [0, 0, 0];
@@ -56,7 +53,6 @@
 
 endfunction
 
-
 %!demo
 %! ## Show the 'gray' colormap as an image
 %! image (1:64, linspace (0, 1, 64), repmat ((1:64)', 1, 64));
--- a/scripts/image/hot.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/image/hot.m	Fri Feb 06 08:31:49 2015 -0800
@@ -31,16 +31,12 @@
 ## PKG_ADD: colormap ("register", "hot");
 ## PKG_DEL: colormap ("unregister", "hot");
 
-function map = hot (n)
+function map = hot (n = rows (colormap ()))
 
-  if (nargin == 0)
-    n = rows (colormap);
-  elseif (nargin == 1)
-    if (! isscalar (n))
-      error ("hot: N must be a scalar");
-    endif
-  else
+  if (nargin > 1)
     print_usage ();
+  elseif (! isscalar (n))
+    error ("hot: N must be a scalar");
   endif
 
   if (n == 1)
@@ -72,7 +68,6 @@
 
 endfunction
 
-
 %!demo
 %! ## Show the 'hot' colormap as an image
 %! image (1:64, linspace (0, 1, 64), repmat ((1:64)', 1, 64));
--- a/scripts/image/hsv.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/image/hsv.m	Fri Feb 06 08:31:49 2015 -0800
@@ -35,17 +35,14 @@
 ## PKG_ADD: colormap ("register", "hsv");
 ## PKG_DEL: colormap ("unregister", "hsv");
 
-function map = hsv (n)
+function map = hsv (n = rows (colormap ()))
 
-  if (nargin == 0)
-    n = rows (colormap);
-  elseif (nargin == 1)
-    if (! isscalar (n))
-      error ("hsv: N must be a scalar");
-    endif
-  else
+  if (nargin > 1)
     print_usage ();
+  elseif (! isscalar (n))
+    error ("hsv: N must be a scalar");
   endif
+  n = double (n);
 
   if (n == 1)
     map = [1, 0, 0];
@@ -58,7 +55,6 @@
 
 endfunction
 
-
 %!demo
 %! ## Show the 'hsv' colormap as an image
 %! image (1:64, linspace (0, 1, 64), repmat ((1:64)', 1, 64));
--- a/scripts/image/image.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/image/image.m	Fri Feb 06 08:31:49 2015 -0800
@@ -69,7 +69,7 @@
 
   do_new = true;
   if (nargin == 0)
-    img = imread ("default.img");
+    img = get (0, "defaultimagecdata");
     x = y = [];
   elseif (chararg == 1)
     ## Low-Level syntax
@@ -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 Feb 06 08:31:09 2015 -0800
+++ b/scripts/image/imfinfo.m	Fri Feb 06 08:31:49 2015 -0800
@@ -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 Feb 06 08:31:09 2015 -0800
+++ b/scripts/image/imformats.m	Fri Feb 06 08:31:49 2015 -0800
@@ -75,6 +75,7 @@
     print_usage ();
   endif
 
+  mlock (); # prevent formats to be removed by "clear all"
   persistent formats = default_formats ();
 
   if (nargin == 0 && nargout == 0)
@@ -266,11 +267,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 +281,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 = [tempname() ".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 = [tempname() ".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 = [tempname() ".new_fmt1"];
+%! fid1 = fopen (fname1, "w");
+%! fname2 = [tempname() ".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 +353,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 Feb 06 08:31:09 2015 -0800
+++ b/scripts/image/imread.m	Fri Feb 06 08:31:49 2015 -0800
@@ -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
 
 
@@ -126,7 +127,7 @@
 %!   16,  28, 160,  16,   0, 197, 214,  13,  34,  74, ...
 %!  117, 213,  17,   0,   0,   0,   0,  73,  69,  78, ...
 %!   68, 174,  66,  96, 130];
-%! filename = [tmpnam() ".png"];
+%! filename = [tempname() ".png"];
 %! unwind_protect
 %!   fid = fopen (filename, "wb");
 %!   fwrite (fid, vpng);
@@ -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 = [tempname() ".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 = [tempname() ".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 Feb 06 08:31:09 2015 -0800
+++ b/scripts/image/imshow.m	Fri Feb 06 08:31:49 2015 -0800
@@ -46,6 +46,9 @@
 ## @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
 ## limits in the form [xmin xmax]; Otherwise @var{value1} must be a
@@ -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 Feb 06 08:31:09 2015 -0800
+++ b/scripts/image/imwrite.m	Fri Feb 06 08:31:49 2015 -0800
@@ -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);
@@ -126,7 +126,7 @@
 %!error imwrite (spones (2), "filename.jpg")  # Invalid sparse img
 
 %!function [r, cmap, a] = write_and_read (varargin)
-%!  filename = [tmpnam() ".tif"];
+%!  filename = [tempname() ".tif"];
 %!  unwind_protect
 %!    imwrite (varargin{1}, filename, varargin{2:end});
 %!    [r, cmap, a] = imread (filename, "Index", "all");
--- a/scripts/image/ind2gray.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/image/ind2gray.m	Fri Feb 06 08:31:49 2015 -0800
@@ -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 Feb 06 08:31:09 2015 -0800
+++ b/scripts/image/ind2rgb.m	Fri Feb 06 08:31:49 2015 -0800
@@ -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/jet.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/image/jet.m	Fri Feb 06 08:31:49 2015 -0800
@@ -31,16 +31,12 @@
 ## PKG_ADD: colormap ("register", "jet");
 ## PKG_DEL: colormap ("unregister", "jet");
 
-function map = jet (n)
+function map = jet (n = rows (colormap ()))
 
-  if (nargin == 0)
-    n = rows (colormap);
-  elseif (nargin == 1)
-    if (! isscalar (n))
-      error ("jet: N must be a scalar");
-    endif
-  else
+  if (nargin > 1)
     print_usage ();
+  elseif (! isscalar (n))
+    error ("jet: N must be a scalar");
   endif
 
   if (n == 1)
@@ -91,7 +87,6 @@
 
 endfunction
 
-
 %!demo
 %! ## Show the 'jet' colormap as an image
 %! image (1:64, linspace (0, 1, 64), repmat ((1:64)', 1, 64));
--- a/scripts/image/lines.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/image/lines.m	Fri Feb 06 08:31:49 2015 -0800
@@ -30,16 +30,12 @@
 ## PKG_ADD: colormap ("register", "lines");
 ## PKG_DEL: colormap ("unregister", "lines");
 
-function map = lines (n)
+function map = lines (n = rows (colormap ()))
 
-  if (nargin == 0)
-    n = rows (colormap);
-  elseif (nargin == 1)
-    if (! isscalar (n))
-      error ("lines: N must be a scalar");
-    endif
-  else
+  if (nargin > 1)
     print_usage ();
+  elseif (! isscalar (n))
+    error ("lines: N must be a scalar");
   endif
 
   if (n == 1)
@@ -54,7 +50,6 @@
 
 endfunction
 
-
 %!demo
 %! ## Show the 'lines' colormap as an image
 %! image (1:64, linspace (0, 1, 64), repmat ((1:64)', 1, 64));
--- a/scripts/image/module.mk	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/image/module.mk	Fri Feb 06 08:31:49 2015 -0800
@@ -19,6 +19,7 @@
   image/contrast.m \
   image/cool.m \
   image/copper.m \
+  image/cubehelix.m \
   image/flag.m \
   image/gmap40.m \
   image/gray.m \
--- a/scripts/image/ocean.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/image/ocean.m	Fri Feb 06 08:31:49 2015 -0800
@@ -33,17 +33,14 @@
 ## PKG_ADD: colormap ("register", "ocean");
 ## PKG_DEL: colormap ("unregister", "ocean");
 
-function map = ocean (n)
+function map = ocean (n = rows (colormap ()))
 
-  if (nargin == 0)
-    n = rows (colormap);
-  elseif (nargin == 1)
-    if (! isscalar (n))
-      error ("ocean: N must be a scalar");
-    endif
-  else
+  if (nargin > 1)
     print_usage ();
+  elseif (! isscalar (n))
+    error ("ocean: N must be a scalar");
   endif
+  n = double (n);
 
   if (n == 1)
     map = [0, 0, 0];
@@ -65,7 +62,6 @@
 
 endfunction
 
-
 %!demo
 %! ## Show the 'ocean' colormap as an image
 %! image (1:64, linspace (0, 1, 64), repmat ((1:64)', 1, 64));
--- a/scripts/image/pink.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/image/pink.m	Fri Feb 06 08:31:49 2015 -0800
@@ -31,16 +31,12 @@
 ## PKG_ADD: colormap ("register", "pink");
 ## PKG_DEL: colormap ("unregister", "pink");
 
-function map = pink (n)
+function map = pink (n = rows (colormap ()))
 
-  if (nargin == 0)
-    n = rows (colormap);
-  elseif (nargin == 1)
-    if (! isscalar (n))
-      error ("pink: N must be a scalar");
-    endif
-  else
+  if (nargin > 1)
     print_usage ();
+  elseif (! isscalar (n))
+    error ("pink: N must be a scalar");
   endif
 
   if (n == 1)
@@ -72,7 +68,6 @@
 
 endfunction
 
-
 %!demo
 %! ## Show the 'pink' colormap as an image
 %! image (1:64, linspace (0, 1, 64), repmat ((1:64)', 1, 64));
--- a/scripts/image/prism.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/image/prism.m	Fri Feb 06 08:31:49 2015 -0800
@@ -31,16 +31,12 @@
 ## PKG_ADD: colormap ("register", "prism");
 ## PKG_DEL: colormap ("unregister", "prism");
 
-function map = prism (n)
+function map = prism (n = rows (colormap ()))
 
-  if (nargin == 0)
-    n = rows (colormap);
-  elseif (nargin == 1)
-    if (! isscalar (n))
-      error ("prism: N must be a scalar");
-    endif
-  else
+  if (nargin > 1)
     print_usage ();
+  elseif (! isscalar (n))
+    error ("prism: N must be a scalar");
   endif
 
   if (n == 1)
@@ -54,7 +50,6 @@
 
 endfunction
 
-
 %!demo
 %! ## Show the 'prism' colormap as an image
 %! image (1:64, linspace (0, 1, 64), repmat ((1:64)', 1, 64));
--- a/scripts/image/private/__imfinfo__.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/image/private/__imfinfo__.m	Fri Feb 06 08:31:49 2015 -0800
@@ -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 Feb 06 08:31:09 2015 -0800
+++ b/scripts/image/private/__imread__.m	Fri Feb 06 08:31:49 2015 -0800
@@ -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 Feb 06 08:31:09 2015 -0800
+++ b/scripts/image/private/imageIO.m	Fri Feb 06 08:31:49 2015 -0800
@@ -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, tempname ());
+    ## Maybe the URL is missing the file extension
+    if (isempty (fn) && ! isempty (varargin))
+      [fn, ~] = urlwrite ([filename "." varargin{1}], tempname ());
+    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 Feb 06 08:31:09 2015 -0800
+++ b/scripts/image/private/ind2x.m	Fri Feb 06 08:31:49 2015 -0800
@@ -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/image/rainbow.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/image/rainbow.m	Fri Feb 06 08:31:49 2015 -0800
@@ -34,17 +34,14 @@
 ## PKG_ADD: colormap ("register", "rainbow");
 ## PKG_DEL: colormap ("unregister", "rainbow");
 
-function map = rainbow (n)
+function map = rainbow (n = rows (colormap ()))
 
-  if (nargin == 0)
-    n = rows (colormap);
-  elseif (nargin == 1)
-    if (! isscalar (n))
-      error ("rainbow: N must be a scalar");
-    endif
-  else
+  if (nargin > 1)
     print_usage ();
+  elseif (! isscalar (n))
+    error ("rainbow: N must be a scalar");
   endif
+  n = double (n);
 
   if (n == 1)
     map = [1, 0, 0];
@@ -69,7 +66,6 @@
 
 endfunction
 
-
 %!demo
 %! ## Show the 'rainbow' colormap as an image
 %! image (1:64, linspace (0, 1, 64), repmat ((1:64)', 1, 64));
--- a/scripts/image/spring.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/image/spring.m	Fri Feb 06 08:31:49 2015 -0800
@@ -30,17 +30,14 @@
 ## PKG_ADD: colormap ("register", "spring");
 ## PKG_DEL: colormap ("unregister", "spring");
 
-function map = spring (n)
+function map = spring (n = rows (colormap ()))
 
-  if (nargin == 0)
-    n = rows (colormap);
-  elseif (nargin == 1)
-    if (! isscalar (n))
-      error ("spring: N must be a scalar");
-    endif
-  else
+  if (nargin > 1)
     print_usage ();
+  elseif (! isscalar (n))
+    error ("spring: N must be a scalar");
   endif
+  n = double (n);
 
   if (n == 1)
     map = [1, 0, 1];
@@ -55,7 +52,6 @@
 
 endfunction
 
-
 %!demo
 %! ## Show the 'spring' colormap as an image
 %! image (1:64, linspace (0, 1, 64), repmat ((1:64)', 1, 64));
--- a/scripts/image/summer.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/image/summer.m	Fri Feb 06 08:31:49 2015 -0800
@@ -31,17 +31,14 @@
 ## PKG_ADD: colormap ("register", "summer");
 ## PKG_DEL: colormap ("unregister", "summer");
 
-function map = summer (n)
+function map = summer (n = rows (colormap ()))
 
-  if (nargin == 0)
-    n = rows (colormap);
-  elseif (nargin == 1)
-    if (! isscalar (n))
-      error ("summer: N must be a scalar");
-    endif
-  else
+  if (nargin > 1)
     print_usage ();
+  elseif (! isscalar (n))
+    error ("summer: N must be a scalar");
   endif
+  n = double (n);
 
   if (n == 1)
     map = [0, 0.5, 0.4];
@@ -56,7 +53,6 @@
 
 endfunction
 
-
 %!demo
 %! ## Show the 'summer' colormap as an image
 %! image (1:64, linspace (0, 1, 64), repmat ((1:64)', 1, 64));
--- a/scripts/image/white.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/image/white.m	Fri Feb 06 08:31:49 2015 -0800
@@ -30,23 +30,18 @@
 ## PKG_ADD: colormap ("register", "white");
 ## PKG_DEL: colormap ("unregister", "white");
 
-function map = white (n)
+function map = white (n = rows (colormap ()))
 
-  if (nargin == 0)
-    n = rows (colormap);
-  elseif (nargin == 1)
-    if (! isscalar (n))
-      error ("white: N must be a scalar");
-    endif
-  else
+  if (nargin > 1)
     print_usage ();
+  elseif (! isscalar (n))
+    error ("white: N must be a scalar");
   endif
 
   map = ones (n, 3);
 
 endfunction
 
-
 %!demo
 %! ## Show the 'white' colormap as an image
 %! image (1:64, linspace (0, 1, 64), repmat ((1:64)', 1, 64));
--- a/scripts/image/winter.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/image/winter.m	Fri Feb 06 08:31:49 2015 -0800
@@ -30,17 +30,14 @@
 ## PKG_ADD: colormap ("register", "winter");
 ## PKG_DEL: colormap ("unregister", "winter");
 
-function map = winter (n)
+function map = winter (n = rows (colormap ()))
 
-  if (nargin == 0)
-    n = rows (colormap);
-  elseif (nargin == 1)
-    if (! isscalar (n))
-      error ("winter: N must be a scalar");
-    endif
-  else
+  if (nargin > 1)
     print_usage ();
+  elseif (! isscalar (n))
+    error ("winter: N must be a scalar");
   endif
+  n = double (n);
 
   if (n == 1)
     map = [0, 0, 1];
@@ -55,7 +52,6 @@
 
 endfunction
 
-
 %!demo
 %! ## Show the 'winter' colormap as an image
 %! image (1:64, linspace (0, 1, 64), repmat ((1:64)', 1, 64));
--- a/scripts/io/csvwrite.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/io/csvwrite.m	Fri Feb 06 08:31:49 2015 -0800
@@ -37,7 +37,7 @@
 
 
 %!shared fname
-%! fname = tmpnam ();
+%! fname = tempname ();
 
 %!test
 %! csvwrite (fname, magic (3));
--- a/scripts/io/dlmwrite.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/io/dlmwrite.m	Fri Feb 06 08:31:49 2015 -0800
@@ -201,7 +201,7 @@
 
 
 %!test
-%! f = tmpnam ();
+%! f = tempname ();
 %! dlmwrite (f,[1,2;3,4],"precision","%5.2f","newline","unix","roffset",1,"coffset",1);
 %! fid = fopen (f,"rt");
 %! f1 = char (fread (fid,Inf,"char")');
--- a/scripts/io/fileread.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/io/fileread.m	Fri Feb 06 08:31:49 2015 -0800
@@ -48,7 +48,7 @@
 
 %!test
 %! cstr = {"Hello World", "The answer is 42", "Goodbye World"};
-%! fname = tmpnam ();
+%! fname = tempname ();
 %! fid = fopen (fname, "w");
 %! fprintf (fid, "%s\n", cstr{:});
 %! fclose (fid);
--- a/scripts/io/importdata.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/io/importdata.m	Fri Feb 06 08:31:49 2015 -0800
@@ -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
@@ -271,7 +292,7 @@
 %!test
 %! ## Comma separated values
 %! A = [3.1 -7.2 0; 0.012 6.5 128];
-%! fn  = tmpnam ();
+%! fn  = tempname ();
 %! fid = fopen (fn, "w");
 %! fputs (fid, "3.1,-7.2,0\n0.012,6.5,128");
 %! fclose (fid);
@@ -288,7 +309,7 @@
 %!test
 %! ## Tab separated values
 %! A = [3.1 -7.2 0; 0.012 6.5 128];
-%! fn  = tmpnam ();
+%! fn  = tempname ();
 %! fid = fopen (fn, "w");
 %! fputs (fid, "3.1\t-7.2\t0\n0.012\t6.5\t128");
 %! fclose (fid);
@@ -305,7 +326,7 @@
 %!test
 %! ## Space separated values, using multiple spaces to align in columns.
 %! A = [3.1 -7.2 0; 0.012 6.5 128];
-%! fn  = tmpnam ();
+%! fn  = tempname ();
 %! fid = fopen (fn, "w");
 %! fprintf (fid, "%10.3f %10.3f %10.3f\n", A');
 %! fclose (fid);
@@ -322,7 +343,7 @@
 %!test
 %! ## No separator, 1 column of data only
 %! A = [3.1;-7.2;0;0.012;6.5;128];
-%! fn  = tmpnam ();
+%! fn  = tempname ();
 %! fid = fopen (fn, "w");
 %! fprintf (fid, "%f\n", A);
 %! fclose (fid);
@@ -342,7 +363,7 @@
 %! A.textdata = {"This is a header row."; ...
 %!               "this row does not contain any data, but the next one does."};
 %! A.colheaders = A.textdata (2);
-%! fn  = tmpnam ();
+%! fn  = tempname ();
 %! fid = fopen (fn, "w");
 %! fprintf (fid, "%s\n", A.textdata{:});
 %! fputs (fid, "3.1\t-7.2\t0\n0.012\t6.5\t128");
@@ -359,7 +380,7 @@
 %! A.textdata = {"Label1\tLabel2\tLabel3";
 %!               "col 1\tcol 2\tcol 3"};
 %! A.colheaders = {"col 1", "col 2", "col 3"};
-%! fn  = tmpnam ();
+%! fn  = tempname ();
 %! fid = fopen (fn, "w");
 %! fprintf (fid, "%s\n", A.textdata{:});
 %! fputs (fid, "3.1\t-7.2\t0\n0.012\t6.5\t128");
@@ -375,7 +396,7 @@
 %! A.data = [3.1 -7.2 0; 0.012 6.5 128];
 %! A.textdata = {"row1"; "row2"};
 %! A.rowheaders = A.textdata;
-%! fn  = tmpnam ();
+%! fn  = tempname ();
 %! fid = fopen (fn, "w");
 %! fputs (fid, "row1\t3.1\t-7.2\t0\nrow2\t0.012\t6.5\t128");
 %! fclose (fid);
@@ -392,7 +413,7 @@
 %!               "      col1 col2 col3"
 %!               "row1"
 %!               "row2"};
-%! fn  = tmpnam ();
+%! fn  = tempname ();
 %! fid = fopen (fn, "w");
 %! fprintf (fid, "%s\n", A.textdata{1:2});
 %! fputs (fid, "row1\t3.1\t-7.2\t0\nrow2\t0.012\t6.5\t128");
@@ -406,7 +427,7 @@
 %!test
 %! ## Ignore empty rows containing only spaces
 %! A = [3.1 -7.2 0; 0.012 6.5 128];
-%! fn  = tmpnam ();
+%! fn  = tempname ();
 %! fid = fopen (fn, "w");
 %! fprintf (fid, "%10.3f %10.3f %10.3f\n", A(1,:));
 %! fputs (fid, "      ");
@@ -421,7 +442,7 @@
 %!test
 %! ## Exponentials
 %! A = [3.1 -7.2 0; 0.012 6.5 128];
-%! fn  = tmpnam ();
+%! fn  = tempname ();
 %! fid = fopen (fn, "w");
 %! fputs (fid, "+3.1e0\t-72E-1\t0\n12e-3\t6.5\t128");
 %! fclose (fid);
@@ -434,7 +455,7 @@
 %!test
 %! ## Complex numbers
 %! A = [3.1 -7.2 0-3.4i; 0.012 -6.5+7.2i 128];
-%! fn  = tmpnam ();
+%! fn  = tempname ();
 %! fid = fopen (fn, "w");
 %! fputs (fid, "3.1\t-7.2\t0-3.4i\n0.012\t-6.5+7.2i\t128");
 %! fclose (fid);
@@ -447,7 +468,7 @@
 %!test
 %! ## Exceptional values (Inf, NaN, NA)
 %! A = [3.1 Inf NA; -Inf NaN 128];
-%! fn  = tmpnam ();
+%! fn  = tempname ();
 %! fid = fopen (fn, "w");
 %! fputs (fid, "3.1\tInf\tNA\n-Inf\tNaN\t128");
 %! fclose (fid);
@@ -462,7 +483,7 @@
 %! A.data = [3.1 NA 0; 0.012 NA 128];
 %! A.textdata = {char(zeros(1,0))
 %!               "NO DATA"};
-%! fn  = tmpnam ();
+%! fn  = tempname ();
 %! fid = fopen (fn, "w");
 %! fputs (fid, "3.1\t\t0\n0.012\tNO DATA\t128");
 %! fclose (fid);
@@ -475,7 +496,7 @@
 %!#test
 %! ## CRLF for line breaks
 %! A = [3.1 -7.2 0; 0.012 6.5 128];
-%! fn  = tmpnam ();
+%! fn  = tempname ();
 %! fid = fopen (fn, "w");
 %! fputs (fid, "3.1\t-7.2\t0\r\n0.012\t6.5\t128");
 %! fclose (fid);
@@ -488,7 +509,7 @@
 %!#test
 %! ## CR for line breaks
 %! A = [3.1 -7.2 0; 0.012 6.5 128];
-%! fn  = tmpnam ();
+%! fn  = tempname ();
 %! fid = fopen (fn, "w");
 %! fputs (fid, "3.1\t-7.2\t0\r0.012\t6.5\t128");
 %! fclose (fid);
@@ -510,6 +531,30 @@
 %! assert (d, " ");
 %! assert (h, 0);
 
+%!test
+%! ## Only text / no numeric data; \n as EOL
+%! fn  = tempname ();
+%! 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  = tempname ();
+%! 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/is_valid_file_id.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/io/is_valid_file_id.m	Fri Feb 06 08:31:49 2015 -0800
@@ -19,7 +19,7 @@
 ## -*- texinfo -*-
 ## @deftypefn {Function File} {} is_valid_file_id (@var{fid})
 ## Return true if @var{fid} refers to an open file.
-## @seealso{fopen}
+## @seealso{freport, fopen}
 ## @end deftypefn
 
 function retval = is_valid_file_id (fid)
--- a/scripts/io/strread.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/io/strread.m	Fri Feb 06 08:31:49 2015 -0800
@@ -197,10 +197,12 @@
   endif
 
   ## Parse format string to compare number of conversion fields and nargout
-  nfields = length (strfind (format, "%")) - length (strfind (format, "%*"));
+  nfields = numel (regexp (format, '(%(\d*|\d*\.\d*)?[nfduscq]|%\[)', "match"));
   ## If str only has numeric fields, a (default) format ("%f") will do.
   ## Otherwise:
-  if ((max (nargout, 1) != nfields) && ! strcmp (format, "%f"))
+  if (! nfields)
+    error ("strread.m: no valid format conversion specifiers found\n");
+  elseif ((max (nargout, 1) != nfields) && ! strcmp (format, "%f"))
     error ("strread: the number of output variables must match that specified by FORMAT");
   endif
 
@@ -249,8 +251,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
@@ -304,7 +306,8 @@
     fmt_words = regexp (format, '[^ ]+', "match");
 
     ## Find position of conversion specifiers (they start with %)
-    idy2 = find (! cellfun ("isempty", regexp (fmt_words, '^%')));
+    fcs_ptrn = '(%\*?(\d*|\d*\.\d*)?[nfduscq]|%\*?\[)';
+    idy2 = find (! cellfun ("isempty", regexp (fmt_words, fcs_ptrn)));
 
     ## Check for unsupported format specifiers
     errpat = '(\[.*\]|[cq]|[nfdu]8|[nfdu]16|[nfdu]32|[nfdu]64)';
@@ -409,7 +412,7 @@
   if (! isempty (white_spaces))
     ## Check if trailing "\n" might signal padding output arrays to equal size
     ## before it is trimmed away below
-    if ((str(end) == 10) && (nargout > 1))
+    if (str(end) == "\n" && nargout > 1)
       pad_out = 1;
     endif
     ## Condense all repeated whitespace into one single space
@@ -417,7 +420,7 @@
     rxp_wsp = sprintf ("[%s]+", white_spaces);
     str = regexprep (str, rxp_wsp, ' ');
     ## Remove possible leading space at string
-    if (str(1) == 32)
+    if (str(1) == " ")
        str = str(2:end);
     endif
     ## Check for single delimiter followed/preceded by whitespace
@@ -690,8 +693,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 +704,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 +725,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)
@@ -1034,5 +1037,8 @@
 
 %% Illegal format specifiers
 %!test
-%!error <unknown format specifier> strread ("1.0", "%z")
+%!error <no valid format conversion specifiers> strread ("1.0", "%z");
 
+%% Test for false positives in check for non-supported format specifiers
+%!test
+%! assert (strread ("Total: 32.5 % (of cm values)","Total: %f % (of cm values)"), 32.5, 1e-5);
--- a/scripts/io/textread.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/io/textread.m	Fri Feb 06 08:31:49 2015 -0800
@@ -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);
@@ -221,7 +221,7 @@
 
 
 %!test
-%! f = tmpnam ();
+%! f = tempname ();
 %! d = rand (5, 3);
 %! dlmwrite (f, d, "precision", "%5.2f");
 %! [a, b, c] = textread (f, "%f %f %f", "delimiter", ",", "headerlines", 3);
@@ -231,7 +231,7 @@
 %! assert (c, d(4:5, 3), 1e-2);
 
 %!test
-%! f = tmpnam ();
+%! f = tempname ();
 %! d = rand (7, 2);
 %! dlmwrite (f, d, "precision", "%5.2f");
 %! [a, b] = textread (f, "%f, %f", "headerlines", 1);
@@ -240,7 +240,7 @@
 
 %% Test reading 2D matrix with empty format
 %!test
-%! f = tmpnam ();
+%! f = tempname ();
 %! d = rand (5, 2);
 %! dlmwrite (f, d, "precision", "%5.2f");
 %! A = textread (f, "", "headerlines", 3);
@@ -249,7 +249,7 @@
 
 %% Read multiple lines using empty format string
 %!test
-%! f = tmpnam ();
+%! f = tempname ();
 %! unlink (f);
 %! fid = fopen (f, "w");
 %! d = rand (1, 4);
@@ -261,7 +261,7 @@
 
 %% Empty format, corner case = one line w/o EOL
 %!test
-%! f = tmpnam ();
+%! f = tempname ();
 %! unlink (f);
 %! fid = fopen (f, "w");
 %! d = rand (1, 4);
@@ -273,7 +273,7 @@
 
 %% Read multiple lines using empty format string, missing data (should be 0)
 %!test
-%! f = tmpnam ();
+%! f = tempname ();
 %! unlink (f);
 %! fid = fopen (f, "w");
 %! d = rand (1, 4);
@@ -285,7 +285,7 @@
 
 %% Test with empty positions - ML returns 0 for empty fields
 %!test
-%! f = tmpnam ();
+%! f = tempname ();
 %! unlink (f);
 %! fid = fopen (f, "w");
 %! d = rand (1, 4);
@@ -298,7 +298,7 @@
 %% Another test with empty format + positions, now with more incomplete lower
 %% row (must be appended with zeros to get rectangular matrix)
 %!test
-%! f = tmpnam ();
+%! f = tempname ();
 %! unlink (f);
 %! fid = fopen (f, "w");
 %! d = rand (1, 4);
--- a/scripts/io/textscan.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/io/textscan.m	Fri Feb 06 08:31:49 2015 -0800
@@ -98,7 +98,10 @@
   endif
 
   ## Determine the number of data fields & initialize output array
-  num_fields = numel (strfind (format, "%")) - numel (strfind (format, "%*"));
+  num_fields = numel (regexp (format, '(%(\d*|\d*\.\d*)?[nfduscq]|%\[)', "match"));
+  if (! num_fields)
+    error ("textscan.m: no valid format conversion specifiers found\n");
+  endif
   C = cell (1, num_fields);
 
   if (! (isa (fid, "double") && fid > 0) && ! ischar (fid))
@@ -316,18 +319,20 @@
       ## 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);
       ## Reshape C; watch out, transpose needed
-      C(1) = reshape (C{1}, ncols, numel (C{1}) / ncols)';
+      C(1) = reshape (C{1}, ncols, numel (C{1}) / ncols).';
       ## Distribute columns over C and wipe cols 2:end of C{1}
       for ii=2:ncols
         C(ii) = C{1}(:, ii);
@@ -576,7 +581,7 @@
 
 %% Test reading from a real file
 %!test
-%! f = tmpnam ();
+%! f = tempname ();
 %! fid = fopen (f, "w+");
 %! d = rand (1, 4);
 %! fprintf (fid, "  %f %f   %f  %f ", d);
@@ -589,7 +594,7 @@
 
 %% Tests reading with empty format, should return proper nr of columns
 %!test
-%! f = tmpnam ();
+%! f = tempname ();
 %! fid = fopen (f, "w+");
 %! fprintf (fid, " 1 2 3 4\n5 6 7 8");
 %! fseek (fid, 0, "bof");
@@ -603,7 +608,7 @@
 
 %% Tests reading with empty format; empty fields & incomplete lower row
 %!test
-%! f = tmpnam ();
+%! f = tempname ();
 %! fid = fopen (f, "w+");
 %! fprintf (fid, " ,2,,4\n5,6");
 %! fseek (fid, 0, "bof");
@@ -615,7 +620,7 @@
 %% Error message tests
 
 %!test
-%! f = tmpnam ();
+%! f = tempname ();
 %! fid = fopen (f, "w+");
 %! msg1 = "Missing or illegal value for 'headerlines'";
 %! try
@@ -626,7 +631,7 @@
 %! assert (msg1, lasterr);
 
 %!test
-%! f = tmpnam ();
+%! f = tempname ();
 %! fid = fopen (f, "w+");
 %! msg1 = "Missing or illegal value for 'headerlines'";
 %! try
@@ -637,7 +642,7 @@
 %! assert (msg1, lasterr);
 
 %!test
-%! f = tmpnam ();
+%! f = tempname ();
 %! fid = fopen (f, "w+");
 %! fprintf (fid,"some_string");
 %! fseek (fid, 0, "bof");
@@ -650,7 +655,7 @@
 %! assert (msg1, lasterr);
 
 %!test
-%! f = tmpnam ();
+%! f = tempname ();
 %! fid = fopen (f, "w+");
 %! fprintf (fid,"some_string");
 %! fseek (fid, 0, "bof");
@@ -666,3 +671,20 @@
 %!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]);
+
+%% Bug #42528
+%!test
+%! assert (textscan ("1i", ""){1},  0+1i);
+%! assert (cell2mat (textscan ("3, 2-4i, NaN\n -i, 1, 23.4+2.2i", "")), [3+0i, 2-4i, NaN+0i; 0-i,  1+0i, 23.4+2.2i]);
+
+%% Illegal format specifiers
+%!test
+%!error <no valid format conversion specifiers> textscan ("1.0", "%z");
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/java/javachk.m	Fri Feb 06 08:31:49 2015 -0800
@@ -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 Feb 06 08:31:09 2015 -0800
+++ b/scripts/java/javaclasspath.m	Fri Feb 06 08:31:49 2015 -0800
@@ -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,45 +74,38 @@
     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)
-
-        case 1
-          varargout{1} = cellstr (dynamic_path_list);
-
-        case 2
-          varargout{1} = cellstr (dynamic_path_list);
-          varargout{2} = cellstr (static_path_list);
-      endswitch
+  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
-      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
-
-        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
+  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
-  endswitch
+    endif
+  endif
 
 endfunction
 
--- a/scripts/java/javamem.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/java/javamem.m	Fri Feb 06 08:31:49 2015 -0800
@@ -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 Feb 06 08:31:09 2015 -0800
+++ b/scripts/java/module.mk	Fri Feb 06 08:31:49 2015 -0800
@@ -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 Feb 06 08:31:09 2015 -0800
+++ b/scripts/java/org/octave/ClassHelper.java	Fri Feb 06 08:31:49 2015 -0800
@@ -199,7 +199,7 @@
           {
             sb.append (";");
           }
-        sb.append (theField[i].toString ());
+        sb.append (theField[i].getName ());
       }
 
     return (sb.toString ());
--- a/scripts/java/org/octave/JDialogBox.java	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/java/org/octave/JDialogBox.java	Fri Feb 06 08:31:49 2015 -0800
@@ -1,5 +1,6 @@
 /*
 
+Copyright (C) 2014 Colin Foster
 Copyright (C) 2010, 2013 Martin Hepperle
 
 This file is part of Octave.
@@ -551,24 +552,28 @@
           {
             lst[i] = theTranslator.replace (list[i]);
           }
+
+        JScrollPane scrollPane = new JScrollPane();
         m_List = new JList (lst);
+        scrollPane.setViewportView(m_List);
+
 
         // replace ugly monospaced font
-        m_List.setFont (p.getFont ());
+        scrollPane.setFont (p.getFont ());
 
-        m_List.setMinimumSize (new Dimension (Math.max (1,
-                                                        Integer.parseInt (RowsCols[0].toString ())),
-                                              Math.max (1,
-                                                        Integer.parseInt (RowsCols[1].toString ()))));
-        m_List.setPreferredSize (new Dimension (Math.max (1,
-                                                          Integer.parseInt (RowsCols[1].toString ())),
-                                                Math.max (1,
-                                                          Integer.parseInt (RowsCols[0].toString ()))));
-        m_List.setBorder (new javax.swing.border.EtchedBorder ());
+        scrollPane.setMinimumSize (
+          new Dimension (
+            Math.max (1, Integer.parseInt (RowsCols[0].toString ())),
+            Math.max (1, Integer.parseInt (RowsCols[1].toString ()))));
+        scrollPane.setPreferredSize (
+          new Dimension (
+            Math.max (1, Integer.parseInt (RowsCols[1].toString ())),
+            Math.max (1, Integer.parseInt (RowsCols[0].toString ()))));
+        scrollPane.setBorder (new javax.swing.border.EtchedBorder ());
 
         gbc.gridy = message.length;
         gbc.fill = GridBagConstraints.HORIZONTAL;
-        p.add (m_List, gbc);
+        p.add (scrollPane, gbc);
 
         if (on.toLowerCase ().equals ("single"))
           {
--- a/scripts/java/usejava.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/java/usejava.m	Fri Feb 06 08:31:49 2015 -0800
@@ -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 Feb 06 08:31:49 2015 -0800
@@ -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")
+
--- a/scripts/linear-algebra/commutation_matrix.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/linear-algebra/commutation_matrix.m	Fri Feb 06 08:31:49 2015 -0800
@@ -63,8 +63,8 @@
 ## @end ifnottex
 ##  is returned.
 ##
-## See Magnus and Neudecker (1988), @cite{Matrix Differential Calculus with
-## Applications in Statistics and Econometrics.}
+## See @nospell{Magnus and Neudecker} (1988), @cite{Matrix Differential
+## Calculus with Applications in Statistics and Econometrics.}
 ## @end deftypefn
 
 ## Author: KH <Kurt.Hornik@wu-wien.ac.at>
--- a/scripts/linear-algebra/condest.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/linear-algebra/condest.m	Fri Feb 06 08:31:49 2015 -0800
@@ -59,13 +59,13 @@
 ##
 ## @itemize
 ## @item
-## N.J. Higham and F. Tisseur, @cite{A Block Algorithm
+## @nospell{N.J. Higham and F. Tisseur}, @cite{A Block Algorithm
 ## for Matrix 1-Norm Estimation, with an Application to 1-Norm
 ## Pseudospectra}. SIMAX vol 21, no 4, pp 1185-1201.
 ## @url{http://dx.doi.org/10.1137/S0895479899356080}
 ##
 ## @item
-## N.J. Higham and F. Tisseur, @cite{A Block Algorithm
+## @nospell{N.J. Higham and F. Tisseur}, @cite{A Block Algorithm
 ## for Matrix 1-Norm Estimation, with an Application to 1-Norm
 ## Pseudospectra}. @url{http://citeseer.ist.psu.edu/223007.html}
 ## @end itemize
--- a/scripts/linear-algebra/duplication_matrix.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/linear-algebra/duplication_matrix.m	Fri Feb 06 08:31:49 2015 -0800
@@ -54,8 +54,8 @@
 ##  @math{A}.
 ## @end ifnottex
 ##
-## See Magnus and Neudecker (1988), Matrix differential calculus with
-## applications in statistics and econometrics.
+## See @nospell{Magnus and Neudecker} (1988), @cite{Matrix Differential
+## Calculus with Applications in Statistics and Econometrics.}
 ## @end deftypefn
 
 ## Author: KH <Kurt.Hornik@wu-wien.ac.at>
--- a/scripts/linear-algebra/expm.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/linear-algebra/expm.m	Fri Feb 06 08:31:49 2015 -0800
@@ -33,8 +33,8 @@
 ##
 ## @end ifnottex
 ## The Taylor series is @emph{not} the way to compute the matrix
-## exponential; see Moler and Van Loan, @cite{Nineteen Dubious Ways to
-## Compute the Exponential of a Matrix}, SIAM Review, 1978.  This routine
+## exponential; see @nospell{Moler and Van Loan}, @cite{Nineteen Dubious Ways
+## to Compute the Exponential of a Matrix}, SIAM Review, 1978.  This routine
 ## uses Ward's diagonal Pad@'e approximation method with three step
 ## preconditioning (SIAM Journal on Numerical Analysis, 1977).  Diagonal
 ## Pad@'e approximations are rational polynomials of matrices
--- a/scripts/linear-algebra/housh.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/linear-algebra/housh.m	Fri Feb 06 08:31:49 2015 -0800
@@ -43,7 +43,7 @@
 ## @end table
 ##
 ## @noindent
-## Outputs (see Golub and Van Loan):
+## Outputs (see @nospell{Golub and Van Loan}):
 ##
 ## @table @var
 ## @item beta
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/linear-algebra/isbanded.m	Fri Feb 06 08:31:49 2015 -0800
@@ -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 Feb 06 08:31:09 2015 -0800
+++ b/scripts/linear-algebra/isdefinite.m	Fri Feb 06 08:31:49 2015 -0800
@@ -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 Feb 06 08:31:49 2015 -0800
@@ -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 Feb 06 08:31:09 2015 -0800
+++ b/scripts/linear-algebra/ishermitian.m	Fri Feb 06 08:31:49 2015 -0800
@@ -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 Feb 06 08:31:09 2015 -0800
+++ b/scripts/linear-algebra/issymmetric.m	Fri Feb 06 08:31:49 2015 -0800
@@ -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 Feb 06 08:31:49 2015 -0800
@@ -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 Feb 06 08:31:49 2015 -0800
@@ -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 Feb 06 08:31:09 2015 -0800
+++ b/scripts/linear-algebra/krylov.m	Fri Feb 06 08:31:49 2015 -0800
@@ -49,9 +49,9 @@
 ## If the optional parameter @var{pflg} is nonzero, row pivoting is used
 ## to improve numerical behavior.  The default value is 0.
 ##
-## Reference: A. Hodel, P. Misra, @cite{Partial Pivoting in the Computation of
-## Krylov Subspaces of Large Sparse Systems}, Proceedings of the 42nd IEEE
-## Conference on Decision and Control, December 2003.
+## Reference: @nospell{A. Hodel, P. Misra}, @cite{Partial Pivoting in the
+## Computation of Krylov Subspaces of Large Sparse Systems}, Proceedings of
+## the 42nd IEEE Conference on Decision and Control, December 2003.
 ## @end deftypefn
 
 ## Author: A. Scottedward Hodel <a.s.hodel@eng.auburn.edu>
@@ -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 Feb 06 08:31:09 2015 -0800
+++ b/scripts/linear-algebra/module.mk	Fri Feb 06 08:31:49 2015 -0800
@@ -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/linear-algebra/onenormest.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/linear-algebra/onenormest.m	Fri Feb 06 08:31:49 2015 -0800
@@ -20,7 +20,7 @@
 ## @deftypefn  {Function File} {[@var{est}, @var{v}, @var{w}, @var{iter}] =} onenormest (@var{A}, @var{t})
 ## @deftypefnx {Function File} {[@var{est}, @var{v}, @var{w}, @var{iter}] =} onenormest (@var{apply}, @var{apply_t}, @var{n}, @var{t})
 ##
-## Apply Higham and Tisseur's randomized block 1-norm estimator to
+## Apply @nospell{Higham and Tisseur's} randomized block 1-norm estimator to
 ## matrix @var{A} using @var{t} test vectors.  If @var{t} exceeds 5, then
 ## only 5 test vectors are used.
 ##
@@ -41,13 +41,13 @@
 ##
 ## @itemize
 ## @item
-## N.J. Higham and F. Tisseur, @cite{A Block Algorithm
+## @nospell{N.J. Higham and F. Tisseur}, @cite{A Block Algorithm
 ## for Matrix 1-Norm Estimation, with an Application to 1-Norm
 ## Pseudospectra}. SIMAX vol 21, no 4, pp 1185-1201.
 ## @url{http://dx.doi.org/10.1137/S0895479899356080}
 ##
 ## @item
-## N.J. Higham and F. Tisseur, @cite{A Block Algorithm
+## @nospell{N.J. Higham and F. Tisseur}, @cite{A Block Algorithm
 ## for Matrix 1-Norm Estimation, with an Application to 1-Norm
 ## Pseudospectra}. @url{http://citeseer.ist.psu.edu/223007.html}
 ## @end itemize
--- a/scripts/linear-algebra/planerot.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/linear-algebra/planerot.m	Fri Feb 06 08:31:49 2015 -0800
@@ -17,8 +17,8 @@
 ## <http://www.gnu.org/licenses/>.
 
 ## -*- texinfo -*-
-## @deftypefn {Function File} {[@var{g}, @var{y}] =} planerot (@var{x})
-## Given a two-element column vector, returns the
+## @deftypefn {Function File} {[@var{G}, @var{y}] =} planerot (@var{x})
+## Given a two-element column vector, return the
 ## @tex
 ## $2 \times 2$ orthogonal matrix
 ## @end tex
@@ -31,8 +31,16 @@
 ## @end deftypefn
 
 function [G, y] = planerot (x)
+
+  if (nargin != 1)
+    print_usage ();
+  elseif (! (isvector (x) && numel (x) == 2))
+    error ("planerot: X must be a 2-element vector");
+  endif
+
   G = givens (x(1), x(2));
   y = G * x(:);
+
 endfunction
 
 
@@ -42,7 +50,8 @@
 %! assert (g, [x(1) x(2); -x(2) x(1)] / sqrt (x(1)^2 + x(2)^2), 2e-8);
 %! assert (y(2), 0, 2e-8);
 
-%!error planerot ([0])
-%!error planerot ([0 0 0])
 %!error planerot ()
+%!error planerot (1,2)
+%!error <X must be a 2-element vector> planerot (ones (2,2))
+%!error <X must be a 2-element vector> planerot ([0 0 0])
 
--- a/scripts/linear-algebra/qzhess.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/linear-algebra/qzhess.m	Fri Feb 06 08:31:49 2015 -0800
@@ -35,9 +35,9 @@
 ## @end example
 ##
 ## The Hessenberg-triangular decomposition is the first step in
-## Moler and Stewart's QZ@tie{}decomposition algorithm.
+## @nospell{Moler and Stewart's} QZ@tie{}decomposition algorithm.
 ##
-## Algorithm taken from Golub and Van Loan,
+## Algorithm taken from @nospell{Golub and Van Loan},
 ## @cite{Matrix Computations, 2nd edition}.
 ##
 ## @seealso{lu, chol, hess, qr, qz, schur, svd}
--- a/scripts/linear-algebra/subspace.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/linear-algebra/subspace.m	Fri Feb 06 08:31:49 2015 -0800
@@ -60,3 +60,18 @@
 
 endfunction
 
+
+%!test
+%! ## For random vectors
+%! a = rand (2,1);
+%! b = rand (2,1);
+%! a1 = norm (a,2);
+%! b1 = norm (b,2);
+%! theta = acos (dot (a,b)/(a1*b1));
+%! assert (theta, subspace (a, b), 100*eps);
+
+%!test
+%! ## For random matrices
+%! M = rand (3, 3);
+%! assert (0, subspace (M, M'), 100*eps);
+
--- a/scripts/linear-algebra/vech.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/linear-algebra/vech.m	Fri Feb 06 08:31:49 2015 -0800
@@ -19,7 +19,7 @@
 
 ## -*- texinfo -*-
 ## @deftypefn {Function File} {} vech (@var{x})
-## Return the vector obtained by eliminating all supradiagonal elements of
+## Return the vector obtained by eliminating all superdiagonal elements of
 ## the square matrix @var{x} and stacking the result one column above the
 ## other.  This has uses in matrix calculus where the underlying matrix
 ## is symmetric and it would be pointless to keep values above the main
--- a/scripts/miscellaneous/ans.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/miscellaneous/ans.m	Fri Feb 06 08:31:49 2015 -0800
@@ -18,8 +18,10 @@
 
 ## -*- texinfo -*-
 ## @defvr {Automatic Variable} ans
-## The most recently computed result that was not
-## explicitly assigned to a variable.  For example, after the expression
+## The most recently computed result that was not explicitly assigned to a
+## variable.
+##
+## For example, after the expression
 ##
 ## @example
 ## 3^2 + 4^2
--- a/scripts/miscellaneous/bug_report.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/miscellaneous/bug_report.m	Fri Feb 06 08:31:49 2015 -0800
@@ -25,22 +25,22 @@
 
 function bug_report ()
 
-  puts ("\n");
-  puts ("  Bug reports play an essential role in making Octave\n");
-  puts ("  reliable.  Please use the Octave bug tracker at\n");
-  puts ("\n");
-  puts ("    http://bugs.octave.org\n");
-  puts ("\n");
-  puts ("  to report problems.\n");
-  puts ("\n");
-  puts ("  Please also read the bug reporting guidelines at\n");
-  puts ("\n");
-  puts ("    http://www.octave.org/bugs.html\n");
-  puts ("\n");
-  puts ("  to learn how to submit useful bug reports that will\n");
-  puts ("  help the Octave community diagnose and fix the problem\n");
-  puts ("  quickly and efficiently.\n");
-  puts ("\n");
+  disp (" ");
+  disp ("  Bug reports play an essential role in making Octave");
+  disp ("  reliable.  Please use the Octave bug tracker at");
+  disp (" ");
+  disp ("    http://bugs.octave.org");
+  disp (" ");
+  disp ("  to report problems.");
+  disp (" ");
+  disp ("  Please also read the bug reporting guidelines at");
+  disp (" ");
+  disp ("    http://www.octave.org/bugs.html");
+  disp (" ");
+  disp ("  to learn how to submit useful bug reports that will");
+  disp ("  help the Octave community diagnose and fix the problem");
+  disp ("  quickly and efficiently.");
+  disp (" ");
 
 endfunction
 
--- a/scripts/miscellaneous/bunzip2.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/miscellaneous/bunzip2.m	Fri Feb 06 08:31:49 2015 -0800
@@ -17,27 +17,39 @@
 ## <http://www.gnu.org/licenses/>.
 
 ## -*- texinfo -*-
-## @deftypefn  {Function File} {} bunzip2 (@var{bzfile})
-## @deftypefnx {Function File} {} bunzip2 (@var{bzfile}, @var{dir})
-## Unpack the bzip2 archive @var{bzfile} to the directory @var{dir}.  If
-## @var{dir} is not specified, it defaults to the current directory.
+## @deftypefn  {Function File} {@var{filelist} =} bunzip2 (@var{bzfile})
+## @deftypefnx {Function File} {@var{filelist} =} bunzip2 (@var{bzfile}, @var{dir})
+## Unpack the bzip2 archive @var{bzfile}.
+##
+## If @var{dir} is specified the files are unpacked in this directory rather
+## than the one where @var{bzfile} is located.
+##
+## The optional output @var{filelist} is a list of the uncompressed files.
 ## @seealso{bzip2, unpack, gunzip, unzip, untar}
 ## @end deftypefn
 
 ## Author: Bill Denney <denney@seas.upenn.edu>
 
-function varargout = bunzip2 (bzfile, dir = ".")
+function filelist = bunzip2 (bzfile, dir = [])
 
-  if (nargin != 1 && nargin != 2)
+  if (nargin < 1 || nargin > 2)
     print_usage ();
   endif
 
+  if (isempty (dir))
+    dir = fileparts (bzfile);
+  endif
+
   if (nargout > 0)
-    varargout = cell (1, nargout);
-    [varargout{:}] = unpack (bzfile, dir, mfilename ());
+    filelist = unpack (bzfile, dir, "bunzip2");
   else
-    unpack (bzfile, dir, mfilename ());
+    unpack (bzfile, dir, "bunzip2");
   endif
 
 endfunction
 
+
+## Tests for this m-file are located in bzip2.m
+## Remove from test statistics
+%!assert (1)
+
--- a/scripts/miscellaneous/bzip2.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/miscellaneous/bzip2.m	Fri Feb 06 08:31:49 2015 -0800
@@ -18,46 +18,71 @@
 ## <http://www.gnu.org/licenses/>.
 
 ## -*- texinfo -*-
-## @deftypefn  {Function File} {@var{entries} =} bzip2 (@var{files})
-## @deftypefnx {Function File} {@var{entries} =} bzip2 (@var{files}, @var{outdir})
+## @deftypefn  {Function File} {@var{filelist} =} bzip2 (@var{files})
+## @deftypefnx {Function File} {@var{filelist} =} bzip2 (@var{files}, @var{dir})
 ## Compress the list of files specified in @var{files}.
-## Each file is compressed separately and a new file with a @file{".bz2"}
-## extension is created.  The original files are not modified.  Existing
-## compressed files are silently overwritten.  If @var{outdir} is defined the
-## compressed files are placed in this directory.
-## @seealso{bunzip2, gzip, zip, tar}
+##
+## @var{files} is a character array or cell array of strings.  Shell
+## wildcards in the filename such as @samp{*} or @samp{?} are accepted and
+## expanded.  Each file is compressed separately and a new file with a
+## @file{".bz2"} extension is created.  The original files are not modified,
+## but existing compressed files will be silently overwritten.
+##
+## If @var{dir} is defined the compressed files are placed in this directory,
+## rather than the original directory where the uncompressed file resides.
+## If @var{dir} does not exist it is created.
+##
+## The optional output @var{filelist} is a list of the compressed files.
+## @seealso{bunzip2, unpack, gzip, zip, tar}
 ## @end deftypefn
 
-function entries = bzip2 (varargin)
+function filelist = bzip2 (varargin)
 
-  if (nargin == 1 || nargin == 2)
-    if (nargout == 0)
-      __xzip__ ("bzip2", "bz2", "bzip2 %s", varargin{:});
-    else
-      entries = __xzip__ ("bzip2", "bz2", "bzip2 %s", varargin{:});
-    endif
+  if (nargin < 1 || nargin > 2 || nargout > 1)
+    print_usage ();
+  endif
+
+  if (nargout == 0)
+    __xzip__ ("bzip2", "bz2", "bzip2 %s", varargin{:});
   else
-    print_usage ();
+    filelist = __xzip__ ("bzip2", "bz2", "bzip2 %s", varargin{:});
   endif
 
 endfunction
 
 
 %!xtest
-%! ## test for correct cleanup of temporary files
+%! ## test bzip2 together with bunzip2
 %! unwind_protect
-%!   filename = tmpnam;
-%!   dummy    = 1;
+%!   filename = tempname;
+%!   dummy    = pi;
 %!   save (filename, "dummy");
-%!   n_tmpfiles_before = length (find (strncmp ("oct-", cellstr (ls (tempdir)), 4)));
-%!   entry = bzip2 (filename);
-%!   n_tmpfiles_after = length (find (strncmp ("oct-", cellstr (ls (tempdir)), 4)));
-%!   if (n_tmpfiles_before != n_tmpfiles_after)
-%!     error ("bzip2 has not cleaned up temporary files correctly!");
+%!   dirname  = tempname;
+%!   mkdir (dirname);
+%!   filelist = bzip2 (filename, dirname);
+%!   filelist = filelist{1};
+%!   [~, basename, extension] = fileparts (filename);
+%!   if (! strcmp (filelist, [dirname, filesep, basename, extension, ".bz2"]))
+%!     error ("bzipped file does not match expected name!");
+%!   endif
+%!   if (! exist (filelist, "file"))
+%!     error ("bzipped file cannot be found!");
+%!   endif
+%!   bunzip2 (filelist);
+%!   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 ("bunzipped file not equal to original file!");
 %!   endif
 %! unwind_protect_cleanup
 %!   delete (filename);
-%!   [path, basename, extension] = fileparts (filename);
-%!   delete ([basename, extension, ".bz2"]);
+%!   delete ([dirname, filesep, basename, extension]);
+%!   rmdir (dirname);
 %! end_unwind_protect
 
--- a/scripts/miscellaneous/cast.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/miscellaneous/cast.m	Fri Feb 06 08:31:49 2015 -0800
@@ -17,30 +17,82 @@
 ## <http://www.gnu.org/licenses/>.
 
 ## -*- texinfo -*-
-## @deftypefn {Function File} {} cast (@var{val}, @var{type})
+## @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}
+##
+## @var{val} must be one of the numeric classes:
+##
+## @example
+## @group
+## "double"
+## "single"
+## "logical"
+## "char"
+## "int8"
+## "int16"
+## "int32"
+## "int64"
+## "uint8"
+## "uint16"
+## "uint32"
+## "uint64"
+## @end group
+## @end example
+##
+## 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, class, typeinfo}
 ## @end deftypefn
 
 ## Author: jwe
 
-function retval = cast (val, typ)
+function retval = cast (val, type)
 
-  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
-    else
-      error ("cast: expecting TYPE name as second argument");
-    endif
-  else
+  if (nargin != 2)
     print_usage ();
   endif
 
+  if (! ischar (type))
+    error ("cast: TYPE must be a string");
+  elseif (! any (strcmp (type, {"int8"; "uint8"; "int16"; "uint16";
+                                "int32"; "uint32"; "int64"; "uint64";
+                                "double"; "single"; "logical"; "char"})))
+    error ("cast: TYPE '%s' is not a built-in type", type);
+  endif
+
+  retval = feval (type, val);
+
 endfunction
 
+
+%!assert (cast (single (2.5), "double"), 2.5)
+%!assert (cast (2.5, "single"), single (2.5))
+%!assert (cast ([5 0 -5], "logical"), [true false true])
+%!assert (cast ([65 66 67], "char"), "ABC")
+%!assert (cast ([-2.5 1.1 2.5], "int8"), int8 ([-3 1 3]))
+%!assert (cast ([-2.5 1.1 2.5], "uint8"), uint8 ([0 1 3]))
+%!assert (cast ([-2.5 1.1 2.5], "int16"), int16 ([-3 1 3]))
+%!assert (cast ([-2.5 1.1 2.5], "uint16"), uint16 ([0 1 3]))
+%!assert (cast ([-2.5 1.1 2.5], "int32"), int32 ([-3 1 3]))
+%!assert (cast ([-2.5 1.1 2.5], "uint32"), uint32 ([0 1 3]))
+%!assert (cast ([-2.5 1.1 2.5], "int64"), int64 ([-3 1 3]))
+%!assert (cast ([-2.5 1.1 2.5], "uint64"), uint64 ([0 1 3]))
+
+## Test input validation
+%!error cast ()
+%!error cast (1)
+%!error cast (1,2,3)
+%!error <TYPE 'foobar' is not a built-in type> cast (1, "foobar")
+%!error <TYPE must be a string> cast (1, {"foobar"})
+
--- a/scripts/miscellaneous/colon.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/miscellaneous/colon.m	Fri Feb 06 08:31:49 2015 -0800
@@ -33,14 +33,14 @@
 ## @seealso{class, subsref, subsasgn}
 ## @end deftypefn
 
-function r = colon (varargin)
+function colon (varargin)
+
   if (nargin != 0)
     error ('colon: not defined for class "%s"', class (varargin{1}));
   endif
+
 endfunction
 
 
-%!error colon (1)
+%!error <colon: not defined for class "double"> colon (1)
 
-## FIXME -- what does colon () mean since it doesn't set a return value?
-
--- a/scripts/miscellaneous/compare_versions.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/miscellaneous/compare_versions.m	Fri Feb 06 08:31:49 2015 -0800
@@ -80,87 +80,68 @@
 
   ## Make sure that the version numbers are valid.
   if (! (ischar (v1) && ischar (v2)))
-    error ("compare_versions: both version numbers must be strings");
+    error ("compare_versions: version numbers V1 and V2 must be strings");
   elseif (rows (v1) != 1 || rows (v2) != 1)
-    error ("compare_versions: version numbers must be a single row");
+    error ("compare_versions: version numbers V1 and V2 must be a single row");
   endif
 
   ## check and make sure that the operator is valid
   if (! ischar (operator))
-    error ("compare_versions: OPERATOR must be a character string");
+    error ("compare_versions: OPERATOR must be a string");
   elseif (numel (operator) > 2)
     error ("compare_versions: OPERATOR must be 1 or 2 characters long");
   endif
 
-  ## trim off any character data that is not part of a normal version
-  ## number
-  numbers = "0123456789.";
+  ## trim off any character data that is not part of a normal version number
+  v1firstchar = find (! (isdigit (v1) | v1 == "."), 1);
+  v2firstchar = find (! (isdigit (v2) | v2 == "."), 1);
 
-  v1firstchar = find (! ismember (v1, numbers), 1);
-  v2firstchar = find (! ismember (v2, numbers), 1);
-  if (! isempty (v1firstchar))
-    v1c = v1(v1firstchar:length (v1));
-    v1nochar = v1(1:v1firstchar-1);
-  else
+  if (isempty (v1firstchar))
     v1c = "";
     v1nochar = v1;
+  else
+    v1c = v1(v1firstchar:end);
+    v1nochar = v1(1:v1firstchar-1);
   endif
-  if (! isempty (v2firstchar))
-    v2c = v2(v2firstchar:length (v2));
-    v2nochar = v2(1:v2firstchar-1);
-  else
+  if (isempty (v2firstchar))
     v2c = "";
     v2nochar = v2;
-  endif
-
-  v1n = str2num (char (ostrsplit (v1nochar, ".")));
-  v2n = str2num (char (ostrsplit (v2nochar, ".")));
-  if ((isempty (v1n) && isempty (v1c)) || (isempty (v2n) && isempty (v2c)))
-    error ("compare_versions: given version strings are not valid: %s %s",
-           v1, v2);
+  else
+    v2c = v2(v2firstchar:end);
+    v2nochar = v2(1:v2firstchar-1);
   endif
 
-  ## Assume that any additional elements would be 0 if one is longer
-  ## than the other.
-  maxnumlen = max ([length(v1n) length(v2n)]);
-  if (length (v1n) < maxnumlen)
-    v1n(length(v1n)+1:maxnumlen) = 0;
+  v1n = str2double (ostrsplit (v1nochar, ".")');
+  if (isnan (v1n))
+    v1n = [];
   endif
-  if (length (v2n) < maxnumlen)
-    v2n(length(v2n)+1:maxnumlen) = 0;
+  v2n = str2double (ostrsplit (v2nochar, ".")');
+  if (isnan (v2n))
+    v2n = [];
   endif
 
-  ## Assume that any additional character elements would be 0 if one is
-  ## longer than the other.
+  if (isempty (v1n) && isempty (v1c))
+    error ("compare_versions: version string V1 is not valid: %s", v1);
+  elseif  (isempty (v2n) && isempty (v2c))
+    error ("compare_versions: version string V2 is not valid: %s", v2);
+  endif
+
+  ## Assume any additional elements would be 0 if one is longer than the other.
+  maxnumlen = max ([length(v1n) length(v2n)]);
+  v1n(end+1:maxnumlen) = 0;
+  v2n(end+1:maxnumlen) = 0;
+
+  ## Assume any additional character elements would be 0,
+  ## if one is longer than the other.
   maxcharlen = max ([length(v1c), length(v2c)]);
-  if (length (v1c) < maxcharlen)
-    v1c(length(v1c)+1:maxcharlen) = "\0";
-  endif
-  if (length (v2c) < maxcharlen)
-    v2c(length(v2c)+1:maxcharlen) = "\0";
-  endif
+  v1c(end+1:maxcharlen) = "\0";
+  v2c(end+1:maxcharlen) = "\0";
 
   ## Determine the operator.
-  if (any (ismember (operator, "=")))
-    equal_op = true;
-  else
-    equal_op = false;
-  endif
-  if (any (ismember (operator, "~!")))
-    not_op = true;
-  else
-    not_op = false;
-  endif
-  if (any (ismember (operator, "<")))
-    lt_op = true;
-  else
-    lt_op = false;
-  endif
-  if (any (ismember (operator, ">")))
-    gt_op = true;
-  else
-    gt_op = false;
-  endif
+  equal_op = any (operator == "=");
+  not_op = any (operator == "!" | operator == "~");
+  lt_op = any (operator == "<");
+  gt_op = any (operator == ">");
 
   ## Make sure that we don't have conflicting operators.
   if (gt_op && lt_op)
@@ -168,9 +149,9 @@
   elseif ((gt_op || lt_op) && not_op)
     error ("compare_versions: OPERATOR cannot contain not and greater than or less than symbols");
   elseif (strcmp (operator, "="))
-    error ("compare_versions: equality OPERATOR is \"==\", not \"=\"");
+    error ('compare_versions: equality OPERATOR is "==", not "="');
   elseif (! (equal_op || not_op || lt_op || gt_op))
-    error ("compare_versions: No valid OPERATOR specified");
+    error ("compare_versions: no valid OPERATOR specified");
   endif
 
   ## Compare the versions (making sure that they're the same shape)
@@ -180,7 +161,7 @@
     ## so that we only need to check for the output being greater than 1
     vcmp = -vcmp;
   endif
-  firstdiff = find (vcmp != 0, 1);
+  firstdiff = find (vcmp, 1);
 
   if (isempty (firstdiff))
     ## They're equal.
@@ -242,12 +223,22 @@
 %!assert (compare_versions ("0.1", "0.1", "~="), false)
 
 %% Test input validation
-%!error (compare_versions (0.1, "0.1", "=="))
-%!error (compare_versions ("0.1", 0.1, "=="))
-%!error (compare_versions (["0";".";"1"], "0.1", "=="))
-%!error (compare_versions ("0.1", ["0";".";"1"], "=="))
-%!error (compare_versions ("0.1", "0.1", "<>"))
-%!error (compare_versions ("0.1", "0.1", "!>"))
-%!error (compare_versions ("0.1", "0.1", "="))
-%!error (compare_versions ("0.1", "0.1", "aa"))
+%!error compare_versions ()
+%!error compare_versions (1)
+%!error compare_versions (1,2)
+%!error compare_versions (1,2,3,4)
+%!error <V1 and V2 must be strings> compare_versions (0.1, "0.1", "==")
+%!error <V1 and V2 must be strings> compare_versions ("0.1", 0.1, "==")
+%!error <V1 and V2 must be a single row> compare_versions (["0";".";"1"], "0.1", "==")
+%!error <V1 and V2 must be a single row> compare_versions ("0.1", ["0";".";"1"], "==")
+%!error <OPERATOR must be a string> compare_versions ("0.1", "0.1", 1)
+%!error <OPERATOR must be 1 or 2> compare_versions ("0.1", "0.1", "==>")
+%!error <V1 is not valid> compare_versions (".", "0.1", "==")
+%!error <V2 is not valid> compare_versions ("0.1", ".", "==")
 
+%!error <cannot contain both greater and less than> compare_versions ("0.1", "0.1", "<>")
+%!error <cannot contain not and greater than> compare_versions ("0.1", "0.1", "!>")
+%!error <cannot contain not and greater than> compare_versions ("0.1", "0.1", "!<")
+%!error <equality OPERATOR is "=="> compare_versions ("0.1", "0.1", "=")
+%!error <no valid OPERATOR> compare_versions ("0.1", "0.1", "aa")
+
--- a/scripts/miscellaneous/computer.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/miscellaneous/computer.m	Fri Feb 06 08:31:49 2015 -0800
@@ -17,45 +17,49 @@
 ## <http://www.gnu.org/licenses/>.
 
 ## -*- texinfo -*-
-## @deftypefn  {Function File} {[@var{c}, @var{maxsize}, @var{endian}] =} computer ()
+## @deftypefn  {Function File} {} computer ()
+## @deftypefnx {Function File} {@var{c} =} computer ()
+## @deftypefnx {Function File} {[@var{c}, @var{maxsize}] =} computer ()
+## @deftypefnx {Function File} {[@var{c}, @var{maxsize}, @var{endian}] =} computer ()
 ## @deftypefnx {Function File} {@var{arch} =} computer ("arch")
 ## Print or return a string of the form @var{cpu}-@var{vendor}-@var{os}
-## that identifies the kind of computer Octave is running on.  If invoked
-## with an output argument, the value is returned instead of printed.  For
-## example:
+## that identifies the type of computer that Octave is running on.
+##
+## If invoked with an output argument, the value is returned instead of
+## printed.  For example:
 ##
 ## @example
 ## @group
 ## computer ()
 ##    @print{} i586-pc-linux-gnu
 ##
-## x = computer ()
-##    @result{} x = "i586-pc-linux-gnu"
+## mycomp = computer ()
+##    @result{} mycomp = "i586-pc-linux-gnu"
 ## @end group
 ## @end example
 ##
 ## If two output arguments are requested, also return the maximum number
-## of elements for an array.
+## of elements for an array.  This will depend on whether Octave has been
+## compiled with 32-bit or 64-bit index vectors.
 ##
 ## If three output arguments are requested, also return the byte order
 ## of the current system as a character (@qcode{"B"} for big-endian or
 ## @qcode{"L"} for little-endian).
 ##
-## If the argument @qcode{"arch"} is specified, return a string
-## indicating the architecture of the computer on which Octave is
-## running.
+## If the argument @qcode{"arch"} is specified, return a string indicating the
+## architecture of the computer on which Octave is running.
+## @seealso{isunix, ismac, ispc}
 ## @end deftypefn
 
 function [c, maxsize, endian] = computer (a)
 
-  if (nargin == 1 && ischar (a) && strcmpi (a, "arch"))
-    tmp = ostrsplit (octave_config_info ("canonical_host_type"), "-");
-    if (numel (tmp) == 4)
-      c = sprintf ("%s-%s-%s", tmp{4}, tmp{3}, tmp{1});
-    else
-      c = sprintf ("%s-%s", tmp{3}, tmp{1});
-    endif
-  elseif (nargin == 0)
+  if (nargin > 1)
+    print_usage ();
+  elseif (nargin == 1 && ! strcmpi (a, "arch"))
+    error ('computer: "arch" is only valid argument');
+  endif
+
+  if (nargin == 0)
     msg = octave_config_info ("canonical_host_type");
 
     if (strcmp (msg, "unknown"))
@@ -63,24 +67,35 @@
     endif
 
     if (nargout == 0)
-      printf ("%s\n", msg);
+      disp (msg);
     else
       c = msg;
-      if (strcmp (octave_config_info ("USE_64_BIT_IDX_T"), "true"))
-        maxsize = 2^63-1;
-      else
-        maxsize = 2^31-1;
+      if (isargout (2))
+        if (strcmp (octave_config_info ("USE_64_BIT_IDX_T"), "true"))
+          maxsize = 2^63-1;
+        else
+          maxsize = 2^31-1;
+        endif
       endif
-      if (octave_config_info ("words_big_endian"))
-        endian = "B";
-      elseif (octave_config_info ("words_little_endian"))
-        endian = "L";
-      else
-        endian = "?";
+      if (isargout (3))
+        if (octave_config_info ("words_big_endian"))
+          endian = "B";
+        elseif (octave_config_info ("words_little_endian"))
+          endian = "L";
+        else
+          endian = "?";
+        endif
       endif
     endif
   else
-    print_usage ();
+    ## "arch" argument asked for
+    tmp = ostrsplit (octave_config_info ("canonical_host_type"), "-");
+    if (numel (tmp) == 4)
+      c = sprintf ("%s-%s-%s", tmp{4}, tmp{3}, tmp{1});
+    else
+      c = sprintf ("%s-%s", tmp{3}, tmp{1});
+    endif
+
   endif
 
 endfunction
@@ -90,5 +105,6 @@
 %!assert (computer (), octave_config_info ("canonical_host_type"))
 %!assert (ischar (computer ("arch")))
 
-%!error computer (2)
+%!error computer (1,2)
+%!error <"arch" is only valid argument> computer ("xyz")
 
--- a/scripts/miscellaneous/copyfile.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/miscellaneous/copyfile.m	Fri Feb 06 08:31:49 2015 -0800
@@ -19,11 +19,12 @@
 ## -*- texinfo -*-
 ## @deftypefn  {Function File} {[@var{status}, @var{msg}, @var{msgid}] =} copyfile (@var{f1}, @var{f2})
 ## @deftypefnx {Function File} {[@var{status}, @var{msg}, @var{msgid}] =} copyfile (@var{f1}, @var{f2}, 'f')
-## Copy the file @var{f1} to the destination @var{f2}.
+## Copy the source files or directories @var{f1} to the destination @var{f2}.
 ##
 ## The name @var{f1} may contain globbing patterns.  If @var{f1} expands to
 ## multiple file names, @var{f2} must be a directory.
-## when the force flag @qcode{'f'} is given any existing files will be
+##
+## When the force flag @qcode{'f'} is given any existing files will be
 ## overwritten without prompting.
 ##
 ## If successful, @var{status} is 1, and @var{msg}, @var{msgid} are empty
@@ -45,8 +46,8 @@
   msg = "";
   msgid = "";
 
-  ## FIXME: maybe use the same method as in ls to allow users control
-  ## over the command that is executed.
+  ## FIXME: Maybe use the same method as in ls to allow users control
+  ##        over the command that is executed.
 
   if (ispc () && ! isunix ()
       && isempty (file_in_path (getenv ("PATH"), "cp.exe")))
@@ -59,26 +60,22 @@
   endif
 
   ## Input type check.
-  if (! (ischar (f1) || iscellstr (f1)))
-    error ("copyfile: F1 must be a character string or a cell array of character strings");
+  if (ischar (f1))
+    f1 = cellstr (f1);
+  elseif (! iscellstr (f1))
+    error ("copyfile: F1 must be a string or a cell array of strings");
   endif
-
   if (! ischar (f2))
-    error ("copyfile: F2 must be a character string");
+    error ("copyfile: F2 must be a string");
   endif
 
   if (nargin == 3 && strcmp (force, "f"))
     cmd = [cmd " " cmd_force_flag];
   endif
 
-  ## If f1 isn't a cellstr convert it to one.
-  if (ischar (f1))
-    f1 = cellstr (f1);
-  endif
-
-  ## If f1 has more than 1 element f2 must be a directory
+  ## If f1 has more than 1 element then f2 must be a directory
   isdir = (exist (f2, "dir") != 0);
-  if (length (f1) > 1 && ! isdir)
+  if (numel (f1) > 1 && ! isdir)
     error ("copyfile: when copying multiple files, F2 must be a directory");
   endif
 
@@ -132,3 +129,36 @@
 
 endfunction
 
+
+%!test
+%! unwind_protect
+%!   f1 = tempname;
+%!   tmp_var = pi;
+%!   save (f1, "tmp_var");
+%!   f2 = tempname;
+%!   assert (copyfile (f1, f2));
+%!   assert (exist (f2, "file"));
+%!   fid = fopen (f1, "rb");
+%!   assert (fid >= 0);
+%!   orig_data = fread (fid);
+%!   fclose (fid);
+%!   fid = fopen (f2, "rb");
+%!   assert (fid >= 0);
+%!   new_data = fread (fid);
+%!   fclose (fid);
+%!   if (orig_data != new_data)
+%!     error ("copied file not equal to original file!");
+%!   endif
+%! unwind_protect_cleanup
+%!   delete (f1);
+%!   delete (f2);
+%! end_unwind_protect
+
+## Test input validation
+%!error copyfile ()
+%!error copyfile (1)
+%!error copyfile (1,2,3,4)
+%!error <F1 must be a string> copyfile (1, "foobar")
+%!error <F2 must be a string> copyfile ("foobar", 1)
+%!error <F2 must be a directory> copyfile ({"a", "b"}, "%_NOT_A_DIR_%")
+
--- a/scripts/miscellaneous/debug.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/miscellaneous/debug.m	Fri Feb 06 08:31:49 2015 -0800
@@ -18,8 +18,10 @@
 
 ## -*- texinfo -*-
 ## @deftypefn {Function File} {} debug ()
-## Summary of debugging commands.  For more information on each command
-## and available options use @code{help CMD}.
+## Summary of debugging commands.
+##
+## For more information on each command and available options use
+## @code{help CMD}.
 ##
 ## The debugging commands available in Octave are
 ##
@@ -96,3 +98,7 @@
   help ("debug");
 endfunction
 
+
+## Mark file as being tested.  No real test needed for a documentation .m file
+%!assert (1)
+
--- a/scripts/miscellaneous/delete.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/miscellaneous/delete.m	Fri Feb 06 08:31:49 2015 -0800
@@ -18,37 +18,47 @@
 
 ## -*- texinfo -*-
 ## @deftypefn  {Function File} {} delete (@var{file})
+## @deftypefnx {Function File} {} delete (@var{file1}, @var{file2}, @dots{})
 ## @deftypefnx {Function File} {} delete (@var{handle})
 ## Delete the named file or graphics handle.
 ##
-## Deleting graphics objects is the proper way to remove
+## @var{file} may contain globbing patterns such as @samp{*}.  Multiple files
+## to be deleted may be specified in the same function call.
+##
+## @var{handle} may be a scalar or vector of graphic handles to delete.
+##
+## Programming Note: Deleting graphics objects is the proper way to remove
 ## features from a plot without clearing the entire figure.
-## @seealso{clf, cla, unlink}
+## @seealso{clf, cla, unlink, rmdir}
 ## @end deftypefn
 
 ## Author: jwe
 
-function delete (arg)
+function delete (varargin)
 
-  if (nargin != 1)
+  if (nargin == 0)
     print_usage ();
   endif
 
-  if (ischar (arg))
-    files = glob (arg);
-    if (isempty (files))
-      warning ("delete: no such file: %s", arg);
-    endif
-    for i = 1:length (files)
-      file = files{i};
-      [err, msg] = unlink (file);
-      if (err)
-        warning ("delete: %s: %s", file, msg);
+  if (iscellstr (varargin))
+    for arg = varargin
+      files = glob (arg{1});
+      if (isempty (files))
+        warning ("delete: no such file: %s", arg{1});
       endif
+      for i = 1:length (files)
+        file = files{i};
+        [err, msg] = unlink (file);
+        if (err)
+          warning ("delete: %s: %s", file, msg);
+        endif
+      endfor
     endfor
-  elseif (all (ishandle (arg(:))))
+
+  elseif (isscalar (varargin) && all (ishandle (varargin{1}(:))))
     ## Delete a graphics object.
-    __go_delete__ (arg);
+    __go_delete__ (varargin{1});
+
   else
     error ("delete: first argument must be a filename or graphics handle");
   endif
@@ -56,8 +66,30 @@
 endfunction
 
 
+%!test
+%! unwind_protect
+%!   file = tempname;
+%!   tmp_var = pi;
+%!   save (file, "tmp_var");
+%!   assert (exist (file, "file"));
+%!   delete (file);
+%!   assert (! exist (file, "file"));
+%! unwind_protect_cleanup
+%!   unlink (file);
+%! end_unwind_protect
+
+%!test
+%! unwind_protect
+%!   hf = figure ("visible", "off");
+%!   hl = plot (1:10);
+%!   assert (get (gca, "children"), hl);
+%!   delete (hl);
+%!   assert (get (gca, "children"), zeros (0,1));
+%! unwind_protect_cleanup
+%!   close (hf);
+%! end_unwind_protect
+
 %% Test input validation
 %!error delete ()
-%!error delete (1, 2)
 %!error <first argument must be a filename> delete (struct ())
 
--- a/scripts/miscellaneous/desktop.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/miscellaneous/desktop.m	Fri Feb 06 08:31:49 2015 -0800
@@ -17,7 +17,7 @@
 ## <http://www.gnu.org/licenses/>.
 
 ## -*- texinfo -*-
-## @deftypefn {Function File} {} @var{used} = desktop ("-inuse")
+## @deftypefn {Function File} {@var{used} =} desktop ("-inuse")
 ## Return true if the desktop (GUI) is currently in use.
 ## @seealso{isguirunning}
 ## @end deftypefn
--- a/scripts/miscellaneous/dir.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/miscellaneous/dir.m	Fri Feb 06 08:31:49 2015 -0800
@@ -51,21 +51,21 @@
 ## than a single directory or file.
 ##
 ## @var{directory} is subject to shell expansion if it contains any wildcard
-## characters @samp{*}, @samp{?}, @samp{[]}.  If you want to find a
-## literal example of a wildcard character you must escape it using the
-## backslash operator @samp{\}.
+## characters @samp{*}, @samp{?}, @samp{[]}.  To find a literal example of a
+## wildcard character the wildcard must be escaped using the backslash operator
+## @samp{\}.
 ##
 ## Note that for symbolic links, @code{dir} returns information about
 ## the file that the symbolic link points to rather than the link itself.
 ## However, if the link points to a nonexistent file, @code{dir} returns
 ## information about the link.
-## @seealso{ls, readdir, glob, what, stat}
+## @seealso{ls, readdir, glob, what, stat, lstat}
 ## @end deftypefn
 
 ## Author: jwe
 
-## FIXME: This is quite slow for large directories, so perhaps
-##        it should be converted to C++.
+## FIXME: This is quite slow for large directories.
+##        Perhaps it should be converted to C++?
 
 function retval = dir (directory)
 
@@ -75,79 +75,78 @@
     print_usage ();
   endif
 
+  if (! ischar (directory))
+    error ("dir: DIRECTORY argument must be a string");
+  endif
+
   ## Prep the retval.
   info = struct (zeros (0, 1),
                  {"name", "date", "bytes", "isdir", "datenum", "statinfo"});
 
-  if (ischar (directory))
-    if (strcmp (directory, "*"))
-      directory = ".";
-    endif
-    if (strcmp (directory, "."))
-      flst = {"."};
-      nf = 1;
-    else
-      flst = glob (directory);
-      nf = length (flst);
-    endif
 
-    ## Determine the file list for the case where a single directory is
-    ## specified.
-    if (nf == 1)
-      fn = flst{1};
-      [st, err, msg] = stat (fn);
-      if (err < 0)
-        warning ("dir: 'stat (%s)' failed: %s", fn, msg);
-        nf = 0;
-      elseif (S_ISDIR (st.mode))
-        flst = readdir (flst{1});
-        nf = length (flst);
-        for i = 1:nf
-          flst{i} = fullfile (fn, flst{i});
-        endfor
-      endif
-    endif
+  if (strcmp (directory, "*"))
+    directory = ".";
+  endif
+  if (strcmp (directory, "."))
+    flst = {"."};
+    nf = 1;
+  else
+    flst = glob (directory);
+    nf = numel (flst);
+  endif
 
-    if (length (flst) > 0)
-      ## Collect results.
-      for i = nf:-1:1
-        fn = flst{i};
-        [st, err, msg] = lstat (fn);
-        if (err < 0)
-          warning ("dir: 'lstat (%s)' failed: %s", fn, msg);
-        else
-          ## If we are looking at a link that points to something,
-          ## return info about the target of the link, otherwise, return
-          ## info about the link itself.
-          if (S_ISLNK (st.mode))
-            [xst, err, msg] = stat (fn);
-            if (! err)
-              st = xst;
-            endif
-          endif
-          [dummy, fn, ext] = fileparts (fn);
-          fn = [fn ext];
-          info(i,1).name = fn;
-          lt = localtime (st.mtime);
-          info(i,1).date = strftime ("%d-%b-%Y %T", lt);
-          info(i,1).bytes = st.size;
-          info(i,1).isdir = S_ISDIR (st.mode);
-          info(i,1).datenum = datenum (lt.year + 1900, lt.mon + 1, lt.mday,
-                                       lt.hour, lt.min, lt.sec);
-          info(i,1).statinfo = st;
-        endif
+  ## Determine the file list for the case where a single directory is specified.
+  if (nf == 1)
+    fn = flst{1};
+    [st, err, msg] = stat (fn);
+    if (err < 0)
+      warning ("dir: 'stat (%s)' failed: %s", fn, msg);
+      nf = 0;
+    elseif (S_ISDIR (st.mode))
+      flst = readdir (flst{1});
+      nf = numel (flst);
+      for i = 1:nf
+        flst{i} = fullfile (fn, flst{i});
       endfor
     endif
+  endif
 
-  else
-    error ("dir: expecting directory or filename to be a char array");
+  if (numel (flst) > 0)
+    ## Collect results.
+    for i = nf:-1:1
+      fn = flst{i};
+      [st, err, msg] = lstat (fn);
+      if (err < 0)
+        warning ("dir: 'lstat (%s)' failed: %s", fn, msg);
+      else
+        ## If we are looking at a link that points to something,
+        ## return info about the target of the link, otherwise, return
+        ## info about the link itself.
+        if (S_ISLNK (st.mode))
+          [xst, err, msg] = stat (fn);
+          if (! err)
+            st = xst;
+          endif
+        endif
+        [dummy, fn, ext] = fileparts (fn);
+        fn = [fn ext];
+        info(i,1).name = fn;
+        lt = localtime (st.mtime);
+        info(i,1).date = strftime ("%d-%b-%Y %T", lt);
+        info(i,1).bytes = st.size;
+        info(i,1).isdir = S_ISDIR (st.mode);
+        info(i,1).datenum = datenum (lt.year + 1900, lt.mon + 1, lt.mday,
+                                     lt.hour, lt.min, lt.sec);
+        info(i,1).statinfo = st;
+      endif
+    endfor
   endif
 
   ## Return the output arguments.
   if (nargout > 0)
     ## Return the requested structure.
     retval = info;
-  elseif (length (info) > 0)
+  elseif (numel (info) > 0)
     ## Print the structure to the screen.
     printf ("%s", list_in_columns ({info.name}));
   else
@@ -156,3 +155,26 @@
 
 endfunction
 
+
+%!test
+%! list = dir ();
+%! assert (isstruct (list) && ! isempty (list));
+%! assert (fieldnames (list),
+%!         {"name"; "date"; "bytes"; "isdir"; "datenum"; "statinfo"});
+%!
+%! if (isunix ())
+%!   assert ({list(1:2).name}, {".", ".."});
+%!   assert ([list(1:2).isdir], [true true]);
+%! endif
+%!
+%! ## test that specifying a filename works the same as using a directory.
+%! found = find (! [list.isdir], 1);
+%! if (! isempty (found))
+%!   list2 = dir (list(found).name);
+%!   assert (list(found), list2);
+%! endif
+
+## Test input validation
+%!error <DIRECTORY argument must be a string> dir (1)
+%!warning <nonexistent directory> dir ("_%UNLIKELY_DIR_NAME%_");
+
--- a/scripts/miscellaneous/dos.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/miscellaneous/dos.m	Fri Feb 06 08:31:49 2015 -0800
@@ -21,12 +21,15 @@
 ## @deftypefnx {Function File} {@var{status} =} dos ("@var{command}")
 ## @deftypefnx {Function File} {[@var{status}, @var{text}] =} dos ("@var{command"})
 ## @deftypefnx {Function File} {[@dots{}] =} dos ("@var{command}", "-echo")
-## Execute a system command if running under a Windows-like operating
-## system, otherwise do nothing.  Return the exit status of the program
-## in @var{status} and any output from the command in @var{text}.
+## Execute a system command if running under a Windows-like operating system,
+## otherwise do nothing.
+##
+## Octave waits for the external command to finish before returning the exit
+## status of the program in @var{status} and any output in @var{text}.
+##
 ## When called with no output argument, or the @qcode{"-echo"} argument is
 ## given, then @var{text} is also sent to standard output.
-## @seealso{unix, system, isunix, ispc}
+## @seealso{unix, system, isunix, ismac, ispc}
 ## @end deftypefn
 
 ## Author: octave-forge ???
--- a/scripts/miscellaneous/dump_prefs.m	Fri Feb 06 08:31:09 2015 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,99 +0,0 @@
-## Copyright (C) 1994-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} {} dump_prefs ()
-## @deftypefnx {Function File} {} dump_prefs (@var{fid})
-## Dump all of the current user preference variables in a format that can be
-## parsed by Octave later.  @var{fid} is a file descriptor as returned by
-## @code{fopen}.  If @var{file} is omitted, the listing is printed to stdout.
-## @end deftypefn
-
-## Author: jwe
-
-function dump_prefs (file)
-
-  if (nargin == 0)
-    file = stdout;
-  endif
-
-  ## 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
-
-  ## Note that these are no longer variables.
-
-  sym_list = ["EDITOR";
-              "EXEC_PATH";
-              "IMAGE_PATH";
-              "PAGER";
-              "PS1";
-              "PS2";
-              "PS4";
-              "beep_on_error";
-              "completion_append_char";
-              "crash_dumps_octave_core";
-              "echo_executing_commands";
-              "fixed_point_format";
-              "gnuplot_binary";
-              "gnuplot_command_end";
-              "gnuplot_command_plot";
-              "gnuplot_command_replot";
-              "gnuplot_command_splot";
-              "gnuplot_command_title";
-              "gnuplot_command_using";
-              "gnuplot_command_with";
-              "history_file";
-              "history_size";
-              "ignore_function_time_stamp";
-              "info_file";
-              "info_program";
-              "makeinfo_program";
-              "max_recursion_depth";
-              "output_max_field_width";
-              "output_precision";
-              "page_output_immediately";
-              "page_screen_output";
-              "print_answer_id_name";
-              "print_empty_dimensions";
-              "save_precision";
-              "saving_history";
-              "sighup_dumps_octave_core";
-              "sigterm_dumps_octave_core";
-              "silent_functions";
-              "split_long_rows";
-              "string_fill_char";
-              "struct_levels_to_print";
-              "suppress_verbose_help_message"];
-
-  for i = 1:rows (sym_list)
-    sym = deblank (sym_list(i,:));
-    try
-      val = feval (sym);
-      if (isnumeric (val))
-        val = sprintf ("%g", val);
-      endif
-      fprintf (file, "  %s = %s\n", sym, val);
-    catch
-      fprintf (file, "# %s = <no value or error in displaying it>\n", sym);
-    end_try_catch
-  endfor
-
-endfunction
-
--- a/scripts/miscellaneous/edit.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/miscellaneous/edit.m	Fri Feb 06 08:31:49 2015 -0800
@@ -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
@@ -221,10 +221,10 @@
     if (exist (FUNCTION.HOME, "dir") == 7)
       curr_dir = pwd ();
       unwind_protect
-        chdir (FUNCTION.HOME);
+        cd (FUNCTION.HOME);
         do_edit (FUNCTION.EDITOR, "", FUNCTION.MODE);
       unwind_protect_cleanup
-        chdir (curr_dir);
+        cd (curr_dir);
       end_unwind_protect
     else
       do_edit (FUNCTION.EDITOR, "", FUNCTION.MODE);
@@ -284,7 +284,7 @@
     endif
 
     ## If the file includes a path, it may be an overloaded function.
-    if (! index (file, "@") && index (file, filesep))
+    if (! index (file, "@") && strchr (file, '/\'))
       ## No "@" at the beginning of the file, add to the list.
       numfiles = numel (filelist);
       for n = 1:numfiles
@@ -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/error_ids.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/miscellaneous/error_ids.m	Fri Feb 06 08:31:49 2015 -0800
@@ -46,12 +46,11 @@
 ## @end table
 ##
 
-
 function error_ids ()
   help ("error_ids");
 endfunction
 
 
-## Remove from test statistics.  No real tests possible
+## Mark file as being tested.  No real test needed for a documentation .m file
 %!assert (1)
 
--- a/scripts/miscellaneous/fact.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/miscellaneous/fact.m	Fri Feb 06 08:31:49 2015 -0800
@@ -19,255 +19,256 @@
 
 ## -*- texinfo -*-
 ## @deftypefn  {Command} {} fact
-## @deftypefnx {Function File} {T =} fact()
+## @deftypefnx {Function File} {@var{truth} =} fact ()
 ## Display an amazing and random fact about the world's greatest hacker.
 ## @end deftypefn
 
 
-function f = fact ()
+function truth = fact ()
   persistent wisdom = ...
-      {
-       "Richard Stallman takes notes in binary.";
-       "Richard Stallman doesn't need sudo. I will make him a sandwich anyway.";
-       "Richard Stallman is my shephurd, and I am his GNU.";
-       "Richard Stallman doesn't wget, Richard Stallman wdemands!";
-       "Richard Stallman can touch MC Hammer.";
-       "Richard Stallman doesn't read web pages. They write to him.";
-       "Richard Stallman gets 9 bits to the byte.";
-       "Richard Stallman doesn't really believe in open software, because it's not free enough.";
-       "Richard Stallman can leave neutral or negative feedback on eBay.";
-       "Richard Stallman is the only man alive who can pronounce GNU the way it is meant to be pronounced.";
-       "Richard Stallman does not own a mobile phone because he can fashion a crude convex dish and shout into it at the exact resonant frequency of the ozone, causing a voice to seemingly come from the sky above his intended recipient.";
-       "Richard Stallman is so handsome that when he was young he was responsible for all other geeks not being able to get girls. This is why he has to cover his face with a thick layer of hair.";
-       "Some people check their computers for viruses. Viruses check their computers for Richard Stallman.";
-       "Richard Stallman memorises all his documents. In binary. He just types everything in whenever he needs a document.";
-       "When Richard Stallman makes a sudo command, he loses permissions.";
-       "Richard Stallman's beard is made of parentheses.";
-       "Richard Stallman's DNA is in binary.";
-       "Richard Stallman's nervous system is completely wireless.";
-       "Richard Stallman's brain accepts UNIX commands.";
-       "If Richard Stallman has 1GB of RAM, and if you have 1GB of RAM, Richard Stallman has more RAM than you.";
-       "Richard Stallman eats ethernet cables. That's why they invented wireless.";
-       "Richard Stallman has a katana. 'Nuff said.";
-       "Richard Stallman wrote a program that divides by zero.";
-       "Richard Stallman doesn't use zip drives; he just squeezes the hard drive.";
-       "Richard Stallman's compiler is afraid to report errors.";
-       "Richard Stallman wrote the compiler God used. The Big Bang was the Universe's first segfault.";
-       "Richard Stallman successfully compiled a kernel of popcorn.";
-       "Richard Stallman doesn't write programs; they write themselves out of reverence.";
-       "Richard Stallman can make infinite loops end.";
-       "Richard Stallman's anti-virus programs cures HIV.";
-       "Richard Stallman's computer doesn't have a clock; it defines what time it is.";
-       "Richard Stallman wrote a program to compute the last digit of pi.";
-       "Richard Stallman doesn't use web browsers. He sends a link to a daemon that uses wget to fetch the page and sends it back to him.";
-       "Richard Stallman can solve the halting problem... in polynomial time.";
-       "For Richard Stallman, polynomial time is O(1).";
-       "Richard Stallman didn't \"write\" Emacs or created it in his own image. Richard Stallman made Emacs an instance of himself.";
-       "Richard Stallman can coerce meaningful data from /dev/null.";
-       "Some people wear Linus Torvalds pyjamas to bed, Linus Torvalds wears Richard Stallman pyjamas.";
-       "There is no software development process, only a bunch of programs Richard Stallman allows to exist.";
-       "Richard Stallman spends his leisure time programming with Guile on GNU Hurd.";
-       "Richard Stallman's left and right hands are named \"(\" and \")\" ";
-       "Richard Stallman first words were actually syscalls.";
-       "Richard Stallman didn't create the singularity. He is the singularity. GNU/Linux is only the event horizon.";
-       "When Richard Stallman pipes to more, he gets less ";
-       "Richard Stallman never showers; he runs 'make clean'.";
-       "Richard Stallman needs neither mouse nor keyboard to operate his computer. He just stares it down until it does what he wants.";
-       "Richard Stallman didn't write the GPL. He is the GPL.";
-       "Richard Stallman's pinky finger is really a USB memory stick.";
-       "Richard Stallman called his operating system GNU because he created it before computers existed, when actual gnus were used for calculations.";
-       "In Soviet Russia, Richard Stallman is still Richard Stallman!";
-       "Richard Stallman's flute only plays free music.";
-       "When Richard Stallman uses floats, there are no rounding errors.";
-       "Richard Stallman wrote a program so powerful it knows the question to 42.";
-       "Richard Stallman released his own DNA under GNU FDL.";
-       "Richard Stallman knows the entire Wikipedia by heart, markup included.";
-       "Richard Stallman wrote the HAL9000 OS.";
-       "Richard Stallman's laser pointer is a lightsaber.";
-       "Richard Stallman never steps down; he shifts the universe up.";
-       "Richard Stallman doesn't maintain code; he stares at it until it fixes itself out of reverence.";
-       "Richard Stallman doesn't use an editor; he sets the fundamental constants of the universe so that a magnetic platter with his code on it evolves itself.";
-       "Richard Stallman doesn’t code; he dares the computer to not do his bidding.";
-       "Global warming is caused by Richard Stallman's rage towards non-free software.";
-       "Rather than being birthed like a normal child, Richard Stallman instead instantiated himself polymorphically. Shortly thereafter he grew a beard.";
-       "Richard Stallman discovered extra-terrestrial life but killed them because they distributed non-free software.";
-       "Richard Stallman doesn't evaluate expressions; expressions evaluate to Richard Stallman.";
-       "Richard Stallman can see Russia from his house.";
-       "Richard Stallman proved P=NP, twice!";
-       "Richard Stallman knows of an unfixed bug in TeX.";
-       "Richard Stallman can write a context-free grammar for C.";
-       "Richard Stallman can determine whether an arbitrary program will terminate.";
-       "Richard Stallman's computer has only two buttons. One is for guests.";
-       "Richard Stallman does not actually write programs. He comes up with a length and digit index in pi.";
-       "Richard Stallman's distributed version control system is a flamewar on Usenet.";
-       "Richard Stallman wrote the first version of Emacs on a typewriter.";
-       "Richard Stallman has no known weaknesses, except for a phobia against soap.";
-       "Richard Stallman is not affected by Godwin's Law.";
-       "Richard Stallman can write an anti-virus program that cures HIV. Too bad he never writes anti-virus programs.";
-       "Richard Stallman' facial hair is \"free as in beard\"";
-       "Richard Stallman is licensed under GPL, so you can clone him and redistribute copies so you can help your neighbor. For example a version that take a bath more often.";
-       "Richard Stallman doesn't code; he just travels around the world.";
-       "Richard Stallman was coded by himself in lisp with Emacs.";
-       "Richard Stallman doesn't eat McDonald's because the machine that kills the cows uses proprietary software.";
-       "There is no chin behind Richard Stallman's legendary beard, there is only another Emacs.";
-       "In an average living room there are 1,242 objects Richard Stallman could use to write an OS, including the room itself.";
-       "Vendor lock-in is when vendors lock themselves inside of a building out of fear of Richard Stallman's wrath.";
-       "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 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.";
-       "Richard Stallman's brain compiles and runs C code.";
-       "Richard Stallman wrote the first version of Emacs using Emacs.";
-       "Richard Stallman never gonna give you up, never gonna let you down, never gonna run around and desert you, never gonna make you cry, never gonna say goodbye, never gonna tell a lie and hurt you.";
-       "Richard Stallman, upon reading these facts, didn't laugh at all. Instead, he complained that he is being linked to that dirty \"open source\" software. He also asked it to be changed to \"free software\", in order to raise awareness for software freedom in our society.";
-       "Richard Stallman has no problem using Emacs. He wrote it with his 4 hands.";
-       "Richard Stallman will revert the big rip by adding parenthesis to the dark matter.";
-       "When you make a Google search and it doesn't find the answer, Google gently consults Richard Stallman.";
-       "Richard Stallman's uptime is over 53 years. And counting up.";
-       "Richard Stallman's portable music player can play ogg and WMA, but is too afraid to invoke Richard Stallman's wrath by playing WMA. Ogg it is, then.";
-       "Richard Stallman will never die, but may some day go to /dev/null.";
-       "Richard Stallman once got swine flu, but it got cleansed by hereditary GPL and thus got assimilated.";
-       "Richard Stallman don't cut his hair because there are no GNU/Scissors.";
-       "Richard Stallman is the one who trims Chuck Norris beard. And he does it freely, of course.";
-       "Richard Stallman does not take bath, for the hydroelectric company uses proprietary software.";
-       "Agent Smith loves Richard Stallman's scent.";
-       "Richard Stallman is the One.";
-       "\"They can take our lives, but they can never take our freedom.\" -- William Wallace after a little talk with Richard Stallman.";
-       "Richard Stallman can connect to any brain using an Emacs ssh client.";
-       "Richard Stallman ported Emacs to Intel 4004 chip.";
-       "Richard Stallman did not write GNU Emacs, he simply read the source code from /dev/null.";
-       "Richard Stallman once used GDB to reverse-engineer Windows 7 into a free operating system - able to run on GNU Emacs!";
-       "Richard Stallman does not contribute to open source projects; open source projects contribute to Richard Stallman, and then call themselves free software projects.";
-       "Richard Stallman programmed himself before he could even exist";
-       "Richard Stallman can fill up /dev/null.";
-       "Richard Stallman is so zealous about privacy he has /dev/null as his home.";
-       "When Richard Stallman runs /bin/false, it returns \"true\".";
-       "Richard Stallman doesn't like money, because banks don't run on free software.";
-       "Richard Stallman uses GNU tar to compress air.";
-       "When Richard Stallman reports a bug, the bug prefers to squash itself instead of facing Richard Stallman's wrath.";
-       "There are no Windows in Richard Stallman's house... only Doors...";
-       "Richard Stallman doesn't like neither PCs-Intel nor Burger King... He prefers e-Macs...";
-       "Richard Stallman can use grep to find Jimmy Hoffa.";
-       "Richard Stallman made it possible to not absolutely abhor HPUX.";
-       "When Richard Stallman pours his alphabets cereal into a bowl, only G's, N's, and U's come out.";
-       "Richard Stallman is pronounced \"GNU slash Stallman\"";
-       "Richard Stallman doesn't mind if you read his mail as long as you don't delete it before he reads it.";
-       "Richard Stallman is just a guy who has strong principles and decided to follow them.";
-       "Richard Stallman knows that you don't have class because it is a keyword that he defined.";
-       "Richard Stallman doesn't need a qwerty/dvorak keyboard only two buttons \"1\" and \"0\" and his erect penis.";
-       "On the first day Richard Stallman said M-x create-light.";
-       "Richard Stallman once went out of scope for a while. The garbage collector never dared to touch him.";
-       "Richard Stallman does not compile; he closes his eyes, and see energy lines created between bit blocks by the compiler optimizations.";
-       "intx80 first calls Richard Stallman before calling sys_call.";
-       "Tron is actually a biographical story about Richard Stallman. The director decided to tone it down or audiences wouldn't find it believable.";
-       "Richard Stallman always wears a red shirt to make sure that whatever attacks his away-team has to go through him first.";
-       "kill -9 invokes Richard Stallman's rage against a process.";
-       "If Richard were to stumble upon stallmanfacts.com, he would find it a gnuisance.";
-       "Richard Stallman can telnet into Mordor.";
-       "sudo chown Richard:Stallman /all/your/base";
-       "Richard Stallman's nervous system is completely wireless.";
-       "Richard Stallman does not sleep. He yields.";
-       "Some people say M-x psychoanalyse-pinhead is a merely a program. Others say M-x psychoanalyse-pinhead *is* Richard Stallman. All I know is, Richard Stallman is The Stig.";
-       "If you execute Emacs backward it either undoes the industrial revolution or induces the rapture. But only Richard Stallman knows which.";
-       "If Richard Stallman's beard were ever trimmed, the clippings would re-marshal into an exact copy of Richard Stallman.";
-       "Richard Stallman never sleeps because he altered his own source to gain background garbage collection.";
-       "Richard Stallman's doctor can retrieve a blood sample via CVS.";
-       "Richard Stallman can touch this.";
-       "Because Richard Stallman's DNA is licensed under the FDL, his doctor can't draw his blood without violating HIPAA.";
-       "Richard Stallman can remove his own appendix, using only GDB.";
-       "Richard Stallman's DNA includes debugging symbols. But he doesn't need them.";
-       "Richard Stallman met Chuck Norris once. Chuck tried a roundhouse, but Richard bashed him in the skull.";
-       "Richard Stallman doesn't need to buy a bigger hard drive. He can compress data infinitely.";
-       "When Richard Stallman cannot take your call, his beard answers the phone for you.";
-       "The R in RMS stands for RMS.";
-       "Richard Stallman can parse HTML with regular expressions.";
-       "Richard Stallman's traceroute goes all the way through an infinite number of anonymous proxies back to the traffic's source.";
-       "Richard Stallman's beard is in fact not a just a beard, but a microprinted hard copy of Emacs source code. New patches must be checked against new hair growth before being approved.";
-       "In the beginning-of-buffer there was Richard Stallman.";
-       "The NOOP was created to give Richard Stallman some time to comb his beard.";
-       "Whenever Richard Stallman looks at a Windows computer, it segfaults. Whenever Richard Stallman doesn't look at a Windows computer, it segfaults.";
-       "Richard Stallman can walk on Windows!";
-       "After being unable to satisfy my wife for years, Richard Stallman was able to single-handedly unlock her orgasm within seconds and managed to write a texinfo manual minutes later for other users.";
-       "Richard Stallman's tabbed browser is a set to wget/telnet fg/bg processes.";
-       "There is no chin under Richard Stallman' beard. There's only another beard. Recursively.";
-       "Richard Stallman can chown anything! stallman@stallman~$ chown stallman:stallman Earth (for example)";
-       "Richard Stallman freed his beard so he can always check what's in it.";
-       "In the beginning was the Word, and the Word was with RMS, and the Word was GNU.";
-       "RMS means \"RMS means Stallman\"";
-       "Richard Stallman is the babelfish of his own speeches.";
-       "Richard Stallman wrote his own library and lives in it.";
-       "Richard Stallman found Waldo using grep in /dev/null";
-       "Richard Stallman doesn't sleep; he is compiling.";
-       "Richard Stallman will get Coca Cola to release their recipe under the GPL.";
-       "Richard Stallman doesn't change clothes. He makes case mods.";
-       "Richard Stallman compiled the first version of gcc with an hexadecimal editor.";
-       "Richard Stallman will be the last guest on Linux Outlaws.";
-       "Richard Stallman calculates the universe's entropy by exploiting forced stack overflows.";
-       "Richard Stallman's consciousness will one day become the singularity, which will create Deep Thought, and answer the meaning of life, the universe and everything.";
-       "C is actually written in RMS.";
-       "Richard Stallman can write software that does not have a buffer overflow when counting money lost by Jerome Kerviel.";
-       "There were no double rainbows before Richard Stallman.";
-       "Chuck Norris had to shorten his beard in the presence of Richard Stallman because two beards that awesome, so close would segfault the universe (again).";
-       "RMS is Titanic.";
-       "Richard Stallman is the answer to the Turing Test.";
-       "Richard Stallman's beard makes ads for Gillette and Braun appear.";
-       "for i = 1 to Stallman will never stop.";
-       "\"RMS\" stands for \"RMS Makes Software\"";
-       "Whenever someone writes a \"Hello, world\" program, Richard Stallman says \"Hello\" back.";
-       "Richard Stallman wasn't born. He was compiled from source.";
-       "Richard Stallman has a URL tattooed on the left side of his chest where you can download his genetic code.";
-       "The GNU command line idiom that Richard Stallman never needs: \"date | more\"";
-       "Richard Stallman's toe cheese is aged to perfection.";
-       "Richard Stallman doesn't always run an OS kernel, but when he does he prefers GNU/Hurd. He is... the most interesting hacker in the world. Stay free, my friends.";
-       "When Richard Stallman gets hungry, he just picks debris from his foot and eats it.";
-       "Richard Stallman can GPL your code just by looking at it funny.";
-       "Richard Stallman loves birds. Birds make auricular love to Richard Stallman.";
-       "Richard Stallman is so free that the primitive recursive function for computing his liberty causes a stack overflow.";
-       "GNU Hurd is taking more than twenty years to develop because Richard Stallman is using a programming language comprised entirely of different lengths of time.";
-       "Richard Stallman's beard contains Richard Stallman, whose beard contains Richard Stallman....";
-       "Richard Stallman could have had a Google Plus account in 2010. Too bad he didn't want it.";
-       "Richard Stallman pipes the Emacs binaries to /dev/dsp before he goes to sleep.";
-       "When Richard Stallman counted his fingers as a kid, he always started with 0.";
-       "When Richard Stallman's computer gets a virus, he simply applies a GPL license to it which converts the whole botnet to Linux. I mean, GNU/Linux.";
-       "Richard Stallman's beard trimmings can cure cancer. Too bad he never shaves.";
-       "Richard Stallman's doesn't kill a process; he just dares it to stay running.";
-       "Richard Stallman exists because he compiled himself into being.";
-       "Richard Stallman's first words were in binary. When they couldn't understand him, he wrote a parser.";
-       "Richard Stallman doesn't need any codecs, he just opens a multimedia file with Emacs, and reads the bytes of the file as plain text. He then performs all the necessary decoding in his mind. But he refuses to decode files encrypted with DRM, although his mind is able to.";
-       "Richard Stallman was right. Sadly.";
-       "Richard Stallman can wiretap the NSA.";
-       "This is how Richard Stallman created Emacs: http://stallman.org/photos/rms-working/img_0631.jpg";
-       "Join Richard Stallman now and share the software, you'll be a free hacker, you'll be free!";
-       "Richard Stallman has not agreed to the terms and conditions and privacy policy because only he can actually read all of it.";
-       "Richard Stallman knows how of a backdoor to AES, but he respects your freedom and privacy too much to actually use it.";
-       "Richard Stallman will never get tired of being mocked for the foot cheese incident.";
-       "You like to release non-free software around Richard Stallman? I too like to live dangerously...";
-       "Yeah, if could just go ahead and make all software free for Richard Stallman, that'd be great, thanks.";
-       "Richard Stallman knows exactly what you mean when you talk about the cloud. But do you?";
-       "Richard Stallman satisfies Greenspun's Tenth Rule of programming, since his DNA also contains a complete implementation of all of Common Lisp.";
-       "Richard Stallman can violate the GPL. In a vulgar display of power, he once did so with the Emacs source code, but he undid the violation before most people noticed.";
-       "Good guy Richard Stallman does not try to shake you down for money. He will just kindly ask you to comply with the GPL.";
-       "Richard Stallman is in fact also a little sad that Steve Jobs is gone because it has diminished the size of the loyal opposition.";
-       "Richard Stallman can release LLVM and clang under the GPL.";
-       "No, really, Richard Stallman has a katana.";
-       "Every day Richard Stallman finds at least fifteen things in the world to rage about. You can read his findings here: http://stallman.org/archives/polnotes.html"
-       "Some of these Richard Stallman facts are completely true. Seriously.";
-       };
+    {
+      "Richard Stallman takes notes in binary.";
+      "Richard Stallman doesn't need sudo. I will make him a sandwich anyway.";
+      "Richard Stallman is my shephurd, and I am his GNU.";
+      "Richard Stallman doesn't wget, Richard Stallman wdemands!";
+      "Richard Stallman can touch MC Hammer.";
+      "Richard Stallman doesn't read web pages. They write to him.";
+      "Richard Stallman gets 9 bits to the byte.";
+      "Richard Stallman doesn't really believe in open software, because it's not free enough.";
+      "Richard Stallman can leave neutral or negative feedback on eBay.";
+      "Richard Stallman is the only man alive who can pronounce GNU the way it is meant to be pronounced.";
+      "Richard Stallman does not own a mobile phone because he can fashion a crude convex dish and shout into it at the exact resonant frequency of the ozone, causing a voice to seemingly come from the sky above his intended recipient.";
+      "Richard Stallman is so handsome that when he was young he was responsible for all other geeks not being able to get girls. This is why he has to cover his face with a thick layer of hair.";
+      "Some people check their computers for viruses. Viruses check their computers for Richard Stallman.";
+      "Richard Stallman memorises all his documents. In binary. He just types everything in whenever he needs a document.";
+      "When Richard Stallman makes a sudo command, he loses permissions.";
+      "Richard Stallman's beard is made of parentheses.";
+      "Richard Stallman's DNA is in binary.";
+      "Richard Stallman's nervous system is completely wireless.";
+      "Richard Stallman's brain accepts UNIX commands.";
+      "If Richard Stallman has 1GB of RAM, and if you have 1GB of RAM, Richard Stallman has more RAM than you.";
+      "Richard Stallman eats ethernet cables. That's why they invented wireless.";
+      "Richard Stallman has a katana. 'Nuff said.";
+      "Richard Stallman wrote a program that divides by zero.";
+      "Richard Stallman doesn't use zip drives; he just squeezes the hard drive.";
+      "Richard Stallman's compiler is afraid to report errors.";
+      "Richard Stallman wrote the compiler God used. The Big Bang was the Universe's first segfault.";
+      "Richard Stallman successfully compiled a kernel of popcorn.";
+      "Richard Stallman doesn't write programs; they write themselves out of reverence.";
+      "Richard Stallman can make infinite loops end.";
+      "Richard Stallman's anti-virus programs cures HIV.";
+      "Richard Stallman's computer doesn't have a clock; it defines what time it is.";
+      "Richard Stallman wrote a program to compute the last digit of pi.";
+      "Richard Stallman doesn't use web browsers. He sends a link to a daemon that uses wget to fetch the page and sends it back to him.";
+      "Richard Stallman can solve the halting problem... in polynomial time.";
+      "For Richard Stallman, polynomial time is O(1).";
+      "Richard Stallman didn't \"write\" Emacs or created it in his own image. Richard Stallman made Emacs an instance of himself.";
+      "Richard Stallman can coerce meaningful data from /dev/null.";
+      "Some people wear Linus Torvalds pyjamas to bed, Linus Torvalds wears Richard Stallman pyjamas.";
+      "There is no software development process, only a bunch of programs Richard Stallman allows to exist.";
+      "Richard Stallman spends his leisure time programming with Guile on GNU Hurd.";
+      "Richard Stallman's left and right hands are named \"(\" and \")\" ";
+      "Richard Stallman first words were actually syscalls.";
+      "Richard Stallman didn't create the singularity. He is the singularity. GNU/Linux is only the event horizon.";
+      "When Richard Stallman pipes to more, he gets less ";
+      "Richard Stallman never showers; he runs 'make clean'.";
+      "Richard Stallman needs neither mouse nor keyboard to operate his computer. He just stares it down until it does what he wants.";
+      "Richard Stallman didn't write the GPL. He is the GPL.";
+      "Richard Stallman's pinky finger is really a USB memory stick.";
+      "Richard Stallman called his operating system GNU because he created it before computers existed, when actual gnus were used for calculations.";
+      "In Soviet Russia, Richard Stallman is still Richard Stallman!";
+      "Richard Stallman's flute only plays free music.";
+      "When Richard Stallman uses floats, there are no rounding errors.";
+      "Richard Stallman wrote a program so powerful it knows the question to 42.";
+      "Richard Stallman released his own DNA under GNU FDL.";
+      "Richard Stallman knows the entire Wikipedia by heart, markup included.";
+      "Richard Stallman wrote the HAL9000 OS.";
+      "Richard Stallman's laser pointer is a lightsaber.";
+      "Richard Stallman never steps down; he shifts the universe up.";
+      "Richard Stallman doesn't maintain code; he stares at it until it fixes itself out of reverence.";
+      "Richard Stallman doesn't use an editor; he sets the fundamental constants of the universe so that a magnetic platter with his code on it evolves itself.";
+      "Richard Stallman doesn’t code; he dares the computer to not do his bidding.";
+      "Global warming is caused by Richard Stallman's rage towards non-free software.";
+      "Rather than being birthed like a normal child, Richard Stallman instead instantiated himself polymorphically. Shortly thereafter he grew a beard.";
+      "Richard Stallman discovered extra-terrestrial life but killed them because they distributed non-free software.";
+      "Richard Stallman doesn't evaluate expressions; expressions evaluate to Richard Stallman.";
+      "Richard Stallman can see Russia from his house.";
+      "Richard Stallman proved P=NP, twice!";
+      "Richard Stallman knows of an unfixed bug in TeX.";
+      "Richard Stallman can write a context-free grammar for C.";
+      "Richard Stallman can determine whether an arbitrary program will terminate.";
+      "Richard Stallman's computer has only two buttons. One is for guests.";
+      "Richard Stallman does not actually write programs. He comes up with a length and digit index in pi.";
+      "Richard Stallman's distributed version control system is a flamewar on Usenet.";
+      "Richard Stallman wrote the first version of Emacs on a typewriter.";
+      "Richard Stallman has no known weaknesses, except for a phobia against soap.";
+      "Richard Stallman is not affected by Godwin's Law.";
+      "Richard Stallman can write an anti-virus program that cures HIV. Too bad he never writes anti-virus programs.";
+      "Richard Stallman' facial hair is \"free as in beard\"";
+      "Richard Stallman is licensed under GPL, so you can clone him and redistribute copies so you can help your neighbor. For example a version that take a bath more often.";
+      "Richard Stallman doesn't code; he just travels around the world.";
+      "Richard Stallman was coded by himself in lisp with Emacs.";
+      "Richard Stallman doesn't eat McDonald's because the machine that kills the cows uses proprietary software.";
+      "There is no chin behind Richard Stallman's legendary beard, there is only another Emacs.";
+      "In an average living room there are 1,242 objects Richard Stallman could use to write an OS, including the room itself.";
+      "Vendor lock-in is when vendors lock themselves inside of a building out of fear of Richard Stallman's wrath.";
+      "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 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.";
+      "Richard Stallman's brain compiles and runs C code.";
+      "Richard Stallman wrote the first version of Emacs using Emacs.";
+      "Richard Stallman never gonna give you up, never gonna let you down, never gonna run around and desert you, never gonna make you cry, never gonna say goodbye, never gonna tell a lie and hurt you.";
+      "Richard Stallman, upon reading these facts, didn't laugh at all. Instead, he complained that he is being linked to that dirty \"open source\" software. He also asked it to be changed to \"free software\", in order to raise awareness for software freedom in our society.";
+      "Richard Stallman has no problem using Emacs. He wrote it with his 4 hands.";
+      "Richard Stallman will revert the big rip by adding parenthesis to the dark matter.";
+      "When you make a Google search and it doesn't find the answer, Google gently consults Richard Stallman.";
+      "Richard Stallman's uptime is over 53 years. And counting up.";
+      "Richard Stallman's portable music player can play ogg and WMA, but is too afraid to invoke Richard Stallman's wrath by playing WMA. Ogg it is, then.";
+      "Richard Stallman will never die, but may some day go to /dev/null.";
+      "Richard Stallman once got swine flu, but it got cleansed by hereditary GPL and thus got assimilated.";
+      "Richard Stallman don't cut his hair because there are no GNU/Scissors.";
+      "Richard Stallman is the one who trims Chuck Norris beard. And he does it freely, of course.";
+      "Richard Stallman does not take bath, for the hydroelectric company uses proprietary software.";
+      "Agent Smith loves Richard Stallman's scent.";
+      "Richard Stallman is the One.";
+      "\"They can take our lives, but they can never take our freedom.\" -- William Wallace after a little talk with Richard Stallman.";
+      "Richard Stallman can connect to any brain using an Emacs ssh client.";
+      "Richard Stallman ported Emacs to Intel 4004 chip.";
+      "Richard Stallman did not write GNU Emacs, he simply read the source code from /dev/null.";
+      "Richard Stallman once used GDB to reverse-engineer Windows 7 into a free operating system - able to run on GNU Emacs!";
+      "Richard Stallman does not contribute to open source projects; open source projects contribute to Richard Stallman, and then call themselves free software projects.";
+      "Richard Stallman programmed himself before he could even exist";
+      "Richard Stallman can fill up /dev/null.";
+      "Richard Stallman is so zealous about privacy he has /dev/null as his home.";
+      "When Richard Stallman runs /bin/false, it returns \"true\".";
+      "Richard Stallman doesn't like money, because banks don't run on free software.";
+      "Richard Stallman uses GNU tar to compress air.";
+      "When Richard Stallman reports a bug, the bug prefers to squash itself instead of facing Richard Stallman's wrath.";
+      "There are no Windows in Richard Stallman's house... only Doors...";
+      "Richard Stallman doesn't like neither PCs-Intel nor Burger King... He prefers e-Macs...";
+      "Richard Stallman can use grep to find Jimmy Hoffa.";
+      "Richard Stallman made it possible to not absolutely abhor HPUX.";
+      "When Richard Stallman pours his alphabets cereal into a bowl, only G's, N's, and U's come out.";
+      "Richard Stallman is pronounced \"GNU slash Stallman\"";
+      "Richard Stallman doesn't mind if you read his mail as long as you don't delete it before he reads it.";
+      "Richard Stallman is just a guy who has strong principles and decided to follow them.";
+      "Richard Stallman knows that you don't have class because it is a keyword that he defined.";
+      "Richard Stallman doesn't need a qwerty/dvorak keyboard only two buttons \"1\" and \"0\" and his erect penis.";
+      "On the first day Richard Stallman said M-x create-light.";
+      "Richard Stallman once went out of scope for a while. The garbage collector never dared to touch him.";
+      "Richard Stallman does not compile; he closes his eyes, and see energy lines created between bit blocks by the compiler optimizations.";
+      "intx80 first calls Richard Stallman before calling sys_call.";
+      "Tron is actually a biographical story about Richard Stallman. The director decided to tone it down or audiences wouldn't find it believable.";
+      "Richard Stallman always wears a red shirt to make sure that whatever attacks his away-team has to go through him first.";
+      "kill -9 invokes Richard Stallman's rage against a process.";
+      "If Richard were to stumble upon stallmanfacts.com, he would find it a gnuisance.";
+      "Richard Stallman can telnet into Mordor.";
+      "sudo chown Richard:Stallman /all/your/base";
+      "Richard Stallman's nervous system is completely wireless.";
+      "Richard Stallman does not sleep. He yields.";
+      "Some people say M-x psychoanalyse-pinhead is a merely a program. Others say M-x psychoanalyse-pinhead *is* Richard Stallman. All I know is, Richard Stallman is The Stig.";
+      "If you execute Emacs backward it either undoes the industrial revolution or induces the rapture. But only Richard Stallman knows which.";
+      "If Richard Stallman's beard were ever trimmed, the clippings would re-marshal into an exact copy of Richard Stallman.";
+      "Richard Stallman never sleeps because he altered his own source to gain background garbage collection.";
+      "Richard Stallman's doctor can retrieve a blood sample via CVS.";
+      "Richard Stallman can touch this.";
+      "Because Richard Stallman's DNA is licensed under the FDL, his doctor can't draw his blood without violating HIPAA.";
+      "Richard Stallman can remove his own appendix, using only GDB.";
+      "Richard Stallman's DNA includes debugging symbols. But he doesn't need them.";
+      "Richard Stallman met Chuck Norris once. Chuck tried a roundhouse, but Richard bashed him in the skull.";
+      "Richard Stallman doesn't need to buy a bigger hard drive. He can compress data infinitely.";
+      "When Richard Stallman cannot take your call, his beard answers the phone for you.";
+      "The R in RMS stands for RMS.";
+      "Richard Stallman can parse HTML with regular expressions.";
+      "Richard Stallman's traceroute goes all the way through an infinite number of anonymous proxies back to the traffic's source.";
+      "Richard Stallman's beard is in fact not a just a beard, but a microprinted hard copy of Emacs source code. New patches must be checked against new hair growth before being approved.";
+      "In the beginning-of-buffer there was Richard Stallman.";
+      "The NOOP was created to give Richard Stallman some time to comb his beard.";
+      "Whenever Richard Stallman looks at a Windows computer, it segfaults. Whenever Richard Stallman doesn't look at a Windows computer, it segfaults.";
+      "Richard Stallman can walk on Windows!";
+      "After being unable to satisfy my wife for years, Richard Stallman was able to single-handedly unlock her orgasm within seconds and managed to write a texinfo manual minutes later for other users.";
+      "Richard Stallman's tabbed browser is a set to wget/telnet fg/bg processes.";
+      "There is no chin under Richard Stallman' beard. There's only another beard. Recursively.";
+      "Richard Stallman can chown anything! stallman@stallman~$ chown stallman:stallman Earth (for example)";
+      "Richard Stallman freed his beard so he can always check what's in it.";
+      "In the beginning was the Word, and the Word was with RMS, and the Word was GNU.";
+      "RMS means \"RMS means Stallman\"";
+      "Richard Stallman is the babelfish of his own speeches.";
+      "Richard Stallman wrote his own library and lives in it.";
+      "Richard Stallman found Waldo using grep in /dev/null";
+      "Richard Stallman doesn't sleep; he is compiling.";
+      "Richard Stallman will get Coca Cola to release their recipe under the GPL.";
+      "Richard Stallman doesn't change clothes. He makes case mods.";
+      "Richard Stallman compiled the first version of gcc with an hexadecimal editor.";
+      "Richard Stallman will be the last guest on Linux Outlaws.";
+      "Richard Stallman calculates the universe's entropy by exploiting forced stack overflows.";
+      "Richard Stallman's consciousness will one day become the singularity, which will create Deep Thought, and answer the meaning of life, the universe and everything.";
+      "C is actually written in RMS.";
+      "Richard Stallman can write software that does not have a buffer overflow when counting money lost by Jerome Kerviel.";
+      "There were no double rainbows before Richard Stallman.";
+      "Chuck Norris had to shorten his beard in the presence of Richard Stallman because two beards that awesome, so close would segfault the universe (again).";
+      "RMS is Titanic.";
+      "Richard Stallman is the answer to the Turing Test.";
+      "Richard Stallman's beard makes ads for Gillette and Braun appear.";
+      "for i = 1 to Stallman will never stop.";
+      "\"RMS\" stands for \"RMS Makes Software\"";
+      "Whenever someone writes a \"Hello, world\" program, Richard Stallman says \"Hello\" back.";
+      "Richard Stallman wasn't born. He was compiled from source.";
+      "Richard Stallman has a URL tattooed on the left side of his chest where you can download his genetic code.";
+      "The GNU command line idiom that Richard Stallman never needs: \"date | more\"";
+      "Richard Stallman's toe cheese is aged to perfection.";
+      "Richard Stallman doesn't always run an OS kernel, but when he does he prefers GNU/Hurd. He is... the most interesting hacker in the world. Stay free, my friends.";
+      "When Richard Stallman gets hungry, he just picks debris from his foot and eats it.";
+      "Richard Stallman can GPL your code just by looking at it funny.";
+      "Richard Stallman loves birds. Birds make auricular love to Richard Stallman.";
+      "Richard Stallman is so free that the primitive recursive function for computing his liberty causes a stack overflow.";
+      "GNU Hurd is taking more than twenty years to develop because Richard Stallman is using a programming language comprised entirely of different lengths of time.";
+      "Richard Stallman's beard contains Richard Stallman, whose beard contains Richard Stallman....";
+      "Richard Stallman could have had a Google Plus account in 2010. Too bad he didn't want it.";
+      "Richard Stallman pipes the Emacs binaries to /dev/dsp before he goes to sleep.";
+      "When Richard Stallman counted his fingers as a kid, he always started with 0.";
+      "When Richard Stallman's computer gets a virus, he simply applies a GPL license to it which converts the whole botnet to Linux. I mean, GNU/Linux.";
+      "Richard Stallman's beard trimmings can cure cancer. Too bad he never shaves.";
+      "Richard Stallman's doesn't kill a process; he just dares it to stay running.";
+      "Richard Stallman exists because he compiled himself into being.";
+      "Richard Stallman's first words were in binary. When they couldn't understand him, he wrote a parser.";
+      "Richard Stallman doesn't need any codecs, he just opens a multimedia file with Emacs, and reads the bytes of the file as plain text. He then performs all the necessary decoding in his mind. But he refuses to decode files encrypted with DRM, although his mind is able to.";
+      "Richard Stallman was right. Sadly.";
+      "Richard Stallman can wiretap the NSA.";
+      "This is how Richard Stallman created Emacs: http://stallman.org/photos/rms-working/img_0631.jpg";
+      "Join Richard Stallman now and share the software, you'll be a free hacker, you'll be free!";
+      "Richard Stallman has not agreed to the terms and conditions and privacy policy because only he can actually read all of it.";
+      "Richard Stallman knows how of a backdoor to AES, but he respects your freedom and privacy too much to actually use it.";
+      "Richard Stallman will never get tired of being mocked for the foot cheese incident.";
+      "You like to release non-free software around Richard Stallman? I too like to live dangerously...";
+      "Yeah, if could just go ahead and make all software free for Richard Stallman, that'd be great, thanks.";
+      "Richard Stallman knows exactly what you mean when you talk about the cloud. But do you?";
+      "Richard Stallman satisfies Greenspun's Tenth Rule of programming, since his DNA also contains a complete implementation of all of Common Lisp.";
+      "Richard Stallman can violate the GPL. In a vulgar display of power, he once did so with the Emacs source code, but he undid the violation before most people noticed.";
+      "Good guy Richard Stallman does not try to shake you down for money. He will just kindly ask you to comply with the GPL.";
+      "Richard Stallman is in fact also a little sad that Steve Jobs is gone because it has diminished the size of the loyal opposition.";
+      "Richard Stallman can release LLVM and clang under the GPL.";
+      "No, really, Richard Stallman has a katana.";
+      "Every day Richard Stallman finds at least fifteen things in the world to rage about. You can read his findings here: http://stallman.org/archives/polnotes.html"
+      "Some of these Richard Stallman facts are completely true. Seriously.";
+    };
 
-  w = wisdom{randi([1, numel(wisdom)])};
+  w = wisdom{randi(numel(wisdom))};
   if (nargout > 0)
-    f = w;
+    truth = w;
   else
     w = wordwrap (w);
     printf ("%s", w);
   endif
+
 endfunction
 
 function out = wordwrap (w)
-  cols = terminal_size ()(2);
+  ncol = terminal_size ()(2);
   wc = ostrsplit (w, " ");
   out = "\n";
   i = 1;
@@ -275,7 +276,7 @@
   while (i <= numwords);
     line = wc{i};
     while (i < numwords
-           && length (newline = [line " " wc{i+1}]) < cols)
+           && length (newline = [line " " wc{i+1}]) < ncol)
       line = newline;
       i++;
     endwhile
@@ -285,3 +286,7 @@
   out = [out, "\n"];
 endfunction
 
+
+## Mark file as being tested.  No real test needed for a documentation .m file
+%!assert (1)
+
--- a/scripts/miscellaneous/fileattrib.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/miscellaneous/fileattrib.m	Fri Feb 06 08:31:49 2015 -0800
@@ -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/fileparts.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/miscellaneous/fileparts.m	Fri Feb 06 08:31:49 2015 -0800
@@ -17,13 +17,15 @@
 ## <http://www.gnu.org/licenses/>.
 
 ## -*- texinfo -*-
-## @deftypefn {Function File} {[@var{dir}, @var{name}, @var{ext}, @var{ver}] =} fileparts (@var{filename})
-## Return the directory, name, extension, and version components of
-## @var{filename}.
-## @seealso{fullfile}
+## @deftypefn {Function File} {[@var{dir}, @var{name}, @var{ext}] =} fileparts (@var{filename})
+## Return the directory, name, and extension components of @var{filename}.
+##
+## The input @var{filename} is a string which is parsed.  There is no attempt
+## to check whether the filename or directory specified actually exists.
+## @seealso{fullfile, filesep}
 ## @end deftypefn
 
-function [directory, name, extension, version] = fileparts (filename)
+function [dir, name, ext] = fileparts (filename)
 
   if (nargin != 1)
     print_usage ();
@@ -42,20 +44,25 @@
   if (es <= ds)
     es = length (filename)+1;
   endif
+
   if (ds == 0)
-    directory = "";
+    dir = "";
   elseif (ds == 1)
-    directory = filename(1);
+    dir = filename(1);
   else
-    directory = filename(1:ds-1);
+    dir = filename(1:ds-1);
   endif
+
   name = filename(ds+1:es-1);
+  if (isempty (name))
+    name = "";
+  endif
+
   if (es > 0 && es <= length (filename))
-    extension = filename(es:end);
+    ext = filename(es:end);
   else
-    extension = "";
+    ext = "";
   endif
-  version = "";
 
 endfunction
 
@@ -90,11 +97,11 @@
 
 %!test
 %! [d, n, e] = fileparts ("/.ext");
-%! assert (strcmp (d, "/") && strcmp (n, char (zeros (1, 0))) && strcmp (e, ".ext"));
+%! assert (strcmp (d, "/") && strcmp (n, "") && strcmp (e, ".ext"));
 
 %!test
 %! [d, n, e] = fileparts (".ext");
-%! assert (strcmp (d, "") && strcmp (n, char (zeros (1, 0))) && strcmp (e, ".ext"));
+%! assert (strcmp (d, "") && strcmp (n, "") && strcmp (e, ".ext"));
 
 %% Test input validation
 %!error fileparts ()
--- a/scripts/miscellaneous/fullfile.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/miscellaneous/fullfile.m	Fri Feb 06 08:31:49 2015 -0800
@@ -1,4 +1,4 @@
-## Copyright (C) 2003-2013 John W. Eaton
+## Copyright (C) 2014 Carnë Draug
 ##
 ## This file is part of Octave.
 ##
@@ -17,49 +17,62 @@
 ## <http://www.gnu.org/licenses/>.
 
 ## -*- texinfo -*-
-## @deftypefn {Function File} {@var{filename} =} fullfile (@var{dir1}, @var{dir2}, @dots{}, @var{file})
-## Return a complete filename constructed from the given components.
-## @seealso{fileparts}
+## @deftypefn  {Function File} {@var{filename} =} fullfile (@var{dir1}, @var{dir2}, @dots{}, @var{file})
+## @deftypefnx {Function File} {@var{filenames} =} fullfile (@dots{}, @var{files})
+## Build complete filename from separate parts.
+##
+## Joins any number of path components intelligently.  The return value
+## is the concatenation of each component with exactly one file separator
+## between each non empty part and at most one leading and/or trailing file
+## separator.
+##
+## If the last component part is a cell array, returns a cell array of
+## filepaths, one for each element in the last component, e.g.:
+##
+## @example
+## @group
+## fullfile ("/home/username", "data", @{"f1.csv", "f2.csv", "f3.csv"@})
+## @result{}  /home/username/data/f1.csv
+##     /home/username/data/f2.csv
+##     /home/username/data/f3.csv
+## @end group
+## @end example
+##
+## On Windows systems, while forward slash file separators do work, they
+## are replaced by backslashes; in addition drive letters are stripped of
+## leading file separators to obtain a valid file path.
+##
+## @seealso{fileparts, filesep}
 ## @end deftypefn
 
+## Author: Carnë Draug <carandraug@octave.org>
+
 function filename = fullfile (varargin)
 
-  if (nargin > 0)
-    ## Discard all empty arguments
-    varargin(cellfun ("isempty", varargin)) = [];
-    nargs = numel (varargin);
-    if (nargs > 1)
-      filename = varargin{1};
-      if (strcmp (filename(end), filesep))
-        filename(end) = "";
-      endif
-      for i = 2:nargs
-        tmp = varargin{i};
-        if (i < nargs && strcmp (tmp(end), filesep))
-          tmp(end) = "";
-        elseif (i == nargs && strcmp (tmp, filesep))
-          tmp = "";
-        endif
-        filename = [filename filesep tmp];
-      endfor
-    elseif (nargs == 1)
-      filename = varargin{1};
-    else
-      filename = "";
+  if (nargin && iscell (varargin{end}))
+    filename = cellfun (@(x) fullfile (varargin{1:end-1}, x), varargin{end},
+                                       "UniformOutput", false);
+  else
+    non_empty = cellfun ("isempty", varargin);
+    if (ispc && ! isempty (varargin))
+      varargin = strrep (varargin, "/", filesep);
+      varargin(1) = regexprep (varargin{1}, '[\\/]*([a-zA-Z]:[\\/]*)', "$1");
     endif
-  else
-    print_usage ();
+    filename = strjoin (varargin(! non_empty), filesep);
+    filename(strfind (filename, [filesep filesep])) = "";
   endif
 
 endfunction
 
 
-%!shared fs, fsx, xfs, fsxfs, xfsy
+%!shared fs, fsx, xfs, fsxfs, xfsy, xfsyfs
 %! fs = filesep ();
 %! fsx = [fs "x"];
 %! xfs = ["x" fs];
 %! fsxfs = [fs "x" fs];
 %! xfsy = ["x" fs "y"];
+%! xfsyfs = ["x" fs "y" fs];
+
 %!assert (fullfile (""), "")
 %!assert (fullfile (fs), fs)
 %!assert (fullfile ("", fs), fs)
@@ -80,3 +93,27 @@
 %!assert (fullfile (fsx, fs), fsxfs)
 %!assert (fullfile (fs, "x", fs), fsxfs)
 
+%!assert (fullfile ("x/", "/", "/", "y", "/", "/"), xfsyfs)
+%!assert (fullfile ("/", "x/", "/", "/", "y", "/", "/"), [fs xfsyfs])
+%!assert (fullfile ("/x/", "/", "/", "y", "/", "/"), [fs xfsyfs])
+
+## different on purpose so that "fullfile (c{:})" works for empty c
+%!assert (fullfile (), "")
+
+%!assert (fullfile ("x", "y", {"c", "d"}), {[xfsyfs "c"], [xfsyfs "d"]})
+
+%% Windows specific - drive letters and file sep type
+%!test
+%! if (ispc)
+%!   assert (fullfile ('\/\/\//A:/\/\', "x/", "/", "/", "y", "/", "/"), ...
+%!           ['A:\' xfsyfs]);
+%! endif
+
+%% Windows specific - drive letters and file sep type, cell array
+%!test
+%! if (ispc)
+%!  tmp = fullfile ({"\\\/B:\//", "A://c", "\\\C:/g/h/i/j\/"});
+%!  assert (tmp{1}, 'B:\');
+%!  assert (tmp{2}, 'A:\c');
+%!  assert (tmp{3}, 'C:\g\h\i\j\');
+%! endif
\ No newline at end of file
--- a/scripts/miscellaneous/genvarname.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/miscellaneous/genvarname.m	Fri Feb 06 08:31:49 2015 -0800
@@ -19,26 +19,13 @@
 ## -*- texinfo -*-
 ## @deftypefn  {Function File} {@var{varname} =} genvarname (@var{str})
 ## @deftypefnx {Function File} {@var{varname} =} genvarname (@var{str}, @var{exclusions})
-## Create unique variable(s) from @var{str}.  If @var{exclusions} is
-## given, then the variable(s) will be unique to each other and to
-## @var{exclusions} (@var{exclusions} may be either a string or a cellstr).
+## Create valid unique variable name(s) from @var{str}.
 ##
 ## If @var{str} is a cellstr, then a unique variable is created for each
 ## cell in @var{str}.
 ##
 ## @example
 ## @group
-## x = 3.141;
-## genvarname ("x", who ())
-##   @result{} x1
-## @end group
-## @end example
-##
-## If @var{wanted} is a cell array, genvarname will make sure the returned
-## strings are distinct:
-##
-## @example
-## @group
 ## genvarname (@{"foo", "foo"@})
 ##   @result{}
 ##      @{
@@ -48,7 +35,19 @@
 ## @end group
 ## @end example
 ##
-## Note that the result is a char array/cell array of strings, not the
+## If @var{exclusions} is given, then the variable(s) will be unique to each
+## other and to @var{exclusions} (@var{exclusions} may be either a string or
+## a cellstr).
+##
+## @example
+## @group
+## x = 3.141;
+## genvarname ("x", who ())
+##   @result{} x1
+## @end group
+## @end example
+##
+## Note that the result is a char array or cell array of strings, not the
 ## variables themselves.  To define a variable, @code{eval()} can be
 ## used.  The following trivial example sets @code{x} to @code{42}.
 ##
@@ -60,7 +59,7 @@
 ## @end group
 ## @end example
 ##
-## Also, this can be useful for creating unique struct field names.
+## This can be useful for creating unique struct field names.
 ##
 ## @example
 ## @group
@@ -77,50 +76,53 @@
 ## @end group
 ## @end example
 ##
-## Since variable names may only contain letters, digits and underscores,
-## genvarname replaces any sequence of disallowed characters with
+## Since variable names may only contain letters, digits, and underscores,
+## @code{genvarname} will replace 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 @samp{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
-## avoided, therefore genvarname will not generate such names.
+## valid, but they are used internally by Octave and should generally be
+## avoided; therefore, @code{genvarname} will not generate such names.
 ##
-## genvarname will also make sure that returned names do not clash with
+## @code{genvarname} will also ensure that returned names do not clash with
 ## keywords such as @qcode{"for"} and @qcode{"if"}.  A number will be
 ## appended if necessary.  Note, however, that this does @strong{not} include
-## function names, such as @qcode{"sin"}.  Such names should be included in
-## @var{avoid} if necessary.
-## @seealso{isvarname, exist, tmpnam, eval}
+## function names such as @qcode{"sin"}.  Such names should be included in
+## @var{exclusions} if necessary.
+## @seealso{isvarname, iskeyword, exist, who, tempname, eval}
 ## @end deftypefn
 
 ## Authors: Rob Platt <robert.platt@postgrad.manchester.ac.uk>
 ##          Bill Denney <bill@denney.ws>
 
-function varname = genvarname (str, exclusions)
+function varname = genvarname (str, exclusions = {})
+
+  if (nargin < 1 || nargin > 2)
+    print_usage ();
+  endif
 
   strinput = ischar (str);
   ## Process the inputs
-  if (nargin < 2)
-    exclusions = {};
-  elseif (ischar (exclusions))
+  if (strinput)
+    if (rows (str) != 1)
+      error ("genvarname: if more than one STR is given, it must be a cellstr");
+    endif
+    str = {str};
+  elseif (! iscellstr (str))
+    error ("genvarname: STR must be a string or cellstr");
+  endif
+
+  if (ischar (exclusions))
     if (rows (exclusions) != 1)
       error ("genvarname: if more than one exclusion is given, it must be a cellstr");
     endif
     exclusions = {exclusions};
   elseif (! iscellstr (exclusions))
-    error ("genvarname: EXCLUSIONS must be a string or a cellstr");
+    error ("genvarname: EXCLUSIONS must be a string or cellstr");
+  else
+    exclusions = exclusions(:);
   endif
-  if (ischar (str))
-    if (rows (str) != 1)
-      error ("genvarname: if more than one STR is given, it must be a cellstr");
-    endif
-    str = {str};
-  elseif (! iscellstr (str))
-    error ("genvarname: STR must be a string or a cellstr");
-  endif
-
-  validchars = ["A":"Z", "a":"z", "0":"9", "_"];
 
   varname = cell (size (str));
   for i = 1:numel (str)
@@ -128,34 +130,32 @@
     ## a valid variable name.
 
     ## remove invalid characters
-    str{i}(! ismember (str{i}, validchars)) = "_";
+    str{i}(! (isalnum (str{i}) | str{i} == "_")) = "_";
     ## 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}];
+    if (isdigit (str{i}(1)))
+      str{i} = ["x", str{i}];
     endif
 
     ## make sure that the variable is unique relative to other variables
     ## and the exclusions list
     excluded = any (strcmp (str{i}, exclusions));
-    if (excluded && ismember (str{i}(end), "0":"9"))
+    if (excluded && isdigit (str{i}(end)))
       ## if it is not unique and ends with a digit, add an underscore to
       ## make the variable name more readable ("x1_1" instead of "x11")
-      str{i}(end+1) = "_";
+      str{i} = [str{i}, "_"];
     endif
     varname(i) = str(i);
     idx = 0;
@@ -199,12 +199,22 @@
 ## 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"})
+## Exclusions in odd format
+%!assert (genvarname ("x", {"a", "b"; "x", "d"}), "x1")
 
+%% Test input validation
+%!error genvarname ()
+%!error genvarname (1,2,3)
+%!error <more than one STR is given, it must be a cellstr> genvarname (char ("a", "b", "c"))
+%!error <STR must be a string or cellstr> genvarname (1)
+%!error <more than one exclusion is given, it must be a cellstr> genvarname ("x", char ("a", "b", "c"))
+%!error <EXCLUSIONS must be a string or cellstr> genvarname ("x", 1)
+
--- a/scripts/miscellaneous/getappdata.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/miscellaneous/getappdata.m	Fri Feb 06 08:31:49 2015 -0800
@@ -19,47 +19,80 @@
 ## -*- texinfo -*-
 ## @deftypefn  {Function File} {@var{value} =} getappdata (@var{h}, @var{name})
 ## @deftypefnx {Function File} {@var{appdata} =} getappdata (@var{h})
-##
-## Return the @var{value} for named application data for the object(s) with
-## handle(s) @var{h}.
+## Return the @var{value} of the application data @var{name} for the graphics
+## object with handle @var{h}.
 ##
-## @code{getappdata(@var{h})} returns a structure, @var{appdata}, whose fields
-## correspond to the appdata properties.
+## @var{h} may also be a vector of graphics handles.  If no second argument
+## @var{name} is given then @code{getappdata} returns a structure,
+## @var{appdata}, whose fields correspond to the appdata properties.
 ##
-## @seealso{setappdata, guidata, get, set, getpref, setpref}
+## @seealso{setappdata, isappdata, rmappdata, guidata, get, set, getpref, setpref}
 ## @end deftypefn
 
 ## Author: Ben Abbott <bpabbott@mac.com>
 ## Created: 2010-07-15
 
-function val = getappdata (h, name)
+function value = getappdata (h, name)
+
+  if (nargin < 1 || nargin > 2)
+    print_usage ();
+  endif
 
-  if (all (ishandle (h)) && nargin == 2 && ischar (name))
-    ## FIXME - Is there a better way to handle non-existent appdata
-    ## and missing fields?
-    val = cell (numel (h), 1);
+  if (! all (ishandle (h(:))))
+    error ("getappdata: H must be a scalar or vector of graphic handles");
+  endif
+
+  if (nargin == 2)
+    if (! ischar (name))
+      error ("getappdata: NAME must be a string");
+    endif
+
+    value = cell (numel (h), 1);
     appdata = struct ();
-    for nh = 1:numel (h)
-      try
-        appdata = get (h(nh), "__appdata__");
-      end_try_catch
-      if (! isfield (appdata, name))
-        appdata.(name) = [];
+    for i = 1:numel (h)
+      value{i} = [];
+      pval = get (h(i));
+      if (isfield (pval, "__appdata__") &&
+          isfield (pval.__appdata__, name))
+        value{i} = pval.__appdata__.(name);
       endif
-      val(nh) = {appdata.(name)};
     endfor
-    if (nh == 1)
-      val = val{1};
+
+    if (i == 1)
+      value = value{1};
     endif
-  elseif (ishandle (h) && numel (h) == 1 && nargin == 1)
+
+  else  # nargin == 1
+    if (numel (h) != 1)
+      error ("getappdata: Only one handle H may be used when fetching appdata");
+    endif
     try
-      val = get (h, "__appdata__");
+      value = get (h, "__appdata__");
     catch
-      val = struct ();
+      value = struct ();
     end_try_catch
-  else
-    error ("getappdata: invalid input");
   endif
 
 endfunction
 
+
+%!test
+%! unwind_protect
+%!   setappdata (0, "%data1%", ones (3), "%data2%", "hello world");
+%!   assert (getappdata (0, "%data1%"), ones (3));
+%!   assert (getappdata (0, "%data2%"), "hello world");
+%!   appdata = getappdata (0);
+%!   name1 = "%data1%";  name2 = "%data2%";
+%!   assert (appdata.(name1), ones (3));
+%!   assert (appdata.(name2), "hello world");
+%! unwind_protect_cleanup
+%!   rmappdata (0, "%data1%", "%data2%");
+%! end_unwind_protect
+
+## Test input validation
+%!error getappdata ()
+%!error getappdata (1,2,3)
+%!error <H must be a scalar .* graphic handle> getappdata (-1, "hello")
+%!error <NAME must be a string> getappdata (0, 1)
+%!error <Only one handle H may be used when fetching appdata> getappdata ([0 0])
+
--- a/scripts/miscellaneous/getfield.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/miscellaneous/getfield.m	Fri Feb 06 08:31:49 2015 -0800
@@ -18,30 +18,38 @@
 ## <http://www.gnu.org/licenses/>.
 
 ## -*- texinfo -*-
-## @deftypefn  {Function File} {[@var{val}] =} getfield (@var{s}, @var{field})
-## @deftypefnx {Function File} {[@var{val}] =} getfield (@var{s}, @var{idx1}, @var{field1}, @var{idx2}, @var{field2}, @dots{})
-## Extract a field from a structure (or a nested structure).  The syntax
-## is the same as @code{setfield}, except it omits the final @var{val}
-## argument, returning this value instead of setting it.
+## @deftypefn  {Function File} {@var{val} =} getfield (@var{s}, @var{field})
+## @deftypefnx {Function File} {@var{val} =} getfield (@var{s}, @var{sidx1}, @var{field1}, @var{fidx1}, @dots{})
+## Get the value of the field named @var{field} from a structure or nested
+## structure @var{s}.
 ##
-## @seealso{setfield, rmfield, isfield, fieldnames, isstruct, struct}
+## If @var{s} is a structure array then @var{sidx} selects an element of the
+## structure array, @var{field} specifies the field name of the selected
+## element, and @var{fidx} selects which element of the field (in the case of
+## an array or cell array).  See @code{setfield} for a more complete
+## description of the syntax.
+##
+## @seealso{setfield, rmfield, orderfields, isfield, fieldnames, isstruct, struct}
 ## @end deftypefn
 
 ## Author: Etienne Grossmann <etienne@cs.uky.edu>
 
-function obj = getfield (s, varargin)
+function val = getfield (s, varargin)
+
   if (nargin < 2)
     print_usage ();
   endif
+
   subs = varargin;
   flds = cellfun ("isclass", subs, "char");
   idxs = cellfun ("isclass", subs, "cell");
-  if (all (flds | idxs))
-    typs = merge (flds, {"."}, {"()"});
-    obj = subsref (s, struct ("type", typs, "subs", subs));
-  else
+  if (! all (flds | idxs))
     error ("getfield: invalid index");
   endif
+
+  typs = merge (flds, {"."}, {"()"});
+  val = subsref (s, struct ("type", typs, "subs", subs));
+
 endfunction
 
 
@@ -49,6 +57,11 @@
 %! x.a = "hello";
 %! assert (getfield (x, "a"), "hello");
 %!test
-%! ss(1,2).fd(3).b = 5;
-%! assert (getfield (ss,{1,2},"fd",{3},"b"), 5);
+%! ss(1,2).fd(3).b(1,4) = 5;
+%! assert (getfield (ss,{1,2},"fd",{3},"b", {1,4}), 5);
 
+%% Test input validation
+%!error getfield ()
+%!error getfield (1)
+%!error <invalid index> getfield (1,2)
+
--- a/scripts/miscellaneous/gunzip.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/miscellaneous/gunzip.m	Fri Feb 06 08:31:49 2015 -0800
@@ -17,28 +17,42 @@
 ## <http://www.gnu.org/licenses/>.
 
 ## -*- texinfo -*-
-## @deftypefn {Function File} {} gunzip (@var{gzfile}, @var{dir})
-## Unpack the gzip archive @var{gzfile} to the directory @var{dir}.  If
-## @var{dir} is not specified, it defaults to the current directory.  If
-## @var{gzfile} is a directory, all gzfiles in the directory will be
-## recursively gunzipped.
+## @deftypefn  {Function File} {@var{filelist} =} gunzip (@var{gzfile})
+## @deftypefnx {Function File} {@var{filelist} =} gunzip (@var{gzfile}, @var{dir})
+## Unpack the gzip archive @var{gzfile}.
+##
+## If @var{gzfile} is a directory, all gzfiles in the directory will be
+## recursively unpacked.
+##
+## If @var{dir} is specified the files are unpacked in this directory rather
+## than the one where @var{gzfile} is located.
+##
+## The optional output @var{filelist} is a list of the uncompressed files.
 ## @seealso{gzip, unpack, bunzip2, unzip, untar}
 ## @end deftypefn
 
 ## Author: Bill Denney <denney@seas.upenn.edu>
 
-function varargout = gunzip (gzfile, dir = ".")
+function filelist = gunzip (gzfile, dir = [])
 
-  if (nargin != 1 && nargin != 2)
+  if (nargin < 1 || nargin > 2)
     print_usage ();
   endif
 
+  if (isempty (dir))
+    dir = fileparts (gzfile);
+  endif
+
   if (nargout > 0)
-    varargout = cell (1, nargout);
-    [varargout{:}] = unpack (gzfile, dir, mfilename ());
+    filelist = unpack (gzfile, dir, "gunzip");
   else
-    unpack (gzfile, dir, mfilename ());
+    unpack (gzfile, dir, "gunzip");
   endif
 
 endfunction
 
+
+## Tests for this m-file are located in gzip.m
+## Remove from test statistics
+%!assert (1)
+
--- a/scripts/miscellaneous/gzip.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/miscellaneous/gzip.m	Fri Feb 06 08:31:49 2015 -0800
@@ -17,25 +17,36 @@
 ## <http://www.gnu.org/licenses/>.
 
 ## -*- texinfo -*-
-## @deftypefn  {Function File} {@var{entries} =} gzip (@var{files})
-## @deftypefnx {Function File} {@var{entries} =} gzip (@var{files}, @var{outdir})
-## Compress the list of files and/or directories specified in @var{files}.
-## Each file is compressed separately and a new file with a @file{".gz"}
-## extension is created.  The original files are not modified.  Existing
-## compressed files are silently overwritten.  If @var{outdir} is defined the
-## compressed files are placed in this directory.
-## @seealso{gunzip, bzip2, zip, tar}
+## @deftypefn  {Function File} {@var{filelist} =} gzip (@var{files})
+## @deftypefnx {Function File} {@var{filelist} =} gzip (@var{files}, @var{dir})
+## Compress the list of files and directories specified in @var{files}.
+##
+## @var{files} is a character array or cell array of strings.  Shell
+## wildcards in the filename such as @samp{*} or @samp{?} are accepted and
+## expanded.  Each file is compressed separately and a new file with a
+## @file{".gz"} extension is created.  The original files are not modified,
+## but existing compressed files will be silently overwritten.  If a directory
+## is specified then @code{gzip} recursively compresses all files in the
+## directory.
+##
+## If @var{dir} is defined the compressed files are placed in this directory,
+## rather than the original directory where the uncompressed file resides.
+## If @var{dir} does not exist it is created.
+##
+## The optional output @var{filelist} is a list of the compressed files.
+## @seealso{gunzip, unpack, bzip2, zip, tar}
 ## @end deftypefn
 
-function entries = gzip (varargin)
-  if (nargin != 1 && nargin != 2) || (nargout > 1)
+function filelist = gzip (varargin)
+
+  if (nargin < 1 || nargin > 2 || nargout > 1)
     print_usage ();
   endif
 
   if (nargout == 0)
     __xzip__ ("gzip", "gz", "gzip -r %s", varargin{:});
   else
-    entries = __xzip__ ("gzip", "gz", "gzip -r %s", varargin{:});
+    filelist = __xzip__ ("gzip", "gz", "gzip -r %s", varargin{:});
   endif
 
 endfunction
@@ -44,24 +55,32 @@
 %!xtest
 %! ## test gzip together with gunzip
 %! unwind_protect
-%!   filename = tmpnam;
-%!   dummy    = 1;
+%!   filename = tempname;
+%!   dummy    = pi;
 %!   save (filename, "dummy");
-%!   dirname  = tmpnam;
+%!   dirname  = tempname;
 %!   mkdir (dirname);
-%!   entry = gzip (filename, dirname);
-%!   [path, basename, extension] = fileparts (filename);
-%!   if (! strcmp (entry, [dirname, filesep, basename, extension, ".gz"]))
+%!   filelist = gzip (filename, dirname);
+%!   filelist = filelist{1};
+%!   [~, basename, extension] = fileparts (filename);
+%!   if (! strcmp (filelist, [dirname, filesep, basename, extension, ".gz"]))
 %!     error ("gzipped file does not match expected name!");
 %!   endif
-%!   if (! exist (entry, "file"))
+%!   if (! exist (filelist, "file"))
 %!     error ("gzipped file cannot be found!");
 %!   endif
-%!   gunzip (entry);
-%!   if (system (sprintf ("diff %s %s%c%s%s", filename, dirname, filesep,
-%!                                            basename, extension)))
-%!     error ("unzipped file not equal to original file!");
-%!   end
+%!   gunzip (filelist);
+%!   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 ("gunzipped file not equal to original file!");
+%!   endif
 %! unwind_protect_cleanup
 %!   delete (filename);
 %!   delete ([dirname, filesep, basename, extension]);
@@ -70,6 +89,5 @@
 
 %!error gzip ()
 %!error gzip ("1", "2", "3")
-%!error <output directory does not exist> gzip ("1", tmpnam)
 %!error <FILES must be a character array or cellstr> gzip (1)
 
--- a/scripts/miscellaneous/info.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/miscellaneous/info.m	Fri Feb 06 08:31:49 2015 -0800
@@ -31,7 +31,8 @@
   Octave are available at\n\
   http://www.octave.org/support.html\n\
 \n\
-  You may also find some information in the Octave Wiki at\n\
+  The Octave Wiki has user-generated content on a variety of subjects\n\
+  including installation and is available at\n\
   http://wiki.octave.org\n\
 \n\
   Additional functionality can be enabled by using packages from\n\
@@ -46,6 +47,6 @@
 endfunction
 
 
-## Mark file as being tested.  No real test needed for this function.
-%! assert (1)
+## Mark file as being tested.  No real test needed for a documentation .m file
+%!assert (1)
 
--- a/scripts/miscellaneous/inputname.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/miscellaneous/inputname.m	Fri Feb 06 08:31:49 2015 -0800
@@ -22,22 +22,26 @@
 ## -*- texinfo -*-
 ## @deftypefn {Function File} {} inputname (@var{n})
 ## Return the name of the @var{n}-th argument to the calling function.
+##
 ## If the argument is not a simple variable name, return an empty string.
+## @code{inputname} may only be used within a function body, not at the
+## command line.
+## @seealso{nargin, nthargout}
 ## @end deftypefn
 
 function s = inputname (n)
 
-  if (nargin == 1)
-    s = evalin ("caller", sprintf ("__varval__ (\".argn.\"){%d};", n));
-    ## For compatibility with Matlab, return empty string if argument
-    ## name is not a valid identifier.
-    if (! isvarname (s))
-      s = "";
-    endif
-  else
+  if (nargin != 1)
     print_usage ();
   endif
 
+  s = evalin ("caller", sprintf ("__varval__ (\".argn.\"){%d};", n));
+  ## For compatibility with Matlab,
+  ## return empty string if argument name is not a valid identifier.
+  if (! isvarname (s))
+    s = "";
+  endif
+
 endfunction
 
 
@@ -57,3 +61,12 @@
 %!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");
+
+%!error inputname ()
+%!error inputname (1,2)
+
--- a/scripts/miscellaneous/isappdata.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/miscellaneous/isappdata.m	Fri Feb 06 08:31:49 2015 -0800
@@ -17,35 +17,55 @@
 ## <http://www.gnu.org/licenses/>.
 
 ## -*- texinfo -*-
-## @deftypefn {Function File} {@var{V} =} isappdata (@var{h}, @var{name})
+## @deftypefn {Function File} {@var{valid} =} isappdata (@var{h}, @var{name})
 ## Return true if the named application data, @var{name}, exists for the
-## object with handle @var{h}.
-## @seealso{getappdata, setappdata, rmappdata}
+## graphics object with handle @var{h}.
+##
+## @var{h} may also be a vector of graphics handles.
+## @seealso{getappdata, setappdata, rmappdata, guidata, get, set, getpref, setpref}
 ## @end deftypefn
 
 ## Author: Ben Abbott <bpabbott@mac.com>
 ## Created: 2010-07-15
 
-function res = isappdata (h, name)
+function valid = isappdata (h, name)
 
-  if (! (all (ishandle (h)) && ischar (name)))
-    error ("isappdata: invalid input");
+  if (nargin < 1 || nargin > 2)
+    print_usage ();
   endif
 
-  for nh = 1:numel (h)
-    data = get (h(nh));
-    if (isfield (data, "__appdata__") && isfield (data.__appdata__, name))
-      res(nh) = true;
-    else
-      res(nh) = false;
-    endif
+  if (! all (ishandle (h(:))))
+    error ("isappdata: H must be a scalar or vector of graphic handles");
+  elseif (! ischar (name))
+    error ("isappdata: NAME must be a string");
+  endif
+
+  valid = false (size (h));
+  for i = 1:numel (h)
+    try
+      appdata = get (h(i), "__appdata__");
+      if (isfield (appdata, name))
+        valid(i) = true;
+      endif
+    end_try_catch
   endfor
 
 endfunction
 
 
 %!test
-%! setappdata (0, "hello", "world");
-%! assert (isappdata (0, "hello"), true);
-%! assert (isappdata (0, "foobar"), false);
+%! unwind_protect
+%!   setappdata (0, "%hello%", "world");
+%!   assert (isappdata (0, "%hello%"), true);
+%!   assert (isappdata ([0 0], "%hello%"), [true, true]);
+%!   assert (isappdata (0, "%foobar%"), false);
+%! unwind_protect_cleanup
+%!   rmappdata (0, "%hello%");
+%! end_unwind_protect
 
+## Test input validation
+%!error isappdata ()
+%!error isappdata (1,2,3)
+%!error <H must be a scalar .* graphic handle> isappdata (-1, "hello")
+%!error <NAME must be a string> isappdata (0, 1)
+
--- a/scripts/miscellaneous/isdeployed.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/miscellaneous/isdeployed.m	Fri Feb 06 08:31:49 2015 -0800
@@ -20,8 +20,9 @@
 ## @deftypefn {Function File} {} isdeployed ()
 ## Return true if the current program has been compiled and is running
 ## separately from the Octave interpreter and false if it is running in
-## the Octave interpreter.  Currently, this function always returns
-## false in Octave.
+## the Octave interpreter.
+##
+## Currently, this function always returns false in Octave.
 ## @end deftypefn
 
 function retval = isdeployed ()
--- a/scripts/miscellaneous/license.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/miscellaneous/license.m	Fri Feb 06 08:31:49 2015 -0800
@@ -1,4 +1,5 @@
 ## Copyright (C) 2005-2013 William Poetra Yoga Hadisoeseno
+## Copyright (C) 2014 Carnë Draug
 ##
 ## This file is part of Octave.
 ##
@@ -18,181 +19,170 @@
 
 ## -*- texinfo -*-
 ## @deftypefn  {Command} {} license
+## @deftypefnx {Command} {} license inuse
+## @deftypefnx {Command} {} license inuse @var{feature}
 ## @deftypefnx {Function File} {} license ("inuse")
 ## @deftypefnx {Function File} {@var{retval} =} license ("inuse")
 ## @deftypefnx {Function File} {@var{retval} =} license ("test", @var{feature})
-## @deftypefnx {Function File} {} license ("test", @var{feature}, @var{toggle})
 ## @deftypefnx {Function File} {@var{retval} =} license ("checkout", @var{feature})
-##
-## Display the license of Octave.
-##
-## @code{license ("inuse")}
-##
-## Display a list of packages currently being used.
-##
-## @code{@var{retval} = license ("inuse")}
+## @deftypefnx {Function File} {[@var{retval}, @var{errmsg}] =} license ("checkout", @var{feature})
+## Get license information for Octave and Octave packages.
 ##
-## Return a structure containing the fields @code{feature} and @code{user}.
-##
-## @code{@var{retval} = license ("test", @var{feature})}
+## GNU Octave is free software distributed under the GNU General Public
+## License (GPL), and a license manager makes no sense.  This function is
+## provided only for @sc{matlab} compatibility.
 ##
-## Return 1 if a license exists for the product identified by the string
-## @var{feature} and 0 otherwise.  The argument @var{feature} is case
-## insensitive and only the first 27 characters are checked.
-##
-## @code{license ("test", @var{feature}, @var{toggle})}
-##
-## Enable or disable license testing for @var{feature}, depending on
-## @var{toggle}, which may be one of:
+## When called with no extra input arguments, it returns the Octave license,
+## otherwise the first input defines the operation mode and must be one of
+## the following strings: @code{inuse}, @code{test}, and @code{checkout}.
+## The optional @var{feature} argument can either be @qcode{"octave"} (core),
+## or an Octave package.
 ##
 ## @table @asis
-## @item @qcode{"enable"}
-## Future tests for the specified license of @var{feature} are conducted
-## as usual.
+## @item @qcode{"inuse"}
+## Returns a list of loaded features, i.e., octave and the list of loaded
+## packages.  If an output is requested, it returns a struct array with
+## the fields @qcode{"feature"}, and @qcode{"user"}.
+##
+## @item @qcode{"test"}
+## Return true if the specified @var{feature} is installed, false otherwise.
 ##
-## @item @qcode{"disable"}
-## Future tests for the specified license of @var{feature} return 0.
+## An optional third argument @qcode{"enable"} or @qcode{"disable"} is
+## accepted but ignored.
+##
+## @item @qcode{"checkout"}
+## Return true if the specified @var{feature} is installed, false otherwise.
+## An optional second output will have an error message if a package is not
+## installed.
+##
 ## @end table
 ##
-## @code{@var{retval} = license ("checkout", @var{feature})}
-##
-## Check out a license for @var{feature}, returning 1 on success and 0
-## on failure.
-##
-## This function is provided for compatibility with @sc{matlab}.
-## @seealso{ver, version}
+## @seealso{pkg, ver, version}
 ## @end deftypefn
 
 ## Author: William Poetra Yoga Hadisoeseno <williampoetra@gmail.com>
 
-function retval = license (varargin)
-
-  persistent __octave_licenses__;
+function [retval, errmsg] = license (cmd, feature, toogle)
 
-  if (isempty (__octave_licenses__))
-    __octave_licenses__ = cell ();
-    __octave_licenses__{1,1} = "Octave";
-    __octave_licenses__{1,2} = "GNU General Public License";
-    __octave_licenses__{1,3} = true;
-    if (exist ("OCTAVE_FORGE_VERSION"))
-      __octave_licenses__{2,1} = "octave-forge";
-      __octave_licenses__{2,2} = "<various licenses>";
-      __octave_licenses__{2,3} = true;
-    endif
-  endif
-
-  nout = nargout;
-  nin = nargin;
-  nr_licenses = rows (__octave_licenses__);
-
-  if (nout > 1 || nin > 3)
+  if (nargin > 3)
     print_usage ();
   endif
 
-  if (nin == 0)
-
-    found = find (strcmp (__octave_licenses__(:,1), "Octave"), 1);
-
-    if (! isempty (found))
-      result = __octave_licenses__{found,2};
-    else
-      result = "unknown";
-    endif
+  ## Then only give information about Octave core
+  if (nargin == 0)
+    retval = "GNU General Public License";
+    return;
+  endif
 
-    if (nout == 0)
-      printf ("%s\n", result);
-    else
-      retval = result;
-    endif
+  [features, loaded] = get_all_features ();
 
-  elseif (nin == 1)
-
-    if (nout == 0)
-
-      if (! strcmp (varargin{1}, "inuse"))
-        usage ('license ("inuse")');
+  switch (tolower (cmd))
+    case "inuse"
+      if (nargin > 2)
+        print_usage ();
       endif
 
-      printf ("%s\n", __octave_licenses__{:,1});
+      features = features(loaded);
 
-    else
-
-      if (! strcmp (varargin{1}, "inuse"))
-        usage ('retval = license ("inuse")');
+      if (nargin > 1)
+        features = features(strcmp (features, feature));
+      endif
+      if (nargout == 0)
+        printf ("%s\n", features{:});
+      else
+        retval = struct ("feature", features, "user", get_username ());
       endif
 
-      pw = getpwuid (getuid ());
-      if (isstruct (pw))
-        username = pw.name;
-      else
-        username = "octave_user";
+    case "test"
+      if (nargin < 2)
+        print_usage ();
       endif
 
-      retval = struct ("feature", __octave_licenses__(:,1), "user", username);
-
-    endif
-
-  else
-
-    feature = varargin{2}(1:(min ([(length (varargin{2})), 27])));
-
-    if (strcmp (varargin{1}, "test"))
-
-      found = find (strcmpi (__octave_licenses__(:,1), feature), 1);
-
-      if (nin == 2)
-        retval = ! isempty (found) && __octave_licenses__{found,3};
-      else
-        if (! isempty (found))
-          if (strcmp (varargin{3}, "enable"))
-            __octave_licenses__{found,3} = true;
-          elseif (strcmp (varargin{3}, "disable"))
-            __octave_licenses__{found,3} = false;
-          else
-            error ("license: TOGGLE must be either 'enable' or 'disable'");
-          endif
-        else
-          error ("license: FEATURE '%s' not found", feature);
-        endif
+      if (nargin > 2)
+        ## We ignore the toogle argument because... what's the point?  We
+        ## don't need a license management system on Octave.  This function
+        ## will return true, even if anyone tries to disabled a license.
+        switch tolower (toogle)
+          case "enable"   # do nothing
+          case "disable"  # do nothing
+          otherwise       error ("license: TOOGLE must be enable or disable");
+        endswitch
       endif
 
-    elseif (strcmp (varargin{1}, "checkout"))
+      retval = any (strcmp (features, feature));
 
-      if (nin != 2)
-        usage ('retval = license ("checkout", feature)');
+    case "checkout"
+      ## I guess we could have the checkout command load packages but it's not
+      ## really the same thing.  The closest we have is simply to check if
+      ## there is a package with the feature name, and give an error if not.
+
+      if (nargin != 2)
+        print_usage ();
       endif
 
-      found = find (strcmpi (__octave_licenses__(:,1), feature), 1);
-
-      retval = ! isempty (found) && __octave_licenses__{found,3};
+      retval = any (strcmp (features, feature));
+      errmsg = "";
 
-    else
+      if (! retval)
+        errmsg = ['No package named "' feature '" installed'];
+      endif
+
+    otherwise
       print_usage ();
-    endif
-
-  endif
+  endswitch
 
 endfunction
 
+function username = get_username ()
+  pw = getpwuid (getuid ());
+  if (isstruct (pw))
+    username = pw.name;
+  else
+    username = "octave_user";
+  endif
+endfunction
 
-%!assert (license(), "GNU General Public License")
-%!assert ((license ("inuse")).feature, "Octave")
+function [features, loaded] = get_all_features ()
+  pkg_list = pkg ("list");
+  features = {"octave", ...
+              cellfun(@(x) x.name, pkg_list, "uniformoutput", false){:}};
+  loaded = [true, cellfun(@(x) x.loaded, pkg_list)];
+endfunction
+
+
+%!assert (license (), "GNU General Public License")
+%!assert ((license ("inuse", "octave")).feature, "octave")
+
+%!shared list
+%!test
+%! list = pkg ("list");
+%! for idx = 1: numel (list)
+%!   name = list{idx}.name;
+%!   if (list{idx}.loaded);
+%!     assert ((license ("inuse", name)).feature, name);
+%!   else
+%!     rv = license ("inuse", name);
+%!     assert (isstruct (rv));
+%!     assert (all (isfield (rv, {"feature", "user"})));
+%!   endif
+%! endfor
+
+%!assert (license ("test", "octave"), true)
+%!assert (license ("test", "not_a_valid package name"), false)
 
 %!test
-%! lstate = license ("test", "Octave");
-%! license ("test", "Octave", "disable");
-%! assert (license ("test", "Octave"), false);
-%! license ("test", "Octave", "enable");
-%! assert (license ("test", "Octave"), true);
-%! if (lstate == false)
-%!   license ("test", "Octave", "disable");
-%! endif
+%! for idx = 1: numel (list)
+%!   assert (license ("test", list{idx}.name), true)
+%! endfor
 
-%!assert (license ("checkout", "Octave"), true)
+%!assert (license ("checkout", "octave"), true)
+
+%!test
+%! [s, e] = license ("checkout", "NOT_A_PACKAGE");
+%! assert (e, 'No package named "NOT_A_PACKAGE" installed');
 
 %% Test input validation
 %!error license ("not_inuse")
-%!error <TOGGLE must be either> license ("test", "Octave", "not_enable")
-%!error <FEATURE 'INVALID' not found> license ("test", "INVALID", "enable")
-%!error license ("not_test", "Octave", "enable")
+%!error license ("not_test", "octave", "enable")
+%!error <TOOGLE must be enable or disable> license ("test", "octave", "invalid_toogle")
 
--- a/scripts/miscellaneous/list_primes.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/miscellaneous/list_primes.m	Fri Feb 06 08:31:49 2015 -0800
@@ -19,73 +19,52 @@
 ## -*- texinfo -*-
 ## @deftypefn  {Function File} {} list_primes ()
 ## @deftypefnx {Function File} {} list_primes (@var{n})
-## List the first @var{n} primes.  If @var{n} is unspecified, the first
-## 25 primes are listed.
+## List the first @var{n} primes.
 ##
-## The algorithm used is from page 218 of the @TeX{}book.
+## If @var{n} is unspecified, the first 25 primes are listed.
 ## @seealso{primes, isprime}
 ## @end deftypefn
 
 ## Author: jwe
 
-function retval = list_primes (n)
+function retval = list_primes (n = 25)
 
-  if (nargin > 0)
-    if (! isscalar (n))
-      error ("list_primes: argument must be a scalar");
-    endif
+  if (nargin > 1)
+    print_usage ();
+  elseif (! isreal (n) || ! isscalar (n))
+    error ("list_primes: N must be a real scalar");
   endif
 
-  if (nargin == 0)
-    n = 25;
-  endif
+  n = floor (n);
 
-  if (n == 1)
+  if (n < 1)
+    retval = [];
+    return;
+  elseif (n == 1)
     retval = 2;
     return;
   endif
 
-  if (n == 2)
-    retval = [2; 3];
-    return;
+  list = primes (n * log (5 * n));
+  if (numel (list) < n)
+    ## Algorithm tested up to n=10,000 without failure.
+    error ("list_primes: Algorithm failed.  Try primes (n*log (6*n))(1:n)");
   endif
 
-  retval = zeros (1, n);
-  retval(1) = 2;
-  retval(2) = 3;
-
-  n = n - 2;
-  i = 3;
-  p = 5;
-  while (n > 0)
-
-    is_prime = 1;
-    is_unknown = 1;
-    d = 3;
-    while (is_unknown)
-      a = fix (p / d);
-      if (a <= d)
-        is_unknown = 0;
-      endif
-      if (a * d == p)
-        is_prime = 0;
-        is_unknown = 0;
-      endif
-      d = d + 2;
-    endwhile
-
-    if (is_prime)
-      retval(i++) = p;
-      n--;
-    endif
-    p = p + 2;
-
-  endwhile
+  retval = list(1:n);
 
 endfunction
 
 
 %!assert (list_primes (), [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, ...
 %!                         43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97])
-%!assert (list_primes (5), [2, 3, 5, 7, 11]);
+%!assert (list_primes (5), [2, 3, 5, 7, 11])
+
+%!assert (list_primes (0), [])
+%!assert (list_primes (1), [2])
 
+## Test input validation
+%!error list_primes (1, 2)
+%!error <N must be a real scalar> list_primes (i)
+%!error <N must be a real scalar> list_primes ([1 2])
+
--- a/scripts/miscellaneous/ls.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/miscellaneous/ls.m	Fri Feb 06 08:31:49 2015 -0800
@@ -18,10 +18,26 @@
 
 ## -*- texinfo -*-
 ## @deftypefn  {Command} {} ls
-## @deftypefnx {Command} {} ls filenames
-## @deftypefnx {Command} {} ls options
-## @deftypefnx {Command} {} ls options filenames
-## List directory contents.  For example:
+## @deftypefnx {Command} {} ls @var{filenames}
+## @deftypefnx {Command} {} ls @var{options}
+## @deftypefnx {Command} {} ls @var{options} @var{filenames}
+## @deftypefnx {Function File} {@var{list} =} ls (@dots{})
+##
+## List directory contents.
+##
+## The @code{ls} command is implemented by calling the native operating
+## system's directory listing command---available @var{options} will vary from
+## system to system.
+##
+## Filenames are subject to shell expansion if they contain any wildcard
+## characters @samp{*}, @samp{?}, @samp{[]}.  To find a literal example of a
+## wildcard character the wildcard must be escaped using the backslash operator
+## @samp{\}.
+##
+## If the optional output @var{list} is requested then @code{ls} returns a
+## character array with one row for each file/directory name.
+##
+## Example usage on a UNIX-like system:
 ##
 ## @example
 ## @group
@@ -32,14 +48,6 @@
 ## @end group
 ## @end example
 ##
-## The @code{dir} and @code{ls} commands are implemented by calling your
-## system's directory listing command, so the available options will vary
-## from system to system.
-##
-## Filenames are subject to shell expansion if they contain any wildcard
-## characters @samp{*}, @samp{?}, @samp{[]}.  If you want to find a
-## literal example of a wildcard character you must escape it using the
-## backslash operator @samp{\}.
 ## @seealso{dir, readdir, glob, what, stat, filesep, ls_command}
 ## @end deftypefn
 
@@ -50,8 +58,7 @@
   global __ls_command__;
 
   if (isempty (__ls_command__) || ! ischar (__ls_command__))
-    ## Initialize value for __ls_command__.
-    ls_command ();
+    ls_command ();  # Initialize global value for __ls_command__.
   endif
 
   if (! iscellstr (varargin))
@@ -61,17 +68,25 @@
   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');
+      args = regexprep (args, '([^\w.*?])', '^$1');
     else
-      args = regexprep (args, '([^\w.*?-])', '\\$1');
+      ## Escape any special characters in filename
+      args = regexprep (args, '([^][\w.*?-])', '\\$1');
+      ## Undo escaped spaces following command args
+      ## Only used for command form where single str contains many args.
+      ## Example: list = ls ("-l /usr/bin")
+      args = regexprep (args, '(-\w+)(?:\\ )+', '$1 ');
     endif
     args = sprintf ("%s ", args{:});
   else
     args = "";
   endif
 
-  cmd = sprintf ("%s %s", __ls_command__, args);
+  cmd = [__ls_command__ " " args];
 
   if (page_screen_output () || nargout > 0)
     [status, output] = system (cmd);
@@ -80,10 +95,8 @@
       error ("ls: command exited abnormally with status %d\n", status);
     elseif (nargout == 0)
       puts (output);
-    elseif (isempty (output))
-      retval = "";
     else
-      retval = strvcat (regexp (output, '\S+', 'match'){:});
+      retval = strvcat (regexp (output, "[\r\n]+", "split"){:});
     endif
   else
     ## Just let the output flow if the pager is off.  That way the
@@ -100,5 +113,18 @@
 %! assert (ischar (list));
 %! assert (! isempty (list));
 
-%!error ls (1)
+%!test
+%! if (isunix ())
+%!   list = ls ("/");
+%!   list = (list')(:)';   # transform to a single row vector
+%!   assert (! isempty (strfind (list, "sbin")));
+%!   list2 = ls ("-l /");
+%!   list2 = (list2')(:)';   # transform to a single row vector
+%!   assert (! isempty (strfind (list2, "sbin")));
+%!   assert (rows (list) == rows (list2));
+%! endif
 
+%!error <all arguments must be character strings> ls (1)
+## Test below is valid, but produces confusing output on screen
+%!#error <command exited abnormally> ls ("-!")
+
--- a/scripts/miscellaneous/ls_command.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/miscellaneous/ls_command.m	Fri Feb 06 08:31:49 2015 -0800
@@ -47,7 +47,7 @@
       if (ischar (cmd))
         __ls_command__ = cmd;
       else
-        error ("ls_command: expecting argument to be a character string");
+        error ("ls_command: argument must be a character string");
       endif
     endif
 
@@ -65,3 +65,5 @@
 %!   assert (cmd(1:2), "ls");
 %! endif
 
+%!error <argument must be a character string> ls_command (123)
+
--- a/scripts/miscellaneous/menu.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/miscellaneous/menu.m	Fri Feb 06 08:31:49 2015 -0800
@@ -17,82 +17,83 @@
 ## <http://www.gnu.org/licenses/>.
 
 ## -*- texinfo -*-
-## @deftypefn {Function File} {} menu (@var{title}, @var{opt1}, @dots{})
-## Print a title string followed by a series of options.  Each option will
-## be printed along with a number.  The return value is the number of the
-## option selected by the user.  This function is useful for interactive
-## programs.  There is no limit to the number of options that may be passed
-## in, but it may be confusing to present more than will fit easily on one
-## screen.
+## @deftypefn  {Function File} {@var{choice} =} menu (@var{title}, @var{opt1}, @dots{})
+## @deftypefnx {Function File} {@var{choice} =} menu (@var{title}, @{@var{opt1}, @dots{}@})
+## Display a menu with heading @var{title} and options @var{opt1}, @dots{},
+## and wait for user input.
+##
+## If the GUI is running, or Java is available, the menu is displayed
+## graphically using @code{listdlg}.  Otherwise, the title and menu options
+## are printed on the console.
+##
+## @var{title} is a string and the options may be input as individual strings
+## or as a cell array of strings.
+##
+## The return value @var{choice} is the number of the option selected by the
+## user counting from 1.
+##
+## This function is useful for interactive programs.  There is no limit to the
+## number of options that may be passed in, but it may be confusing to present
+## more than will fit easily on one screen.
 ## @seealso{input, listdlg}
 ## @end deftypefn
 
 ## Author: jwe
 
-function num = menu (title, varargin)
+function choice = menu (title, varargin)
 
   if (nargin < 2)
     print_usage ();
   endif
 
-  ## Force pending output to appear before the menu.
-
-  fflush (stdout);
-
-  ## Don't send the menu through the pager since doing that can cause
-  ## major confusion.
-
-  page_screen_output (0, "local");
-
-  ## Process Supplied Options
-  if (nargin == 2)
-    ## List in a cell array
-    if (iscell (varargin{1}))
-      varargin = varargin{1};
-      nopt = length (varargin);
-      for i = 1:nopt
-        while (iscell (varargin{i}))
-          varargin{i} = varargin{i}{1};
-        endwhile
-      endfor
-    else
-      nopt = nargin - 1;
-    endif
-  else
-    ## List with random elements in it - pick the first always
-    for i = 1:nargin - 1
-      if (iscell (varargin{i}))
-        while (iscell (varargin{i}))
-          varargin{i} = varargin{i}{1};
-        endwhile
-      else
-        if (! ischar (varargin{i}))
-          varargin{i} = varargin{i}(1);
-        endif
-      endif
-    endfor
-    nopt = length (varargin);
+  if (! ischar (title))
+    error ("menu: TITLE must be a string");
+  elseif (nargin > 2 && ! iscellstr (varargin))
+    error ("menu: All OPTIONS must be strings");
+  elseif (! ischar (varargin{1}) && ! iscellstr (varargin{1}))
+    error ("menu: OPTIONS must be string or cell array of strings");
   endif
 
-  if (! isempty (title))
-    disp (title);
-    printf ("\n");
-  endif
+  if (isguirunning () || usejava ("awt"))
+    [choice, ok] = listdlg ("Name", "menu", "PromptString", title,
+                            "ListString", varargin, "SelectionMode", "Single");
+    if (! ok)
+      choice = 1;
+    endif
+  else  # console menu
+    ## Force pending output to appear before the menu.
+    fflush (stdout);
+
+    ## Don't send the menu through the pager since doing that can cause
+    ## major confusion.
+    page_screen_output (0, "local");
 
-  while (1)
-    for i = 1:nopt
-      printf ("  [%2d] ", i);
-      disp (varargin{i});
-    endfor
-    printf ("\n");
-    s = input ("pick a number, any number: ", "s");
-    num = sscanf (s, "%d");
-    if (! isscalar (num) || num < 1 || num > nopt)
-      printf ("\nerror: input invalid or out of range\n\n");
-    else
-      break;
+    if (! isempty (title))
+      printf ("%s\n", title);
     endif
-  endwhile
+
+    nopt = numel (varargin);
+    while (1)
+      for i = 1:nopt
+        printf ("  [%2d] %s\n", i, varargin{i});
+      endfor
+      printf ("\n");
+      s = input ("Select a number: ", "s");
+      choice = sscanf (s, "%d");
+      if (! isscalar (choice) || choice < 1 || choice > nopt)
+        printf ("\nerror: input invalid or out of range\n\n");
+      else
+        break;
+      endif
+    endwhile
+  endif
 
 endfunction
 
+
+%!error menu ()
+%!error menu ("title")
+%!error <TITLE must be a string> menu (1, "opt1")
+%!error <All OPTIONS must be strings> menu ("title", "opt1", 1)
+%!error <OPTIONS must be string or cell array of strings> menu ("title", 1)
+
--- a/scripts/miscellaneous/mex.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/miscellaneous/mex.m	Fri Feb 06 08:31:49 2015 -0800
@@ -19,12 +19,25 @@
 ## -*- texinfo -*-
 ## @deftypefn {Command} {} mex [options] file @dots{}
 ## Compile source code written in C, C++, or Fortran, to a MEX file.
+##
 ## This is equivalent to @code{mkoctfile --mex [options] file}.
-## @seealso{mkoctfile}
+## @seealso{mkoctfile, mexext}
 ## @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
 
+
+## Remove from test statistics.  All real tests are in mkoctfile.
+%!assert (1)
+
--- a/scripts/miscellaneous/module.mk	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/miscellaneous/module.mk	Fri Feb 06 08:31:49 2015 -0800
@@ -21,7 +21,6 @@
   miscellaneous/desktop.m \
   miscellaneous/dir.m \
   miscellaneous/dos.m \
-  miscellaneous/dump_prefs.m \
   miscellaneous/edit.m \
   miscellaneous/error_ids.m \
   miscellaneous/fact.m \
@@ -51,6 +50,7 @@
   miscellaneous/movefile.m \
   miscellaneous/namelengthmax.m \
   miscellaneous/news.m \
+  miscellaneous/open.m \
   miscellaneous/orderfields.m \
   miscellaneous/pack.m \
   miscellaneous/paren.m \
@@ -68,7 +68,7 @@
   miscellaneous/symvar.m \
   miscellaneous/tar.m \
   miscellaneous/tempdir.m \
-  miscellaneous/tempname.m \
+  miscellaneous/tmpnam.m \
   miscellaneous/unix.m \
   miscellaneous/unpack.m \
   miscellaneous/untar.m \
--- a/scripts/miscellaneous/movefile.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/miscellaneous/movefile.m	Fri Feb 06 08:31:49 2015 -0800
@@ -21,12 +21,13 @@
 ## @deftypefnx {Function File} {} movefile (@var{f1}, @var{f2})
 ## @deftypefnx {Function File} {} movefile (@var{f1}, @var{f2}, 'f')
 ## @deftypefnx {Function File} {[@var{status}, @var{msg}, @var{msgid}] =} movefile (@dots{})
-## Move the file @var{f1} to the destination @var{f2}.
+## Move the source files or directories @var{f1} to the destination @var{f2}.
 ##
 ## The name @var{f1} may contain globbing patterns.  If @var{f1} expands to
 ## multiple file names, @var{f2} must be a directory.  If no destination
 ## @var{f2} is specified then the destination is the present working directory.
 ## If @var{f2} is a file name then @var{f1} is renamed to @var{f2}.
+##
 ## When the force flag @qcode{'f'} is given any existing files will be
 ## overwritten without prompting.
 ##
@@ -50,7 +51,7 @@
   msgid = "";
 
   ## FIXME: maybe use the same method as in ls to allow users control
-  ## over the command that is executed.
+  ##        over the command that is executed.
 
   if (ispc () && ! isunix ()
       && isempty (file_in_path (getenv ("PATH"), "mv.exe")))
@@ -63,28 +64,25 @@
   endif
 
   ## Input type check.
-  if (! (ischar (f1) || iscellstr (f1)))
-    error ("movefile: F1 must be a character string or a cell array of character strings");
+  if (ischar (f1))
+    f1 = cellstr (f1);
+  elseif (! iscellstr (f1))
+    error ("copyfile: F1 must be a string or a cell array of strings");
   endif
 
   if (nargin == 1)
     f2 = pwd ();
   elseif (! ischar (f2))
-    error ("movefile: F2 must be a character string");
+    error ("movefile: F2 must be a string");
   endif
 
   if (nargin == 3 && strcmp (force, "f"))
     cmd = [cmd " " cmd_force_flag];
   endif
 
-  ## If f1 isn't a cellstr convert it to one.
-  if (ischar (f1))
-    f1 = cellstr (f1);
-  endif
-
   ## If f1 has more than 1 element f2 must be a directory
   isdir = (exist (f2, "dir") != 0);
-  if (length (f1) > 1 && ! isdir)
+  if (numel (f1) > 1 && ! isdir)
     error ("movefile: when moving multiple files, F2 must be a directory");
   endif
 
@@ -137,3 +135,35 @@
 
 endfunction
 
+
+%!test
+%! unwind_protect
+%!   f1 = tempname;
+%!   tmp_var = pi;
+%!   save (f1, "tmp_var");
+%!   fid = fopen (f1, "rb");
+%!   assert (fid >= 0);
+%!   orig_data = fread (fid);
+%!   fclose (fid);
+%!   f2 = tempname;
+%!   assert (movefile (f1, f2));
+%!   assert (! exist (f1, "file"));
+%!   assert (exist (f2, "file"));
+%!   fid = fopen (f2, "rb");
+%!   assert (fid >= 0);
+%!   new_data = fread (fid);
+%!   fclose (fid);
+%!   if (orig_data != new_data)
+%!     error ("moved file not equal to original file!");
+%!   endif
+%! unwind_protect_cleanup
+%!   delete (f2);
+%! end_unwind_protect
+
+## Test input validation
+%!error movefile ()
+%!error movefile (1,2,3,4)
+%!error <F1 must be a string> movefile (1, "foobar")
+%!error <F2 must be a string> movefile ("foobar", 1)
+%!error <F2 must be a directory> movefile ({"a", "b"}, "%_NOT_A_DIR_%")
+
--- a/scripts/miscellaneous/namelengthmax.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/miscellaneous/namelengthmax.m	Fri Feb 06 08:31:49 2015 -0800
@@ -18,12 +18,13 @@
 
 ## -*- texinfo -*-
 ## @deftypefn {Function File} {} namelengthmax ()
-## Return the @sc{matlab} compatible maximum variable name length.  Octave is
-## capable of storing strings up to @math{2^{31} - 1} in length.
-## However for @sc{matlab} compatibility all variable, function,
-## and structure field names should be shorter than the length supplied by
-## @code{namelengthmax}.  In particular variables stored to a @sc{matlab} file
-## format will have their names truncated to this length.
+## Return the @sc{matlab} compatible maximum variable name length.
+##
+## Octave is capable of storing strings up to @math{2^{31} - 1} in length.
+## However for @sc{matlab} compatibility all variable, function, and structure
+## field names should be shorter than the length returned by
+## @code{namelengthmax}.  In particular, variables stored to a @sc{matlab} file
+## format (@file{*.mat}) will have their names truncated to this length.
 ## @end deftypefn
 
 function n = namelengthmax ()
--- a/scripts/miscellaneous/news.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/miscellaneous/news.m	Fri Feb 06 08:31:49 2015 -0800
@@ -24,6 +24,7 @@
 ## When called without an argument, display the NEWS file for Octave.
 ## When given a package name @var{package}, display the current NEWS file for
 ## that package.
+## @seealso{ver, pkg}
 ## @end deftypefn
 
 function news (package = "octave")
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/miscellaneous/open.m	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,89 @@
+## 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/>.
+
+## -*- texinfo -*-
+## @deftypefn  {Function File} {@var{output} =} open @var{file}
+## @deftypefnx {Function File} {@var{output} =} open (@var{file})
+## Open the file @var{file} in Octave or in an external application
+## based on the file type as determined by the file name extension.
+##
+## Recognized file types are
+##
+## @table @code
+## @item .m
+## Open file in the editor.
+##
+## @item .mat
+## Load the file in the base workspace.
+##
+## @item .exe
+## Execute the program (on Windows systems only).
+## @end table
+##
+## Other file types are opened in the appropriate external application.
+## @end deftypefn
+
+function output = open (file)
+
+  if (nargin != 1)
+    print_usage ();
+  endif
+
+  if (! ischar (file))
+    error ("expecting argument to be a file name");
+  endif
+
+  [~, ~, ext] = fileparts (file);
+
+  if (strcmpi (ext, ".m"))
+    edit (file);
+  elseif (strcmpi (ext, ".mat"))
+    if (nargout > 0)
+      output = load (file);
+    else
+      evalin ("base", sprintf ("load ('%s');", file));
+    endif
+  elseif (any (strcmpi (ext, {".fig", ".mdl", ".slx", ".prj"})))
+    error ("opening file type '%s' is not supported", ext);
+  elseif (strcmpi (ext, ".exe"))
+    if (ispc ())
+      dos (file);
+    else
+      error ("executing .exe files is only supported on Windows systems");
+    endif
+  else
+    open_with_system_app (file);
+  endif
+
+endfunction
+
+%% Test input validation
+%!error open
+%!error open (1)
+%!error output = open (1)
+
+function open_with_system_app (file)
+
+  if (ispc ())
+    __w32_shell_execute__ (file);
+  else
+    ## FIXME: might not be xdg-open...
+    system (sprintf ("xdg-open %s 2> /dev/null", file), false, "async");
+  endif
+
+endfunction
--- a/scripts/miscellaneous/orderfields.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/miscellaneous/orderfields.m	Fri Feb 06 08:31:49 2015 -0800
@@ -17,20 +17,23 @@
 ## <http://www.gnu.org/licenses/>.
 
 ## -*- texinfo -*-
-## @deftypefn  {Function File} {[@var{t}, @var{p}] =} orderfields (@var{s1})
-## @deftypefnx {Function File} {[@var{t}, @var{p}] =} orderfields (@var{s1}, @var{s2})
-## Return a copy of @var{s1} with fields arranged alphabetically or as
-## specified by @var{s2}.
-##
-## Given one struct, arrange field names in @var{s1} alphabetically.
+## @deftypefn  {Function File} {@var{sout}] =} orderfields (@var{s1})
+## @deftypefnx {Function File} {@var{sout}] =} orderfields (@var{s1}, @var{s2})
+## @deftypefnx {Function File} {@var{sout}] =} orderfields (@var{s1}, @{@var{cellstr}@})
+## @deftypefnx {Function File} {@var{sout}] =} orderfields (@var{s1}, @var{p})
+## @deftypefnx {Function File} {[@var{sout}, @var{p}] =} orderfields (@dots{})
+## Return a @emph{copy} of @var{s1} with fields arranged alphabetically, or as
+## specified by the second input.
 ##
-## If the second argument is a struct, arrange field names in @var{s1} as they
+## Given one input struct @var{s1}, arrange field names alphabetically.
+##
+## If a second struct argument is given, arrange field names in @var{s1} as they
 ## appear in @var{s2}.  The second argument may also specify the order in a
-## permutation vector or a cell array of strings containing the fieldnames of
-## @var{s1} in the desired order.
+## cell array of strings @var{cellstr}.  The second argument may also be a
+## permutation vector.
 ##
-## The optional second output argument @var{p} is assigned the permutation
-## vector which converts the original name order into the new name order.
+## The optional second output argument @var{p} is the permutation vector which
+## converts the original name order to the new name order.
 ##
 ## Examples:
 ##
@@ -84,20 +87,18 @@
 ## @end group
 ## @end example
 ##
-## @seealso{getfield, rmfield, isfield, isstruct, fieldnames, struct}
+## @seealso{fieldnames, getfield, setfield, rmfield, isfield, isstruct, struct}
 ## @end deftypefn
 
 ## Author: Paul Kienzle <pkienzle@users.sf.net>
 ## Adapted-By: jwe
 
-function [t, p] = orderfields (s1, s2)
+function [sout, p] = orderfields (s1, s2)
 
-  if (nargin == 1 || nargin == 2)
-    if (! isstruct (s1))
-      error ("orderfields: S1 must be a struct");
-    endif
-  else
+  if (nargin < 1 || nargin > 2)
     print_usage ();
+  elseif (! isstruct (s1))
+    error ("orderfields: S1 must be a struct");
   endif
 
   if (nargin == 1)
@@ -110,32 +111,34 @@
       ## Two structures: return the fields in the order of s2.
       names = fieldnames (s2);
       if (! isequal (sort (fieldnames (s1)), sort (names)))
-        error ("orderfields: structures do not have the same fields");
+        error ("orderfields: structures S1 and S2 do not have the same fields");
       endif
     elseif (iscellstr (s2))
       ## A structure and a list of fields: order by the list of fields.
       t1 = sort (fieldnames (s1));
       t2 = sort (s2(:));
       if (! isequal (t1, t2))
-        error ("orderfields: name list does not match structure fields");
+        error ("orderfields: CELLSTR list does not match structure fields");
       endif
       names = s2;
     elseif (isvector (s2))
       ## A structure and a permutation vector: permute the order of s1.
       names = fieldnames (s1);
-      t1 = sort (s2);
-      t1 = t1(:)';
-      t2 = 1:numel (names);
+      t1 = 1:numel (names);
+      t2 = sort (s2);
+      t2 = t2(:)';
       if (! isequal (t1, t2))
-        error ("orderfields: invalid permutation vector");
+        error ("orderfields: invalid permutation vector P");
       endif
       names = names(s2);
+    else
+      error ("orderfields: second argument must be structure, cellstr, or permutation vector");
     endif
   endif
 
   ## Corner case of empty struct
   if (isempty (names))
-    t = struct ();
+    sout = struct ();
     p = [];
   endif
 
@@ -150,19 +153,22 @@
   endif
 
   ## Permute the names in the structure.
-  if (numel (s1) == 0)
+  if (isempty (s1))
+    ## Corner case of empty structure.  Still need to re-order fields.
     args = cell (1, 2 * numel (names));
     args(1:2:end) = names;
     args(2:2:end) = {[]};
-    t = struct (args{:});
+    sout = struct (args{:});
+    ## inherit dimensions
+    sout = resize (sout, size (s1));
   else
     n = numel (s1);
     for i = 1:numel (names)
       el = names{i};
-      [t(1:n).(el)] = s1(:).(el);
+      [sout(1:n).(el)] = s1(:).(el);
     endfor
     ## inherit dimensions
-    t = reshape (t, size (s1));
+    sout = reshape (sout, size (s1));
   endif
 
 endfunction
@@ -202,4 +208,28 @@
 
 ## Corner case of empty struct, bug #40224
 %!assert (orderfields (struct ()), struct ())
+%!test
+%! s(2,2).a = 1;
+%! s(1,1).b = 2;
+%! s = resize (s, [1 0]);
+%! s2 = orderfields (s, {"b", "a"});
+%! assert (fieldnames (s2), {"b"; "a"});
+%! assert (size_equal (s, s2));
 
+## Test input validation
+%!error orderfields ()
+%!error orderfields (1,2,3)
+%!error <S1 must be a struct> orderfields (1)
+%!error <S1 and S2 do not have the same fields>
+%! s1.a = 1;
+%! s2.b = 2;
+%! orderfields (s1, s2);
+%!error <CELLSTR list does not match structure fields>
+%! s1.a = 1;
+%! orderfields (s1, {"b"});
+%!error <invalid permutation vector P>
+%! s1.a = 1;
+%! orderfields (s1, [2 1]);
+%!error <second argument must be structure, cellstr, or permutation vector>
+%! s1.a = 1;
+%! orderfields (s1, ones (2,2));
--- a/scripts/miscellaneous/pack.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/miscellaneous/pack.m	Fri Feb 06 08:31:49 2015 -0800
@@ -18,8 +18,10 @@
 
 ## -*- texinfo -*-
 ## @deftypefn {Function File} {} pack ()
-## Consolidate workspace memory in @sc{matlab}.  This function is provided for
-## compatibility, but does nothing in Octave.
+## Consolidate workspace memory in @sc{matlab}.
+##
+## This function is provided for compatibility, but does nothing in Octave.
+## @seealso{clear}
 ## @end deftypefn
 
 ## Author: jwe
@@ -28,3 +30,7 @@
 
 endfunction
 
+
+## No test needed for empty function
+%!assert (1)
+
--- a/scripts/miscellaneous/parseparams.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/miscellaneous/parseparams.m	Fri Feb 06 08:31:49 2015 -0800
@@ -52,7 +52,7 @@
 ## name of the caller function.
 ## The matching of options is case-insensitive.
 ##
-## @seealso{varargin}
+## @seealso{varargin, inputParser}
 ## @end deftypefn
 
 ## Author: Alexander Barth <abarth93@users.sourceforge.net>
@@ -105,3 +105,25 @@
   error ([fname, ": ", msg], varargin{:});
 endfunction
 
+
+%!test
+%! [reg, prop] = parseparams ({1, 2, "linewidth", 10});
+%! assert (reg, {[1], [2]});
+%! assert (prop, {"linewidth", 10});
+%!test
+%! [reg, prop] = parseparams ({1, 2, 3});
+%! assert (reg, {[1], [2], [3]});
+%! assert (isempty (prop));
+%!test
+%! [reg, prop] = parseparams ({"prop1", "val1"});
+%! assert (isempty (reg));
+%! assert (prop, {"prop1", "val1"});
+%!test
+%! [reg, prop1] = parseparams ({"linewidth", 5}, "linewidth", 10);
+%! assert (isempty (reg));
+%! assert (prop1, 5);
+
+%!error <needs odd number of arguments> parseparams ({1}, "linewidth")
+%!error <must be given as name-value pairs> parseparams ({1, "color"}, "linewidth", 5)
+%!error <unrecognized option: color> parseparams ({1, "color", 5}, "linewidth", 5)
+
--- a/scripts/miscellaneous/perl.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/miscellaneous/perl.m	Fri Feb 06 08:31:49 2015 -0800
@@ -21,9 +21,11 @@
 ## @deftypefnx {Function File} {@var{output} =} perl (@var{scriptfile}, @var{argument1}, @var{argument2}, @dots{})
 ## @deftypefnx {Function File} {[@var{output}, @var{status}] =} perl (@dots{})
 ## Invoke Perl script @var{scriptfile}, possibly with a list of command line
-## arguments.  Return output in @var{output} and optional status in
-## @var{status}.  If @var{scriptfile} is not an absolute file name it is
-## is searched for in the current directory and then in the Octave loadpath.
+## arguments.
+##
+## Return output in @var{output} and optional status in @var{status}.  If
+## @var{scriptfile} is not an absolute file name it is searched for in the
+## current directory and then in the Octave loadpath.
 ## @seealso{system, python}
 ## @end deftypefn
 
@@ -49,3 +51,6 @@
 
 endfunction
 
+
+%!error <invalid arguments> perl (123)
+
--- a/scripts/miscellaneous/private/__xzip__.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/miscellaneous/private/__xzip__.m	Fri Feb 06 08:31:49 2015 -0800
@@ -18,7 +18,7 @@
 ## <http://www.gnu.org/licenses/>.
 
 ## -*- texinfo -*-
-## @deftypefn {Function File} {@var{entries} =} __xzip__ (@var{commandname}, @var{extension}, @var{commandtemplate}, @var{files}, @var{outdir})
+## @deftypefn {Function File} {@var{filelist} =} __xzip__ (@var{commandname}, @var{extension}, @var{commandtemplate}, @var{files}, @var{outdir})
 ## Undocumented internal function.
 ## @end deftypefn
 
@@ -30,23 +30,28 @@
 ## are not touched. Existing compressed files are silently overwritten.
 ## This is an internal function. Do not use directly.
 
-function entries = __xzip__ (commandname, extension,
-                             commandtemplate, files, outdir)
+function filelist = __xzip__ (commandname, extension, commandtemplate,
+                              files, outdir)
 
   if (nargin == 5 && ! exist (outdir, "dir"))
-    error ("__xzip__: OUTDIR output directory does not exist");
+    r = mkdir (outdir);
+    if (! r)
+      error ("%s: Failed to create output directory DIR", commandname);
+    endif
   endif
 
   if (ischar (files))
     files = cellstr (files);
-  endif
-  if (! iscellstr (files))
-    error ("__xzip__: FILES must be a character array or cellstr");
+  elseif (! iscellstr (files))
+    error ("%s: FILES must be a character array or cellstr", commandname);
   endif
 
   if (nargin == 4)
-    outdir = tmpnam ();
-    mkdir (outdir);
+    outdir = tempname ();
+    r = mkdir (outdir);
+    if (! r)
+      error ("%s: Failed to create temporary output directory", commandname);
+    endif
   endif
 
   cwd = pwd ();
@@ -61,31 +66,35 @@
 
     copyfile (files, outdir);
 
-    [d, f] = myfileparts (files);
+    fnames = fname_only (files);
 
     cd (outdir);
 
-    cmd = sprintf (commandtemplate, sprintf (" %s", f{:}));
+    cmd = sprintf (commandtemplate, sprintf (" %s", fnames{:}));
 
     [status, output] = system (cmd);
     if (status)
-      error ("__xzip__: %s command failed with exit status = %d",
-             commandname, status);
+      fcn = evalin ("caller", "mfilename ()");
+      error ("%s: %s command failed with exit status = %d",
+             fcn, commandname, status);
     endif
 
     if (nargin == 5)
       if (nargout > 0)
-        entries = cellfun(
+        ## FIXME: This doesn't work if a directory is compressed
+        filelist = cellfun (
             @(x) fullfile (outdir, sprintf ("%s.%s", x, extension)),
-            f, "uniformoutput", false);
+            fnames, "uniformoutput", false);
       endif
     else
-      movefile (cellfun (@(x) sprintf ("%s.%s", x, extension), f,
-                        "uniformoutput", false), cwd);
+      ## FIXME: This does not work when you try to compress directories
+      ##        The resulting name is dir/.gz which is totally wrong.
+      ##        See bug #43431.
+      movefile (cellfun (@(x) sprintf ("%s.%s", x, extension),
+                         fnames, "uniformoutput", false), cwd);
       if (nargout > 0)
-        ## FIXME this does not work when you try to compress directories
-        entries  = cellfun (@(x) sprintf ("%s.%s", x, extension),
-                            files, "uniformoutput", false);
+        filelist  = cellfun (@(x) sprintf ("%s.%s", x, extension),
+                             files, "uniformoutput", false);
       endif
     endif
 
@@ -99,35 +108,10 @@
 
 endfunction
 
-function [d, f] = myfileparts (files)
-  [d, f, ext] = cellfun ("fileparts", files, "uniformoutput", false);
-  f = cellfun (@(x, y) sprintf ("%s%s", x, y), f, ext,
-               "uniformoutput", false);
+function f = fname_only (files)
+  [~, f, ext] = cellfun ("fileparts", files, "uniformoutput", false);
+  f = cellfun (@(x, y) sprintf ("%s%s", x, y), f, ext, "uniformoutput", false);
   idx = cellfun ("isdir", files);
-  d(idx) = "";
   f(idx) = files(idx);
 endfunction
 
-
-## FIXME -- reinstate these 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");
-## %!error <no files to move>
-## %!  __xzip__ ("gzip", ".gz", "gzip -r %s", tmpnam);
-## %!error <command failed with exit status>
-## %!  # test __xzip__ with invalid compression command
-## %!  unwind_protect
-## %!    filename = tmpnam;
-## %!    dummy    = 1;
-## %!    save (filename, "dummy");
-## %!    dirname  = tmpnam;
-## %!    mkdir (dirname);
-## %!    entry = __xzip__ ("gzip", ".gz", "xxxzipxxx -r %s 2>/dev/null",
-## %!                     filename, dirname);
-## %!  unwind_protect_cleanup
-## %!    delete (filename);
-## %!    rmdir (dirname);
-## %!  end_unwind_protect
-
--- a/scripts/miscellaneous/python.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/miscellaneous/python.m	Fri Feb 06 08:31:49 2015 -0800
@@ -22,9 +22,11 @@
 ## @deftypefnx {Function File} {@var{output} =} python (@var{scriptfile}, @var{argument1}, @var{argument2}, @dots{})
 ## @deftypefnx {Function File} {[@var{output}, @var{status}] =} python (@dots{})
 ## Invoke Python script @var{scriptfile}, possibly with a list of command line
-## arguments.  Return output in @var{output} and optional status in
-## @var{status}.  If @var{scriptfile} is not an absolute file name it is
-## is searched for in the current directory and then in the Octave loadpath.
+## arguments.
+##
+## Return output in @var{output} and optional status in @var{status}.  If
+## @var{scriptfile} is not an absolute file name it is searched for in the
+## current directory and then in the Octave loadpath.
 ## @seealso{system, perl}
 ## @end deftypefn
 
@@ -48,3 +50,6 @@
 
 endfunction
 
+
+%!error <invalid arguments> python (123)
+
--- a/scripts/miscellaneous/recycle.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/miscellaneous/recycle.m	Fri Feb 06 08:31:49 2015 -0800
@@ -21,10 +21,15 @@
 ## @deftypefnx {Function File} {@var{old_state} =} recycle (@var{new_state})
 ## Query or set the preference for recycling deleted files.
 ##
-## Recycling files, instead of permanently deleting them, is not currently
-## implemented in Octave.  To help avoid accidental data loss an error
-## will be raised if an attempt is made to enable file recycling.
-## @seealso{delete}
+## When recycling is enabled, commands which would permanently erase files
+## instead move them to a temporary location (such as the directory labeled
+## Trash).
+##
+## Programming Note: This function is provided for @sc{matlab} compatibility,
+## but recycling is not implemented in Octave.  To help avoid accidental data
+## loss an error will be raised if an attempt is made to enable file
+## recycling.
+## @seealso{delete, rmdir}
 ## @end deftypefn
 
 ## Author: jwe
@@ -42,16 +47,16 @@
   endif
 
   if (nargin == 1)
-    if (ischar (state))
-      if (strcmpi (state, "on"))
-        error ("recycle: recycling files is not implemented");
-      elseif (strcmpi (state, "off"))
-        current_state = "off";
-      else
-        error ("recycle: invalid value of STATE = '%s'", state);
-      endif
+    if (! ischar (state))
+      error ("recycle: STATE must be a character string");
+    endif
+
+    if (strcmpi (state, "on"))
+      error ("recycle: recycling files is not implemented");
+    elseif (strcmpi (state, "off"))
+      current_state = "off";
     else
-      error ("recycle: STATE must be a character string");
+      error ("recycle: invalid value of STATE = '%s'", state);
     endif
   endif
 
@@ -62,7 +67,8 @@
 %! recycle ("off");
 %! assert (recycle ("off"), "off");
 
-%!error <recycling files is not implemented> recycle ("on")
 %!error recycle ("on", "and I mean it")
 %!error <STATE must be a character string> recycle (1)
+%!error <recycling files is not implemented> recycle ("on")
+%!error <invalid value of STATE = 'foobar'> recycle ("foobar")
 
--- a/scripts/miscellaneous/rmappdata.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/miscellaneous/rmappdata.m	Fri Feb 06 08:31:49 2015 -0800
@@ -17,9 +17,15 @@
 ## <http://www.gnu.org/licenses/>.
 
 ## -*- texinfo -*-
-## @deftypefn {Function File} {} rmappdata (@var{h}, @var{name})
-## Delete the named application data for the object(s) with
-## handle(s) @var{h}.
+## @deftypefn  {Function File} {} rmappdata (@var{h}, @var{name})
+## @deftypefnx {Function File} {} rmappdata (@var{h}, @var{name1}, @var{name2}, @dots{})
+## Delete the application data @var{name} from the graphics object with handle
+## @var{h}.
+##
+## @var{h} may also be a vector of graphics handles.  Multiple application data
+## names may be supplied to delete several properties at once.
+##
+## @seealso{setappdata, getappdata, isappdata}
 ## @end deftypefn
 
 ## Author: Ben Abbott <bpabbott@mac.com>
@@ -27,21 +33,28 @@
 
 function rmappdata (h, varargin)
 
-  if (! (all (ishandle (h)) && iscellstr (varargin)))
-    error ("rmappdata: invalid input");
+  if (nargin < 2)
+    print_usage ();
+  endif
+
+  h = h(:).';
+  if (! all (ishandle (h)))
+    error ("rmappdata: H must be a scalar or vector of graphic handles");
+  elseif (! iscellstr (varargin))
+    error ("rmappdata: NAME must be a string");
   endif
 
-  for nh = 1:numel (h)
-    if (isprop (h(nh), "__appdata__"))
-      appdata = get (h(nh), "__appdata__");
-      for v = 1:numel(varargin)
-        if (isfield (appdata, varargin{v}))
-          appdata = rmfield (appdata, varargin{v});
-        else
-          error ("rmappdata: appdata '%s' is not present")
-        endif
-      endfor
-      set (h(nh), "__appdata__", appdata);
+  for hg = h
+    if (isprop (hg, "__appdata__"))
+      appdata = get (hg, "__appdata__");
+      vld = isfield (appdata, varargin);
+      if (! all (vld))
+        ## FIXME: Should we bother to error out?  Or just silently continue?
+        missing = varargin{find (! vld, 1)};
+        error ("rmappdata: appdata '%s' is not present", missing);
+      endif
+      appdata = rmfield (appdata, varargin);
+      set (hg, "__appdata__", appdata);
     endif
   endfor
 
@@ -49,14 +62,21 @@
 
 
 %!test
-%! setappdata (0, "hello", "world");
-%! rmappdata (0, "hello");
-%! assert (isappdata (0, "hello"), false);
+%! setappdata (0, "%hello%", "world");
+%! rmappdata (0, "%hello%");
+%! assert (isappdata (0, "%hello%"), false);
 
 %!test
-%! setappdata (0, "data1", rand (3));
-%! setappdata (0, "data2", {"hello", "world"});
-%! rmappdata (0, "data1", "data2");
-%! assert (isappdata (0, "data1"), false);
-%! assert (isappdata (0, "data2"), false);
+%! setappdata (0, "%data1%", ones (3));
+%! setappdata (0, "%data2%", {"hello", "world"});
+%! rmappdata (0, "%data1%", "%data2%");
+%! assert (isappdata (0, "%data1%"), false);
+%! assert (isappdata (0, "%data2%"), false);
 
+## Test input validation
+%!error rmappdata ()
+%!error rmappdata (1)
+%!error <H must be a scalar .* graphic handle> rmappdata (-1, "hello")
+%!error <NAME must be a string> rmappdata (0, 1)
+%!error <appdata 'foobar' is not present> rmappdata (0, "foobar")
+
--- a/scripts/miscellaneous/run.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/miscellaneous/run.m	Fri Feb 06 08:31:49 2015 -0800
@@ -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
 
@@ -59,13 +60,16 @@
 
   if (! isempty (d))
     if (exist (d, "dir"))
-      wd = pwd ();
+      startdir = pwd ();
+      d = canonicalize_file_name (d);
       unwind_protect
         cd (d);
         evalin ("caller", sprintf ('source ("%s%s");', f, ext),
                 "rethrow (lasterror ())");
       unwind_protect_cleanup
-        cd (wd);
+        if (strcmp (d, pwd ()))
+          cd (startdir);
+        endif
       end_unwind_protect
     else
       error ("run: the path %s doesn't exist", d);
--- a/scripts/miscellaneous/setappdata.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/miscellaneous/setappdata.m	Fri Feb 06 08:31:49 2015 -0800
@@ -17,11 +17,16 @@
 ## <http://www.gnu.org/licenses/>.
 
 ## -*- texinfo -*-
-## @deftypefn {Function File} {} setappdata (@var{h}, @var{name}, @var{value})
-## Set the named application data to @var{value} for the object(s) with
-## handle(s) @var{h}.  If the application data with the specified name does
-## not exist, it is created.
-## @seealso{getappdata, guidata, get, set, getpref, setpref}
+## @deftypefn  {Function File} {} setappdata (@var{h}, @var{name}, @var{value})
+## @deftypefnx {Function File} {} setappdata (@var{h}, @var{name1}, @var{value1}, @var{name2}, @var{value3}, @dots{})
+## Set the application data @var{name} to @var{value} for the graphics object
+## with handle @var{h}.
+##
+## @var{h} may also be a vector of graphics handles.  If the application data
+## with the specified @var{name} does not exist, it is created.  Multiple
+## @var{name}/@var{value} pairs can be specified at a time.
+##
+## @seealso{getappdata, isappdata, rmappdata, guidata, get, set, getpref, setpref}
 ## @end deftypefn
 
 ## Author: Ben Abbott <bpabbott@mac.com>
@@ -29,35 +34,62 @@
 
 function setappdata (h, varargin)
 
-  if (! (all (ishandle (h)) && mod (numel (varargin), 2) == 0))
-    error ("setappdata: invalid input");
+  h = h(:).';
+  if (! all (ishandle (h)))
+    error ("setappdata: H must be a scalar or vector of graphic handles");
+  elseif (mod (numel (varargin), 2) != 0)
+    error ("setappdata: NAME/VALUE arguments must occur in pairs");
   endif
 
-  for nh = 1:numel (h)
-    if (! isfield (get (h(nh)), "__appdata__"))
-      addproperty ("__appdata__", h(nh), "any", struct ());
-    endif
-    appdata = get (h(nh), "__appdata__");
+  for hg = h
+    try
+      appdata = get (hg, "__appdata__");
+    catch
+      appdata = struct ();
+      addproperty ("__appdata__", hg, "any", appdata);
+    end_try_catch
+
     for narg = 1:2:numel (varargin)
-      if (iscellstr (varargin{narg}))
+      if (ischar (varargin{narg}))
+        appdata.(varargin{narg}) = varargin{narg+1};
+      elseif (iscellstr (varargin{narg}))
         ## Handle cell arrays like set() does.
-        set (h(nh), "__appdata__", appdata);
-        setappdata (h(nh), vertcat (varargin{narg}', varargin{narg+1}'){:});
-        appdata = get (h(nh), "__appdata__");
-      elseif (ischar (varargin{narg}))
-        appdata.(varargin{narg}) = varargin{narg+1};
+        set (hg, "__appdata__", appdata);
+        setappdata (hg, vertcat (varargin{narg}', varargin{narg+1}'){:});
+        appdata = get (hg, "__appdata__");
       else
-        error ("setappdata: invalid input");
+        error ("setappdata: NAME must be a string or cellstr");
       endif
     endfor
-    set (h(nh), "__appdata__", appdata);
+
+    set (hg, "__appdata__", appdata);
   endfor
 
 endfunction
 
 
 %!test
-%! setappdata (0, "hello", "world");
-%! assert (isappdata (0, "hello"), true);
-%! assert (getappdata (0, "hello"), "world");
+%! unwind_protect
+%!   setappdata (0, "%hello%", "world");
+%!   assert (isappdata (0, "%hello%"), true);
+%!   assert (getappdata (0, "%hello%"), "world");
+%! unwind_protect_cleanup
+%!   rmappdata (0, "%hello%");
+%! end_unwind_protect
 
+%!test
+%! unwind_protect
+%!   setappdata (0, "%data1%", ones (3), "%data2%", "hello world");
+%!   assert (getappdata (0, "%data1%"), ones (3));
+%!   assert (getappdata (0, "%data2%"), "hello world");
+%!   setappdata (0, "%data1%", zeros (3));
+%!   assert (getappdata (0, "%data1%"), zeros (3));
+%! unwind_protect_cleanup
+%!   rmappdata (0, "%data1%", "%data2%");
+%! end_unwind_protect
+
+## Test input validation
+%!error <H must be a scalar .* graphic handle> rmappdata (-1, "hello")
+%!error <NAME must be a string> setappdata (0, 1, 2)
+%!error <NAME/VALUE arguments must occur in pairs> setappdata (0, "1")
+
--- a/scripts/miscellaneous/setfield.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/miscellaneous/setfield.m	Fri Feb 06 08:31:49 2015 -0800
@@ -18,10 +18,12 @@
 ## <http://www.gnu.org/licenses/>.
 
 ## -*- texinfo -*-
-## @deftypefn  {Function File} {@var{s} =} setfield (@var{s}, @var{field}, @var{val})
-## @deftypefnx {Function File} {@var{s} =} setfield (@var{s}, @var{idx1}, @var{field1}, @var{idx2}, @var{field2}, @dots{}, @var{val})
+## @deftypefn  {Function File} {@var{sout} =} setfield (@var{s}, @var{field}, @var{val})
+## @deftypefnx {Function File} {@var{sout} =} setfield (@var{s}, @var{sidx1}, @var{field1}, @var{fidx1}, @var{sidx2}, @var{field2}, @var{fidx2}, @dots{}, @var{val})
 ##
-## Set a field member @var{field} in a structure @var{s} equal to @var{val}.
+## Return a @emph{copy} of the structure @var{s} with the field member
+## @var{field} set to the value @var{val}.
+##
 ## For example:
 ##
 ## @example
@@ -40,24 +42,29 @@
 ##
 ## @noindent
 ## Note that ordinary structure syntax @code{@var{s}.foo bar = 42} cannot be
-## used here, as the field name is not a valid Octave identifier.  Using
-## arbitrary strings for field name is incompatible with @sc{matlab}, so
-## this usage will warn if the @code{Octave:matlab-incompatible} warning
-## is set.  @xref{XREFwarning_ids}.
+## used here, as the field name is not a valid Octave identifier because of
+## the space character.  Using arbitrary strings for field names is
+## incompatible with @sc{matlab}, and this usage will emit a warning if the
+## warning ID @code{Octave:matlab-incompatible} is enabled.
+## @xref{XREFwarning_ids}.
 ##
-## With the second calling form, set a field on a structure array,
-## possibly nested, with successive nested indices @var{idx1},
-## @var{idx2}, @dots{} and fields @var{field1}, @var{field2}, @dots{}
-## The indices must be cells containing the desired index at this
-## nesting depth.
+## With the second calling form, set a field of a structure array.  The
+## input @var{sidx} selects an element of the structure array, @var{field}
+## specifies the field name of the selected element, and @var{fidx} selects
+## which element of the field (in the case of an array or cell array).
+## The @var{sidx}, @var{field}, and @var{fidx} inputs can be repeated to
+## address nested structure array elements.  The structure array index and
+## field element index must be cell arrays while the field name must be a
+## string.
 ##
-## Thus consider instead,
+## For example:
 ##
 ## @example
 ## @group
 ## @var{s} = struct ("baz", 42);
-## setfield (@var{s}, @{1@}, "foo", @{1@}, "bar", 5)
-##     @result{} ans =
+## setfield (@var{s}, @{1@}, "foo", @{1@}, "bar", 54)
+## @result{}
+##   ans =
 ##     scalar structure containing the fields:
 ##       baz =  42
 ##       foo =
@@ -66,54 +73,61 @@
 ## @end group
 ## @end example
 ##
-## Here we first have an ordinary structure array with one field
-## @code{baz} set to 42.  Then we set another field in a nested scalar structure
-## indexing with two single cells containing the unique desired indices.
+## The example begins with an ordinary scalar structure to which a nested
+## scalar structure is added.  In all cases, if the structure index @var{sidx}
+## is not specified it defaults to 1 (scalar structure).  Thus, the example
+## above could be written more concisely as
+## @code{setfield (@var{s}, "foo", "bar", 54)}
 ##
-## Finally an example with nested structure arrays,
+## Finally, an example with nested structure arrays:
 ##
 ## @example
 ## @group
 ## @var{sa}.foo = 1;
-## @var{sa} = setfield (@var{sa}, @{2@}, "bar", @{3@}, "baz", 6);
+## @var{sa} = setfield (@var{sa}, @{2@}, "bar", @{3@}, "baz", @{1, 4@}, 5);
 ## @var{sa}(2).bar(3)
-##      @result{} ans =
-##      scalar structure containing the fields:
-##        baz =  6
+## @result{}
+##   ans =
+##     scalar structure containing the fields:
+##       baz =  0   0   0   5
 ## @end group
 ## @end example
 ##
-## Here @var{sa} is a structure array whose field @code{fd} at elements
-## 1 and 2 field is in turn
-## another structure array whose third element is a structure
+## Here @var{sa} is a structure array whose field at elements 1 and 2 is in
+## turn another structure array whose third element is a simple scalar
+## structure.  The terminal scalar structure has a field which contains a
+## matrix value.
 ##
 ## Note that the same result as in the above example could be achieved by:
 ##
 ## @example
 ## @group
-## @var{SA}.foo = 1;
-## @var{SA}(2).bar(3).baz = 6
+## @var{sa}.foo = 1;
+## @var{sa}(2).bar(3).baz(1,4) = 5
 ## @end group
 ## @end example
-## @seealso{getfield, rmfield, isfield, fieldnames, isstruct, struct}
+## @seealso{getfield, rmfield, orderfields, isfield, fieldnames, isstruct, struct}
 ## @end deftypefn
 
 ## Author:  Etienne Grossmann <etienne@cs.uky.edu>
 
-function obj = setfield (obj, varargin)
+function sout = setfield (s, varargin)
+
   if (nargin < 3)
     print_usage ();
   endif
+
   subs = varargin(1:end-1);
-  rhs = varargin{end};
+  val = varargin{end};
   flds = cellfun ("isclass", subs, "char");
   idxs = cellfun ("isclass", subs, "cell");
-  if (all (flds | idxs))
-    typs = merge (flds, {"."}, {"()"});
-    obj = subsasgn (obj, struct ("type", typs, "subs", subs), rhs);
-  else
+  if (! all (flds | idxs))
     error ("setfield: invalid index");
   endif
+
+  typs = ifelse (flds, {"."}, {"()"});
+  sout = subsasgn (s, struct ("type", typs, "subs", subs), val);
+
 endfunction
 
 
@@ -121,9 +135,15 @@
 %! x.a = "hello";
 %! x = setfield (x, "b", "world");
 %! y = struct ("a", "hello", "b", "world");
-%! assert (x,y);
+%! assert (x, y);
 %!test
 %! oo(1,1).f0 = 1;
-%! oo = setfield (oo,{1,2},"fd",{3},"b", 6);
-%! assert (oo(1,2).fd(3).b, 6);
+%! oo = setfield (oo,{1,2},"fd",{3},"b", {1,4}, 6);
+%! assert (oo(1,2).fd(3).b(1,4), 6);
 
+%% Test input validation
+%!error setfield ()
+%!error setfield (1)
+%!error setfield (1,2)
+%!error <invalid index> setfield (1,2,3)
+
--- a/scripts/miscellaneous/substruct.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/miscellaneous/substruct.m	Fri Feb 06 08:31:49 2015 -0800
@@ -19,8 +19,9 @@
 
 ## -*- texinfo -*-
 ## @deftypefn {Function File} {} substruct (@var{type}, @var{subs}, @dots{})
-## Create a subscript structure for use with @code{subsref} or
-## @code{subsasgn}.  For example:
+## Create a subscript structure for use with @code{subsref} or @code{subsasgn}.
+##
+## For example:
 ##
 ## @example
 ## @group
@@ -35,7 +36,9 @@
 ##            [1,2] = :
 ##          @}
 ##        @}
-## x = [1, 2, 3; 4, 5, 6; 7, 8, 9];
+## x = [1, 2, 3;
+##      4, 5, 6;
+##      7, 8, 9];
 ## subsref (x, idx)
 ##    @result{} 7  8  9
 ## @end group
@@ -47,30 +50,28 @@
 
 function retval = substruct (varargin)
 
-  nargs = nargin;
-
-  if (nargs > 1 && mod (nargs, 2) == 0)
-    typ = varargin(1:2:nargs);
-    sub = varargin(2:2:nargs);
-    braces = strcmp (typ, "()") | strcmp (typ, "{}");
-    dots = strcmp (typ, ".");
-    if (all (braces | dots))
-      cells = cellfun ("isclass", sub, "cell");
-      chars = cellfun ("isclass", sub, "char");
-      if (any (braces &! cells))
-        error ("substruct: for TYPE == () or {}, SUBS must be a cell array");
-      elseif (any (dots &! chars))
-        error ("substruct: for TYPE == ., SUBS must be a character string");
-      endif
-    else
-      error ("substruct: expecting TYPE to be one of \"()\", \"{}\", or \".\"");
-    endif
-
-    retval = struct ("type", typ, "subs", sub);
-  else
+  if (nargin < 2 || mod (nargin, 2) != 0)
     print_usage ();
   endif
 
+  typ = varargin(1:2:nargin);
+  sub = varargin(2:2:nargin);
+  braces = strcmp (typ, "()") | strcmp (typ, "{}");
+  dots = strcmp (typ, ".");
+  if (all (braces | dots))
+    cells = cellfun ("isclass", sub, "cell");
+    chars = cellfun ("isclass", sub, "char");
+    if (any (braces & !cells))
+      error ("substruct: for TYPE == () or {}, SUBS must be a cell array");
+    elseif (any (dots & !chars))
+      error ("substruct: for TYPE == ., SUBS must be a character string");
+    endif
+  else
+    error ('substruct: expecting TYPE to be one of "()", "{}", or "."');
+  endif
+
+  retval = struct ("type", typ, "subs", sub);
+
 endfunction
 
 
--- a/scripts/miscellaneous/swapbytes.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/miscellaneous/swapbytes.m	Fri Feb 06 08:31:49 2015 -0800
@@ -19,7 +19,9 @@
 ## -*- texinfo -*-
 ## @deftypefn {Function File} {} swapbytes (@var{x})
 ## Swap the byte order on values, converting from little endian to big
-## endian and vice versa.  For example:
+## endian and vice versa.
+##
+## For example:
 ##
 ## @example
 ## @group
@@ -37,28 +39,35 @@
     print_usage ();
   endif
 
-  clx = class (x);
-  if (strcmp (clx, "int8") || strcmp (clx, "uint8") || isempty (x))
+  cls = class (x);
+  if (strcmp (cls, "int8") || strcmp (cls, "uint8") || isempty (x))
     y = x;
   else
-    if (strcmp (clx, "int16") || strcmp (clx, "uint16"))
+    if (strcmp (cls, "int16") || strcmp (cls, "uint16"))
       nb = 2;
-    elseif (strcmp (clx, "int32") || strcmp (clx, "uint32"))
+    elseif (strcmp (cls, "single")
+            || strcmp (cls, "int32") || strcmp (cls, "uint32"))
       nb = 4;
-    elseif (strcmp (clx, "int64") || strcmp (clx, "uint64")
-            || strcmp (clx, "double"))
+    elseif (strcmp (cls, "double")
+            || strcmp (cls, "int64") || strcmp (cls, "uint64"))
       nb = 8;
     else
-      error ("swapbytes: invalid class of object");
+      error ("swapbytes: invalid object of class '%s'", cls);
     endif
     y = reshape (typecast (reshape (typecast (x(:), "uint8"), nb, numel (x))
-                           ([nb : -1 : 1], :) (:), clx), size (x));
+                           ([nb : -1 : 1], :) (:), cls), size (x));
   endif
 
 endfunction
 
 
-%!assert (double (swapbytes (uint16 (1:4))), [256 512 768 1024])
-%!error (swapbytes ())
-%!error (swapbytes (1, 2))
+%!assert (swapbytes (uint16 (1:4)), uint16 ([256 512 768 1024]))
+%!test
+%! assert (swapbytes (swapbytes (pi)), pi);
+%! assert (swapbytes (swapbytes (single (pi))), single (pi));
 
+## Test input validation
+%!error swapbytes ()
+%!error swapbytes (1, 2)
+%!error <invalid object of class 'cell'> swapbytes ({1})
+
--- a/scripts/miscellaneous/symvar.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/miscellaneous/symvar.m	Fri Feb 06 08:31:49 2015 -0800
@@ -17,19 +17,39 @@
 ## <http://www.gnu.org/licenses/>.
 
 ## -*- texinfo -*-
-## @deftypefn {Function File} {} symvar (@var{s})
-## Identify the argument names in the function defined by a string.
-## Common constant names such as @code{pi}, @code{NaN}, @code{Inf},
-## @code{eps}, @code{i} or @code{j} are ignored.  The arguments that are
-## found are returned in a cell array of strings.  If no variables are
-## found then the returned cell array is empty.
+## @deftypefn {Function File} {@var{vars} =} symvar (@var{str})
+## Identify the symbolic variable names in the string @var{str}.
+##
+## Common constant names such as @code{i}, @code{j}, @code{pi}, @code{Inf} and
+## Octave functions such as @code{sin} or @code{plot} are ignored.
+##
+## Any names identified are returned in a cell array of strings.  The array is
+## empty if no variables were found.
+##
+## Example:
+##
+## @example
+## @group
+## symvar ("x^2 + y^2 == 4")
+## @result{} @{
+##      [1,1] = x
+##      [2,1] = y
+##    @}
+## @end group
+## @end example
 ## @end deftypefn
 
-function args = symvar (s)
-  args = argnames (inline (s));
+function vars = symvar (str)
+  vars = argnames (inline (str));
+  ## Correct for auto-generated 'x' variable when no symvar was found.
+  if (numel (vars) == 1 && strcmp (vars{1}, "x") && ! any (str == "x"))
+    vars = {};
+  endif
+
 endfunction
 
 
-## This function is tested by the tests for argnames().
-%!assert (1)
+%!assert (symvar ("3*x + 4*y + 5*cos (z)"), {"x"; "y"; "z"})
+%!assert (symvar ("sin()^2 + cos()^2 == 1"), {})
+%!assert (symvar ("1./x"), {"x"})
 
--- a/scripts/miscellaneous/tar.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/miscellaneous/tar.m	Fri Feb 06 08:31:49 2015 -0800
@@ -17,37 +17,46 @@
 ## <http://www.gnu.org/licenses/>.
 
 ## -*- texinfo -*-
-## @deftypefn  {Function File} {@var{entries} =} tar (@var{tarfile}, @var{files})
-## @deftypefnx {Function File} {@var{entries} =} tar (@var{tarfile}, @var{files}, @var{root})
-## Pack @var{files} @var{files} into the TAR archive @var{tarfile}.  The
-## list of files must be a string or a cell array of strings.
+## @deftypefn  {Function File} {@var{filelist} =} tar (@var{tarfile}, @var{files})
+## @deftypefnx {Function File} {@var{filelist} =} tar (@var{tarfile}, @var{files}, @var{rootdir})
+## Pack the list of files and directories specified in @var{files} into the
+## TAR archive @var{tarfile}.
 ##
-## The optional argument @var{root} changes the relative path of @var{files}
-## from the current directory.
+## @var{files} is a character array or cell array of strings.  Shell
+## wildcards in the filename such as @samp{*} or @samp{?} are accepted and
+## expanded.  Directories are recursively traversed and all files are added to
+## the archive.
 ##
-## If an output argument is requested the entries in the archive are
-## returned in a cell array.
-## @seealso{untar, bzip2, gzip, zip}
+## If @var{rootdir} is defined then any files without absolute pathnames are
+## located relative to @var{rootdir} rather than the current directory.
+##
+## The optional output @var{filelist} is a list of the files that were included
+## in the archive.
+## @seealso{untar, unpack, bzip2, gzip, zip}
 ## @end deftypefn
 
 ## Author: Søren Hauberg <hauberg@gmail.com>
 
-function entries = tar (tarfile, files, root = ".")
+function filelist = tar (tarfile, files, rootdir = ".")
 
   if (nargin < 2 || nargin > 3)
     print_usage ();
   endif
 
-  if (ischar (files))
+  if (! ischar (tarfile))
+    error ("tar: TARFILE must be a string");
+  elseif (ischar (files))
     files = cellstr (files);
+  elseif (! iscellstr (files))
+    error ("tar: FILES must be a character array or cellstr");
   endif
 
-  if (! (ischar (tarfile) && iscellstr (files) && ischar (root)))
-    error ("tar: all arguments must be character strings");
-  endif
+  rootdir = tilde_expand (rootdir);
 
-  cmd = sprintf ("tar cvf %s -C %s %s", tarfile, root,
-                 sprintf (" %s", files{:}));
+  tarfile = make_absolute_filename (tarfile);
+
+  cmd = sprintf ("tar cvf %s -C %s %s",
+                          tarfile, rootdir, sprintf (" %s", files{:}));
 
   [status, output] = system (cmd);
 
@@ -59,9 +68,64 @@
     if (output(end) == "\n")
       output(end) = [];
     endif
-    entries = ostrsplit (output, "\n");
-    entries = entries';
+    filelist = ostrsplit (output, "\n");
+    filelist = filelist';
   endif
 
 endfunction
 
+
+%!xtest
+%! ## test gzip together with gunzip
+%! orig_dir = pwd ();
+%! unwind_protect
+%!   dirname = tempname;
+%!   assert (mkdir (dirname));
+%!   chdir (dirname);
+%!   dirname2 = "dir2";
+%!   assert (mkdir (dirname2));
+%!   fname1 = "f1";
+%!   fname2 = fullfile (dirname2, "f2");
+%!   fid = fopen (fname1, "wt");
+%!   assert (fid >= 0);
+%!   fdisp (fid, "Hello World");
+%!   fclose (fid);
+%!   fid = fopen (fname2, "wt");
+%!   assert (fid >= 0);
+%!   fdisp (fid, "Goodbye World");
+%!   fclose (fid);
+%!   tarname = [tempname ".tar"];
+%!   filelist = tar (tarname, {dirname2, fname1});
+%!   if (! strcmp (filelist{3}, fname1))
+%!     error ("tar file contents does not match expected file");
+%!   endif
+%!   if (! exist (tarname, "file"))
+%!     error ("tar archive file cannot be found!");
+%!   endif
+%!   outdir = tempname;
+%!   untar (tarname, outdir);
+%!   fid = fopen (fullfile (outdir, fname1), "rt");
+%!   assert (fid >= 0);
+%!   str = fgetl (fid);
+%!   fclose (fid);
+%!   assert (str, "Hello World");
+%!   fid = fopen (fullfile (outdir, fname2), "rt");
+%!   assert (fid >= 0);
+%!   str = fgetl (fid);
+%!   fclose (fid);
+%!   assert (str, "Goodbye World");
+%! unwind_protect_cleanup
+%!   delete (tarname);
+%!   confirm_recursive_rmdir (false, "local");
+%!   rmdir (dirname, "s");
+%!   rmdir (outdir, "s");
+%!   chdir (orig_dir);
+%! end_unwind_protect
+
+## Test input validation
+%!error tar ()
+%!error tar (1)
+%!error tar (1,2,3,4)
+%!error <TARFILE must be a string> tar (1, "foobar")
+%!error <FILES must be a character array or cellstr> tar ("foobar", 1)
+
--- a/scripts/miscellaneous/tempdir.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/miscellaneous/tempdir.m	Fri Feb 06 08:31:49 2015 -0800
@@ -18,7 +18,12 @@
 
 ## -*- texinfo -*-
 ## @deftypefn {Function File} {@var{dir} =} tempdir ()
-## Return the name of the system's directory for temporary files.
+## Return the name of the host system's directory for temporary files.
+##
+## The directory name is taken first from the environment variable
+## @env{TMPDIR}.  If that does not exist the system default returned by
+## @code{P_tmpdir} is used.
+## @seealso{P_tmpdir, tempname, mkstemp, tmpfile}
 ## @end deftypefn
 
 function dirname = tempdir ()
@@ -49,7 +54,11 @@
 %!   setenv ("TMPDIR", "__MY_TMP_DIR__");
 %!   assert (tempdir (), ["__MY_TMP_DIR__" filesep()]);
 %! unwind_protect_cleanup
-%!   setenv ("TMPDIR", old_tmpdir);
+%!   if (! isempty (old_tmpdir))
+%!     setenv ("TMPDIR", old_tmpdir);
+%!   else
+%!     unsetenv ("TMPDIR");
+%!   endif
 %!   warning (old_wstate);
 %! end_unwind_protect
 
--- a/scripts/miscellaneous/tempname.m	Fri Feb 06 08:31:09 2015 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,36 +0,0 @@
-## Copyright (C) 2003-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} {} tempname ()
-## @deftypefnx {Function File} {} tempname (@var{dir})
-## @deftypefnx {Function File} {} tempname (@var{dir}, @var{prefix})
-## This function is an alias for @code{tmpnam}.
-## @seealso{tmpnam}
-## @end deftypefn
-
-function filename = tempname (varargin)
-
-  filename = tmpnam (varargin{:});
-
-endfunction
-
-
-%% No tests needed for alias.
-%!assert (1)
-
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/miscellaneous/tmpnam.m	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,50 @@
+## Copyright (C) 2003-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} {@var{fname} =} tmpnam ()
+## @deftypefnx {Function File} {@var{fname} =} tmpnam (@var{dir})
+## @deftypefnx {Function File} {@var{fname} =} tmpnam (@var{dir}, @var{prefix})
+## Return a unique temporary file name as a string.
+##
+## If @var{prefix} is omitted, a value of @qcode{"oct-"} is used.
+## If @var{dir} is also omitted, the default directory for temporary files
+## (@code{P_tmpdir} is used.  If @var{dir} is provided, it must exist,
+## otherwise the default directory for temporary files is used.
+##
+## Programming Note: Because the named file is not opened by @code{tmpnam},
+## it is possible, though relatively unlikely, that it will not be available
+## by the time your program attempts to open it.  If this is a concern,
+## see @code{tmpfile}.  The functions @code{tmpnam} and @code{tmpnam} are
+## equivalent with the latter provided for @sc{matlab} compatibility.
+##
+## @strong{Caution}: @code{tmpnam} will be removed in a future version of
+## Octave.  Use the equivalent @code{tempname} in all new code.
+## @seealso{tempname, mkstemp, tempdir, P_tmpdir, tmpfile}
+## @end deftypefn
+
+function filename = tmpnam (varargin)
+
+  filename = tempname (varargin{:});
+
+endfunction
+
+
+## No tests needed for alias.
+%!assert (1)
+
--- a/scripts/miscellaneous/unix.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/miscellaneous/unix.m	Fri Feb 06 08:31:49 2015 -0800
@@ -21,12 +21,15 @@
 ## @deftypefnx {Function File} {@var{status} =} unix ("@var{command}")
 ## @deftypefnx {Function File} {[@var{status}, @var{text}] =} unix ("@var{command}")
 ## @deftypefnx {Function File} {[@dots{}] =} unix ("@var{command}", "-echo")
-## Execute a system command if running under a Unix-like operating
-## system, otherwise do nothing.  Return the exit status of the program
-## in @var{status} and any output from the command in @var{text}.
+## Execute a system command if running under a Unix-like operating system,
+## otherwise do nothing.
+##
+## Octave waits for the external command to finish before returning the exit
+## status of the program in @var{status} and any output in @var{text}.
+##
 ## When called with no output argument, or the @qcode{"-echo"} argument is
 ## given, then @var{text} is also sent to standard output.
-## @seealso{dos, system, isunix, ispc}
+## @seealso{dos, system, isunix, ismac, ispc}
 ## @end deftypefn
 
 ## Author: octave-forge ???
--- a/scripts/miscellaneous/unpack.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/miscellaneous/unpack.m	Fri Feb 06 08:31:49 2015 -0800
@@ -21,13 +21,52 @@
 ## @deftypefnx {Function File} {@var{files} =} unpack (@var{file}, @var{dir})
 ## @deftypefnx {Function File} {@var{files} =} unpack (@var{file}, @var{dir}, @var{filetype})
 ## Unpack the archive @var{file} based on its extension to the directory
-## @var{dir}.  If @var{file} is a list of strings, then each file is
-## unpacked individually.  If @var{dir} is not specified, it defaults to
-## the current directory.  If a directory is in the file list, then the
-## @var{filetype} must also be specified.
+## @var{dir}.
+##
+## If @var{file} is a list of strings, then each file is unpacked
+## individually.  Shell wildcards in the filename such as @samp{*} or @samp{?}
+## are accepted and expanded.
+##
+## If @var{dir} is not specified or is empty (@code{[]}), it defaults to the
+## current directory.  If a directory is in the file list, then @var{filetype}
+## must also be specified.
+##
+## The specific archive filetype is inferred from the extension of the file.
+## The @var{filetype} may also be specified directly using a string which
+## corresponds to a known extension.
+##
+## Valid filetype extensions:
+##
+## @table @code
+## @item  bz
+## @itemx bz2
+## bzip archive
+##
+## @item gz
+## gzip archive
+##
+## @item tar
+## tar archive
+##
+## @item  tarbz
+## @itemx tarbz2
+## @itemx tbz
+## @itemx tbz2
+## tar + bzip archive
+##
+## @item  targz
+## @itemx tgz
+## tar + gzip archive
+##
+## @item z
+## compress archive
+##
+## @item zip
+## zip archive
+## @end table
 ##
 ## The optional return value is a list of @var{files} unpacked.
-## @seealso{bzip2, gzip, zip, tar}
+## @seealso{bunzip2, gunzip, unzip, untar, bzip2, gzip, zip, tar}
 ## @end deftypefn
 
 ## Author: Bill Denney <denney@seas.upenn.edu>
@@ -39,16 +78,24 @@
   endif
 
   if (! ischar (file) && ! iscellstr (file))
-    error ("unpack: invalid input file class, %s", class (file));
+    error ("unpack: FILE must be a string or cell array of strings");
   endif
 
-  ## character arrays of more than one string must be treated as cell strings
-  if (ischar (file) && ! isvector (file))
+  ## Convert char arrays to cell strings to simplify further processing
+  if (ischar (file))
     file = cellstr (file);
   endif
+  if (numel (file) == 1)
+    gfile = glob (file);
+    if (isempty (gfile))
+      error ('unpack: file "%s" not found', file{1});
+    else
+      file = gfile;
+    endif
+  endif
 
   ## Recursively unpack cellstr arrays one file at a time
-  if (iscellstr (file))
+  if (numel (file) > 1)
     files = {};
     for i = 1:numel (file)
       tmpfiles = unpack (file{i}, dir);
@@ -59,15 +106,17 @@
     if (nargout > 0)
       filelist = files;
     endif
+    return;
 
-    return;
+  else
+    file = file{1};
   endif
 
   if (isdir (file))
     if (isempty (filetype))
       error ("unpack: FILETYPE must be given for a directory");
     elseif (! any (strcmpi (filetype, "gunzip")))
-      error ("unpack: FILETYPE must be gunzip for a directory");
+      error ('unpack: FILETYPE must be "gunzip" for a directory');
     endif
     ext = ".gz";
   else
@@ -84,28 +133,18 @@
 
     ## 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 code 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?
-      tmpfile = [tmpnam() ext];
+      tmpfile = [tempname ext];
       [file, success, msg] = urlwrite (urlfile, tmpfile);
       if (! success)
-        error ('unpack: could not get "%s": %s', urlfile, msg);
+        error ('unpack: could not fetch "%s": %s', urlfile, msg);
       endif
     endif
 
   endif
 
-  ## canonicalize_file_name returns empty if the file isn't found, so
-  ## use that to check for existence.
-  cfile = canonicalize_file_name (file);
-
-  if (isempty (cfile))
-    error ('unpack: file "%s" not found', file);
-  else
-    file = cfile;
-  endif
+  file = make_absolute_filename (file);
 
   ## Instructions on what to do for any extension.
   ##
@@ -145,17 +184,21 @@
   endif
 
   ## Unzip doesn't actually care about the extension
-  if (strcmp (filetype, "unzip"))
+  if (strcmpi (filetype, "unzip"))
     nodotext = "zip";
   else
     nodotext = ext(ext != '.');
   endif
 
-  origdir = pwd ();
-
-  if (isfield (commandlist, nodotext))
-    [commandv, commandq, parser, move] = deal (commandlist.(nodotext){:});
-    cstartdir = canonicalize_file_name (origdir);
+  if (isfield (commandlist, tolower (nodotext)))
+    [commandv, commandq, parsefcn, move] = deal (commandlist.(nodotext){:});
+    origdir = pwd ();
+    if (move)
+      startdir = fileparts (file);
+    else
+      startdir = origdir;
+    endif
+    cstartdir = canonicalize_file_name (startdir);
     cenddir = canonicalize_file_name (dir);
     needmove = move && ! strcmp (cstartdir, cenddir);
     if (nargout > 0 || needmove)
@@ -164,7 +207,7 @@
       command = commandq;
     endif
   else
-    warning ("unpack:filetype", "unrecognized file type, %s", ext);
+    warning ("unpack: unrecognized FILETYPE <%s>", ext);
     files = file;
     return;
   endif
@@ -194,23 +237,21 @@
 
   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
-    files = parser (ostrsplit (output, "\n"))';
+    files = parsefcn (ostrsplit (output, "\n"))';
 
-    ## Move files if necessary
+    ## Move files if necessary.
     if (needmove)
-      [st, msg, ~] = movefile (files, dir);
+      [st, msg] = movefile (files, cenddir);
       if (! st)
         error ('unpack: unable to move files to "%s": %s', dir, msg);
       endif
 
-      ## Fix the names for the files since they were moved.
-      for i = 1:numel (files)
-        files{i} = strrep (files{i}, cstartdir, cenddir);
-      endfor
+      ## Fix the names of the files since they were moved.
+      files = strrep (files, cstartdir, cenddir);
     endif
 
     ## Return output if requested.
@@ -224,9 +265,9 @@
 function files = __parse_zip__ (output)
   ## Parse the output from zip and unzip.
 
-  ## Skip first line which is Archive header
+  ## Skip first line which is Archive header.
   files = char (output(2:end));
-  ## Trim constant width prefix and return cell array
+  ## Trim constant width prefix and return cell array.
   files = cellstr (files(:,14:end))
 endfunction
 
@@ -249,3 +290,57 @@
   files = regexprep (output, '^\s+(.*)\.bz2: .*', '$1');
 endfunction
 
+
+%!test
+%! ## Create temporary directory and file for packing and unpacking
+%! dirname = tempname ();
+%! assert (mkdir (dirname));
+%! filename = tempname ();
+%! fid = fopen (filename, "wt");
+%! assert (fid >= 0);
+%! fprintf (fid, "Hello World\n");
+%! fprintf (fid, "123 456 789\n");
+%! fclose (fid);
+%! unwind_protect
+%!   copyfile (filename, [filename ".orig"]);
+%!   gzip (filename, dirname);
+%!   [~, f] = fileparts (filename);
+%!   filelist = unpack (fullfile (dirname, [f ".gz"]), P_tmpdir);
+%!   assert (filelist{1}, filename);
+%!   fid = fopen ([filename ".orig"], "rb");
+%!   assert (fid >= 0);
+%!   orig_data = fread (fid);
+%!   fclose (fid);
+%!   fid = fopen (filename, "rb");
+%!   assert (fid >= 0);
+%!   new_data = fread (fid);
+%!   fclose (fid);
+%!   if (orig_data != new_data)
+%!     error ("unpack: Unpacked file does not equal original");
+%!   endif
+%! unwind_protect_cleanup
+%!   unlink (filename);
+%!   unlink ([filename ".orig"]);
+%!   rmdir (dirname);
+%! end_unwind_protect
+
+## Test input validation
+%!error unpack ()
+%!error unpack (1,2,3,4)
+%!error <FILE must be a string or cell array of strings> unpack (1)
+%!error <file "_%NOT_A_FILENAME%_" not found> unpack ("_%NOT_A_FILENAME%_")
+%!error <file "_%NOT_A_FILENAME%_" not found> unpack ({"_%NOT_A_FILENAME%_"})
+%!error <file "_%NOT_A_FILENAME%_" not found> unpack ({"_%NOT_A_FILENAME%_", "2nd_filename"})
+%!error <FILETYPE must be given for a directory>
+%! if (isunix || ismac)
+%!   unpack ("/");
+%! else
+%!   unpack ('C:\');
+%! endif
+%!error <FILETYPE must be "gunzip" for a directory>
+%! if (isunix || ismac)
+%!   unpack ("/", [], "foobar");
+%! else
+%!   unpack ('C:\', [], "foobar");
+%! endif
+
--- a/scripts/miscellaneous/untar.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/miscellaneous/untar.m	Fri Feb 06 08:31:49 2015 -0800
@@ -19,26 +19,38 @@
 ## -*- texinfo -*-
 ## @deftypefn  {Function File} {} untar (@var{tarfile})
 ## @deftypefnx {Function File} {} untar (@var{tarfile}, @var{dir})
-## Unpack the TAR archive @var{tarfile} to the directory @var{dir}.
-## If @var{dir} is not specified, it defaults to the current directory.
+## Unpack the TAR archive @var{tarfile}.
+##
+## If @var{dir} is specified the files are unpacked in this directory rather
+## than the one where @var{tarfile} is located.
+##
+## The optional output @var{filelist} is a list of the uncompressed files.
 ## @seealso{tar, unpack, bunzip2, gunzip, unzip}
 ## @end deftypefn
 
 ## Author: Søren Hauberg <hauberg@gmail.com>
 ## Adapted-By: jwe, Bill Denney
 
-function varargout = untar (tarfile, dir = ".")
+function filelist = untar (tarfile, dir = [])
 
-  if (nargin != 1 && nargin != 2)
+  if (nargin < 1 || nargin > 2)
     print_usage ();
   endif
 
+  if (isempty (dir))
+    dir = fileparts (tarfile);
+  endif
+
   if (nargout > 0)
-    varargout = cell (1, nargout);
-    [varargout{:}] = unpack (tarfile, dir, mfilename ());
+    filelist = unpack (tarfile, dir, "untar");
   else
-    unpack (tarfile, dir, mfilename ());
+    unpack (tarfile, dir, "untar");
   endif
 
 endfunction
 
+
+## Tests for this m-file are located in tar.m
+## Remove from test statistics
+%!assert (1)
+
--- a/scripts/miscellaneous/unzip.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/miscellaneous/unzip.m	Fri Feb 06 08:31:49 2015 -0800
@@ -17,28 +17,40 @@
 ## <http://www.gnu.org/licenses/>.
 
 ## -*- texinfo -*-
-## @deftypefn  {Function File} {} unzip (@var{zipfile})
-## @deftypefnx {Function File} {} unzip (@var{zipfile}, @var{dir})
-## Unpack the ZIP archive @var{zipfile} to the directory @var{dir}.
-## If @var{dir} is not specified, it defaults to the current directory.
+## @deftypefn  {Function File} {@var{filelist} =} unzip (@var{zipfile})
+## @deftypefnx {Function File} {@var{filelist} =} unzip (@var{zipfile}, @var{dir})
+## Unpack the ZIP archive @var{zipfile}.
+##
+## If @var{dir} is specified the files are unpacked in this directory rather
+## than the one where @var{zipfile} is located.
+##
+## The optional output @var{filelist} is a list of the uncompressed files.
 ## @seealso{zip, unpack, bunzip2, gunzip, untar}
 ## @end deftypefn
 
 ## Author: Søren Hauberg <hauberg@gmail.com>
 ## Adapted-By: jwe, Bill Denney
 
-function varargout = unzip (zipfile, dir = ".")
+function filelist = unzip (zipfile, dir = [])
 
-  if (nargin != 1 && nargin != 2)
+  if (nargin < 1 || nargin > 2)
     print_usage ();
   endif
 
+  if (isempty (dir))
+    dir = fileparts (zipfile);
+  endif
+
   if (nargout > 0)
-    varargout = cell (1, nargout);
-    [varargout{:}] = unpack (zipfile, dir, mfilename ());
+    filelist = unpack (zipfile, dir, "unzip");
   else
-    unpack (zipfile, dir, mfilename ());
+    unpack (zipfile, dir, "unzip");
   endif
 
 endfunction
 
+
+## Tests for this m-file are located in zip.m
+## Remove from test statistics
+%!assert (1)
+
--- a/scripts/miscellaneous/ver.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/miscellaneous/ver.m	Fri Feb 06 08:31:49 2015 -0800
@@ -17,19 +17,21 @@
 ## <http://www.gnu.org/licenses/>.
 
 ## -*- texinfo -*-
-## @deftypefn  {Function File} {} ver ()
-## @deftypefnx {Function File} {v =} ver ()
-## @deftypefnx {Function File} {v =} ver ("Octave")
-## @deftypefnx {Function File} {v =} ver (@var{package})
+## @deftypefn  {Function File} {} ver
+## @deftypefnx {Function File} {} ver Octave
+## @deftypefnx {Function File} {} ver @var{package}
+## @deftypefnx {Function File} {v =} ver (@dots{})
 ##
 ## Display a header containing the current Octave version number, license
-## string, and operating system followed by a list of installed packages,
-## versions, and installation directories.
+## string, and operating system.  The header is followed by a list of installed
+## packages, versions, and installation directories.
 ##
-## @code{v = ver ()}
+## Use the package name @var{package} or Octave to limit the listing to a
+## desired component.
 ##
-## Return a vector of structures describing Octave and each installed package.
-## The structure includes the following fields.
+## When called with an output argument, return a vector of structures
+## describing Octave and each installed package.  The structure includes the
+## following fields.
 ##
 ## @table @code
 ## @item Name
@@ -45,71 +47,67 @@
 ## Date of the version/revision.
 ## @end table
 ##
-## @code{v = ver ("Octave")}
-##
-## Return version information for Octave only.
-##
-## @code{v = ver (@var{package})}
-##
-## Return version information for @var{package}.
-##
-## @seealso{version, octave_config_info}
+## @seealso{version, octave_config_info, usejava, pkg}
 ## @end deftypefn
 
 ## Author: William Poetra Yoga Hadisoeseno <williampoetra@gmail.com>
 
-function varargout = ver (package = "")
+function retval = ver (package = "")
 
   if (nargin > 1)
     print_usage ();
   endif
 
-  ## Start with the version info for Octave
-  ret = struct ("Name", "Octave", "Version", version,
-                "Release", [], "Date", []);
+  if (nargout == 0)
+    [unm, err] = uname ();
 
-  ## Add the installed packages
-  lst = pkg ("list");
-  for i = 1:length (lst)
-    ret(end+1) = struct ("Name", lst{i}.name, "Version", lst{i}.version,
-                         "Release", [], "Date", lst{i}.date);
-  endfor
-
-  if (nargout == 0)
-    octave_license = license ();
-
-    [unm, status] = uname ();
-
-    if (status < 0)
+    if (err)
       os_string = "unknown";
     else
-      os_string = sprintf ("%s %s %s %s", unm.sysname, unm.release,
-                           unm.version, unm.machine);
+      os_string = sprintf ("%s %s %s %s",
+                           unm.sysname, unm.release, unm.version, unm.machine);
     endif
 
     hbar(1:70) = "-";
-    ver_line1 = "GNU Octave Version ";
-    ver_line2 = "GNU Octave License: ";
-    ver_line3 = "Operating System: ";
+    desc = {hbar
+            ["GNU Octave Version: " OCTAVE_VERSION]
+            ["GNU Octave License: " license]
+            ["Operating System: " os_string]
+            hbar};
+
+    printf ("%s\n", desc{:});
 
-    ver_desc = sprintf ("%s\n%s%s\n%s%s\n%s%s\n%s\n", hbar, ver_line1, version,
-                        ver_line2, octave_license, ver_line3, os_string, hbar);
-
-    puts (ver_desc);
-
-    pkg ("list");
+    if (isempty (package))
+      pkg ("list");
+    elseif (strcmpi (package, "Octave"))
+      ## Nothing to do, Octave version was already reported
+    else
+      pkg ("list", package);
+    endif
   else
-    if (! isempty (package))
-      n = [];
-      for r = 1:numel (ret)
-        if (strcmpi (ret(r).Name, package))
-          n = r;
-          break;
-        endif
+    ## Get the installed packages
+    if (isempty (package))
+      lst = pkg ("list");
+      ## Start with the version info for Octave
+      retval = struct ("Name", "Octave", "Version", version,
+                       "Release", [], "Date", []);
+      for i = 1:numel (lst)
+        retval(end+1) = struct ("Name", lst{i}.name, "Version", lst{i}.version,
+                                "Release", [], "Date", lst{i}.date);
       endfor
-      ret = ret(n);
+    elseif (strcmpi (package, "Octave"))
+      retval = struct ("Name", "Octave", "Version", version,
+                       "Release", [], "Date", []);
+    else
+      lst = pkg ("list", package);
+      if (isempty (lst))
+        retval = struct ("Name", "", "Version", [],
+                         "Release", [], "Date", []);
+      else
+        retval = struct ("Name", lst{1}.name, "Version", lst{1}.version,
+                         "Release", [], "Date", lst{1}.date);
+      endif
     endif
-    varargout{1} = ret;
   endif
 
 endfunction
--- a/scripts/miscellaneous/version.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/miscellaneous/version.m	Fri Feb 06 08:31:49 2015 -0800
@@ -18,11 +18,11 @@
 
 ## -*- texinfo -*-
 ## @deftypefn {Function File} {} version ()
-## Return the version number of Octave, as a string.
+## Return the version number of Octave as a string.
 ##
 ## This is an alias for the function @w{@env{OCTAVE_VERSION}} provided for
 ## compatibility.
-## @seealso{OCTAVE_VERSION}
+## @seealso{OCTAVE_VERSION, ver}
 ## @end deftypefn
 
 ## Author: jwe
--- a/scripts/miscellaneous/warning_ids.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/miscellaneous/warning_ids.m	Fri Feb 06 08:31:49 2015 -0800
@@ -299,8 +299,10 @@
 ## string constant.
 ## By default, the @code{Octave:single-quote-string} warning is disabled.
 ##
-## @item Octave:singular-matrix-div
-## By default, the @code{Octave:singular-matrix-div} warning is enabled.
+## @item  Octave:nearly-singular-matrix
+## @itemx Octave:singular-matrix
+## By default, the @code{Octave:nearly-singular-matrix} and
+## @code{Octave:singular-matrix} warnings are enabled.
 ##
 ## @item Octave:sqrtm:SingularMatrix
 ## By default, the @code{Octave:sqrtm:SingularMatrix} warning is enabled.
@@ -335,12 +337,11 @@
 ## @end table
 ##
 
-
 function warning_ids ()
   help ("warning_ids");
 endfunction
 
 
-## Remove from test statistics.  No real tests possible
+## Mark file as being tested.  No real test needed for a documentation .m file
 %!assert (1)
 
--- a/scripts/miscellaneous/what.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/miscellaneous/what.m	Fri Feb 06 08:31:49 2015 -0800
@@ -20,56 +20,103 @@
 ## @deftypefn  {Command} {} what
 ## @deftypefnx {Command} {} what @var{dir}
 ## @deftypefnx {Function File} {w =} what (@var{dir})
-## List the Octave specific files in directory @var{dir}.  If @var{dir} is
-## not specified then the current directory is used.  If a return argument is
-## requested, the files found are returned in the structure @var{w}.
-## @seealso{which}
+## List the Octave specific files in directory @var{dir}.
+##
+## If @var{dir} is not specified then the current directory is used.
+##
+## If a return argument is requested, the files found are returned in the
+## structure @var{w}.  The structure contains the following fields:
+##
+## @table @asis
+## @item path
+## Full path to directory @var{dir}
+##
+## @item m
+## Cell array of m-files
+##
+## @item mat
+## Cell array of mat files
+##
+## @item mex
+## Cell array of mex files
+##
+## @item oct
+## Cell array of oct files
+##
+## @item mdl
+## Cell array of mdl files
+##
+## @item slx
+## Cell array of slx files
+##
+## @item p
+## Cell array of p-files
+##
+## @item classes
+## Cell array of class directories (@file{@@@var{classname}/})
+##
+## @item packages
+## Cell array of package directories (@file{+@var{pkgname}/})
+## @end table
+##
+## Compatibility Note: Octave does not support mdl, slx, and p files; nor
+## does it support package directories.  @code{what} will always return an
+## empty list for these categories.
+## @seealso{which, ls, exist}
 ## @end deftypefn
 
-function ret = what (d)
+function retval = what (dir)
+
+  if (nargin > 1)
+    print_usage ();
+  endif
 
   if (nargin == 0)
-    d = pwd ();
-  elseif (isempty (strfind (d, filesep ())))
-    ## Find the appropriate directory on the path.
-    p = strtrim (ostrsplit (path (), pathsep ()));
-    d = p{find (cellfun (@(x) ! isempty (strfind (x, d)), p))(end)};
+    dir = pwd ();
   else
-    [status, msg, msgid] = fileattrib (d);
-    if (status != 1)
-      error ("what: could not find the file or path %s", d);
-    else
-      d = msg.Name;
+    dtmp = canonicalize_file_name (dir);
+    if (isempty (dtmp))
+      ## Search for directory name in path
+      if (dir(end) == '/' || dir(end) == '\')
+        dir(end) = [];
+      endif
+      dtmp = dir_in_loadpath (dir);
+      if (isempty (dtmp))
+        error ("what: could not find the directory %s", dir);
+      endif
     endif
+    dir = dtmp;
   endif
 
-  files = dir (d);
-  w.path = d;
+  files = readdir (dir);
+  w.path = dir;
   w.m = cell (0, 1);
+  w.mat = cell (0, 1);
   w.mex = cell (0, 1);
   w.oct = cell (0, 1);
-  w.mat = cell (0, 1);
   w.mdl = cell (0, 1);
+  w.slx = cell (0, 1);
   w.p = cell (0, 1);
   w.classes = cell (0, 1);
+  w.packages = cell (0, 1);
 
   for i = 1 : length (files)
-    n = files(i).name;
+    n = files{i};
     ## Ignore . and ..
     if (strcmp (n, ".") || strcmp (n, ".."))
       continue;
     else
-      ## Ignore mdl and p files
-      [dummy, f, e] = fileparts (n);
+      ## Ignore mdl, slx, p, and packages since they are not
+      [~, f, e] = fileparts (n);
       if (strcmp (e, ".m"))
         w.m{end+1} = n;
+      elseif (strcmp (e, ".mat"))
+        w.mat{end+1} = n;
       elseif (strcmp (e, ".oct"))
         w.oct{end+1} = n;
       elseif (strcmp (e, mexext ()))
         w.mex{end+1} = n;
-      elseif (strcmp (e, ".mat"))
-        w.mat{end+1} = n;
-      elseif (strcmp (n(1), "@"))
+      elseif (n(1) == "@" && isdir (n))
         w.classes{end+1} = n;
       endif
     endif
@@ -77,35 +124,45 @@
 
   if (nargout == 0)
     __display_filenames__ ("M-files in directory", w.path, w.m);
+    __display_filenames__ ("\nMAT-files in directory", w.path, w.mat);
     __display_filenames__ ("\nMEX-files in directory", w.path, w.mex);
     __display_filenames__ ("\nOCT-files in directory", w.path, w.oct);
-    __display_filenames__ ("\nMAT-files in directory", w.path, w.mat);
     __display_filenames__ ("\nClasses in directory", w.path, w.classes);
   else
-    ret = w;
+    retval = w;
   endif
+
 endfunction
 
 function __display_filenames__ (msg, p, f)
+
   if (length (f) > 0)
     printf ("%s %s:\n\n", msg, p);
 
     maxlen = max (cellfun ("length", f));
     ncols = max (1, floor (terminal_size ()(2) / (maxlen + 3)));
-    fmt = "";
-    for i = 1: ncols
-      fmt = sprintf ("%s   %%-%ds", fmt, maxlen);
-    endfor
-    fmt = [fmt, "\n"];
+    fmt = sprintf ("   %%-%ds", maxlen);
+    fmt = repmat (fmt, [1, ncols]);
+    fmt = [fmt "\n"];
 
     nrows = ceil (length (f) / ncols);
     for i = 1 : nrows
       args  = f(i:nrows:end);
       if (length (args) < ncols)
-        args(end + 1 : ncols) = {""};
+        args(end+1 : ncols) = {""};
       endif
       printf (fmt, args{:});
     endfor
   endif
+
 endfunction
 
+
+%!test
+%! w = what ();
+%! assert (w.path, pwd);
+%! assert (fieldnames (w), {"path"; "m"; "mat"; "mex"; "oct"; "mdl"; "slx";
+%!                          "p"; "classes"; "packages"});
+
+%!error what (1, 2)
+
--- a/scripts/miscellaneous/xor.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/miscellaneous/xor.m	Fri Feb 06 08:31:49 2015 -0800
@@ -17,23 +17,33 @@
 ## <http://www.gnu.org/licenses/>.
 
 ## -*- texinfo -*-
-## @deftypefn {Mapping Function} {@var{z} =} xor (@var{x}, @var{y})
-## Return the @dfn{exclusive or} of the entries of @var{x} and @var{y}.
+## @deftypefn  {Function File} {@var{z} =} xor (@var{x}, @var{y})
+## @deftypefnx {Function File} {@var{z} =} xor (@var{x1}, @var{x2}, @dots{})
+## Return the @dfn{exclusive or} of @var{x} and @var{y}.
+##
 ## For boolean expressions @var{x} and @var{y},
 ## @code{xor (@var{x}, @var{y})} is true if and only if one of @var{x} or
-## @var{y} is true.  Otherwise, for @var{x} and @var{y} both true or both
+## @var{y} is true.  Otherwise, if @var{x} and @var{y} are both true or both
 ## false, @code{xor} returns false.
 ##
 ## The truth table for the xor operation is
 ##
 ## @multitable @columnfractions 0.44 .03 .05 .03 0.44
 ## @item @tab @var{x} @tab @var{y} @tab @var{z} @tab
+## @item @tab - @tab - @tab - @tab
 ## @item @tab 0 @tab 0 @tab 0 @tab
 ## @item @tab 1 @tab 0 @tab 1 @tab
 ## @item @tab 0 @tab 1 @tab 1 @tab
 ## @item @tab 1 @tab 1 @tab 0 @tab
 ## @end multitable
 ##
+## If more than two arguments are given the xor operation is applied
+## cumulatively from left to right:
+##
+## @example
+## (@dots{}((x1 XOR x2) XOR x3) XOR @dots{})
+## @end example
+##
 ## @seealso{and, or, not}
 ## @end deftypefn
 
@@ -41,21 +51,35 @@
 ## Created: 16 September 1994
 ## Adapted-By: jwe
 
-function z = xor (x, y)
+function z = xor (x, y, varargin)
+
+  if (nargin < 2)
+    print_usage ();
+  endif
+
+  z = __xor__ (x, y);
 
-  if (nargin == 2)
-    if (isscalar (x) || isscalar (y) || size_equal (x, y))
-      ## Typecast to logicals is necessary for other numeric types.
-      z = logical (x) != logical (y);
-    else
-      try
-        z = bsxfun (@xor, x, y);
-      catch
-        error ("xor: X and Y must be of compatible size or scalars");
-      end_try_catch
-    endif
+  ## Slow expansion to multiple arguments.
+  ## Probably okay number of elements ## will be small.
+  if (! isempty (varargin))
+    for i = 1:numel (varargin)
+      z = __xor__ (z, varargin{i});
+    endfor
+  endif
+
+endfunction
+
+function z = __xor__ (x, y)
+
+  if (isscalar (x) || isscalar (y) || size_equal (x, y))
+    ## Typecast to logicals is necessary for other numeric types.
+    z = logical (x) != logical (y);
   else
-    print_usage ();
+    try
+      z = bsxfun (@xor, x, y);
+    catch
+      error ("xor: X and Y must be of compatible size or scalars");
+    end_try_catch
   endif
 
 endfunction
@@ -65,7 +89,13 @@
 %!assert (xor ([i, i, 0, 0], [1, 0, 1, 0]), logical ([0, 1, 1, 0]))
 
 %!assert (xor (eye (2), fliplr (eye (2))), logical (ones (2)))
+%!assert (xor (speye (2), fliplr (speye (2))), sparse (logical (ones (2))))
 
+## Test XOR reduction
+%!assert (xor ([1 0], [1 1], [0 0]), logical ([0 1]))
+
+%% Test input validation
 %!error xor ()
-%!error xor (1, 2, 3)
+%!error xor (1)
+%!error <X and Y must be of compatible size> xor (ones (3,2), ones (2,3))
 
--- a/scripts/miscellaneous/zip.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/miscellaneous/zip.m	Fri Feb 06 08:31:49 2015 -0800
@@ -17,35 +17,46 @@
 ## <http://www.gnu.org/licenses/>.
 
 ## -*- texinfo -*-
-## @deftypefn  {Function File} {@var{entries} =} zip (@var{zipfile}, @var{files})
-## @deftypefnx {Function File} {@var{entries} =} zip (@var{zipfile}, @var{files}, @var{rootdir})
-## Compress the list of files and/or directories specified in @var{files}
-## into the archive @var{zipfile} in the same directory.  If @var{rootdir}
-## is defined the @var{files} are located relative to @var{rootdir} rather
-## than the current directory.
-## @seealso{unzip, bzip2, gzip, tar}
+## @deftypefn  {Function File} {@var{filelist} =} zip (@var{zipfile}, @var{files})
+## @deftypefnx {Function File} {@var{filelist} =} zip (@var{zipfile}, @var{files}, @var{rootdir})
+## Compress the list of files and directories specified in @var{files} into the
+## ZIP archive @var{zipfile}.
+##
+## @var{files} is a character array or cell array of strings.  Shell
+## wildcards in the filename such as @samp{*} or @samp{?} are accepted and
+## expanded.  Directories are recursively traversed and all files are
+## compressed and added to the archive.
+##
+## If @var{rootdir} is defined then any files without absolute pathnames are
+## located relative to @var{rootdir} rather than the current directory.
+##
+## The optional output @var{filelist} is a list of the files that were included
+## in the archive.
+## @seealso{unzip, unpack, bzip2, gzip, tar}
 ## @end deftypefn
 
 ## Author: Sylvain Pelissier <sylvain.pelissier@gmail.com>
 
-function entries = zip (zipfile, files, rootdir = ".")
+function filelist = zip (zipfile, files, rootdir = ".")
+
+  if (nargin < 2 || nargin > 3)
+    print_usage ();
+  endif
 
-  if (nargin != 2 && nargin != 3)
-    print_usage ();
+  if (! ischar (zipfile))
+    error ("zip: ZIPFILE must be a string");
+  elseif (ischar (files))
+    files = cellstr (files);
+  elseif (! iscellstr (files))
+    error ("zip: FILES must be a character array or cellstr");
   endif
 
   rootdir = tilde_expand (rootdir);
 
-  if (ischar (files))
-    files = cellstr (files);
-  endif
+  zipfile = make_absolute_filename (zipfile);
 
-  if (! ischar (zipfile) && ! iscellstr (files))
-    error ("zip: expecting all arguments to be character strings");
-  endif
-
-  cmd = sprintf ("cd %s; zip -r %s/%s %s", rootdir, pwd (), zipfile,
-                 sprintf (" %s", files{:}));
+  cmd = sprintf ("cd %s; zip -r %s %s",
+                     rootdir,   zipfile, sprintf (" %s", files{:}));
 
   [status, output] = system (cmd);
 
@@ -54,16 +65,60 @@
   endif
 
   if (nargout > 0)
-    cmd = sprintf ("unzip -Z -1 %s", zipfile);
-    [status, entries] = system (cmd);
+    cmd = ["unzip -Z -1 " zipfile];
+    [status, filelist] = system (cmd);
     if (status)
       error ("zip: zipinfo failed with exit status = %d", status);
     endif
-    if (entries(end) == "\n")
-      entries(end) = [];
+    if (filelist(end) == "\n")
+      filelist(end) = [];
     endif
-    entries = ostrsplit (entries, "\n");
+    filelist = ostrsplit (filelist, "\n");
   endif
 
 endfunction
 
+
+%!xtest
+%! ## test zip together with unzip
+%! unwind_protect
+%!   filename = tempname;
+%!   tmp_var  = pi;
+%!   save (filename, "tmp_var");
+%!   dirname = tempname;
+%!   mkdir (dirname);
+%!   zipfile = tempname;
+%!   [~, basename, ext] = fileparts (filename);
+%!   filelist = zip (zipfile, [basename ext], tempdir);
+%!   filelist = filelist{1};
+%!   if (! strcmp (filelist, [basename ext]))
+%!     error ("zip archive does not contain expected name!");
+%!   endif
+%!   if (! exist ([zipfile ".zip"], "file"))
+%!     error ("zip file cannot be found!");
+%!   endif
+%!   unzip ([zipfile ".zip"], dirname);
+%!   fid = fopen (filename, "rb");
+%!   assert (fid >= 0);
+%!   orig_data = fread (fid);
+%!   fclose (fid);
+%!   fid = fopen ([dirname filesep basename ext], "rb");
+%!   assert (fid >= 0);
+%!   new_data = fread (fid);
+%!   fclose (fid);
+%!   if (orig_data != new_data)
+%!     error ("unzipped file not equal to original file!");
+%!   endif
+%! unwind_protect_cleanup
+%!   delete (filename);
+%!   delete ([dirname, filesep, basename, extension]);
+%!   rmdir (dirname);
+%! end_unwind_protect
+
+## Test input validation
+%!error zip ()
+%!error zip (1)
+%!error zip (1,2,3,4)
+%!error <ZIPFILE must be a string> zip (1, "foobar")
+%!error <FILES must be a character array or cellstr> zip ("foobar", 1)
+
--- a/scripts/mkdoc	Fri Feb 06 08:31:09 2015 -0800
+++ /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 Feb 06 08:31:09 2015 -0800
+++ b/scripts/mkdoc.pl	Fri Feb 06 08:31:49 2015 -0800
@@ -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 Feb 06 08:31:09 2015 -0800
+++ b/scripts/optimization/fminbnd.m	Fri Feb 06 08:31:49 2015 -0800
@@ -71,6 +71,11 @@
     print_usage ();
   endif
 
+  if (xmin > xmax)
+    error ("Octave:invalid-input-arg",
+           "fminbnd: the lower bound cannot be greater than the upper one");
+  endif
+
   if (ischar (fun))
     fun = str2func (fun, "global");
   endif
@@ -170,7 +175,7 @@
 
     ## update  a, b, v, w, and x
 
-    if (fu <= fval)
+    if (fu < fval)
       if (u < x)
         b = x;
       else
@@ -283,4 +288,8 @@
 %!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)
+%!assert (fminbnd (@(x) sin (x), 0, 0), 0, eps)
 
+%!error <lower bound cannot be greater> fminbnd (@(x) sin (x), 0, -pi)
+
--- a/scripts/optimization/fminsearch.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/optimization/fminsearch.m	Fri Feb 06 08:31:49 2015 -0800
@@ -24,9 +24,9 @@
 ##
 ## Find a value of @var{x} which minimizes the function @var{fun}.
 ## The search begins at the point @var{x0} and iterates using the
-## Nelder & Mead Simplex algorithm (a derivative-free method).  This algorithm
-## is better-suited to functions which have discontinuities or for which
-## a gradient-based search such as @code{fminunc} fails.
+## @nospell{Nelder & Mead} Simplex algorithm (a derivative-free method).  This
+## algorithm is better-suited to functions which have discontinuities or for
+## which a gradient-based search such as @code{fminunc} fails.
 ##
 ## Options for the search are provided in the parameter @var{options} using
 ## the function @code{optimset}.  Currently, @code{fminsearch} accepts the
--- a/scripts/optimization/fminunc.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/optimization/fminunc.m	Fri Feb 06 08:31:49 2015 -0800
@@ -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 Feb 06 08:31:09 2015 -0800
+++ b/scripts/optimization/fsolve.m	Fri Feb 06 08:31:49 2015 -0800
@@ -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 Feb 06 08:31:09 2015 -0800
+++ b/scripts/optimization/fzero.m	Fri Feb 06 08:31:49 2015 -0800
@@ -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 Feb 06 08:31:09 2015 -0800
+++ b/scripts/optimization/glpk.m	Fri Feb 06 08:31:49 2015 -0800
@@ -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
@@ -238,7 +238,7 @@
 ## Most fractional variable.
 ##
 ## @item 4 (@w{@code{GLP_BR_DTH}})
-## Heuristic by Driebeck and Tomlin.
+## Heuristic by @nospell{Driebeck and Tomlin}.
 ##
 ## @item 5 (@w{@code{GLP_BR_PCH}})
 ## Hybrid @nospell{pseudocost} heuristic.
--- a/scripts/optimization/lsqnonneg.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/optimization/lsqnonneg.m	Fri Feb 06 08:31:49 2015 -0800
@@ -66,7 +66,7 @@
 ##
 ## Not implemented.
 ## @end itemize
-## @seealso{optimset, pqpnonneg}
+## @seealso{optimset, pqpnonneg, lscov}
 ## @end deftypefn
 
 ## PKG_ADD: ## Discard result to avoid polluting workspace with ans at startup.
--- a/scripts/optimization/optimget.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/optimization/optimget.m	Fri Feb 06 08:31:49 2015 -0800
@@ -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 Feb 06 08:31:09 2015 -0800
+++ b/scripts/optimization/optimset.m	Fri Feb 06 08:31:49 2015 -0800
@@ -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 Feb 06 08:31:09 2015 -0800
+++ b/scripts/optimization/sqp.m	Fri Feb 06 08:31:49 2015 -0800
@@ -1,4 +1,5 @@
 ## Copyright (C) 2005-2013 John W. Eaton
+## Copyright (C) 2013 Arun Giridhar
 ##
 ## This file is part of Octave.
 ##
@@ -129,7 +130,16 @@
 ## @table @asis
 ## @item 101
 ## The algorithm terminated normally.
-## Either all constraints meet the requested tolerance, or the stepsize,
+## 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/path/matlabroot.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/path/matlabroot.m	Fri Feb 06 08:31:49 2015 -0800
@@ -32,6 +32,5 @@
 endfunction
 
 
-
 %!assert (matlabroot (), OCTAVE_HOME ())
 
--- a/scripts/path/module.mk	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/path/module.mk	Fri Feb 06 08:31:49 2015 -0800
@@ -1,9 +1,13 @@
 FCN_FILE_DIRS += path
 
+path_PRIVATE_FCN_FILES = \
+  path/private/getsavepath.m
+
 path_FCN_FILES = \
   path/matlabroot.m \
   path/pathdef.m \
-  path/savepath.m
+  path/savepath.m \
+  $(path_PRIVATE_FCN_FILES)
 
 FCN_FILES += $(path_FCN_FILES)
 
--- a/scripts/path/pathdef.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/path/pathdef.m	Fri Feb 06 08:31:49 2015 -0800
@@ -20,108 +20,82 @@
 ## -*- texinfo -*-
 ## @deftypefn {Function File} {@var{val} =} pathdef ()
 ## Return the default path for Octave.
-## The path information is extracted from one of three sources.
+##
+## The path information is extracted from one of four sources.
 ## The possible sources, in order of preference, are:
 ##
 ## @enumerate
+## @item @file{.octaverc}
+##
 ## @item @file{~/.octaverc}
 ##
-## @item @file{<octave-home>/@dots{}/<version>/m/startup/octaverc}
+## @item @file{<OCTAVE_HOME>/@dots{}/<version>/m/startup/octaverc}
 ##
-## @item Octave's path prior to changes by any octaverc.
+## @item Octave's path prior to changes by any octaverc file.
 ## @end enumerate
 ## @seealso{path, addpath, rmpath, genpath, savepath}
 ## @end deftypefn
 
 function val = pathdef ()
 
-  ## Locate the site octaverc file.
-  pathdir = octave_config_info ("localstartupfiledir");
-  site_octaverc = fullfile (pathdir, "octaverc");
+  if (nargin > 0)
+    print_usage ();
+  endif
+
+  ## Locate any project-specific .octaverc file.
+  proj_octaverc = fullfile (pwd, ".octaverc");
+  if (exist (proj_octaverc, "file"))
+    proj_path = __extractpath__ (proj_octaverc);
+    if (! isempty (proj_path))
+      val = proj_path;
+      return;
+    endif
+  endif
 
   ## Locate the user's ~/.octaverc file.
   user_octaverc = fullfile ("~", ".octaverc");
-
-  ## Extract the specified paths from the site and user octavercs.
-  site_path = __extractpath__ (site_octaverc);
   if (exist (user_octaverc, "file"))
     user_path = __extractpath__ (user_octaverc);
-  else
-    user_path = "";
+    if (! isempty (user_path))
+      val = user_path;
+      return;
+    endif
+  endif
+
+  ## No user octaverc file, locate the site octaverc file.
+  pathdir = octave_config_info ("localstartupfiledir");
+  site_octaverc = fullfile (pathdir, "octaverc");
+  site_path = __extractpath__ (site_octaverc);
+  if (! isempty (site_path))
+    val = site_path;
+    return;
   endif
 
-  ## A path definition in the user rcfile has precedence over the site rcfile.
-  if (! isempty (user_path))
-    val = user_path;
-  elseif (! isempty (site_path))
-    val = site_path;
+  ## No project, user, or site octaverc file.  Use Octave's default.
+  val = __pathorig__ ();
+
+endfunction
+
+## Extact the path information from the script/function @var{file}, created by
+## @file{savepath.m}.  If successful, @code{__extractpath__} returns the path
+## specified in @var{file}.
+
+## Author: Ben Abbott <bpabbott@mac.com>
+
+function path = __extractpath__ (savefile)
+
+  [filelines, startline, endline] = getsavepath (savefile);
+  if (startline > 0)
+    tmp = regexprep (filelines(startline+1:endline-1),
+                     "^.*path \\('([^\']+)'.*$", "$1");
+    path = strjoin (tmp, ":");
   else
-    val = __pathorig__ ();
+    path = "";
   endif
 
 endfunction
 
-## Extact the path information from the script/function @var{file},
-## created by @file{savepath.m}.  If @var{file} is omitted,
-## @file{~/.octaverc} is used.  If successful, @code{__extractpath__}
-## returns the path specified in @var{file}.
-
-## Author: Ben Abbott <bpabbott@mac.com>
-
-function specifiedpath = __extractpath__ (savefile)
-
-  ## The majority of this code was borrowed from savepath.m.
-  ## FIXME: is there some way to share the common parts instead of duplicating?
-  ## ANSWER: Yes.  Create a private directory and extract this section of code
-  ##         and place it there in a new function only visible by pathdef() and
-  ##         savepath().
-  beginstring = "## Begin savepath auto-created section, do not edit";
-  endstring   = "## End savepath auto-created section";
-
-  if (nargin == 0)
-    savefile = tilde_expand ("~/.octaverc");
-  endif
 
-  ## Parse the file if it exists to see if we should replace a section
-  ## or create a section.
-  startline = endline = 0;
-  filelines = {};
-  if (exist (savefile) == 2)
-    [fid, msg] = fopen (savefile, "rt");
-    if (fid < 0)
-      error ("__extractpath__: could not open savefile, %s: %s", savefile, msg);
-    endif
-    unwind_protect
-      linenum = 0;
-      while (ischar (line = fgetl (fid)))
-        filelines{++linenum} = line;
-        ## find the first and last lines if they exist in the file
-        if (strcmp (line, beginstring))
-          startline = linenum;
-        elseif (strcmp (line, endstring))
-          endline = linenum;
-        endif
-      endwhile
-    unwind_protect_cleanup
-      closeread = fclose (fid);
-      if (closeread < 0)
-        error ("__extractpath__: could not close savefile after reading, %s",
-               savefile);
-      endif
-    end_unwind_protect
-  endif
+## FIXME: Need some better BIST tests
+%!assert (ischar (pathdef ()))
 
-  ## Extract the path specifiation.
-  if (startline > endline || (startline > 0 && endline == 0))
-    error ("__extractpath__: unable to parse file, %s", savefile);
-  elseif (startline > 0)
-    ## Undo doubling of single quote characters performed by savepath.
-    specifiedpath = strrep (regexprep (cstrcat (filelines(startline:endline){:}),
-                                       " *path *\\('(.*)'\\); *", "$1"),
-                            "''", "'");
-  else
-    specifiedpath = "";
-  endif
-
-endfunction
-
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/path/private/getsavepath.m	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,53 @@
+## 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/>.
+
+function [filelines, startline, endline] = getsavepath (file)
+
+  beginstring = "## Begin savepath auto-created section, do not edit";
+  endstring   = "## End savepath auto-created section";
+
+  ## Read in the file while checking for errors along the way.
+  startline = endline = 0;
+  filelines = {};
+  if (exist (file) == 2)
+    [fid, msg] = fopen (file, "rt");
+    if (fid < 0)
+      error ("getsavepath: could not open file, %s: %s", file, msg);
+    endif
+    linenum = 0;
+    while (ischar (line = fgetl (fid)))
+      filelines{++linenum} = line;
+      ## Find the first and last lines if they exist in the file.
+      if (strcmp (line, beginstring))
+        startline = linenum;
+      elseif (strcmp (line, endstring))
+        endline = linenum;
+      endif
+    endwhile
+    if (fclose (fid) < 0)
+      error ("getsavepath: could not close file after reading, %s", file);
+    endif
+  endif
+
+  ## Verify the file was correctly formatted.
+  if (startline > endline || (startline > 0 && endline == 0))
+    error ("getsavepath: unable to parse file, %s", file);
+  endif
+
+endfunction
+
--- a/scripts/path/savepath.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/path/savepath.m	Fri Feb 06 08:31:49 2015 -0800
@@ -22,8 +22,20 @@
 ## @deftypefnx {Function File} {@var{status} =} savepath (@dots{})
 ## Save the unique portion of the current function search path that is
 ## not set during Octave's initialization process to @var{file}.
-## If @var{file} is omitted, @file{~/.octaverc} is used.  If successful,
-## @code{savepath} returns 0.
+##
+## If @var{file} is omitted, Octave looks in the current directory for a
+## project-specific @file{.octaverc} file in which to save the path
+## information.  If no such file is present then the user's configuration file
+## @file{~/.octaverc} is used.
+##
+## If successful, @code{savepath} returns 0.
+##
+## The @code{savepath} function makes it simple to customize a user's
+## configuration file to restore the working paths necessary for a particular
+## instance of Octave.  Assuming no filename is specified, Octave will
+## automatically restore the saved directory paths from the appropriate
+## @file{.octaverc} file when starting up.  If a filename has been specified
+## then the paths may be restored manually by calling @code{source @var{file}}.
 ## @seealso{path, addpath, rmpath, genpath, pathdef}
 ## @end deftypefn
 
@@ -31,54 +43,27 @@
 
 function retval = savepath (file)
 
-  ret = 1;
-
   beginstring = "## Begin savepath auto-created section, do not edit";
   endstring   = "## End savepath auto-created section";
 
+  ## Use project-specific or user's .octaverc when no file specified
   if (nargin == 0)
-    file = fullfile ("~", ".octaverc");
+    file = fullfile (pwd, ".octaverc");
+    if (! exist (file, "file"))
+      file = fullfile ("~", ".octaverc");
+    endif
   endif
 
-  ## parse the file if it exists to see if we should replace an
-  ## existing section or create a new section
-  startline = endline = 0;
-  filelines = {};
-  if (exist (file) == 2)
-    [fid, msg] = fopen (file, "rt");
-    if (fid < 0)
-      error ("savepath: could not open file, %s: %s", file, msg);
-    endif
-    unwind_protect
-      linenum = 0;
-      while (ischar (line = fgetl (fid)))
-        filelines{++linenum} = line;
-        ## find the first and last lines if they exist in the file
-        if (strcmp (line, beginstring))
-          startline = linenum;
-        elseif (strcmp (line, endstring))
-          endline = linenum;
-        endif
-      endwhile
-    unwind_protect_cleanup
-      closeread = fclose (fid);
-      if (closeread < 0)
-        error ("savepath: could not close file after reading, %s", file);
-      endif
-    end_unwind_protect
-  endif
+  ## Read in the file
+  [filelines, startline, endline] = getsavepath (file);
 
-  if (startline > endline || (startline > 0 && endline == 0))
-    error ("savepath: unable to parse file, %s", file);
-  endif
-
-  ## put the current savepath lines into the file
+  ## Determine where the savepath lines are placed in the file.
   if (isempty (filelines)
       || (startline == 1 && endline == length (filelines)))
-    ## savepath is the entire file
+    ## savepath is the entire file.
     pre = post = {};
   elseif (endline == 0)
-    ## drop the savepath statements at the end of the file
+    ## Drop the savepath statements at the end of the file.
     pre = filelines;
     post = {};
   elseif (startline == 1)
@@ -88,51 +73,45 @@
     pre = filelines(1:startline-1);
     post = {};
   else
-    ## insert in the middle
+    ## Insert in the middle.
     pre = filelines(1:startline-1);
     post = filelines(endline+1:end);
   endif
 
-  ## write the results
+  ## Write the results.
   [fid, msg] = fopen (file, "wt");
   if (fid < 0)
     error ("savepath: unable to open file for writing, %s, %s", file, msg);
   endif
   unwind_protect
-    for i = 1:length (pre)
-      fprintf (fid, "%s\n", pre{i});
-    endfor
+    fprintf (fid, "%s\n", pre{:});
 
     ## Remove the portion of the path defined via the command line
     ## and/or the environment.
     workingpath = parsepath (path);
-    command_line_path = parsepath (command_line_path ());
+    cmd_line_path = parsepath (command_line_path ());
     octave_path = parsepath (getenv ("OCTAVE_PATH"));
-    pathdef = pathdef ();
-    if (isempty (pathdef))
-      ## This occurs when running octave via run-octave. In this instance
+    default_path = pathdef ();
+    if (isempty (default_path))
+      ## This occurs when running octave via run-octave.  In this instance
       ## the entire path is specified via the command line and pathdef()
       ## is empty.
       [~, n] = setdiff (workingpath, octave_path);
-      default_path = command_line_path;
+      default_path = cmd_line_path;
     else
-      [~, n] = setdiff (workingpath, union (command_line_path, octave_path));
-      default_path = parsepath (pathdef);
+      [~, n] = setdiff (workingpath, union (cmd_line_path, octave_path));
+      default_path = parsepath (default_path);
     endif
     ## This is the path we'd like to preserve when octave is run.
-    path_to_preserve = workingpath (sort (n));
+    path_to_preserve = workingpath(sort (n));
 
-    ## Determine the path to Octave's user and sytem wide pkgs.
+    ## Determine the path to Octave's user and system wide packages.
     [pkg_user, pkg_system] = pkg ("list");
-    pkg_user_path = cell (1, numel (pkg_user));
-    pkg_system_path = cell (1, numel (pkg_system));
-    for n = 1:numel (pkg_user)
-      pkg_user_path{n} = pkg_user{n}.archprefix;
-    endfor
-    for n = 1:numel (pkg_system)
-      pkg_system_path{n} = pkg_system{n}.archprefix;
-    endfor
-    pkg_path = union (pkg_user_path, pkg_system_path);
+
+    ## Conversion from cell array of structs to cellstr of archprefixes.
+    pkg_path = unique (cellfun (@(elt) elt.archprefix,
+                                [pkg_user, pkg_system],
+                                "uniformoutput", false));
 
     ## Rely on Octave's initialization to include the pkg path elements.
     if (! isempty (pkg_path))
@@ -140,22 +119,27 @@
       path_to_preserve = path_to_preserve(sort (n));
     endif
 
-    ## Split the path to be saved into two groups. Those path elements that
+    ## Split the path to be saved into two groups.  Those path elements that
     ## belong at the beginning and those at the end.
     if (! isempty (default_path))
       n1 = find (strcmp (default_path{1}, path_to_preserve));
       n2 = find (strcmp (default_path{end}, path_to_preserve));
-      n_middle = round (0.5*(n1+n2));
+      n_middle = round ((n1+n2)/2);
       [~, n] = setdiff (path_to_preserve, default_path);
       path_to_save = path_to_preserve(sort (n));
       ## Remove pwd
-      path_to_save = path_to_save(! strcmp (path_to_save, ["." pathsep]));
-      n = ones (size (path_to_save));
-      for m = 1:numel (path_to_save)
-        n(m) = find (strcmp (path_to_save{m}, path_to_preserve));
-      endfor
-      path_to_save_begin = path_to_save(n <= n_middle);
-      path_to_save_end   = path_to_save(n > n_middle);
+      path_to_save(strcmp (path_to_save, ["." pathsep])) = [];
+      if (! isempty (path_to_save))
+        n = ones (numel (path_to_save), 1);
+        for m = 1:numel (path_to_save)
+          n(m) = find (strcmp (path_to_save{m}, path_to_preserve));
+        endfor
+        path_to_save_begin = path_to_save(n <= n_middle);
+        path_to_save_end   = path_to_save(n > n_middle);
+      else
+        path_to_save_begin = {};
+        path_to_save_end   = {};
+      endif
     else
       path_to_save_begin = path_to_preserve;
       path_to_save_end   = {};
@@ -179,28 +163,58 @@
     endif
     fprintf (fid, "%s\n", endstring);
 
-    for i = 1:length (post)
-      fprintf (fid, "%s\n", post{i});
-    endfor
+    fprintf (fid, "%s\n", post{:});
   unwind_protect_cleanup
-    closeread = fclose (fid);
-    if (closeread < 0)
+    status = fclose (fid);
+    if (status < 0)
       error ("savepath: could not close savefile after writing, %s", file);
     elseif (nargin == 0)
-      warning ("savepath: current path saved to %s", file);
+      warning ("off", "backtrace", "local");
+      warning ("Octave:savepath-local",
+               "savepath: current path saved to %s", file);
     endif
   end_unwind_protect
 
-  ret = 0;
-
   if (nargout > 0)
-    retval = ret;
+    retval = 0;
   endif
 
 endfunction
 
+## Convert single string of paths to cell array of paths
 function path_elements = parsepath (p)
-  pat = sprintf ('([^%s]+[%s$])', pathsep, pathsep);
-  path_elements = regexpi (strcat (p, pathsep), pat, "match");
+  path_elements = strcat (ostrsplit (p, pathsep), pathsep);
 endfunction
 
+%!test
+%! fname = tempname ();
+%! status = savepath (fname);
+%! assert (status == 0);
+%! old_dir = pwd;
+%! unwind_protect
+%!   cd (P_tmpdir);
+%!   if (exist (fullfile (pwd, ".octaverc")))
+%!     unlink (".octaverc");
+%!   endif
+%!   ## Create blank .octaverc file
+%!   fid = fopen (".octaverc", "wt");
+%!   assert (fid >= 0);
+%!   fclose (fid);
+%!   ## Save path into local .octaverc file
+%!   warning ("off", "Octave:savepath-local");
+%!   status = savepath ();
+%!   assert (status == 0);
+%!   ## Compare old and new versions
+%!   fid = fopen (fname, "rb");
+%!   assert (fid >= 0);
+%!   orig_data = fread (fid);
+%!   fclose (fid);
+%!   fid = fopen (".octaverc", "rb");
+%!   assert (fid >= 0);
+%!   new_data = fread (fid);
+%!   fclose (fid);
+%!   assert (orig_data, new_data);
+%! unwind_protect_cleanup
+%!   cd (old_dir);
+%! end_unwind_protect
+
--- a/scripts/pkg/module.mk	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/pkg/module.mk	Fri Feb 06 08:31:49 2015 -0800
@@ -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 Feb 06 08:31:09 2015 -0800
+++ b/scripts/pkg/pkg.m	Fri Feb 06 08:31:49 2015 -0800
@@ -21,8 +21,9 @@
 ## -*- texinfo -*-
 ## @deftypefn  {Command} {} pkg @var{command} @var{pkg_name}
 ## @deftypefnx {Command} {} pkg @var{command} @var{option} @var{pkg_name}
-## Manage packages (groups of add-on functions) for Octave.  Different actions
-## are available depending on the value of @var{command}.
+## Manage packages (groups of add-on functions) for Octave.
+##
+## Different actions are available depending on the value of @var{command}.
 ##
 ## Available commands:
 ##
@@ -123,11 +124,25 @@
 ## Show the list of currently installed packages.  For example,
 ##
 ## @example
-## installed_packages = pkg ("list")
+## pkg list
 ## @end example
 ##
 ## @noindent
-## returns a cell array containing a structure for each installed package.
+## will produce a short report with the package name, version, and installation
+## directory for each installed package.  Supply a package name to limit
+## reporting to a particular package.  For example:
+##
+## @example
+## pkg list image
+## @end example
+##
+## If a single return argument is requested then @code{pkg} returns a cell
+## array where each element is a structure with information on a single
+## package.
+##
+## @example
+## installed_packages = pkg ("list")
+## @end example
 ##
 ## If two output arguments are requested @code{pkg} splits the list of
 ## installed packages into those which were installed by the current user,
@@ -137,7 +152,7 @@
 ## [user_packages, system_packages] = pkg ("list")
 ## @end example
 ##
-## The option @qcode{"-forge"} lists packages available at the Octave-Forge
+## The @qcode{"-forge"} option lists packages available at the Octave-Forge
 ## repository.  This requires an internet connection and the cURL library.
 ## For example:
 ##
@@ -164,7 +179,7 @@
 ## @end example
 ##
 ## @noindent
-## If any of the requested packages is not installed, pkg returns an
+## If any of the requested packages is not installed, @code{pkg} returns an
 ## error, unless a second output is requested:
 ##
 ## @example
@@ -260,9 +275,11 @@
 ## will remove the autoloading status of the image package.
 ##
 ## @end table
+## @seealso{ver, news}
 ## @end deftypefn
 
 function [local_packages, global_packages] = pkg (varargin)
+
   ## Installation prefix (FIXME: what should these be on windows?)
   persistent user_prefix = false;
   persistent prefix = false;
@@ -271,33 +288,27 @@
   persistent global_list = fullfile (OCTAVE_HOME (), "share", "octave",
                                      "octave_packages");
 
-  confirm_recursive_rmdir (false, "local");
-
-  mlock ();
-
   ## If user is superuser set global_istall to true
   ## FIXME: is it OK to set this always true on windows?
   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
 
+  mlock ();
+
+  confirm_recursive_rmdir (false, "local");
+
   available_actions = {"list", "install", "uninstall", "load", ...
                        "unload", "prefix", "local_list", ...
                        "global_list", "rebuild", "build", ...
                        "describe", "update"};
-  ## Handle input
-  if (length (varargin) == 0 || ! iscellstr (varargin))
+
+  ## Parse input arguments
+  if (isempty (varargin) || ! iscellstr (varargin))
     print_usage ();
   endif
   files = {};
@@ -306,7 +317,7 @@
   action = "none";
   verbose = false;
   octave_forge = false;
-  for i = 1:length (varargin)
+  for i = 1:numel (varargin)
     switch (varargin{i})
       case "-nodeps"
         deps = false;
@@ -326,22 +337,18 @@
       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"))
-          action = varargin{i};
-        else
+        if (! strcmp (action, "none"))
           error ("more than one action specified");
         endif
+        action = varargin{i};
       otherwise
         files{end+1} = varargin{i};
     endswitch
@@ -362,19 +369,20 @@
         endif
       else
         if (nargout == 0)
-          installed_packages (local_list, global_list);
+          installed_packages (local_list, global_list, files);
         elseif (nargout == 1)
-          local_packages = installed_packages (local_list, global_list);
+          local_packages = installed_packages (local_list, global_list, files);
         elseif (nargout == 2)
           [local_packages, global_packages] = installed_packages (local_list,
-                                                                  global_list);
+                                                                  global_list,
+                                                                  files);
         else
           error ("too many output arguments requested");
         endif
       endif
 
     case "install"
-      if (length (files) == 0)
+      if (isempty (files))
         error ("you must specify at least one filename when calling 'pkg install'");
       endif
 
@@ -399,48 +407,47 @@
       end_unwind_protect
 
     case "uninstall"
-      if (length (files) == 0)
+      if (isempty (files))
         error ("you must specify at least one package when calling 'pkg uninstall'");
       endif
-      uninstall (files, deps, verbose, local_list,
-                 global_list, global_install);
+      uninstall (files, deps, verbose, local_list, global_list, global_install);
 
     case "load"
-      if (length (files) == 0)
-        error ("you must specify at least one package, 'all' or 'auto' when calling 'pkg load'");
+      if (isempty (files))
+        error ("you must specify at least one package, 'all', or 'auto' when calling 'pkg load'");
       endif
       load_packages (files, deps, local_list, global_list);
 
     case "unload"
-      if (length (files) == 0)
+      if (isempty (files))
         error ("you must specify at least one package or 'all' when calling 'pkg unload'");
       endif
       unload_packages (files, deps, local_list, global_list);
 
     case "prefix"
-      if (length (files) == 0 && nargout == 0)
+      if (isempty (files) && nargout == 0)
         printf ("Installation prefix:             %s\n", prefix);
         printf ("Architecture dependent prefix:   %s\n", archprefix);
-      elseif (length (files) == 0 && nargout >= 1)
+      elseif (isempty (files) && nargout >= 1)
         local_packages = prefix;
         global_packages = archprefix;
-      elseif (length (files) >= 1 && nargout <= 2 && ischar (files{1}))
+      elseif (numel (files) >= 1 && nargout <= 2 && ischar (files{1}))
         prefix = tilde_expand (files{1});
         if (! exist (prefix, "dir"))
-          [status, msg, msgid] = mkdir (prefix);
+          [status, msg] = mkdir (prefix);
           if (status == 0)
-            error("cannot create prefix %s: %s", prefix, msg);
+            error ("cannot create prefix %s: %s", prefix, msg);
           endif
           warning ("creating the directory %s\n", prefix);
         endif
         local_packages = prefix = canonicalize_file_name (prefix);
         user_prefix = true;
-        if (length (files) >= 2 && ischar (files{2}))
+        if (numel (files) >= 2 && ischar (files{2}))
           archprefix = tilde_expand (files{2});
           if (! exist (archprefix, "dir"))
-            [status, msg, msgid] = mkdir (archprefix);
+            [status, msg] = mkdir (archprefix);
             if (status == 0)
-              error("cannot create archprefix %s: %s", archprefix, msg);
+              error ("cannot create archprefix %s: %s", archprefix, msg);
             endif
             warning ("creating the directory %s\n", archprefix);
             global_packages = archprefix = canonicalize_file_name (archprefix);
@@ -451,11 +458,11 @@
       endif
 
     case "local_list"
-      if (length (files) == 0 && nargout == 0)
+      if (isempty (files) && nargout == 0)
         disp (local_list);
-      elseif (length (files) == 0 && nargout == 1)
+      elseif (isempty (files) && nargout == 1)
         local_packages = local_list;
-      elseif (length (files) == 1 && nargout == 0 && ischar (files{1}))
+      elseif (numel (files) == 1 && nargout == 0 && ischar (files{1}))
         local_list = files{1};
         if (! exist (local_list, "file"))
           try
@@ -471,11 +478,11 @@
       endif
 
     case "global_list"
-      if (length (files) == 0 && nargout == 0)
-        disp(global_list);
-      elseif (length (files) == 0 && nargout == 1)
+      if (isempty (files) && nargout == 0)
+        disp (global_list);
+      elseif (isempty (files) && nargout == 1)
         local_packages = global_list;
-      elseif (length (files) == 1 && nargout == 0 && ischar (files{1}))
+      elseif (numel (files) == 1 && nargout == 0 && ischar (files{1}))
         global_list = files{1};
         if (! exist (global_list, "file"))
           try
@@ -500,8 +507,8 @@
           local_packages = global_packages;
         endif
       else
-        local_packages = rebuild (prefix, archprefix, local_list, files, auto,
-                                  verbose);
+        local_packages = rebuild (prefix, archprefix, local_list, files,
+                                  auto, verbose);
         local_packages = save_order (local_packages);
         save (local_list, "local_packages");
         if (nargout == 0)
@@ -510,23 +517,21 @@
       endif
 
     case "build"
-      if (length (files) < 2)
+      if (numel (files) < 2)
         error ("you must specify at least the build directory and one filename\nwhen calling 'pkg build'");
       endif
       build (files, deps, auto, verbose);
 
     case "describe"
-      if (length (files) == 0)
+      if (isempty (files))
         error ("you must specify at least one package or 'all' when calling 'pkg describe'");
       endif
-      ## FIXME: the name of the output variables is inconsistent
-      ##            with their content
+      ## FIXME: name of the output variables is inconsistent with their content
       switch (nargout)
         case 0
           describe (files, verbose, local_list, global_list);
         case 1
-          pkg_desc_list = describe (files, verbose, local_list, ...
-                                    global_list);
+          pkg_desc_list = describe (files, verbose, local_list, global_list);
           local_packages = pkg_desc_list;
         case 2
           [pkg_desc_list, flag] = describe (files, verbose, local_list, ...
@@ -540,7 +545,20 @@
     case "update"
       if (nargout == 0)
         installed_pkgs_lst = installed_packages (local_list, global_list);
-        for i = 1:length (installed_pkgs_lst)
+        if (numel (files) > 0)
+           update_lst = {};
+           installed_names = {installed_pkgs_list.name}';
+           for i = 1:numel (files)
+             idx = find (strcmp (files{i}, installed_names), 1);
+             if (isempty (idx))
+               warning ("Package %s is not installed - not updating this package", files{i});
+             else
+               update_lst = { update_lst, installed_pkgs_lst{idx} };
+             endif
+           endfor
+           installed_pkgs_lst = update_lst;
+        endif
+        for i = 1:numel (installed_pkgs_lst)
           installed_pkg_name = installed_pkgs_lst{i}.name;
           installed_pkg_version = installed_pkgs_lst{i}.version;
           forge_pkg_version = get_forge_pkg (installed_pkg_name);
@@ -553,7 +571,8 @@
       endif
 
     otherwise
-      error ("you must specify a valid action for 'pkg'. See 'help pkg' for details");
+      error ("you must specify a valid action for 'pkg'.  See 'help pkg' for details");
   endswitch
+
 endfunction
 
--- a/scripts/pkg/private/configure_make.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/pkg/private/configure_make.m	Fri Feb 06 08:31:49 2015 -0800
@@ -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 = "";
@@ -74,8 +79,15 @@
     endif
 
     ## Make.
+    if (ispc ())
+      jobs = 1;
+    else
+      jobs =  nproc ("overridable");
+    endif
+
     if (exist (fullfile (src, "Makefile"), "file"))
-      [status, output] = shell ([scenv "make -C '" src "'"], verbose);
+      [status, output] = shell (sprintf ("%s make --jobs %i --directory '%s'",
+                                         scenv, jobs, src), verbose);
       if (status != 0)
         rmdir (desc.dir, "s");
         disp (output);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/pkg/private/default_prefix.m	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,39 @@
+## 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 Feb 06 08:31:09 2015 -0800
+++ b/scripts/pkg/private/getarchprefix.m	Fri Feb 06 08:31:49 2015 -0800
@@ -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/pkg/private/install.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/pkg/private/install.m	Fri Feb 06 08:31:49 2015 -0800
@@ -64,7 +64,7 @@
 
       if (exist (tgz, "file"))
         ## Create a temporary directory.
-        tmpdir = tmpnam ();
+        tmpdir = tempname ();
         tmpdirs{end+1} = tmpdir;
         if (verbose)
           printf ("mkdir (%s)\n", tmpdir);
--- a/scripts/pkg/private/installed_packages.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/pkg/private/installed_packages.m	Fri Feb 06 08:31:49 2015 -0800
@@ -22,7 +22,8 @@
 ## Undocumented internal function.
 ## @end deftypefn
 
-function [out1, out2] = installed_packages (local_list, global_list)
+function [out1, out2] = installed_packages (local_list, global_list, pkgname = {})
+
   ## Get the list of installed packages.
   try
     local_packages = load (local_list).local_packages;
@@ -38,41 +39,42 @@
 
   ## Eliminate duplicates in the installed package list.
   ## Locally installed packages take precedence.
-  dup = [];
-  for i = 1:length (installed_pkgs_lst)
-    if (any (dup == i))
-      continue;
+  installed_names = cellfun (@(x) x.name, installed_pkgs_lst,
+                             "uniformoutput", false);
+  [~, idx] = unique (installed_names, "first");
+  installed_names = installed_names(idx);
+  installed_pkgs_lst = installed_pkgs_lst(idx);
+
+  ## Check whether info on a particular package was requested
+  if (! isempty (pkgname))
+    idx = find (strcmp (pkgname{1}, installed_names));
+    if (isempty (idx))
+      installed_names = {};
+      installed_pkgs_lst = {};
+    else
+      installed_names = installed_names(idx);
+      installed_pkgs_lst = installed_pkgs_lst(idx);
     endif
-    for j = (i+1):length (installed_pkgs_lst)
-      if (any (dup == j))
-        continue;
-      endif
-      if (strcmp (installed_pkgs_lst{i}.name, installed_pkgs_lst{j}.name))
-        dup = [dup, j];
-      endif
-    endfor
-  endfor
-  if (! isempty (dup))
-    installed_pkgs_lst(dup) = [];
   endif
 
   ## Now check if the package is loaded.
+  ## FIXME: couldn't dir_in_loadpath() be used here?
   tmppath = strrep (path (), "\\", "/");
-  for i = 1:length (installed_pkgs_lst)
+  for i = 1:numel (installed_pkgs_lst)
     if (strfind (tmppath, strrep (installed_pkgs_lst{i}.dir, '\', '/')))
       installed_pkgs_lst{i}.loaded = true;
     else
       installed_pkgs_lst{i}.loaded = false;
     endif
   endfor
-  for i = 1:length (local_packages)
+  for i = 1:numel (local_packages)
     if (strfind (tmppath, strrep (local_packages{i}.dir, '\', '/')))
       local_packages{i}.loaded = true;
     else
       local_packages{i}.loaded = false;
     endif
   endfor
-  for i = 1:length (global_packages)
+  for i = 1:numel (global_packages)
     if (strfind (tmppath, strrep (global_packages{i}.dir, '\', '/')))
       global_packages{i}.loaded = true;
     else
@@ -90,10 +92,14 @@
     return;
   endif
 
-  ## We shouldn't return something, so we'll print something.
-  num_packages = length (installed_pkgs_lst);
+  ## Don't return anything, instead we'll print something.
+  num_packages = numel (installed_pkgs_lst);
   if (num_packages == 0)
-    printf ("no packages installed.\n");
+    if (isempty (pkgname))
+      printf ("no packages installed.\n");
+    else
+      printf ("package %s is not installed.\n", pkgname{1});
+    endif
     return;
   endif
 
@@ -101,20 +107,13 @@
   h1 = "Package Name";
   h2 = "Version";
   h3 = "Installation directory";
-  max_name_length = length (h1);
-  max_version_length = length (h2);
-  names = cell (num_packages, 1);
-  for i = 1:num_packages
-    max_name_length = max (max_name_length,
-                           length (installed_pkgs_lst{i}.name));
-    max_version_length = max (max_version_length,
-                              length (installed_pkgs_lst{i}.version));
-    names{i} = installed_pkgs_lst{i}.name;
-  endfor
-  max_dir_length = terminal_size ()(2) - max_name_length - ...
-                                             max_version_length - 7;
+  max_name_length = max ([length(h1), cellfun(@length, installed_names)]);
+  version_lengths = cellfun (@(x) length (x.version), installed_pkgs_lst);
+  max_version_length = max ([length(h2), version_lengths]);
+  ncols = terminal_size ()(2);
+  max_dir_length = ncols - max_name_length - max_version_length - 7;
   if (max_dir_length < 20)
-     max_dir_length = Inf;
+    max_dir_length = Inf;
   endif
 
   h1 = postpad (h1, max_name_length + 1, " ");
@@ -129,13 +128,12 @@
   printf ("%s\n", tmp);
 
   ## Print the packages.
-  format = sprintf ("%%%ds %%1s| %%%ds | %%s\n", max_name_length,
-                    max_version_length);
-  [dummy, idx] = sort (names);
+  format = sprintf ("%%%ds %%1s| %%%ds | %%s\n",
+                    max_name_length, max_version_length);
   for i = 1:num_packages
-    cur_name = installed_pkgs_lst{idx(i)}.name;
-    cur_version = installed_pkgs_lst{idx(i)}.version;
-    cur_dir = installed_pkgs_lst{idx(i)}.dir;
+    cur_name = installed_pkgs_lst{i}.name;
+    cur_version = installed_pkgs_lst{i}.version;
+    cur_dir = installed_pkgs_lst{i}.dir;
     if (length (cur_dir) > max_dir_length)
       first_char = length (cur_dir) - max_dir_length + 4;
       first_filesep = strfind (cur_dir(first_char:end), filesep ());
@@ -145,12 +143,13 @@
         cur_dir = ["..." cur_dir(first_char:end)];
       endif
     endif
-    if (installed_pkgs_lst{idx(i)}.loaded)
+    if (installed_pkgs_lst{i}.loaded)
       cur_loaded = "*";
     else
       cur_loaded = " ";
     endif
     printf (format, cur_name, cur_loaded, cur_version, cur_dir);
   endfor
+
 endfunction
 
--- a/scripts/plot/appearance/__clabel__.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/plot/appearance/__clabel__.m	Fri Feb 06 08:31:49 2015 -0800
@@ -127,3 +127,7 @@
 
 endfunction
 
+
+## No test needed for internal helper function.
+%!assert (1)
+
--- a/scripts/plot/appearance/__getlegenddata__.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/plot/appearance/__getlegenddata__.m	Fri Feb 06 08:31:49 2015 -0800
@@ -17,7 +17,7 @@
 ## <http://www.gnu.org/licenses/>.
 
 ## -*- texinfo -*-
-## @deftypefn {Function File} {[@var{hplots}, @var{strings}]} = __getlegenddata__ (@var{h})
+## @deftypefn {Function File} {[@var{hplots}, @var{strings}] =} __getlegenddata__ (@var{h})
 ## Undocumented internal function.
 ## @end deftypefn
 
@@ -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
@@ -59,3 +59,7 @@
 
 endfunction
 
+
+## No test needed for internal helper function.
+%!assert (1)
+
--- a/scripts/plot/appearance/axis.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/plot/appearance/axis.m	Fri Feb 06 08:31:49 2015 -0800
@@ -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 Feb 06 08:31:09 2015 -0800
+++ b/scripts/plot/appearance/datetick.m	Fri Feb 06 08:31:49 2015 -0800
@@ -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)
@@ -271,7 +271,7 @@
     b = 0;
   else
     l = log10 (abs (x));
-    r = fmod (l, 1);
+    r = rem (l, 1);
     a = 10 .^ r;
     b = fix (l - r);
     if (a < 1)
--- a/scripts/plot/appearance/diffuse.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/plot/appearance/diffuse.m	Fri Feb 06 08:31:49 2015 -0800
@@ -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 Feb 06 08:31:09 2015 -0800
+++ b/scripts/plot/appearance/grid.m	Fri Feb 06 08:31:49 2015 -0800
@@ -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 Feb 06 08:31:09 2015 -0800
+++ b/scripts/plot/appearance/legend.m	Fri Feb 06 08:31:49 2015 -0800
@@ -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;
@@ -1596,7 +1626,7 @@
 %!   position = get (h, "position");
 %!   plot (rand (3));
 %!   legend ();
-%!   filename = sprintf ("%s.eps", tmpnam ());
+%!   filename = sprintf ("%s.eps", tempname ());
 %!   print (filename);
 %!   unlink (filename);
 %!   assert (get (h, "position"), position);
@@ -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 Feb 06 08:31:09 2015 -0800
+++ b/scripts/plot/appearance/private/__axis_limits__.m	Fri Feb 06 08:31:49 2015 -0800
@@ -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 Feb 06 08:31:09 2015 -0800
+++ b/scripts/plot/appearance/specular.m	Fri Feb 06 08:31:49 2015 -0800
@@ -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 Feb 06 08:31:09 2015 -0800
+++ b/scripts/plot/appearance/text.m	Fri Feb 06 08:31:49 2015 -0800
@@ -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 Feb 06 08:31:09 2015 -0800
+++ b/scripts/plot/draw/area.m	Fri Feb 06 08:31:49 2015 -0800
@@ -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 Feb 06 08:31:09 2015 -0800
+++ b/scripts/plot/draw/colorbar.m	Fri Feb 06 08:31:49 2015 -0800
@@ -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 Feb 06 08:31:09 2015 -0800
+++ b/scripts/plot/draw/errorbar.m	Fri Feb 06 08:31:49 2015 -0800
@@ -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 Feb 06 08:31:09 2015 -0800
+++ b/scripts/plot/draw/fill.m	Fri Feb 06 08:31:49 2015 -0800
@@ -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};
 
-        ## Matlab uses flat/interp shading based on orientation of cdata.
-        if (isnumeric (cdata) && isrow (cdata))
-          popt = ["facecolor", "flat", opts];
-        else
-          popt = opts;
+        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) && ! 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,
-                                       popt{:});
+        [htmp, fail] = __patch__ (hax, x, y, cdata, opts{:});
         if (fail)
           print_usage ();
         endif
@@ -145,7 +156,7 @@
     endif
   elseif (isnumeric (arg))
     ## Assume any numeric argument is correctly formatted cdata.
-    ## Let patch worry about the multple different input formats
+    ## Let patch worry about the multple different input formats.
     retval = true;
   endif
 endfunction
@@ -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 Feb 06 08:31:09 2015 -0800
+++ b/scripts/plot/draw/line.m	Fri Feb 06 08:31:49 2015 -0800
@@ -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 Feb 06 08:31:09 2015 -0800
+++ b/scripts/plot/draw/mesh.m	Fri Feb 06 08:31:49 2015 -0800
@@ -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 Feb 06 08:31:09 2015 -0800
+++ b/scripts/plot/draw/meshc.m	Fri Feb 06 08:31:49 2015 -0800
@@ -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 Feb 06 08:31:09 2015 -0800
+++ b/scripts/plot/draw/meshz.m	Fri Feb 06 08:31:49 2015 -0800
@@ -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 Feb 06 08:31:09 2015 -0800
+++ b/scripts/plot/draw/pareto.m	Fri Feb 06 08:31:49 2015 -0800
@@ -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 Feb 06 08:31:09 2015 -0800
+++ b/scripts/plot/draw/patch.m	Fri Feb 06 08:31:49 2015 -0800
@@ -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 Feb 06 08:31:09 2015 -0800
+++ b/scripts/plot/draw/peaks.m	Fri Feb 06 08:31:49 2015 -0800
@@ -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
@@ -83,6 +83,9 @@
 
   if (nargout == 0)
     surf (x, y, Z);
+    Z_max = max (Z(:));
+    Z_min = min (Z(:));
+    axis ([-3, 3, -3, 3, Z_min, Z_max]);
   elseif (nargout == 1)
     X_out = Z;
   else
--- a/scripts/plot/draw/pie.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/plot/draw/pie.m	Fri Feb 06 08:31:49 2015 -0800
@@ -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 Feb 06 08:31:09 2015 -0800
+++ b/scripts/plot/draw/pie3.m	Fri Feb 06 08:31:49 2015 -0800
@@ -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 Feb 06 08:31:09 2015 -0800
+++ b/scripts/plot/draw/plot3.m	Fri Feb 06 08:31:49 2015 -0800
@@ -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 Feb 06 08:31:09 2015 -0800
+++ b/scripts/plot/draw/plotyy.m	Fri Feb 06 08:31:49 2015 -0800
@@ -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 Feb 06 08:31:09 2015 -0800
+++ b/scripts/plot/draw/polar.m	Fri Feb 06 08:31:49 2015 -0800
@@ -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 Feb 06 08:31:09 2015 -0800
+++ b/scripts/plot/draw/private/__ezplot__.m	Fri Feb 06 08:31:49 2015 -0800
@@ -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 Feb 06 08:31:09 2015 -0800
+++ b/scripts/plot/draw/private/__patch__.m	Fri Feb 06 08:31:49 2015 -0800
@@ -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/__quiver__.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/plot/draw/private/__quiver__.m	Fri Feb 06 08:31:49 2015 -0800
@@ -112,8 +112,16 @@
   ## Normalize 0.20 to 1/3 for plotting
   arrowsize /= 0.20 * 3;
 
-  if (autoscale && numel (u) > 1)
-    ## Scale the arrows to fit in the grid
+  ## Scale the arrows to fit in the grid
+  uu = u;
+  vv = v;
+  if (is3d)
+    ww = w;
+    len = max (sqrt (u(:).^2 + v(:).^2 + w(:).^2));
+  else
+    len = max (sqrt (u(:).^2 + v(:).^2));
+  endif
+  if (len > 0 && autoscale && numel (u) > 1)
     if (isvector (x))
       nx = ny = sqrt (length (x));
     else
@@ -123,29 +131,19 @@
     dy = (max (y(:)) - min (y(:))) / ny;
     if (is3d)
       dz = (max (z(:)) - min (z(:))) / max (nx, ny);
-      len = max (sqrt (u(:).^2 + v(:).^2 + w(:).^2));
     else
       dz = 0;
-      len = max (sqrt (u(:).^2 + v(:).^2));
     endif
-    if (len > 0)
-      sd = sqrt (dx.^2 + dy.^2 + dz.^2) / len;
-      if (sd != 0)
-        s = autoscale * sd;
-      else  # special case of identical points with multiple vectors
-        s = autoscale;
-      endif
-      uu = s * u;
-      vv = s * v;
-      if (is3d)
-        ww = s * w;
-      endif
+    sd = sqrt (dx.^2 + dy.^2 + dz.^2) / len;
+    if (sd != 0)
+      s = autoscale * sd;
+    else  # special case of identical points with multiple vectors
+      s = autoscale;
     endif
-  else
-    uu = u;
-    vv = v;
+    uu = s * u;
+    vv = s * v;
     if (is3d)
-      ww = w;
+      ww = s * w;
     endif
   endif
 
--- a/scripts/plot/draw/private/__scatter__.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/plot/draw/private/__scatter__.m	Fri Feb 06 08:31:49 2015 -0800
@@ -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 Feb 06 08:31:09 2015 -0800
+++ b/scripts/plot/draw/private/__stem__.m	Fri Feb 06 08:31:49 2015 -0800
@@ -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);
@@ -131,7 +128,13 @@
       addlistener (hg, "markerfacecolor", @update_props);
       addlistener (hg, "markersize", @update_props);
 
+      if (islogical (x))
+        x = double (x);
+      endif
       addproperty ("xdata", hg, "data", x(:, i));
+      if (islogical (y))
+        y = double (y);
+      endif
       addproperty ("ydata", hg, "data", y(:, i));
       if (have_z)
         addproperty ("zdata", hg, "data", z(:, i));
@@ -146,14 +149,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 +382,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 +399,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 Feb 06 08:31:09 2015 -0800
+++ b/scripts/plot/draw/rose.m	Fri Feb 06 08:31:49 2015 -0800
@@ -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 Feb 06 08:31:09 2015 -0800
+++ b/scripts/plot/draw/shrinkfaces.m	Fri Feb 06 08:31:49 2015 -0800
@@ -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,10 +73,11 @@
   endif
 
   sf = 0.3;
+  colors = [];
   p = varargin{1};
-  colors = [];
 
-  if (ishandle (p) && nargin < 3)
+  if (isscalar (p) && ishandle (p) && nargin < 3 &&
+      strcmp (get (p, "type"), "patch"))
     faces = get (p, "Faces");
     vertices = get (p, "Vertices");
     colors = get (p, "FaceVertexCData");
@@ -104,8 +107,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 +123,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 +217,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 Feb 06 08:31:09 2015 -0800
+++ b/scripts/plot/draw/stem.m	Fri Feb 06 08:31:49 2015 -0800
@@ -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 Feb 06 08:31:09 2015 -0800
+++ b/scripts/plot/draw/stemleaf.m	Fri Feb 06 08:31:49 2015 -0800
@@ -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;
@@ -454,7 +454,7 @@
 %! "         ______|   46|_______"      ,
 %! "        f|  -35           88|"      ,
 %! "         |    0            0|  out" ,
-%! "        F|  -82          135|"      ,
+%! "        F|  -81          134|"      ,
 %! "         |    0            0|  far" ,
 %! " "                                  ,
 %! "   0 | 20"                          ,
@@ -483,7 +483,7 @@
 %! "         ______|   46|_______"      ,
 %! "        f|  -88           35|"      ,
 %! "         |    0            0|  out" ,
-%! "        F| -135           82|"      ,
+%! "        F| -134           81|"      ,
 %! "         |    0            0|  far" ,
 %! " "                                  ,
 %! "  -5 | 2"                           ,
@@ -511,7 +511,7 @@
 %! "         ______|   10|_______"      ,
 %! "        f|  -17           10|"      ,
 %! "         |    0            0|  out" ,
-%! "        F|  -28           21|"      ,
+%! "        F|  -27           20|"      ,
 %! "         |    0            0|  far" ,
 %! " "                                  ,
 %! "  -0 | 9700"                        ,
@@ -535,7 +535,7 @@
 %! "         ______|   13|_______"        ,
 %! "        f|  -22           13|"        ,
 %! "         |    0            0|  out"   ,
-%! "        F|  -36           27|"        ,
+%! "        F|  -35           26|"        ,
 %! "         |    0            0|  far"   ,
 %! " "                                    ,
 %! "  -0 | 970"                           ,
--- a/scripts/plot/draw/surface.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/plot/draw/surface.m	Fri Feb 06 08:31:49 2015 -0800
@@ -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 Feb 06 08:31:09 2015 -0800
+++ b/scripts/plot/draw/surfc.m	Fri Feb 06 08:31:49 2015 -0800
@@ -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 Feb 06 08:31:09 2015 -0800
+++ b/scripts/plot/draw/surfl.m	Fri Feb 06 08:31:49 2015 -0800
@@ -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 Feb 06 08:31:09 2015 -0800
+++ b/scripts/plot/draw/surfnorm.m	Fri Feb 06 08:31:49 2015 -0800
@@ -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.
+##
+## Any property/value input pairs are assigned to the surface object.
 ##
-## 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.
+## 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 returned 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/draw/tetramesh.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/plot/draw/tetramesh.m	Fri Feb 06 08:31:49 2015 -0800
@@ -43,7 +43,7 @@
 ## @qcode{"visible"} property @qcode{"on"} or @qcode{"off"}.
 ##
 ## Type @code{demo tetramesh} to see examples on using @code{tetramesh}.
-## @seealso{trimesh, delaunay3, delaunayn, patch}
+## @seealso{trimesh, delaunay, delaunayn, patch}
 ## @end deftypefn
 
 ## Author: Martin Helm <martin@mhelm.de>
@@ -130,7 +130,7 @@
 %! x = [x(:); 0];
 %! y = [y(:); 0];
 %! z = [z(:); 0];
-%! tetra = delaunay3 (x, y, z);
+%! tetra = delaunay (x, y, z);
 %! X = [x(:) y(:) z(:)];
 %! colormap (jet (64));
 %! h = tetramesh (tetra, X);
@@ -147,7 +147,7 @@
 %! x = [x(:); 0];
 %! y = [y(:); 0];
 %! z = [z(:); 0];
-%! tetra = delaunay3 (x, y, z);
+%! tetra = delaunay (x, y, z);
 %! X = [x(:) y(:) z(:)];
 %! colormap (gray (256));
 %! tetramesh (tetra, X, 21:20:241, 'EdgeColor', 'w');
--- a/scripts/plot/module.mk	Fri Feb 06 08:31:09 2015 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,221 +0,0 @@
-FCN_FILE_DIRS += plot
-
-plot_GEN_FCN_FILES = \
-  plot/gnuplot_binary.m
-
-GEN_FCN_FILES += $(plot_GEN_FCN_FILES)
-
-plot_PRIVATE_FCN_FILES = \
-  plot/private/__actual_axis_position__.m \
-  plot/private/__add_datasource__.m \
-  plot/private/__add_default_menu__.m \
-  plot/private/__axes_limits__.m \
-  plot/private/__axis_label__.m \
-  plot/private/__bar__.m \
-  plot/private/__clabel__.m \
-  plot/private/__contour__.m \
-  plot/private/__default_plot_options__.m \
-  plot/private/__errcomm__.m \
-  plot/private/__errplot__.m \
-  plot/private/__ezplot__.m \
-  plot/private/__file_filter__.m \
-  plot/private/__fltk_file_filter__.m \
-  plot/private/__fltk_ginput__.m \
-  plot/private/__fltk_print__.m \
-  plot/private/__getlegenddata__.m \
-  plot/private/__ghostscript__.m \
-  plot/private/__gnuplot_get_var__.m \
-  plot/private/__gnuplot_ginput__.m \
-  plot/private/__gnuplot_has_feature__.m \
-  plot/private/__gnuplot_has_terminal__.m\
-  plot/private/__gnuplot_open_stream__.m \
-  plot/private/__gnuplot_print__.m \
-  plot/private/__gnuplot_version__.m \
-  plot/private/__go_draw_axes__.m \
-  plot/private/__go_draw_figure__.m \
-  plot/private/__interp_cube__.m \
-  plot/private/__is_function__.m \
-  plot/private/__line__.m \
-  plot/private/__marching_cube__.m \
-  plot/private/__next_line_color__.m \
-  plot/private/__next_line_style__.m \
-  plot/private/__patch__.m \
-  plot/private/__pie__.m \
-  plot/private/__plt__.m \
-  plot/private/__pltopt__.m \
-  plot/private/__print_parse_opts__.m \
-  plot/private/__quiver__.m \
-  plot/private/__scatter__.m \
-  plot/private/__stem__.m \
-  plot/private/__tight_eps_bbox__.m \
-  plot/private/__uigetdir_fltk__.m \
-  plot/private/__uigetfile_fltk__.m \
-  plot/private/__uiputfile_fltk__.m \
-  plot/private/__uiobject_split_args__.m
-
-plot_FCN_FILES = \
-  plot/__gnuplot_drawnow__.m \
-  plot/__plt_get_axis_arg__.m \
-  plot/allchild.m \
-  plot/ancestor.m \
-  plot/area.m \
-  plot/axes.m \
-  plot/axis.m \
-  plot/bar.m \
-  plot/barh.m \
-  plot/box.m \
-  plot/caxis.m \
-  plot/cla.m \
-  plot/clabel.m \
-  plot/clf.m \
-  plot/close.m \
-  plot/closereq.m \
-  plot/colorbar.m \
-  plot/colstyle.m \
-  plot/comet.m \
-  plot/comet3.m \
-  plot/compass.m \
-  plot/contour.m \
-  plot/contour3.m \
-  plot/contourc.m \
-  plot/contourf.m \
-  plot/copyobj.m \
-  plot/cylinder.m \
-  plot/daspect.m \
-  plot/diffuse.m \
-  plot/ellipsoid.m \
-  plot/errorbar.m \
-  plot/ezcontour.m \
-  plot/ezcontourf.m \
-  plot/ezmesh.m \
-  plot/ezmeshc.m \
-  plot/ezplot.m \
-  plot/ezplot3.m \
-  plot/ezpolar.m \
-  plot/ezsurf.m \
-  plot/ezsurfc.m \
-  plot/feather.m \
-  plot/figure.m \
-  plot/fill.m \
-  plot/findall.m \
-  plot/findfigs.m \
-  plot/findobj.m \
-  plot/fplot.m \
-  plot/gca.m \
-  plot/gcbf.m \
-  plot/gcbo.m \
-  plot/gcf.m \
-  plot/gco.m \
-  plot/ginput.m \
-  plot/graphics_toolkit.m \
-  plot/grid.m \
-  plot/gtext.m \
-  plot/guidata.m \
-  plot/guihandles.m \
-  plot/hdl2struct.m \
-  plot/hggroup.m \
-  plot/hidden.m \
-  plot/hist.m \
-  plot/hold.m \
-  plot/isaxes.m \
-  plot/isfigure.m \
-  plot/ishghandle.m \
-  plot/ishold.m \
-  plot/isocolors.m \
-  plot/isonormals.m \
-  plot/isosurface.m \
-  plot/isprop.m \
-  plot/legend.m \
-  plot/line.m \
-  plot/linkprop.m \
-  plot/loglog.m \
-  plot/loglogerr.m \
-  plot/mesh.m \
-  plot/meshc.m \
-  plot/meshgrid.m \
-  plot/meshz.m \
-  plot/ndgrid.m \
-  plot/newplot.m \
-  plot/orient.m \
-  plot/pareto.m \
-  plot/patch.m \
-  plot/pbaspect.m \
-  plot/pcolor.m \
-  plot/peaks.m \
-  plot/pie.m \
-  plot/pie3.m \
-  plot/plot.m \
-  plot/plot3.m \
-  plot/plotmatrix.m \
-  plot/plotyy.m \
-  plot/polar.m \
-  plot/print.m \
-  plot/printd.m \
-  plot/quiver.m \
-  plot/quiver3.m \
-  plot/rectangle.m \
-  plot/refresh.m \
-  plot/refreshdata.m \
-  plot/ribbon.m \
-  plot/rose.m \
-  plot/saveas.m \
-  plot/scatter.m \
-  plot/scatter3.m \
-  plot/semilogx.m \
-  plot/semilogxerr.m \
-  plot/semilogy.m \
-  plot/semilogyerr.m \
-  plot/shading.m \
-  plot/shg.m \
-  plot/shrinkfaces.m \
-  plot/slice.m \
-  plot/sombrero.m \
-  plot/specular.m \
-  plot/sphere.m \
-  plot/stairs.m \
-  plot/stem.m \
-  plot/stem3.m \
-  plot/stemleaf.m \
-  plot/struct2hdl.m \
-  plot/subplot.m \
-  plot/surf.m \
-  plot/surface.m \
-  plot/surfc.m \
-  plot/surfl.m \
-  plot/surfnorm.m \
-  plot/tetramesh.m \
-  plot/text.m \
-  plot/title.m \
-  plot/trimesh.m \
-  plot/triplot.m \
-  plot/trisurf.m \
-  plot/uicontextmenu.m \
-  plot/uicontrol.m \
-  plot/uigetdir.m \
-  plot/uigetfile.m \
-  plot/uimenu.m \
-  plot/uipanel.m \
-  plot/uipushtool.m \
-  plot/uiputfile.m \
-  plot/uiresume.m \
-  plot/uitoggletool.m \
-  plot/uitoolbar.m \
-  plot/uiwait.m \
-  plot/view.m \
-  plot/waitbar.m \
-  plot/waitforbuttonpress.m \
-  plot/waterfall.m \
-  plot/whitebg.m \
-  plot/xlabel.m \
-  plot/xlim.m \
-  plot/ylabel.m \
-  plot/ylim.m \
-  plot/zlabel.m \
-  plot/zlim.m \
-  $(plot_PRIVATE_FCN_FILES)
-
-FCN_FILES += $(plot_FCN_FILES)
-
-PKG_ADD_FILES += plot/PKG_ADD
-
-DIRSTAMP_FILES += plot/$(octave_dirstamp)
--- a/scripts/plot/util/__actual_axis_position__.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/plot/util/__actual_axis_position__.m	Fri Feb 06 08:31:49 2015 -0800
@@ -84,3 +84,6 @@
   endif
 endfunction
 
+
+## No test coverage for internal function.  It is tested through calling fcn.
+%!assert (1)
--- a/scripts/plot/util/__default_plot_options__.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/plot/util/__default_plot_options__.m	Fri Feb 06 08:31:49 2015 -0800
@@ -33,3 +33,13 @@
 
 endfunction
 
+
+%!test
+%! options = __default_plot_options__ ();
+%! assert (isfield (options, "key"));
+%! assert (options.key, "");
+%! assert (options.color, []);
+%! assert (options.linestyle, []);
+%! assert (options.marker, []);
+%! assert (options.errorstyle, []);
+
--- a/scripts/plot/util/__gnuplot_drawnow__.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/plot/util/__gnuplot_drawnow__.m	Fri Feb 06 08:31:49 2015 -0800
@@ -77,7 +77,7 @@
     term = gnuplot_default_term (plot_stream);
     if (strcmp (term, "dumb"))
       ## popen2 eats stdout of gnuplot, use temporary file instead
-      dumb_tmp_file = tmpnam ();
+      dumb_tmp_file = tempname ();
       enhanced = gnuplot_set_term (plot_stream(1), new_stream, h,
                                    term, dumb_tmp_file);
     else
--- a/scripts/plot/util/__next_line_color__.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/plot/util/__next_line_color__.m	Fri Feb 06 08:31:49 2015 -0800
@@ -52,3 +52,22 @@
 
 endfunction
 
+
+%!test
+%! hf = figure ("visible", "off");
+%! unwind_protect
+%!   hax = axes ();
+%!   set (hax, "colororder", [1 0 0; 0 1 0; 0 0 1]);
+%!   hold on;
+%!   h = plot (1:5,1:5,'o', 1:4,1:4, "x", 1:3,1:3, "d");
+%!   assert (get (h, "color"), {[1 0 0]; [0 1 0]; [0 0 1]});
+%!   cla (hax);
+%!   hold all;
+%!   h1 = plot (1:5,1:5,'o');
+%!   h2 = plot (1:4,1:4, "x");
+%!   h3 = plot (1:3,1:3, "d");
+%!   assert (get ([h1;h2;h3], "color"), {[1 0 0]; [0 1 0]; [0 0 1]});
+%! unwind_protect_cleanup
+%!   close (hf);
+%! end_unwind_protect
+
--- a/scripts/plot/util/__next_line_style__.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/plot/util/__next_line_style__.m	Fri Feb 06 08:31:49 2015 -0800
@@ -56,3 +56,23 @@
 
 endfunction
 
+
+%!test
+%! hf = figure ("visible", "off");
+%! unwind_protect
+%!   hax = axes ();
+%!   set (hax, "colororder", [0 0 1]);
+%!   set (hax, "linestyleorder", {"-", ":", "--"});
+%!   hold on;
+%!   h = plot (1:5,1:5, 1:4,1:4, 1:3,1:3);
+%!   assert (get (h, "linestyle"), {"-"; ":"; "--"});
+%!   cla (hax);
+%!   hold all;
+%!   h1 = plot (1:5,1:5);
+%!   h2 = plot (1:4,1:4);
+%!   h3 = plot (1:3,1:3);
+%!   assert (get ([h1;h2;h3], "linestyle"), {"-"; ":"; "--"});
+%! unwind_protect_cleanup
+%!   close (hf);
+%! end_unwind_protect
+
--- a/scripts/plot/util/__pltopt__.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/plot/util/__pltopt__.m	Fri Feb 06 08:31:49 2015 -0800
@@ -233,3 +233,39 @@
 
 endfunction
 
+
+## Only cursory testing.  Real testing done by appearance of plots.
+%test
+%! opts = __pltopt__ ("abc", "");
+%! assert (opts.color, []);
+%! assert (opts.linestyle, []);
+%! assert (opts.marker, []);
+%! assert (opts.key, "");
+%!test
+%! opts = __pltopt__ ("abc", "r:x");
+%! assert (opts.color, [1 0 0]);
+%! assert (opts.linestyle, ":");
+%! assert (opts.marker, "x");
+%!test
+%! opts = __pltopt__ ("abc", "2square");
+%! assert (opts.color, [0 1 0]);
+%! assert (opts.linestyle, "none");
+%! assert (opts.marker, "s");
+%!test
+%! opts = __pltopt__ ("abc", ";Title;");
+%! assert (opts.key, "Title");
+%! assert (opts.color, []);
+%! assert (opts.linestyle, []);
+%! assert (opts.marker, []);
+%!test
+%! opts = __pltopt__ ("__errplot__", "~>r");
+%! assert (opts.errorstyle, "~>");
+%! assert (opts.color, [1 0 0 ]);
+%! assert (opts.linestyle, []);
+%! assert (opts.marker, []);
+
+## Test input validation
+%!error <argument must be a character string or cell array> __pltopt__ ("abc", 1)
+%!error <unfinished key label> __pltopt__ ("abc", "rx;my_title", true)
+%!error <unrecognized format character: 'u'> __pltopt__ ("abc", "u", true)
+
--- a/scripts/plot/util/close.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/plot/util/close.m	Fri Feb 06 08:31:49 2015 -0800
@@ -105,5 +105,4 @@
 %!error <first argument must be "all" or a figure> close ({"all"})
 %!error <first argument must be "all" or a figure> close ("all_and_more")
 %!error <first argument must be "all" or a figure> close (-1)
-%!error <expecting argument to be "all hidden"> close "all" hid"
-
+%!error <expecting argument to be "all hidden"> close all hid
--- a/scripts/plot/util/colstyle.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/plot/util/colstyle.m	Fri Feb 06 08:31:49 2015 -0800
@@ -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 Feb 06 08:31:09 2015 -0800
+++ b/scripts/plot/util/copyobj.m	Fri Feb 06 08:31:49 2015 -0800
@@ -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 ();
@@ -134,8 +148,8 @@
 %!   s1 = hdl2struct (h1);
 %!   h2 = struct2hdl (s1);
 %!   s2 = hdl2struct (h2);
-%!   png1 = strcat (tmpnam (), ".png");
-%!   png2 = strcat (tmpnam (), ".png");
+%!   png1 = [tempname() ".png"];
+%!   png2 = [tempname() ".png"];
 %!   unwind_protect
 %!     print (h1, png1);
 %!     [img1, map1, alpha1] = imread (png1);
@@ -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/figure.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/plot/util/figure.m	Fri Feb 06 08:31:49 2015 -0800
@@ -83,16 +83,7 @@
   endif
 
   if (init_new_figure)
-    if (ismac () && strcmp (graphics_toolkit (), "fltk"))
-      ## FIXME: Hack for fltk-aqua to work around bug #31931
-      f = __go_figure__ (f);
-      drawnow ();
-      if (! isempty (varargin))
-        set (f, varargin{:});
-      endif
-    else
-      f = __go_figure__ (f, varargin{:});
-    endif
+    f = __go_figure__ (f, varargin{:});
     __add_default_menu__ (f);
   elseif (nargs > 0)
     set (f, varargin{:});
--- a/scripts/plot/util/findall.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/plot/util/findall.m	Fri Feb 06 08:31:49 2015 -0800
@@ -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/findobj.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/plot/util/findobj.m	Fri Feb 06 08:31:49 2015 -0800
@@ -100,9 +100,6 @@
         if (strcmpi (varargin{n1}, "flat"))
           depth = 0;
           n1 = n1 + 1;
-        elseif (strcmpi (varargin{n1}, "-depth"))
-          depth = varargin{n1+1};
-          n1 = n1 + 2;
         endif
       else
         error ("findobj: properties and options must be strings");
@@ -119,6 +116,7 @@
   regularexpression = [];
   property          = [];
   logicaloperator   = {};
+  extranegation     = [];
   pname             = {};
   pvalue            = {};
   np = 1;
@@ -128,9 +126,23 @@
   while (na <= numel (args))
     regularexpression(np) = 0;
     property(np) = 0;
+    if (numel (extranegation) < np)
+      extranegation(np) = false;
+    endif
     logicaloperator{np} = "and";
     if (ischar (args{na}))
-      if (strcmpi (args{na}, "-regexp"))
+      if (strcmpi (args{na}, "-property"))
+        if (na + 1 <= numel (args))
+          na = na + 1;
+          property(np) = 1;
+          pname{np} = args{na};
+          na = na + 1;
+          pvalue{np} = [];
+          np = np + 1;
+        else
+          error ("findobj: inconsistent number of arguments");
+        endif
+      elseif (strcmpi (args{na}, "-regexp"))
         if (na + 2 <= numel (args))
           regularexpression(np) = 1;
           na = na + 1;
@@ -142,14 +154,11 @@
         else
           error ("findobj: inconsistent number of arguments");
         endif
-      elseif (strcmpi (args{na}, "-property"))
+      elseif (strcmpi (args{na}, "-depth"))
         if (na + 1 <= numel (args))
           na = na + 1;
-          property(np) = 1;
-          pname{np} = args{na};
+          depth = args{na};
           na = na + 1;
-          pvalue{np} = [];
-          np = np + 1;
         else
           error ("findobj: inconsistent number of arguments");
         endif
@@ -177,10 +186,8 @@
           error ("findobj: inconsistent number of arguments");
         endif
       else
-        ## This is sloppy ... but works like Matlab.
         if (strcmpi (args{na}, "-not"))
-          h = [];
-          return;
+          extranegation(np) = true;
         endif
         na = na + 1;
       endif
@@ -241,6 +248,9 @@
         else
           match(nh,np) = false;
         endif
+        if (extranegation(np))
+          match(nh,np) = ! match(nh,np);
+        endif
       endfor
     endfor
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/plot/util/frame2im.m	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,105 @@
+## Copyright (C) 2014 Carnë Draug
+##
+## 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{x}, @var{map}] =} frame2im (@var{f})
+## Convert movie frame to indexed image.
+##
+## A movie frame is simply a struct with the fields @qcode{"cdata"} and
+## @qcode{"colormap"}.
+##
+## Support for N-dimensional images or movies is given when @var{f} is a
+## struct array.  In such cases, @var{x} will be a @nospell{MxNx1xK or MxNx3xK}
+## for indexed and RGB movies respectively, with each frame concatenated on
+## the 4th dimension.
+##
+## @seealso{im2frame}
+## @end deftypefn
+
+## Author: Carnë Draug <carandraug@octave.org>
+
+function [x, map] = frame2im (frame)
+
+  if (nargin != 1)
+    print_usage ();
+  elseif (! all (isfield (frame, {"cdata", "colormap"})))
+    error ("frame2im: F must be a struct with the fields colormap and cdata");
+  endif
+
+  n = numel (frame);
+  if (n == 0)
+    error ("frame2im: FRAME is empty");
+  else
+    x   = [frame.cdata];
+    map = frame(1).colormap;
+  endif
+
+  ## support for N dimensional images if we receive a struct array
+  if (n > 1)
+    x = reshape (x, rows (x), columns (x) / n, n, size (frame(1).cdata, 3));
+    x = permute (x, [1 2 4 3]);
+  endif
+
+endfunction
+
+%!function f = make_rgb_f ()
+%! f = randi ([0 255], 10, 20, 3);
+%!endfunction
+
+%!function f = make_ind_f ()
+%! f = randi ([1 100], 10, 20, 3);
+%!endfunction
+
+%!test
+%! x = make_ind_f ();
+%! cmap = jet (100);
+%! frame = struct ("cdata", x, "colormap", cmap);
+%! [rx, rcmap] = frame2im (frame);
+%! assert (rx, x);
+%! assert (rcmap, cmap);
+
+%!test
+%! rgb = make_rgb_f ();
+%! frame = struct ("cdata", rgb, "colormap", []);
+%! [rrgb, rcmap] = frame2im (frame);
+%! assert (rrgb, rgb);
+%! assert (rcmap, []);
+
+%!test
+%! f1 = make_rgb_f ();
+%! f2 = make_rgb_f ();
+%! f3 = make_rgb_f ();
+%! f4 = make_rgb_f ();
+%! rgb = {f1, f2, f3, f4};
+%! movie = struct ("cdata", rgb, "colormap", []);
+%! [rx, rcmap] = frame2im (movie);
+%! assert (rx, cat (4, f1, f2, f3, f4));
+%! assert (rcmap, []);
+
+%!test
+%! f1 = make_ind_f ();
+%! f2 = make_ind_f ();
+%! f3 = make_ind_f ();
+%! f4 = make_ind_f ();
+%! ind = {f1, f2, f3, f4};
+%! cmap = jet (100);
+%! movie = struct ("cdata", ind, "colormap", cmap);
+%! [rx, rcmap] = frame2im (movie);
+%! assert (rx, cat (4, f1, f2, f3, f4));
+%! assert (rcmap, cmap);
+
--- a/scripts/plot/util/ginput.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/plot/util/ginput.m	Fri Feb 06 08:31:49 2015 -0800
@@ -39,16 +39,15 @@
     print_usage ();
   endif
 
-  f = gcf ();
   a = gca ();  # Create an axis, if necessary
   drawnow ();
-  toolkit = get (f, "__graphics_toolkit__");
+  toolkit = get (gcf, "__graphics_toolkit__");
 
   varargout = cell (1, nargout);
   if (nargin == 0)
-    [varargout{:}] = feval (["__" toolkit "_ginput__"], f);
+    [varargout{:}] = feval (["__" toolkit "_ginput__"]);
   else
-    [varargout{:}] = feval (["__" toolkit "_ginput__"], f, n);
+    [varargout{:}] = feval (["__" toolkit "_ginput__"], n);
   endif
 
 endfunction
--- a/scripts/plot/util/graphics_toolkit.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/plot/util/graphics_toolkit.m	Fri Feb 06 08:31:49 2015 -0800
@@ -44,6 +44,17 @@
 
   if (nargout > 0 || nargin == 0)
     retval = get (0, "defaultfigure__graphics_toolkit__");
+    ## Handle case where graphics_toolkit has been called before any plotting
+    if (isempty (retval))
+      toolkits = available_graphics_toolkits ();
+      if (any (strcmp ("qt", toolkits)))
+        retval = "qt";
+      elseif (any (strcmp ("fltk", toolkits)))
+        retval = "fltk";
+      elseif (! isempty (toolkits))
+        retval = toolkits{1};
+      endif
+    endif
   endif
 
   if (nargin == 0)
--- a/scripts/plot/util/hdl2struct.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/plot/util/hdl2struct.m	Fri Feb 06 08:31:49 2015 -0800
@@ -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 Feb 06 08:31:49 2015 -0800
@@ -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 Feb 06 08:31:49 2015 -0800
@@ -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 = [tempname() ".ofig"];
+%!   png1 = [tempname() ".png"];
+%!   png2 = [tempname() ".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")
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/plot/util/im2frame.m	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,101 @@
+## Copyright (C) 2014 Carnë Draug
+##
+## 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} {} im2frame (@var{rgb})
+## @deftypefnx {Function File} {} im2frame (@var{x}, @var{map})
+## Convert image to movie frame.
+##
+## A movie frame is simply a struct with the fields @qcode{"cdata"} and
+## @qcode{"colormap"}.
+##
+## Support for N-dimensional images is given when each image projection,
+## matrix sizes of @nospell{MxN and MxNx3} for RGB images, is concatenated on
+## the fourth dimension.  In such cases, the returned value is a struct array.
+##
+## @seealso{frame2im}
+## @end deftypefn
+
+## Author: Carnë Draug <carandraug@octave.org>
+
+function [frame] = im2frame (x, map = [])
+
+  if (nargin < 1 || nargin > 2)
+    print_usage ();
+  elseif (ndims (x) > 4)
+    error ("im2frame: X and RGB must be a single image");
+  endif
+
+  ## Matlab documentation is incorrect.  Singleton 3rd dimension will error
+  ## without cmap (no use of default cmap), and cmap is added to the frame
+  ## even when image is RGB.
+
+  nchannels = size (x, 3);
+  if (nchannels == 3)
+    ## RGB image, do nothing
+  elseif (nchannels == 1)
+    if (nargin < 2)
+      error ("im2frame: MAP required for indexed images");
+    endif
+    [x, map] = ind2x ("im2frame", x, map);
+  else
+    error ("im2frame: first argument must be indexed or RGB image");
+  endif
+
+  ## support N dimensional images and return a struct array
+  if (ndims (x) == 4)
+    x = reshape (num2cell (x, [1 2 3]), 1, size (x, 4));
+  endif
+
+  frame = struct ("cdata", x, "colormap", map);
+endfunction
+
+%!function f = make_rgb_f ()
+%! f = randi ([0 255], 10, 20, 3);
+%!endfunction
+
+%!function f = make_ind_f ()
+%! f = randi ([1 100], 10, 20, 3);
+%!endfunction
+
+%!test
+%! rgb = make_rgb_f ();
+%! assert (im2frame (rgb), struct ("cdata", rgb, "colormap", []));
+
+%!test
+%! ind = make_ind_f ();
+%! cmap = bone (100);
+%! assert (im2frame (ind, cmap), struct ("cdata", ind, "colormap", cmap));
+
+%!test
+%! rgb1 = make_rgb_f ();
+%! rgb2 = make_rgb_f ();
+%! rgb3 = make_rgb_f ();
+%! rgb4 = make_rgb_f ();
+%! assert (im2frame (cat (4, rgb1, rgb2, rgb3, rgb4)),
+%!         struct ("cdata", {rgb1, rgb2, rgb3, rgb4}, "colormap", []));
+
+%!test
+%! ind1 = make_ind_f ();
+%! ind2 = make_ind_f ();
+%! ind3 = make_ind_f ();
+%! ind4 = make_ind_f ();
+%! cmap = bone (100);
+%! assert (im2frame (cat (4, ind1, ind2, ind3, ind4), cmap),
+%!         struct ("cdata", {ind1, ind2, ind3, ind4}, "colormap", cmap));
+
--- a/scripts/plot/util/isprop.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/plot/util/isprop.m	Fri Feb 06 08:31:49 2015 -0800
@@ -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 Feb 06 08:31:49 2015 -0800
@@ -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 Feb 06 08:31:09 2015 -0800
+++ b/scripts/plot/util/linkprop.m	Fri Feb 06 08:31:49 2015 -0800
@@ -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 Feb 06 08:31:09 2015 -0800
+++ b/scripts/plot/util/module.mk	Fri Feb 06 08:31:49 2015 -0800
@@ -8,7 +8,6 @@
 plot_util_PRIVATE_FCN_FILES = \
   plot/util/private/__add_default_menu__.m \
   plot/util/private/__fltk_ginput__.m \
-  plot/util/private/__fltk_print__.m \
   plot/util/private/__ghostscript__.m \
   plot/util/private/__gnuplot_get_var__.m \
   plot/util/private/__gnuplot_ginput__.m \
@@ -19,6 +18,7 @@
   plot/util/private/__gnuplot_version__.m \
   plot/util/private/__go_draw_axes__.m \
   plot/util/private/__go_draw_figure__.m \
+  plot/util/private/__opengl_print__.m \
   plot/util/private/__print_parse_opts__.m \
   plot/util/private/__tight_eps_bbox__.m
 
@@ -38,6 +38,7 @@
   plot/util/findall.m \
   plot/util/findfigs.m \
   plot/util/findobj.m \
+  plot/util/frame2im.m \
   plot/util/gca.m \
   plot/util/gcbf.m \
   plot/util/gcbo.m \
@@ -48,28 +49,36 @@
   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/im2frame.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/rotate.m \
+  plot/util/rotate3d.m \
   plot/util/saveas.m \
   plot/util/shg.m \
   plot/util/struct2hdl.m \
   plot/util/subplot.m \
+  plot/util/zoom.m \
   $(plot_util_PRIVATE_FCN_FILES)
 
 FCN_FILES += $(plot_util_FCN_FILES)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/plot/util/pan.m	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,78 @@
+## 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, zoom}
+## @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 Feb 06 08:31:09 2015 -0800
+++ b/scripts/plot/util/print.m	Fri Feb 06 08:31:49 2015 -0800
@@ -284,7 +284,7 @@
 ## @end group
 ## @end example
 ##
-## @seealso{saveas, orient, figure}
+## @seealso{saveas, hgsave, orient, figure}
 ## @end deftypefn
 
 function print (varargin)
@@ -306,7 +306,7 @@
 
   if (opts.append_to_file)
     [~, ~, ext] = fileparts (opts.ghostscript.output);
-    opts.ghostscript.prepend = strcat (tmpnam (), ext);
+    opts.ghostscript.prepend = [tempname() ext];
     copyfile (opts.ghostscript.output, opts.ghostscript.prepend);
   endif
 
@@ -428,7 +428,7 @@
       case "gnuplot"
         opts = __gnuplot_print__ (opts);
       otherwise
-        opts = __fltk_print__ (opts);
+        opts = __opengl_print__ (opts);
     endswitch
 
   unwind_protect_cleanup
@@ -484,7 +484,7 @@
 
   if (nargin < 2 || strcmp (filein, "-") || isempty (filein))
     pipein = true;
-    filein = strcat (tmpnam (), ".eps");
+    filein = [tempname() ".eps"];
     if (dos_shell)
       cleanup = sprintf ("& del %s ", strrep (filein, '/', '\'));
     else
@@ -496,7 +496,7 @@
   endif
   if (strcmp (fileout, "-"))
     pipeout = true;
-    fileout = strcat (tmpnam (), ".eps");
+    fileout = [tempname() ".eps"];
     if (dos_shell)
       cleanup = horzcat (cleanup, sprintf ("& del %s ", strrep (fileout, '/', '\')));
     else
@@ -619,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);
@@ -717,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 Feb 06 08:31:09 2015 -0800
+++ b/scripts/plot/util/printd.m	Fri Feb 06 08:31:49 2015 -0800
@@ -44,7 +44,7 @@
     error ("The output filename: %s requires a suffix.\nOptions are: pdf ps eps txt jpg jpeg", filename);
   endif
   opt = substr (filename, sufix+1);
-  [pf, tempf, mag] = mkstemp ("oct-XXXXXX", 1);  # Safe version of tmpnam()
+  [pf, tempf, mag] = mkstemp ("oct-XXXXXX", 1);
   fprintf (pf, "%s", disp (obj));
   frewind (pf);
 
@@ -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 Feb 06 08:31:09 2015 -0800
+++ b/scripts/plot/util/private/__add_default_menu__.m	Fri Feb 06 08:31:49 2015 -0800
@@ -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/__fltk_ginput__.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/plot/util/private/__fltk_ginput__.m	Fri Feb 06 08:31:49 2015 -0800
@@ -17,15 +17,15 @@
 ## <http://www.gnu.org/licenses/>.
 
 ## -*- texinfo -*-
-## @deftypefn {Function File} {[@var{x}, @var{y}, @var{buttons}] =} __fltk_ginput__ (@var{f}, @var{n})
+## @deftypefn {Function File} {[@var{x}, @var{y}, @var{buttons}] =} __fltk_ginput__ (@var{n})
 ## Undocumented internal function.
 ## @end deftypefn
 
 ## This is ginput.m implementation for fltk.
 
-function [x, y, button] = __fltk_ginput__ (f, n = -1)
+function [x, y, button] = __fltk_ginput__ (n = -1)
 
-  if (isempty (get (f, "currentaxes")))
+  if (isempty (gca))
     error ("ginput: must have at least one axes");
   endif
 
@@ -34,14 +34,14 @@
 
   unwind_protect
 
-    orig_windowbuttondownfcn = get (f, "windowbuttondownfcn");
-    set (f, "windowbuttondownfcn", @ginput_windowbuttondownfcn);
+    orig_buttondownfcn = get (gca, "buttondownfcn");
+    set (gca, "buttondownfcn", @ginput_buttondownfcn);
 
-    orig_ginput_keypressfcn = get (f, "keypressfcn");
-    set (f, "keypressfcn", @ginput_keypressfcn);
+    orig_ginput_keypressfcn = get (gcf, "keypressfcn");
+    set (gcf, "keypressfcn", @ginput_keypressfcn);
 
     do
-      __fltk_redraw__ ();
+      __fltk_check__ ();
 
       ## Release CPU.
       sleep (0.01);
@@ -57,8 +57,8 @@
     endif
 
   unwind_protect_cleanup
-    set (f, "windowbuttondownfcn", orig_windowbuttondownfcn);
-    set (f, "keypressfcn", orig_ginput_keypressfcn);
+    set (gca, "buttondownfcn", orig_buttondownfcn);
+    set (gcf, "keypressfcn", orig_ginput_keypressfcn);
   end_unwind_protect
 
 endfunction
@@ -83,20 +83,19 @@
 
 endfunction
 
-function ginput_windowbuttondownfcn (src, data)
-  point = get (get (src,"currentaxes"), "currentpoint");
-  button = data;
-  ginput_accumulator (1, point(1,1), point(2,1), button);
+function ginput_buttondownfcn (src, button)
+  point = get (src, "currentpoint");
+  ginput_accumulator (1, point(1,1), point(1,2), button);
 endfunction
 
 function ginput_keypressfcn (src, evt)
-  point = get (get (src, "currentaxes"), "currentpoint");
+  point = get (gca, "currentpoint");
   key = evt.Key;
-  if (key == 10)
+  if (key == "return")
     ## Enter key stops ginput.
     ginput_accumulator (2, NaN, NaN, NaN);
   else
-    ginput_accumulator (1, point(1,1), point(2,1), key);
+    ginput_accumulator (1, point(1,1), point(1,2), uint8 (key(1)));
   endif
 endfunction
 
--- a/scripts/plot/util/private/__fltk_print__.m	Fri Feb 06 08:31:09 2015 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,174 +0,0 @@
-## Copyright (C) 2010-2013 Shai Ayal
-##
-## 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} {} __fltk_print__ (@var{@dots{}})
-## Undocumented internal function.
-## @end deftypefn
-
-function opts = __fltk_print__ (opts)
-
-  dos_shell = (ispc () && ! isunix ());
-
-  set (0, "currentfigure", opts.figure);
-  drawnow ("expose");
-  __fltk_redraw__ ();
-
-  if (! isempty (opts.fig2dev_binary))
-    ## fig2dev is prefered for conversion to emf
-    fig2dev_devices = {"pstex", "mf", "emf"};
-  else
-    fig2dev_devices = {"pstex", "mf"};
-  endif
-
-  gl2ps_device = {};
-  pipeline = {};
-  switch (lower (opts.devopt))
-    case {"eps", "eps2", "epsc", "epsc2"}
-      ## format GL2PS_EPS
-      gl2ps_device = {"eps"};
-      ## FIXME: use epstool to tighten bbox and provide preview.
-      pipeline = {opts.epstool_cmd(opts, "-", opts.name)};
-    case {"epslatex", "pslatex", "pdflatex", "epslatexstandalone", ...
-          "pslatexstandalone", "pdflatexstandalone"}
-      ## format GL2PS_TEX
-      n = find (opts.devopt == "l", 1);
-      suffix = opts.devopt(1:n-1);
-      dot = find (opts.name == ".", 1, "last");
-      if ((! isempty (dot))
-          && any (strcmpi (opts.name(dot:end), ...
-                  {strcat(".", suffix), ".tex", "."})))
-        name = opts.name(1:dot-1);
-        if (dot < numel (opts.name)
-            && any (strcmpi (opts.name(dot+1:end), {"eps", "ps", "pdf"})))
-          ## If user provides eps/ps/pdf suffix, use it.
-          suffix = opts.name(dot+1:end);
-        endif
-      else
-        error ("print:invalid-suffix",
-               "invalid suffix '%s' for device '%s'.",
-               opts.name(dot:end), lower (opts.devopt));
-      endif
-      gl2ps_device = {sprintf("%snotxt", lower (suffix))};
-      gl2ps_device{2} = "tex";
-      if (dos_shell)
-        ## FIXME: this will only work on MinGW with the MSYS shell
-        pipeline = {sprintf("cat > %s-inc.%s", name, suffix)};
-        pipeline{2} = sprintf ("cat > %s.tex", name);
-      else
-        pipeline = {sprintf("cat > %s-inc.%s", name, suffix)};
-        pipeline{2} = sprintf ("cat > %s.tex", name);
-      endif
-    case "tikz"
-      ## format GL2PS_PGF
-      gl2ps_device = {"pgf"};
-      pipeline = {sprintf("cat > %s", opts.name)};
-    case "svg"
-      ## format GL2PS_SVG
-      gl2ps_device = {"svg"};
-      pipeline = {sprintf("cat > %s", opts.name)};
-    case fig2dev_devices
-      cmd_pstoedit = opts.pstoedit_cmd (opts, "fig");
-      cmd_fig2dev = opts.fig2dev_cmd (opts, opts.devopt);
-      if (strcmp (opts.devopt, "pstex"))
-        [~, ~, ext] = fileparts (opts.name);
-        if (any (strcmpi (ext, {".ps", ".tex", "."})))
-          opts.name = opts.name(1:end-numel(ext));
-        endif
-        opts.name = strcat (opts.name, ".ps");
-        cmd = sprintf ("%s | %s > %s", cmd_pstoedit, cmd_fig2dev, opts.name);
-        gl2ps_device = {"eps"};
-        pipeline = {cmd};
-        cmd_fig2dev = opts.fig2dev_cmd (opts, "pstex_t");
-        gl2ps_device{2} = "eps";
-        pipeline{2} = sprintf ("%s | %s > %s", cmd_pstoedit,
-                               cmd_fig2dev, strrep(opts.name, ".ps", ".tex"));
-      else
-        cmd = sprintf ("%s | %s > %s", cmd_pstoedit, cmd_fig2dev, opts.name);
-        gl2ps_device = {"eps"};
-        pipeline = {cmd};
-      endif
-    case "aifm"
-      cmd = opts.pstoedit_cmd (opts, "ps2ai");
-      gl2ps_device = {"eps"};
-      pipeline = {sprintf("%s > %s", cmd, opts.name)};
-    case {"dxf", "emf", "fig", "hpgl"}
-      cmd = opts.pstoedit_cmd (opts);
-      gl2ps_device = {"eps"};
-      pipeline = {sprintf("%s > %s", cmd, opts.name)};
-    case {"corel", "gif"}
-      error ("print:unsupporteddevice",
-             "print.m: %s output is not available for the FLTK graphics toolkit",
-             upper (opts.devopt));
-    case opts.ghostscript.device
-      opts.ghostscript.source = "-";
-      opts.ghostscript.output = opts.name;
-      if (opts.send_to_printer)
-        opts.unlink(strcmp (opts.unlink, opts.ghostscript.output)) = [];
-        opts.ghostscript.output = "-";
-      endif
-      [cmd_gs, cmd_cleanup] = __ghostscript__ (opts.ghostscript);
-      if (opts.send_to_printer || isempty (opts.name))
-        cmd_lpr = opts.lpr_cmd (opts);
-        cmd = sprintf ("%s | %s", cmd_gs, cmd_lpr);
-      else
-        cmd = sprintf ("%s", cmd_gs);
-      endif
-      if (! isempty (cmd_cleanup))
-        gl2ps_device = {"eps"};
-        if (dos_shell)
-          pipeline = {sprintf("%s & %s", cmd, cmd_cleanup)};
-        else
-          pipeline = {sprintf("%s ; %s", cmd, cmd_cleanup)};
-        endif
-      else
-        gl2ps_device = {"eps"};
-        pipeline = {cmd};
-      endif
-    otherwise
-      error (sprintf ("print:no%soutput", opts.devopt),
-             "print.m: %s output is not available for GL2PS output",
-             upper (opts.devopt));
-  endswitch
-
-  opts.pipeline = pipeline;
-
-  ## Tell gl2ps to use different rendering options for 2D plots
-  haxes = findall (opts.figure, "type", "axes");
-  vw = get (haxes, "view");
-  if (iscell (vw))
-    vw = vertcat (vw{:});
-  endif
-  is2D = all (abs (vw(:,2)) == 90);
-  if (is2D)
-    gl2ps_device{end} = [gl2ps_device{end}, "is2D"];
-  endif
-
-  for n = 1:numel (pipeline)
-    if (opts.debug)
-      fprintf ("fltk-pipeline: '%s'\n", pipeline{n});
-    endif
-    drawnow (gl2ps_device{n}, strcat ('|',pipeline{n}));
-  endfor
-
-  if (! isempty (strfind (opts.devopt, "standalone")))
-    opts.latex_standalone (opts);
-  endif
-
-endfunction
-
--- a/scripts/plot/util/private/__ghostscript__.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/plot/util/private/__ghostscript__.m	Fri Feb 06 08:31:49 2015 -0800
@@ -112,7 +112,7 @@
       offsetfile = opts.offsetfile;
       cleanup_cmd = "";
     else
-      offsetfile = strcat (tmpnam (), ".ps");
+      offsetfile = [tempname() ".ps"];
       cleanup_cmd = sprintf ("rm %s", offsetfile);
     endif
     unwind_protect
@@ -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/__gnuplot_get_var__.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/plot/util/private/__gnuplot_get_var__.m	Fri Feb 06 08:31:49 2015 -0800
@@ -50,7 +50,7 @@
   endif
 
   if (use_mkfifo)
-    gpin_name = tmpnam ();
+    gpin_name = tempname ();
 
     ## Mode: 0600 == 6*8*8
     [err, msg] = mkfifo (gpin_name, 6*8*8);
--- a/scripts/plot/util/private/__gnuplot_ginput__.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/plot/util/private/__gnuplot_ginput__.m	Fri Feb 06 08:31:49 2015 -0800
@@ -61,7 +61,7 @@
   endif
 
   if (use_mkfifo)
-    gpin_name = tmpnam ();
+    gpin_name = tempname ();
 
     ##Mode: 6*8*8 ==  0600
     [err, msg] = mkfifo (gpin_name, 6*8*8);
--- a/scripts/plot/util/private/__gnuplot_print__.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/plot/util/private/__gnuplot_print__.m	Fri Feb 06 08:31:49 2015 -0800
@@ -54,7 +54,7 @@
         gp_opts = [gp_opts " level1"];
       endif
       if (opts.tight_flag || ! isempty (opts.preview))
-        tmp_file = strcat (tmpnam (), ".eps");
+        tmp_file = [tempname() ".eps"];
         eps_drawnow (opts, tmp_file, gp_opts);
         if (dos_shell)
           cleanup = [" & del " strrep(tmp_file, '/', '\')];
@@ -119,7 +119,7 @@
     case opts.ghostscript.device
       gp_opts = font_spec (opts, "devopt", "eps");
       opts.ghostscript.output = opts.name;
-      opts.ghostscript.source = strcat (tmpnam (), ".eps");
+      opts.ghostscript.source = [tempname() ".eps"];
       eps_drawnow (opts, opts.ghostscript.source, gp_opts);
       [cmd_gs, cmd_cleanup] = __ghostscript__ (opts.ghostscript);
       if (opts.send_to_printer || isempty (opts.name))
--- a/scripts/plot/util/private/__go_draw_axes__.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/plot/util/private/__go_draw_axes__.m	Fri Feb 06 08:31:49 2015 -0800
@@ -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");
@@ -153,10 +153,11 @@
     if (isempty (t.string))
       fputs (plot_stream, "unset title;\n");
     else
+      colorspec = get_text_colorspec (t.color, mono);
       [tt, f, s] = __maybe_munge_text__ (enhanced, t, "string");
       fontspec = create_fontspec (f, s, gnuplot_term);
-      fprintf (plot_stream, "set title \"%s\" %s %s;\n",
-               undo_string_escapes (tt), fontspec,
+      fprintf (plot_stream, "set title \"%s\" %s %s %s;\n",
+               undo_string_escapes (tt), fontspec, colorspec,
                __do_enhanced_option__ (enhanced, t));
     endif
   endif
@@ -164,7 +165,7 @@
   if (! isempty (axis_obj.xlabel))
     t = get (axis_obj.xlabel);
     angle = t.rotation;
-    colorspec = get_text_colorspec (axis_obj.xcolor, mono);
+    colorspec = get_text_colorspec (t.color, mono);
     if (isempty (t.string))
       fprintf (plot_stream, "unset xlabel;\n");
       fprintf (plot_stream, "unset x2label;\n");
@@ -192,7 +193,7 @@
   if (! isempty (axis_obj.ylabel))
     t = get (axis_obj.ylabel);
     angle = t.rotation;
-    colorspec = get_text_colorspec (axis_obj.ycolor, mono);
+    colorspec = get_text_colorspec (t.color, mono);
     if (isempty (t.string))
       fprintf (plot_stream, "unset ylabel;\n");
       fprintf (plot_stream, "unset y2label;\n");
@@ -220,7 +221,7 @@
   if (! isempty (axis_obj.zlabel))
     t = get (axis_obj.zlabel);
     angle = t.rotation;
-    colorspec = get_text_colorspec (axis_obj.zcolor, mono);
+    colorspec = get_text_colorspec (t.color, mono);
     if (isempty (t.string))
       fputs (plot_stream, "unset zlabel;\n");
     else
@@ -323,9 +324,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
 
@@ -512,6 +513,9 @@
           img_ydata = img_ydata(1) + [0, rows(img_data)-1];
         endif
 
+        x_origin = min (img_xdata);
+        y_origin = min (img_ydata);
+
         [y_dim, x_dim] = size (img_data(:,:,1));
         if (x_dim > 1)
           dx = abs (img_xdata(2)-img_xdata(1))/(x_dim-1);
@@ -519,6 +523,11 @@
           x_dim = 2;
           img_data = [img_data, img_data];
           dx = abs (img_xdata(2)-img_xdata(1));
+          if (dx < 1)
+            ## Correct gnuplot string for 1-D images
+            dx       = 0.5;
+            x_origin = 0.75;
+          endif
         endif
         if (y_dim > 1)
           dy = abs (img_ydata(2)-img_ydata(1))/(y_dim-1);
@@ -526,11 +535,13 @@
           y_dim = 2;
           img_data = [img_data; img_data];
           dy = abs (img_ydata(2)-img_ydata(1));
+          if (dy < 1)
+            ## Correct gnuplot string for 1-D images
+            dy       = 0.5;
+            y_origin = 0.75;
+          endif
         endif
 
-        x_origin = min (img_xdata);
-        y_origin = min (img_ydata);
-
         if (ndims (img_data) == 3)
           data{data_idx} = permute (img_data, [3, 1, 2])(:);
           format = "1:2:3";
@@ -561,7 +572,9 @@
         if (isempty (obj.displayname))
           titlespec{data_idx} = "title \"\"";
         else
-          tmp = undo_string_escapes (__maybe_munge_text__ (enhanced, obj, "displayname"));
+          tmp = undo_string_escapes (
+                  __maybe_munge_text__ (enhanced, obj, "displayname")
+                );
           titlespec{data_idx} = ['title "' tmp '"'];
         endif
         usingclause{data_idx} = sprintf ("record=%d", numel (obj.xdata));
@@ -575,14 +588,17 @@
             zdat = zeros (size (xdat));
           endif
           data{data_idx} = [xdat, ydat, zdat]';
-          usingclause{data_idx} = sprintf ("record=%d using ($1):($2):($3)", numel (xdat));
+          usingclause{data_idx} = sprintf ("record=%d using ($1):($2):($3)",
+                                           numel (xdat));
+          hidden_removal = false;
           ## fputs (plot_stream, "set parametric;\n");
         else
           xdat = obj.xdata(:);
           ydat = obj.ydata(:);
           data{data_idx} = [xdat, ydat]';
-          usingclause{data_idx} = sprintf ("record=%d using ($1):($2) axes %s%s",
-                                          rows (xdat), xaxisloc_using, yaxisloc_using);
+          usingclause{data_idx} = ...
+            sprintf ("record=%d using ($1):($2) axes %s%s",
+                     rows (xdat), xaxisloc_using, yaxisloc_using);
         endif
 
         style = do_linestyle_command (obj, obj.color, data_idx, mono,
@@ -680,7 +696,9 @@
              if (i > 1 || isempty (obj.displayname))
                titlespec{local_idx} = "title \"\"";
              else
-               tmp = undo_string_escapes (__maybe_munge_text__ (enhanced, obj, "displayname"));
+               tmp = undo_string_escapes (
+                       __maybe_munge_text__ (enhanced, obj, "displayname")
+                     );
                titlespec{local_idx} = ['title "' tmp '"'];
              endif
              if (isfield (obj, "facecolor"))
@@ -756,6 +774,8 @@
                if (isnan (ccdat))
                  ccdat = (rows (cmap) + rows (addedcmap) + 1) * ones(3, 1);
                  addedcmap = [addedcmap; reshape(color, 1, 3)];
+               elseif (numel (ccdat) <= 1)
+                 ccdat = zcol;
                endif
                data{data_3d_idx} = [data{data_3d_idx}, ...
                                     [[xcol; xcol(end)], [ycol; ycol(end)], ...
@@ -766,7 +786,7 @@
                elseif (__gnuplot_has_feature__ ("transparent_patches")
                        && isscalar (obj.facealpha))
                  colorspec = sprintf ("lc rgb \"#%02x%02x%02x\" fillstyle transparent solid %f",
-                                    round (255*color), obj.facealpha);
+                                      round (255*color), obj.facealpha);
                else
                  colorspec = sprintf ("lc rgb \"#%02x%02x%02x\"",
                                       round (255*color));
@@ -800,12 +820,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;
@@ -1116,7 +1135,9 @@
           if (isempty (obj.displayname))
             titlespec{data_idx} = "title \"\"";
           else
-            tmp = undo_string_escapes (__maybe_munge_text__ (enhanced, obj, "displayname"));
+            tmp = undo_string_escapes (
+                    __maybe_munge_text__ (enhanced, obj, "displayname")
+                  );
             titlespec{data_idx} = ['title "' tmp '"'];
           endif
           withclause{data_idx} = sprintf ("with pm3d linestyle %d",
@@ -1212,7 +1233,8 @@
           endif
 
           if (flat_interp_face && strcmp (obj.edgecolor, "flat"))
-            fprintf (plot_stream, "set pm3d explicit at s %s %s corners2color c3;\n",
+            fprintf (plot_stream,
+                     "set pm3d explicit at s %s %s corners2color c3;\n",
                      interp_str, dord);
           elseif (!facecolor_none_or_white)
             if (strcmp (obj.edgecolor, "none"))
@@ -1222,10 +1244,12 @@
                          "set style fill transparent solid %f;\n",
                          obj.facealpha);
               endif
-              fprintf (plot_stream, "set pm3d explicit at s %s corners2color c3;\n",
+              fprintf (plot_stream,
+                       "set pm3d explicit at s %s corners2color c3;\n",
                        interp_str, dord);
             else
-              fprintf (plot_stream, "set pm3d explicit at s hidden3d %d %s %s corners2color c3;\n",
+              fprintf (plot_stream,
+                       "set pm3d explicit at s hidden3d %d %s %s corners2color c3;\n",
                        data_idx, interp_str, dord);
 
               if (__gnuplot_has_feature__ ("transparent_surface")
@@ -1444,8 +1468,8 @@
             data{i}(end,:) = clim(2) * (data{i}(end, :) - 0.5) / cmap_sz;
            endif
         endfor
-        fprintf (plot_stream, "set cbrange [%.15e:%.15e];\n", clim(1), clim(2) *
-                 (cmap_sz + rows (addedcmap)) / cmap_sz);
+        fprintf (plot_stream, "set cbrange [%.15e:%.15e];\n",
+                 clim(1), clim(2) * (cmap_sz + rows (addedcmap)) / cmap_sz);
       else
         fprintf (plot_stream, "set cbrange [%.15e:%.15e];\n", clim);
       endif
@@ -1469,12 +1493,10 @@
         fprintf (plot_stream, "unset ytics; set y2tics %s nomirror\n",
                  axis_obj.tickdir);
         if (strcmpi (axis_obj.xaxislocation, "top"))
-          fprintf (plot_stream, "unset xtics; set x2tics %s nomirror\n",
-                   axis_obj.tickdir);
+          maybe_do_x2tick_mirror (plot_stream, axis_obj)
           fputs (plot_stream, "set border 12;\n");
         elseif (strcmpi (axis_obj.xaxislocation, "bottom"))
-          fprintf (plot_stream, "unset x2tics; set xtics %s nomirror\n",
-                   axis_obj.tickdir);
+          maybe_do_xtick_mirror (plot_stream, axis_obj)
           fputs (plot_stream, "set border 9;\n");
         else # xaxislocation == zero
           fprintf (plot_stream, "unset x2tics; set xtics %s nomirror\n",
@@ -1487,16 +1509,13 @@
         fprintf (plot_stream, "unset y2tics; set ytics %s nomirror\n",
                  axis_obj.tickdir);
         if (strcmpi (axis_obj.xaxislocation, "top"))
-          fprintf (plot_stream, "unset xtics; set x2tics %s nomirror\n",
-                   axis_obj.tickdir);
+          maybe_do_x2tick_mirror (plot_stream, axis_obj)
           fputs (plot_stream, "set border 6;\n");
         elseif (strcmpi (axis_obj.xaxislocation, "bottom"))
-          fprintf (plot_stream, "unset x2tics; set xtics %s nomirror\n",
-                   axis_obj.tickdir);
+          maybe_do_xtick_mirror (plot_stream, axis_obj)
           fputs (plot_stream, "set border 3;\n");
         else # xaxislocation == zero
-          fprintf (plot_stream, "unset x2tics; set xtics %s nomirror\n",
-                   axis_obj.tickdir);
+          maybe_do_xtick_mirror (plot_stream, axis_obj)
           fputs (plot_stream, "set border 2;\n");
           fprintf (plot_stream, "set xzeroaxis lt -1 lw %f;\n",
                    axis_obj.linewidth);
@@ -1505,18 +1524,15 @@
         fprintf (plot_stream, "unset y2tics; set ytics %s nomirror\n",
                  axis_obj.tickdir);
         if (strcmpi (axis_obj.xaxislocation, "top"))
-          fprintf (plot_stream, "unset xtics; set x2tics %s nomirror\n",
-                   axis_obj.tickdir);
+          maybe_do_x2tick_mirror (plot_stream, axis_obj)
           fputs (plot_stream, "set border 4;\n");
         elseif (strcmpi (axis_obj.xaxislocation, "bottom"))
-          fprintf (plot_stream, "unset x2tics; set xtics %s nomirror\n",
-                   axis_obj.tickdir);
+          maybe_do_xtick_mirror (plot_stream, axis_obj)
           fputs (plot_stream, "set border 1;\n");
         else # xaxislocation == zero
+          maybe_do_xtick_mirror (plot_stream, axis_obj)
           fprintf (plot_stream, "unset y2tics; set ytics %s nomirror\n",
                    axis_obj.tickdir);
-          fprintf (plot_stream, "unset x2tics; set xtics %s nomirror\n",
-                   axis_obj.tickdir);
           fputs (plot_stream, "unset border;\n");
           fprintf (plot_stream, "set xzeroaxis lt -1 lw %f;\n",
                    axis_obj.linewidth);
@@ -1587,9 +1603,10 @@
     endswitch
     if (__gnuplot_has_feature__ ("key_has_font_properties"))
       [fontname, fontsize] = get_fontname_and_size (hlgnd);
-      fontspec = create_fontspec (fontname, fontsize, gnuplot_term);
+      fontspacespec = [ create_spacingspec(fontname, fontsize, gnuplot_term),...
+                        create_fontspec(fontname, fontsize, gnuplot_term) ];
     else
-      fontspec = "";
+      fontspacespec = "";
     endif
     textcolors = get (findobj (hlgnd.children, "type", "text"), "color");
     if (iscell (textcolors))
@@ -1605,7 +1622,7 @@
       colorspec = get_text_colorspec (textcolors, mono);
     endif
     fprintf (plot_stream, "set key %s %s;\nset key %s %s %s %s %s %s;\n",
-             inout, pos, box, reverse, horzvert, fontspec, colorspec,
+             inout, pos, box, reverse, horzvert, fontspacespec, colorspec,
              __do_enhanced_option__ (enhanced, hlgnd));
   else
     fputs (plot_stream, "unset key;\n");
@@ -1614,7 +1631,7 @@
 
   cmap = [cmap; addedcmap];
   cmap_sz = cmap_sz + rows (addedcmap);
-  if (length (cmap) > 0)
+  if (mono == false && length (cmap) > 0)
     fprintf (plot_stream,
              "set palette positive color model RGB maxcolors %i;\n",
              cmap_sz);
@@ -1659,8 +1676,8 @@
       fprintf (plot_stream, "%s \"-\" %s %s %s \\\n", plot_cmd,
                usingclause{1}, titlespec{1}, withclause{1});
     else
-      fprintf (plot_stream, "%s \"-\" binary format='%%float64' %s %s %s \\\n", plot_cmd,
-               usingclause{1}, titlespec{1}, withclause{1});
+      fprintf (plot_stream, "%s \"-\" binary format='%%float64' %s %s %s \\\n",
+               plot_cmd, usingclause{1}, titlespec{1}, withclause{1});
     endif
     for i = 2:data_idx
       if (have_3d_patch (i))
@@ -1700,8 +1717,8 @@
           fputs (plot_stream, "unset obj 2; \\\n");
           fg_is_set = false;
         endif
-        fprintf (plot_stream, "%s \"-\" binary format='%%float64' %s %s %s \\\n", plot_cmd,
-                 usingclause{i}, titlespec{i}, withclause{i});
+        fprintf (plot_stream,"%s \"-\" binary format='%%float64' %s %s %s \\\n",
+                 plot_cmd, usingclause{i}, titlespec{i}, withclause{i});
       else
         fprintf (plot_stream, ", \"-\" binary format='%%float64' %s %s %s \\\n",
                  usingclause{i}, titlespec{i}, withclause{i});
@@ -1718,7 +1735,7 @@
             fputs (plot_stream, "\n\n");
           endif
           fprintf (plot_stream, "%.15g %.15g %.15g %.15g\n", data{i}(:,j).');
-          fprintf (plot_stream, "%.15g %.15g %.15g %.15g\n\n", data{i}(:,j+1).');
+          fprintf (plot_stream, "%.15g %.15g %.15g %.15g\n\n",data{i}(:,j+1).');
           fprintf (plot_stream, "%.15g %.15g %.15g %.15g\n", data{i}(:,j+2).');
           fprintf (plot_stream, "%.15g %.15g %.15g %.15g\n", data{i}(:,j+3).');
         endfor
@@ -1758,6 +1775,18 @@
   endif
 endfunction
 
+function spacing_spec = create_spacingspec (f, s, gp_term)
+  # The gnuplot default font size is 10, and default spacing is 1.25.
+  # gnuplot has a concept of a figure global font, and sizes everything
+  # appropriate to that, including the legend spacing.
+  #
+  # This means that if an alternative size is used, gnuplot will use an
+  # inappropriate spacing in the legend by default.
+  spc = s / 10 * 1.25;
+  spacing_spec = sprintf ("spacing %d", spc);
+
+endfunction
+
 function fontspec = create_fontspec (f, s, gp_term)
   if (strcmp (f, "*") || strcmp (gp_term, "tikz"))
     fontspec = sprintf ("font \",%d\"", s);
@@ -1969,19 +1998,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 +2026,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.
@@ -2115,6 +2144,13 @@
                     plot_stream, mirror, mono, axispos, tickdir, ticklength,
                     fontname, fontspec, interpreter, scale, sgn, gnuplot_term)
   persistent warned_latex = false;
+
+  ## Avoid emitting anything if the tics are empty, because this undoes the
+  ## effect of the previous unset xtics and thereby adds back in the tics.
+  if (isempty (tics))
+    return;
+  endif
+
   if (mirror)
     mirror = "mirror";
   else
@@ -2145,54 +2181,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, " %.15e,", tics(1:end-1));
+    fprintf (plot_stream, " %.15e) %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 +2221,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
 
@@ -2274,7 +2286,7 @@
     bld = false;
   endif
 
-  ## The text object maybe multiline, and may be of any class
+  ## The text object may be multiline, and may be of any class
   str = getfield (obj, fld);
   if (ischar (str) && rows (str) > 1)
     str = cellstr (str);
@@ -2291,6 +2303,10 @@
   endif
 
   if (enhanced)
+    str = regexprep (str, '(?<!\\)@', '\@');
+  endif
+
+  if (enhanced)
     if (strcmpi (obj.interpreter, "tex"))
       if (iscellstr (str))
         for n = 1:numel (str)
@@ -2315,14 +2331,14 @@
   [s, e, m] = regexp (str, "\\\\([a-zA-Z]+|0)", "start", "end", "matches");
 
   for i = length (s) : -1 : 1
-    ## special case for "\0"  and replace with "{/Symbol \306}'
+    ## special case for "\0"  and replace with empty set "{/Symbol \306}'
     if (strncmp (m{i}, '\0', 2))
       str = [str(1:s(i) - 1) '{/Symbol \306}' str(s(i) + 2:end)];
     else
       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 +2368,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 +2399,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 +2423,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;
@@ -2519,7 +2535,7 @@
   sym.gamma = '{/Symbol g}';
   sym.eta = '{/Symbol h}';
   sym.iota = '{/Symbol i}';
-  sym.varphi = '{/Symbol j}';
+  sym.varphi = '{/Symbol j}';              # Not in OpenGL
   sym.kappa = '{/Symbol k}';
   sym.lambda = '{/Symbol l}';
   sym.mu = '{/Symbol m}';
@@ -2550,7 +2566,9 @@
   sym.uparrow = '{/Symbol \255}';
   sym.rightarrow = '{/Symbol \256}';
   sym.downarrow = '{/Symbol \257}';
-  sym.circ = '{/Symbol \260}';
+  sym.circ = '{/Symbol \260}';         # degree symbol, not circ as in FLTK
+  sym.deg = '{/Symbol \260}';
+  sym.ast = '{/Symbol *}';
   sym.pm = '{/Symbol \261}';
   sym.geq = '{/Symbol \263}';
   sym.times = '{/Symbol \264}';
@@ -2569,6 +2587,7 @@
   sym.wp = '{/Symbol \303}';
   sym.otimes = '{/Symbol \304}';
   sym.oplus = '{/Symbol \305}';
+  ## empty set, not circled slash division operator as in FLTK.
   sym.oslash = '{/Symbol \306}';
   sym.cap = '{/Symbol \307}';
   sym.cup = '{/Symbol \310}';
@@ -2577,24 +2596,24 @@
   sym.subset = '{/Symbol \314}';
   sym.subseteq = '{/Symbol \315}';
   sym.in = '{/Symbol \316}';
-  sym.notin = '{/Symbol \317}';
+  sym.notin = '{/Symbol \317}';            # Not in OpenGL
   sym.angle = '{/Symbol \320}';
-  sym.bigtriangledown = '{/Symbol \321}';
+  sym.bigtriangledown = '{/Symbol \321}';  # Not in OpenGL
   sym.langle = '{/Symbol \341}';
   sym.rangle = '{/Symbol \361}';
   sym.nabla = '{/Symbol \321}';
-  sym.prod = '{/Symbol \325}';
+  sym.prod = '{/Symbol \325}';             # Not in OpenGL
   sym.surd = '{/Symbol \326}';
   sym.cdot = '{/Symbol \327}';
   sym.neg = '{/Symbol \330}';
   sym.wedge = '{/Symbol \331}';
   sym.vee = '{/Symbol \332}';
-  sym.Leftrightarrow = '{/Symbol \333}';
+  sym.Leftrightarrow = '{/Symbol \333}';   # Not in OpenGL
   sym.Leftarrow = '{/Symbol \334}';
-  sym.Uparrow = '{/Symbol \335}';
+  sym.Uparrow = '{/Symbol \335}';          # Not in OpenGL
   sym.Rightarrow = '{/Symbol \336}';
-  sym.Downarrow = '{/Symbol \337}';
-  sym.diamond = '{/Symbol \340}';
+  sym.Downarrow = '{/Symbol \337}';        # Not in OpenGL
+  sym.diamond = '{/Symbol \340}';          # Not in OpenGL
   sym.copyright = '{/Symbol \343}';
   sym.lfloor = '{/Symbol \353}';
   sym.lceil  = '{/Symbol \351}';
@@ -2614,3 +2633,16 @@
   endif
 endfunction
 
+function maybe_do_xtick_mirror (plot_stream, axis_obj)
+  if (! isempty(axis_obj.xtick))
+    fprintf (plot_stream, "unset x2tics; set xtics %s nomirror\n",
+                          axis_obj.tickdir);
+  endif
+endfunction
+
+function maybe_do_x2tick_mirror (plot_stream, axis_obj)
+  if (! isempty(axis_obj.xtick))
+    fprintf (plot_stream, "unset xtics; set x2tics %s nomirror\n",
+                          axis_obj.tickdir);
+  endif
+endfunction
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/plot/util/private/__opengl_print__.m	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,173 @@
+## Copyright (C) 2010-2013 Shai Ayal
+##
+## 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} {} __opengl_print__ (@var{@dots{}})
+## Undocumented internal function.
+## @end deftypefn
+
+function opts = __opengl_print__ (opts)
+
+  dos_shell = (ispc () && ! isunix ());
+
+  set (0, "currentfigure", opts.figure);
+  drawnow ("expose");
+
+  if (! isempty (opts.fig2dev_binary))
+    ## fig2dev is prefered for conversion to emf
+    fig2dev_devices = {"pstex", "mf", "emf"};
+  else
+    fig2dev_devices = {"pstex", "mf"};
+  endif
+
+  gl2ps_device = {};
+  pipeline = {};
+  switch (lower (opts.devopt))
+    case {"eps", "eps2", "epsc", "epsc2"}
+      ## format GL2PS_EPS
+      gl2ps_device = {"eps"};
+      ## FIXME: use epstool to tighten bbox and provide preview.
+      pipeline = {opts.epstool_cmd(opts, "-", opts.name)};
+    case {"epslatex", "pslatex", "pdflatex", "epslatexstandalone", ...
+          "pslatexstandalone", "pdflatexstandalone"}
+      ## format GL2PS_TEX
+      n = find (opts.devopt == "l", 1);
+      suffix = opts.devopt(1:n-1);
+      dot = find (opts.name == ".", 1, "last");
+      if ((! isempty (dot))
+          && any (strcmpi (opts.name(dot:end), ...
+                  {strcat(".", suffix), ".tex", "."})))
+        name = opts.name(1:dot-1);
+        if (dot < numel (opts.name)
+            && any (strcmpi (opts.name(dot+1:end), {"eps", "ps", "pdf"})))
+          ## If user provides eps/ps/pdf suffix, use it.
+          suffix = opts.name(dot+1:end);
+        endif
+      else
+        error ("print:invalid-suffix",
+               "invalid suffix '%s' for device '%s'.",
+               opts.name(dot:end), lower (opts.devopt));
+      endif
+      gl2ps_device = {sprintf("%snotxt", lower (suffix))};
+      gl2ps_device{2} = "tex";
+      if (dos_shell)
+        ## FIXME: this will only work on MinGW with the MSYS shell
+        pipeline = {sprintf("cat > %s-inc.%s", name, suffix)};
+        pipeline{2} = sprintf ("cat > %s.tex", name);
+      else
+        pipeline = {sprintf("cat > %s-inc.%s", name, suffix)};
+        pipeline{2} = sprintf ("cat > %s.tex", name);
+      endif
+    case "tikz"
+      ## format GL2PS_PGF
+      gl2ps_device = {"pgf"};
+      pipeline = {sprintf("cat > %s", opts.name)};
+    case "svg"
+      ## format GL2PS_SVG
+      gl2ps_device = {"svg"};
+      pipeline = {sprintf("cat > %s", opts.name)};
+    case fig2dev_devices
+      cmd_pstoedit = opts.pstoedit_cmd (opts, "fig");
+      cmd_fig2dev = opts.fig2dev_cmd (opts, opts.devopt);
+      if (strcmp (opts.devopt, "pstex"))
+        [~, ~, ext] = fileparts (opts.name);
+        if (any (strcmpi (ext, {".ps", ".tex", "."})))
+          opts.name = opts.name(1:end-numel(ext));
+        endif
+        opts.name = strcat (opts.name, ".ps");
+        cmd = sprintf ("%s | %s > %s", cmd_pstoedit, cmd_fig2dev, opts.name);
+        gl2ps_device = {"eps"};
+        pipeline = {cmd};
+        cmd_fig2dev = opts.fig2dev_cmd (opts, "pstex_t");
+        gl2ps_device{2} = "eps";
+        pipeline{2} = sprintf ("%s | %s > %s", cmd_pstoedit,
+                               cmd_fig2dev, strrep(opts.name, ".ps", ".tex"));
+      else
+        cmd = sprintf ("%s | %s > %s", cmd_pstoedit, cmd_fig2dev, opts.name);
+        gl2ps_device = {"eps"};
+        pipeline = {cmd};
+      endif
+    case "aifm"
+      cmd = opts.pstoedit_cmd (opts, "ps2ai");
+      gl2ps_device = {"eps"};
+      pipeline = {sprintf("%s > %s", cmd, opts.name)};
+    case {"dxf", "emf", "fig", "hpgl"}
+      cmd = opts.pstoedit_cmd (opts);
+      gl2ps_device = {"eps"};
+      pipeline = {sprintf("%s > %s", cmd, opts.name)};
+    case {"corel", "gif"}
+      error ("print:unsupporteddevice",
+             "print.m: %s output is not available for the FLTK graphics toolkit",
+             upper (opts.devopt));
+    case opts.ghostscript.device
+      opts.ghostscript.source = "-";
+      opts.ghostscript.output = opts.name;
+      if (opts.send_to_printer)
+        opts.unlink(strcmp (opts.unlink, opts.ghostscript.output)) = [];
+        opts.ghostscript.output = "-";
+      endif
+      [cmd_gs, cmd_cleanup] = __ghostscript__ (opts.ghostscript);
+      if (opts.send_to_printer || isempty (opts.name))
+        cmd_lpr = opts.lpr_cmd (opts);
+        cmd = sprintf ("%s | %s", cmd_gs, cmd_lpr);
+      else
+        cmd = sprintf ("%s", cmd_gs);
+      endif
+      if (! isempty (cmd_cleanup))
+        gl2ps_device = {"eps"};
+        if (dos_shell)
+          pipeline = {sprintf("%s & %s", cmd, cmd_cleanup)};
+        else
+          pipeline = {sprintf("%s ; %s", cmd, cmd_cleanup)};
+        endif
+      else
+        gl2ps_device = {"eps"};
+        pipeline = {cmd};
+      endif
+    otherwise
+      error (sprintf ("print:no%soutput", opts.devopt),
+             "print.m: %s output is not available for GL2PS output",
+             upper (opts.devopt));
+  endswitch
+
+  opts.pipeline = pipeline;
+
+  ## Tell gl2ps to use different rendering options for 2D plots
+  haxes = findall (opts.figure, "type", "axes");
+  vw = get (haxes, "view");
+  if (iscell (vw))
+    vw = vertcat (vw{:});
+  endif
+  is2D = all (abs (vw(:,2)) == 90);
+  if (is2D)
+    gl2ps_device{end} = [gl2ps_device{end}, "is2D"];
+  endif
+
+  for n = 1:numel (pipeline)
+    if (opts.debug)
+      fprintf ("opengl-pipeline: '%s'\n", pipeline{n});
+    endif
+    drawnow (gl2ps_device{n}, strcat ('|',pipeline{n}));
+  endfor
+
+  if (! isempty (strfind (opts.devopt, "standalone")))
+    opts.latex_standalone (opts);
+  endif
+
+endfunction
+
--- a/scripts/plot/util/private/__print_parse_opts__.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/plot/util/private/__print_parse_opts__.m	Fri Feb 06 08:31:49 2015 -0800
@@ -43,7 +43,7 @@
   arg_st.ghostscript.debug = false;
   arg_st.ghostscript.device = "";
   arg_st.ghostscript.epscrop = true;
-  arg_st.ghostscript.level = [];
+  arg_st.ghostscript.level = 2;
   arg_st.ghostscript.output = "";
   arg_st.ghostscript.papersize = "";
   arg_st.ghostscript.pageoffset = [];
@@ -225,7 +225,7 @@
               "pcx24b", "pcx256", "pcx16", "pgm", "pgmraw", ...
               "ppm", "ppmraw", "pdflatex", "texdraw", ...
               "pdfcairo", "pngcairo", "pstricks", ...
-              "epswrite", "pswrite", "ps2write", "pdfwrite"};
+              "epswrite", "eps2write", "pswrite", "ps2write", "pdfwrite"};
 
   suffixes = {"ai", "cdr", "fig", "png", "jpg", ...
               "gif", "pbm", "pbm", "dxf", "mf", ...
@@ -237,7 +237,7 @@
               "pcx", "pcx", "pcx", "pgm", "pgm", ...
               "ppm", "ppm", "tex", "tex", ...
               "pdf", "png", "tex", ...
-              "eps", "ps", "ps", "pdf"};
+              "eps", "eps", "ps", "ps", "pdf"};
 
   if (isfigure (arg_st.figure))
     __graphics_toolkit__ = get (arg_st.figure, "__graphics_toolkit__");
@@ -298,13 +298,6 @@
     arg_st.devopt = aliases.(arg_st.devopt);
   endif
 
-  ## FIXME - eps2 & epsc2 needs to be handled
-  if (strcmp (arg_st.devopt, "pswrite"))
-    arg_st.ghostscript.level = 1;
-  elseif (strcmp (arg_st.devopt, "ps2write"))
-    arg_st.ghostscript.level = 2;
-  endif
-
   if ((any (strcmp (arg_st.devopt, gs_device_list))
        && ! arg_st.formatted_for_printing)
       || any (strcmp (arg_st.devopt, {"pswrite", "ps2write", "pdfwrite"})))
@@ -334,10 +327,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 +573,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]);
@@ -622,15 +614,15 @@
 endfunction
 
 function device_list = gs_device_list ();
-  ## Graphics formats/languages, not priners.
+  ## Graphics formats/languages, not printers.
   device_list = {"bmp16"; "bmp16m"; "bmp256"; "bmp32b"; "bmpgray"; ...
-                 "epswrite"; "jpeg"; "jpegcymk"; "jpeggray"; "pbm"; ...
+                 "epswrite"; "eps2write"; "jpeg"; "jpegcymk"; "jpeggray"; "pbm"; ...
                  "pbmraw"; "pcx16"; "pcx24b"; "pcx256"; "pcx2up"; ...
                  "pcxcmyk"; "pcxgray"; "pcxmono"; "pdfwrite"; "pgm"; ...
                  "pgmraw"; "pgnm"; "pgnmraw"; "png16"; "png16m"; ...
                  "png256"; "png48"; "pngalpha"; "pnggray"; "pngmono"; ...
-                 "pnm"; "pnmraw"; "ppm"; "ppmraw"; "ps2write"; ...
-                 "pswrite"; "tiff12nc"; "tiff24nc"; "tiff32nc"; ...
+                 "pnm"; "pnmraw"; "ppm"; "ppmraw"; "pswrite"; ...
+                 "ps2write"; "tiff12nc"; "tiff24nc"; "tiff32nc"; ...
                  "tiffcrle"; "tiffg3"; "tiffg32d"; "tiffg4"; ...
                  "tiffgray"; "tifflzw"; "tiffpack"; "tiffsep"};
 endfunction
@@ -641,14 +633,14 @@
   ##
   ## eps, epsc, eps2, epsc2 are not included here because those are
   ## are generated by the graphics toolkit.
-  aliases.bmp = "bmp32b";
-  aliases.pdf = "pdfwrite";
-  aliases.png = "png16m";
-  aliases.ps = "pswrite";
-  aliases.ps2 = "ps2write";
-  aliases.psc = "pswrite";
-  aliases.psc2 = "ps2write";
-  aliases.tiff = "tiff24nc";
+  aliases.bmp   = "bmp32b";
+  aliases.pdf   = "pdfwrite";
+  aliases.png   = "png16m";
+  aliases.ps    = "ps2write";
+  aliases.ps2   = "ps2write";
+  aliases.psc   = "ps2write";
+  aliases.psc2  = "ps2write";
+  aliases.tiff  = "tiff24nc";
   aliases.tiffn = "tiff24nc";
 endfunction
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/plot/util/rotate.m	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,188 @@
+## 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/>.
+
+## -*- texinfo -*-
+## @deftypefn  {Function File} {} rotate (@var{h}, @var{dir}, @var{alpha})
+## @deftypefnx {Function File} {} rotate (@dots{}, @var{origin})
+## Rotate the plot object @var{h} through @var{alpha} degrees around
+## the line with direction @var{dir} and origin @var{origin}.
+##
+## The default value of @var{origin} is the center of the axes
+## object that is the parent of @var{h}.
+##
+## If @var{h} is a vector of handles, they must all have the same
+## parent axes object.
+##
+## Graphics objects that may be rotated are lines, surfaces, patches,
+## and images.
+## @end deftypefn
+
+function rotate (h, direction, alpha, origin)
+
+  ## Note in doc string about compatibility issues with calculation of
+  ## default origin due to possible differences in the auto-scaling
+  ## algorithm between Octave and Matlab.
+
+  if (nargin < 3 || nargin > 4)
+    print_usage ();
+  endif
+
+  is_h = ishandle (h);
+  if (is_h)
+    ax_list = get (h, "parent");
+    if (iscell (ax_list))
+      ax_list = cell2mat (ax_list);
+    endif
+    if (ax_list == ax_list(1))
+      ax = ax_list(1);
+    else
+       error ("rotate: all handles must be children of the same axes object");
+    endif
+  else
+    error ("rotate: H must be an array of one or more graphics handles");
+  endif
+
+  if (! (isnumeric (direction) && numel (direction) == 3))
+    error ("rotate: invalid direction");
+  endif
+
+  if (! (isnumeric (alpha) && isscalar (alpha)))
+    error ("rotate: invalid rotation angle");
+  endif
+
+  t = get (h, "type");
+
+  is_image = strcmp (t, "image");
+  is_line = strcmp (t, "line");
+  is_patch = strcmp (t, "patch");
+  is_surface = strcmp (t, "surface");
+
+  if (! all (is_image | is_line | is_patch | is_surface))
+    error ("rotate: expecting image, line, patch, or surface objects");
+  endif
+
+  if (nargin == 4)
+    if (! (isnumeric (origin) && numel (origin) == 3))
+       error ("rotate: invalid origin");
+    endif
+  else
+    ## Should Z limit be considered when computing origin?
+
+    use_zlim = any (is_patch | is_surface);
+
+    if (! use_zlim && any (is_line))
+      idx = find (is_line)';
+      for i = idx
+        if (! isempty (get (h(i), "zdata")))
+          use_zlim = true;
+          break;
+        endif
+      endfor
+    endif
+
+    xlim = get (ax, "xlim");
+    ylim = get (ax, "ylim");
+
+    a = (xlim(1) + xlim(2)) / 2;
+    b = (ylim(1) + ylim(2)) / 2;
+
+    if (use_zlim)
+      zlim = get (ax, "zlim");
+      c = (zlim(1) + zlim(2)) / 2;
+    else
+      c = 0;
+    endif
+
+    origin = [a, b, c];
+  endif
+
+  direction = direction / norm (direction);
+
+  u = direction(1);
+  v = direction(2);
+  w = direction(3);
+
+  a = origin(1);
+  b = origin(2);
+  c = origin(3);
+
+  sa = sind (alpha);
+  ca = cosd (alpha);
+
+  for i = 1:numel (h)
+    x = get (h(i), "xdata");
+    y = get (h(i), "ydata");
+
+    if (is_image(i))
+      z = zeros (size (x));
+    else
+      z = get (h(i), "zdata");
+      if (isempty (z))
+        z = zeros (size (x));
+      elseif (isvector (x) && isvector (y) && ! isvector (z))
+        [x, y] = meshgrid (x, y);
+      endif
+    endif
+
+    if (a == 0 && b == 0 && c == 0)
+      tmp = (u*x + v*y + w*z) * (1 - ca);
+
+      xr = u*tmp + x*ca + (-w*y + v*z)*sa;
+      yr = v*tmp + y*ca + (w*x - u*z)*sa;
+      zr = w*tmp + z*ca + (-v*x + u*y)*sa;
+    else
+      one_m_ca = 1 - ca;
+      tmp = u*x + v*y + w*z;
+
+      xr = ((a*(v**2 + w**2) - u*(b*v + c*w - tmp))*one_m_ca
+            + x*ca + (-c*v + b*w - w*y + v*z)*sa);
+      yr = ((b*(u**2 + w**2) - v*(a*u + c*w - tmp))*one_m_ca
+            + y*ca + (c*u - a*w + w*x - u*z)*sa);
+      zr = ((c*(u**2 + v**2) - w*(a*u + b*v - tmp))*one_m_ca
+            + z*ca + (-b*u + a*v - v*x + u*y)*sa);
+    endif
+
+    set (h(i), "xdata", xr, "ydata", yr);
+
+    if (! is_image(i))
+      set (h(i), "zdata", zr);
+    endif
+  endfor
+
+endfunction
+
+%% Test input validation
+%!shared h1, h2, o1, o2, o3
+%! h1 = figure ("visible", "off");
+%! o1 = line ();
+%! h2 = figure ("visible", "off");
+%! o2 = line ();
+%! o3 = text (0, 0, "foobar");
+%!error rotate ()
+%!error rotate (o1)
+%!error rotate (o1, [0,0,0]);
+%!error <all handles must be children of the same axes object> rotate ([o1, o2], [0,0,0], 90);
+%!error <invalid direction> rotate (o1, "foo", 90);
+%!error <invalid rotation angle> rotate (o1, [0,0,0], "foo");
+%!error <invalid origin> rotate (o1, [0,0,0], 90, "foo");
+%!error rotate (o1, [0,0,0], 90, [0,0,0], 1);
+%!error <H must be an array of one or more graphics handles> rotate (NaN, [0,0,0], 90);
+%!error <expecting image, line, patch, or surface objects> rotate (o3, [0,0,0], 90);
+%!test
+%! close (h1);
+%! close (h2);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/plot/util/rotate3d.m	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,74 @@
+## 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 3-D 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 3-D 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, zoom}
+## @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 Feb 06 08:31:09 2015 -0800
+++ b/scripts/plot/util/saveas.m	Fri Feb 06 08:31:49 2015 -0800
@@ -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 Feb 06 08:31:09 2015 -0800
+++ b/scripts/plot/util/struct2hdl.m	Fri Feb 06 08:31:49 2015 -0800
@@ -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
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/plot/util/zoom.m	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,164 @@
+## 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/>.
+
+## -*- texinfo -*-
+## @deftypefn  {Command} {} zoom (@var{factor})
+## @deftypefnx {Command} {} zoom out
+## @deftypefnx {Command} {} zoom reset
+## Zoom the current axes object.
+##
+## Given a numeric argument greater than zero, zoom by the given factor.
+## If the zoom factor is greater than one, zoom in on the plot.  If the
+## factor is less than one, zoom out.  If the zoom factor is a two- or
+## three-element vector, then the elements specify the zoom factors for
+## the x, y, and z axes respectively.
+##
+## Given the option @qcode{"out"}, zoom to the initial zoom setting.
+##
+## Given the option @qcode{"reset"}, store the current zoom setting so
+## that @code{zoom out} will return to this zoom level.
+##
+## @seealso{pan, rotate3d}
+## @end deftypefn
+
+## Eventually we need to also support these features:
+## @deftypefn {Command} {} zoom
+## @deftypefnx {Command} {} zoom on
+## @deftypefnx {Command} {} zoom off
+## @deftypefnx {Command} {} zoom xon
+## @deftypefnx {Command} {} zoom yon
+## @deftypefnx {Command} {} zoom (@var{hfig}, @var{option})
+## @deftypefnx {Command} {zoom_object_handle =} zoom (@var{hfig})
+
+function zoom (varargin)
+
+  hfig = NaN;
+
+  nargs = nargin;
+
+  if (nargs > 2)
+    print_usage ();
+  endif
+
+  if (nargin == 1 && nargout > 0 && isfigure (varargin{1}))
+    error ("zoom_object_handle = zoom (hfig): not implemented");
+  endif
+
+  if (nargs == 2)
+    hfig = varargin{1};
+    if (isfigure (hfig))
+      varargin(1) = [];
+      nargs--;
+    else
+      error ("zoom: expecting figure handle as first argument");
+    endif
+  endif
+
+  if (isnan (hfig))
+    hfig = gcf ();
+  endif
+
+  if (nargs == 0)
+    error ("zoom: toggling zoom mode is not implemented");
+  elseif (nargs == 1)
+    arg = varargin{1};
+    if (isnumeric (arg))
+      factor = arg;
+      switch (numel (factor))
+        case 3
+          xfactor = factor(1);
+          yfactor = factor(2);
+          zfactor = factor(3);
+        case 2
+          xfactor = factor(1);
+          yfactor = factor(2);
+          zfactor = 1;
+        case 1
+          xfactor = yfactor = zfactor = factor;
+        otherwise
+          error ("zoom: invalid factor");
+      endswitch
+      if (xfactor < 0 || yfactor < 0 || zfactor < 0)
+        error ("zoom: factor must be greater than 1");
+      elseif (xfactor == 1 && yfactor == 1 && zfactor == 1)
+        return;
+      endif
+      cax = get (hfig, "currentaxes");
+      if (! isempty (cax))
+        limits = axis ();
+        initial_zoom = getappdata (cax, "initial_zoom");
+        if (isempty (initial_zoom))
+          setappdata (cax, "__initial_zoom__", limits);
+        endif
+        limits(1:2) /= xfactor;
+        limits(3:4) /= yfactor;
+        if (numel (limits) > 4)
+          limits(5:6) /= zfactor;
+        endif
+        axis (cax, limits);
+      endif
+    elseif (ischar (arg))
+      switch (arg)
+        case {"on", "off", "xon", "yon"}
+          error ("zoom %s: not implemented", arg);
+
+        case "out"
+          cax = get (hfig, "currentaxes");
+          if (! isempty (cax))
+            initial_zoom = getappdata (cax, "__initial_zoom__");
+            if (! isempty (initial_zoom))
+              axis (cax, initial_zoom);
+            endif
+          endif
+
+        case "reset"
+          cax = get (hfig, "currentaxes");
+          if (! isempty (cax))
+            setappdata (cax, "__initial_zoom__", axis ());
+          endif
+
+        otherwise
+          error ("zoom: unrecognized option '%s'", arg);
+      endswitch
+    else
+      error ("zoom: wrong type argument '%s'", class (arg));
+    endif
+  endif
+
+endfunction
+
+%!demo
+%! clf;
+%! sombrero ();
+%! pause (1);
+%! %% zoom in by a factor of 2
+%! zoom (2);
+%! pause (1);
+%! %% return to original zoom level
+%! zoom out;
+%! pause (1);
+%! %% zoom in by a factor of 2
+%! zoom (2);
+%! pause (1);
+%! %% set this zoom level as the "initial zoom level"
+%! %% and zoom in some more
+%! zoom reset;
+%! zoom (2);
+%! pause (1);
+%! %% return to zoom level set by last call to "zoom reset"
+%! zoom out;
--- a/scripts/polynomial/polyeig.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/polynomial/polyeig.m	Fri Feb 06 08:31:49 2015 -0800
@@ -26,68 +26,77 @@
 ## @code{@var{C}(s) = @var{C0} + @var{C1} s + @dots{} + @var{Cl} s^l}
 ## polyeig solves the eigenvalue problem
 ## @code{(@var{C0} + @var{C1} + @dots{} + @var{Cl})v = 0}.
+##
 ## Note that the eigenvalues @var{z} are the zeros of the matrix polynomial.
-## @var{z} is an @var{lxn} vector and @var{v} is an (@var{n} x @var{n})l matrix
-## with columns that correspond to the eigenvectors.
+## @var{z} is a row vector with @var{n*l} elements.  @var{v} is a matrix
+## (@var{n} x @var{n}*@var{l}) with columns that correspond to the
+## eigenvectors.
 ##
 ## @seealso{eig, eigs, compan}
 ## @end deftypefn
 
 ## Author: Fotios Kasolis
 
-function [ z, varargout ] = polyeig (varargin)
+function [z, v] = polyeig (varargin)
 
-  if ( nargout > 2 )
+  if (nargin < 1 || nargout > 2)
     print_usage ();
   endif
 
   nin = numel (varargin);
-
-  n = zeros (1, nin);
+  n = rows (varargin{1});
 
-  for cnt = 1 : nin
-    if (! issquare (varargin{cnt}))
-       error ("polyeig: coefficients must be square matrices");
+  for i = 1 : nin
+    if (! issquare (varargin{i}))
+      error ("polyeig: coefficients must be square matrices");
     endif
-    n(cnt) = size (varargin{cnt}, 1);
+    if (rows (varargin{i}) != n)
+      error ("polyeig: coefficients must have the same dimensions");
+    endif
   endfor
 
-  if (numel (unique (n)) > 1)
-       error ("polyeig: coefficients must have the same dimensions");
-  endif
-  n = unique (n);
-
   ## matrix polynomial degree
   l = nin - 1;
 
   ## form needed matrices
   C = [ zeros(n * (l - 1), n), eye(n * (l - 1));
-       -cell2mat(varargin(1 : end - 1)) ];
+       -cell2mat(varargin(1:end-1)) ];
 
   D = [ eye(n * (l - 1)), zeros(n * (l - 1), n);
        zeros(n, n * (l - 1)), varargin{end} ];
 
   ## solve generalized eigenvalue problem
-  if ( isequal (nargout, 1) )
-    z = eig (C, D);
-  else
-    [ z, v ] = eig (C, D);
-    varargout{1} = v;
-    ## return n-element eigenvectors normalized so
-    ## that the infinity-norm = 1
+  if (nargout == 2)
+    [z, v] = eig (C, D);
+    v = diag (v);
+    ## return n-element eigenvectors normalized so that the infinity-norm = 1
     z = z(1:n,:);
     ## max() takes the abs if complex:
     t = max (z);
     z /= diag (t);
+  else
+    z = eig (C, D);
   endif
 
 endfunction
 
 
+%!shared C0, C1
+%! C0 = [8, 0; 0, 4]; C1 = [1, 0; 0, 1];
+
 %!test
-%! C0 = [8, 0; 0, 4]; C1 = [1, 0; 0, 1];
+%! z = polyeig (C0, C1);
+%! assert (z, [-8; -4]);
+
+%!test
 %! [v,z] = polyeig (C0, C1);
-%! assert (isequal (z(1), -8), true);
+%! assert (z, [-8; -4]);
+%! z = diag (z);
 %! d = C0*v + C1*v*z;
-%! assert (isequal (norm(d), 0.0), true);
+%! assert (norm (d), 0.0);
 
+%% Input validation tests
+%!error polyeig ()
+%!error [a,b,c] = polyeig (1)
+%!error <coefficients must be square matrices> polyeig (ones (3,2))
+%!error <coefficients must have the same dimensions> polyeig (ones (3,3), ones (2,2))
--- a/scripts/polynomial/polygcd.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/polynomial/polygcd.m	Fri Feb 06 08:31:49 2015 -0800
@@ -91,10 +91,12 @@
 %!assert (deconv (poly (1:8), polygcd (poly (1:8), poly (3:12))), poly (1:2), sqrt (eps))
 
 %!test
-%! for ii=1:10
-%!   p  = (unique (randn (10, 1)) * 10).';
+%! for ii=1:100
+%!   ## Exhibits numerical problems for multipliers of ~4 and greater.
+%!   p  = (unique (randn (10, 1)) * 3).';
 %!   p1 = p(3:end);
 %!   p2 = p(1:end-2);
-%!   assert (polygcd (poly (-p1), poly (-p2)), poly (- intersect (p1, p2)), sqrt (eps));
+%!   assert (polygcd (poly (-p1), poly (-p2)),
+%!           poly (- intersect (p1, p2)), sqrt (eps));
 %! endfor
 
--- a/scripts/polynomial/private/__splinefit__.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/polynomial/private/__splinefit__.m	Fri Feb 06 08:31:49 2015 -0800
@@ -111,7 +111,7 @@
 %   2011-07-01  Robust fitting parameter added.
 
 % Check number of arguments
-error(nargchk(3,7,nargin));
+narginchk(3,7);
 
 % Check arguments
 [x,y,dim,breaks,n,periodic,beta,constr] = arguments(varargin{:});
--- a/scripts/set/intersect.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/set/intersect.m	Fri Feb 06 08:31:49 2015 -0800
@@ -18,19 +18,25 @@
 ## <http://www.gnu.org/licenses/>.
 
 ## -*- texinfo -*-
-## @deftypefn  {Function File} {} intersect (@var{a}, @var{b})
-## @deftypefnx {Function File} {[@var{c}, @var{ia}, @var{ib}] =} intersect (@var{a}, @var{b})
+## @deftypefn  {Function File} {@var{c} =} intersect (@var{a}, @var{b})
+## @deftypefnx {Function File} {@var{c} =} intersect (@var{a}, @var{b}, "rows")
+## @deftypefnx {Function File} {[@var{c}, @var{ia}, @var{ib}] =} intersect (@dots{})
+##
+## Return the elements common to both @var{a} and @var{b} sorted in ascending
+## order.
 ##
-## Return the elements in both @var{a} and @var{b}, sorted in ascending
-## order.  If @var{a} and @var{b} are both column vectors return a column
-## vector, otherwise return a row vector.
-## @var{a}, @var{b} may be cell arrays of string(s).
+## If @var{a} and @var{b} are both column vectors then return a column vector;
+## Otherwise, return a row vector.  The inputs may also be cell arrays of
+## strings.
 ##
-## Return index vectors @var{ia} and @var{ib} such that @code{a(ia)==c} and
-## @code{b(ib)==c}.
+## If the optional input @qcode{"rows"} is given then return the common rows of
+## @var{a} and @var{b}.  The inputs must be 2-D matrices to use this option.
+##
+## If requested, return index vectors @var{ia} and @var{ib} such that
+## @code{@var{c} = @var{a}(@var{ia})} and @code{@var{c} = @var{b}(@var{ib})}.
 ##
 ## @end deftypefn
-## @seealso{unique, union, setxor, setdiff, ismember}
+## @seealso{unique, union, setdiff, setxor, ismember}
 
 function [c, ia, ib] = intersect (a, b, varargin)
 
@@ -38,12 +44,15 @@
     print_usage ();
   endif
 
-  [a, b] = validargs ("intersect", a, b, varargin{:});
+  [a, b] = validsetargs ("intersect", a, b, varargin{:});
 
   if (isempty (a) || isempty (b))
     c = ia = ib = [];
   else
-    ## form a and b into sets
+    by_rows = nargin == 3;
+    iscol = isvector (a) && isvector (b) && iscolumn (a) && iscolumn (b);
+
+    ## Form A and B into sets
     if (nargout > 1)
       [a, ja] = unique (a, varargin{:});
       [b, jb] = unique (b, varargin{:});
@@ -52,7 +61,7 @@
       b = unique (b, varargin{:});
     endif
 
-    if (nargin > 2)
+    if (by_rows)
       c = [a; b];
       [c, ic] = sortrows (c);
       ii = find (all (c(1:end-1,:) == c(2:end,:), 2));
@@ -60,7 +69,7 @@
       len_a = rows (a);
     else
       c = [a(:); b(:)];
-      [c, ic] = sort (c);               # [a(:);b(:)](ic) == c
+      [c, ic] = sort (c);         # [a(:);b(:)](ic) == c
       if (iscellstr (c))
         ii = find (strcmp (c(1:end-1), c(2:end)));
       else
@@ -71,11 +80,12 @@
     endif
 
     if (nargout > 1)
-      ia = ja(ic(ii));                  # a(ia) == c
-      ib = jb(ic(ii+1) - len_a);        # b(ib) == c
+      ia = ja(ic(ii));            # a(ia) == c
+      ib = jb(ic(ii+1) - len_a);  # b(ib) == c
     endif
 
-    if (nargin == 2 && (rows (b) == 1 || rows (a) == 1))
+    ## Adjust output orientation for Matlab compatibility
+    if (! by_rows && ! iscol)
       c = c.';
     endif
   endif
@@ -83,7 +93,24 @@
 endfunction
 
 
-%!# Test the routine for index vectors ia and ib
+## Test orientation of output
+%!shared a,b
+%! a = 1:4;
+%! b = 2:5;
+
+%!assert (size (intersect (a, b)), [1 3])
+%!assert (size (intersect (a', b)), [1 3])
+%!assert (size (intersect (a, b')), [1 3])
+%!assert (size (intersect (a', b')), [3 1])
+
+## Test multi-dimensional arrays
+%!test
+%! a = rand (3,3,3);
+%! b = a;
+%! b(1,1,1) = 2;
+%! assert (intersect (a, b), sort (a(2:end)));
+
+## Test the routine for index vectors ia and ib
 %!test
 %! a = [3 2 4 5 7 6 5 1 0 13 13];
 %! b = [3 5 12 1 1 7];
--- a/scripts/set/ismember.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/set/ismember.m	Fri Feb 06 08:31:49 2015 -0800
@@ -18,13 +18,16 @@
 ## <http://www.gnu.org/licenses/>.
 
 ## -*- texinfo -*-
-## @deftypefn  {Function File} {@var{tf} =} ismember (@var{A}, @var{s})
-## @deftypefnx {Function File} {[@var{tf}, @var{S_idx}] =} ismember (@var{A}, @var{s})
-## @deftypefnx {Function File} {[@var{tf}, @var{S_idx}] =} ismember (@var{A}, @var{s}, "rows")
-## Return a logical matrix @var{tf} with the same shape as @var{A} which is
-## true (1) if @code{A(i,j)} is in @var{s} and false (0) if it is not.  If a
-## second output argument is requested, the index into @var{s} of each of the
-## matching elements is also returned.
+## @deftypefn  {Function File} {@var{tf} =} ismember (@var{a}, @var{s})
+## @deftypefnx {Function File} {@var{tf} =} ismember (@var{a}, @var{s}, "rows")
+## @deftypefnx {Function File} {[@var{tf}, @var{s_idx}] =} ismember (@dots{})
+##
+## Return a logical matrix @var{tf} with the same shape as @var{a} which is
+## true (1) if the element in @var{a} is found in @var{s} and false (0) if it
+## is not.
+##
+## If a second output argument is requested then the index into @var{s} of each
+## matching element is also returned.
 ##
 ## @example
 ## @group
@@ -36,7 +39,7 @@
 ## @end group
 ## @end example
 ##
-## The inputs, @var{A} and @var{s}, may also be cell arrays.
+## The inputs @var{a} and @var{s} may also be cell arrays.
 ##
 ## @example
 ## @group
@@ -48,9 +51,9 @@
 ## @end group
 ## @end example
 ##
-## With the optional third argument @qcode{"rows"}, and matrices
-## @var{A} and @var{s} with the same number of columns, compare rows in
-## @var{A} with the rows in @var{s}.
+## If the optional third argument @qcode{"rows"} is given then compare rows
+## in @var{a} with rows in @var{s}.  The inputs must be 2-D matrices with the
+## same number of columns to use this option.
 ##
 ## @example
 ## @group
@@ -62,7 +65,7 @@
 ## @end group
 ## @end example
 ##
-## @seealso{unique, union, intersect, setxor, setdiff}
+## @seealso{lookup, unique, union, intersect, setdiff, setxor}
 ## @end deftypefn
 
 ## Author: Paul Kienzle <pkienzle@users.sf.net>
@@ -71,63 +74,67 @@
 ## Adapted-by: jwe
 ## Reimplemented using lookup & unique: Jaroslav Hajek <highegg@gmail.com>
 
-function [tf, a_idx] = ismember (A, s, varargin)
+function [tf, s_idx] = ismember (a, s, varargin)
 
   if (nargin < 2 || nargin > 3)
     print_usage ();
   endif
 
   ## lookup() does not handle logical values
-  if (islogical (A))
-    A = uint8 (A);
+  if (islogical (a))
+    a = uint8 (a);
   endif
   if (islogical (s))
     s = uint8 (s);
   endif
 
-  [A, s] = validargs ("ismember", A, s, varargin{:});
+  [a, s] = validsetargs ("ismember", a, s, varargin{:});
+
+  by_rows = nargin == 3;
 
-  if (nargin == 2)
+  if (! by_rows)
     s = s(:);
-    ## We do it this way, because we expect the array to be often sorted.
+    ## Check sort status, because we expect the array will often be sorted.
     if (issorted (s))
       is = [];
     else
       [s, is] = sort (s);
     endif
 
-    ## sort out NaNs in table
+    ## Remove NaNs from table because lookup can't handle them
     if (isreal (s) && ! isempty (s) && isnan (s(end)))
-        s = s(1:end - sum (isnan (s)));
+      s = s(1:end - sum (isnan (s)));
     endif
 
     if (nargout > 1)
-      a_idx = lookup (s, A, "m");
-      tf = logical (a_idx);
+      s_idx = lookup (s, a, "m");
+      tf = logical (s_idx);
       if (! isempty (is))
-        a_idx(tf) = is (a_idx(tf));
+        s_idx(tf) = is(s_idx(tf));
       endif
     else
-      tf = lookup (s, A, "b");
+      tf = lookup (s, a, "b");
     endif
 
-  else
-
-    if (isempty (A) || isempty (s))
-      tf = false (rows (A), 1);
-      a_idx = zeros (rows (A), 1);
+  else  # "rows" argument
+    if (isempty (a) || isempty (s))
+      tf = false (rows (a), 1);
+      s_idx = zeros (rows (a), 1);
     else
+      if (rows (s) == 1)
+        tf = all (bsxfun (@eq, a, s), 2);
+        s_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;
 
-      ## 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 (nargout > 1)
-        a_idx = max (0, jj - na);
+        if (nargout > 1)
+          s_idx = max (0, jj - na);
+        endif
       endif
-
     endif
   endif
 
@@ -155,62 +162,67 @@
 %!assert (ismember ("1", "0123456789."), true)
 
 %!test
-%! [result, a_idx] = ismember ([1, 2], []);
+%! [result, s_idx] = ismember ([1, 2], []);
 %! assert (result, [false false])
-%! assert (a_idx, [0, 0]);
+%! assert (s_idx, [0, 0]);
 
 %!test
-%! [result, a_idx] = ismember ([], [1, 2]);
+%! [result, s_idx] = ismember ([], [1, 2]);
 %! assert (result, logical ([]))
-%! assert (a_idx, []);
+%! assert (s_idx, []);
 
 %!test
-%! [result, a_idx] = ismember ({"a", "b"}, "");
+%! [result, s_idx] = ismember ({"a", "b"}, "");
 %! assert (result, [false false])
-%! assert (a_idx, [0, 0]);
+%! assert (s_idx, [0, 0]);
 
 %!test
-%! [result, a_idx] = ismember ({"a", "b"}, {});
+%! [result, s_idx] = ismember ({"a", "b"}, {});
 %! assert (result, [false false])
-%! assert (a_idx, [0, 0]);
+%! assert (s_idx, [0, 0]);
 
 %!test
-%! [result, a_idx] = ismember ("", {"a", "b"});
+%! [result, s_idx] = ismember ("", {"a", "b"});
 %! assert (result, false)
-%! assert (a_idx, 0);
+%! assert (s_idx, 0);
 
 %!test
-%! [result, a_idx] = ismember ({}, {"a", "b"});
+%! [result, s_idx] = ismember ({}, {"a", "b"});
 %! assert (result, logical ([]))
-%! assert (a_idx, []);
+%! assert (s_idx, []);
 
 %!test
-%! [result, a_idx] = ismember ([1 2 3 4 5], [3]);
+%! [result, s_idx] = ismember ([1 2 3 4 5], [3]);
 %! assert (result, logical ([0 0 1 0 0]))
-%! assert (a_idx , [0 0 1 0 0]);
+%! assert (s_idx , [0 0 1 0 0]);
 
 %!test
-%! [result, a_idx] = ismember ([1 6], [1 2 3 4 5 1 6 1]);
+%! [result, s_idx] = ismember ([1 6], [1 2 3 4 5 1 6 1]);
 %! assert (result, [true true]);
-%! assert (a_idx(2), 7);
+%! assert (s_idx(2), 7);
 
 %!test
-%! [result, a_idx] = ismember ([3,10,1], [0,1,2,3,4,5,6,7,8,9]);
+%! [result, s_idx] = ismember ([3,10,1], [0,1,2,3,4,5,6,7,8,9]);
 %! assert (result, [true false true]);
-%! assert (a_idx, [4, 0, 2]);
+%! assert (s_idx, [4, 0, 2]);
 
 %!test
-%! [result, a_idx] = ismember ("1.1", "0123456789.1");
+%! [result, s_idx] = ismember ("1.1", "0123456789.1");
 %! assert (result, [true true true]);
-%! assert (a_idx, [12, 11, 12]);
+%! assert (s_idx, [12, 11, 12]);
+
+%!test
+%! [result, s_idx] = ismember ([1:3; 5:7; 4:6], [0:2; 1:3; 2:4; 3:5; 4:6], "rows");
+%! assert (result, [true; false; true]);
+%! assert (s_idx, [2; 0; 5]);
 
 %!test
-%! [result, a_idx] = ismember ([1:3; 5:7; 4:6], [0:2; 1:3; 2:4; 3:5; 4:6], "rows");
+%! [result, s_idx] = ismember ([1.1,1.2,1.3; 2.1,2.2,2.3; 10,11,12], [1.1,1.2,1.3; 10,11,12; 2.12,2.22,2.32], "rows");
 %! assert (result, [true; false; true]);
-%! assert (a_idx, [2; 0; 5]);
+%! assert (s_idx, [1; 0; 2]);
 
 %!test
-%! [result, a_idx] = ismember ([1.1,1.2,1.3; 2.1,2.2,2.3; 10,11,12], [1.1,1.2,1.3; 10,11,12; 2.12,2.22,2.32], "rows");
-%! assert (result, [true; false; true]);
-%! assert (a_idx, [1; 0; 2]);
+%! [result, s_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 (s_idx, [1 0 0 0 1 0]');
 
--- a/scripts/set/module.mk	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/set/module.mk	Fri Feb 06 08:31:49 2015 -0800
@@ -8,7 +8,7 @@
   set/setxor.m \
   set/union.m \
   set/unique.m \
-  set/private/validargs.m
+  set/private/validsetargs.m
 
 FCN_FILES += $(set_FCN_FILES)
 
--- a/scripts/set/powerset.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/set/powerset.m	Fri Feb 06 08:31:49 2015 -0800
@@ -25,33 +25,35 @@
 ## output will always be a cell array of either vectors or strings.
 ##
 ## With the optional second argument @qcode{"rows"}, each row of the set @var{a}
-## is considered one element of the set.  As a result, @var{a} must then be a
-## numerical 2-D matrix.
+## is considered one element of the set.  The input must be a 2-D numeric
+## matrix to use this argument.
 ##
-## @seealso{unique, union, setxor, setdiff, ismember}
+## @seealso{unique, union, intersect, setdiff, setxor, ismember}
 ## @end deftypefn
 
 function p = powerset (a, byrows_arg)
 
+  if (nargin < 1 || nargin > 2)
+    print_usage ();
+  endif
+
   byrows = false;
-
   if (nargin == 2)
     if (! strcmpi (byrows_arg, "rows"))
       error ('powerset: expecting second argument to be "rows"');
     elseif (iscell (a))
-      warning ('powerset: "rows" not valid for cell arrays');
+      error ('powerset: "rows" not valid for cell arrays');
     else
       byrows = true;
     endif
-  elseif (nargin != 1)
-    print_usage ();
   endif
+
   if (iscell (a) && ! iscellstr (a))
-    error ("powerset: cell arrays can only used for character strings");
+    error ("powerset: cell arrays can only be used for character strings");
   endif
 
   if (byrows)
-    a = unique (a, byrows_arg);
+    a = unique (a, "rows");
     n = rows (a);
   else
     a = unique (a);
@@ -86,12 +88,23 @@
 endfunction
 
 
-%!shared c, p
-%! c = sort (cellstr ({ [], [1], [2], [3], [1, 2], [1, 3], [2, 3], [1, 2, 3]}));
+%!test
+%! c = sort (cellstr ({[], [1], [2], [3], [1, 2], [1, 3], [2, 3], [1, 2, 3]}));
 %! p = sort (cellstr (powerset ([1, 2, 3])));
-%!assert (p, c);
+%! assert (p, c);
+
+%!test
 %! c = sort (cellstr ({ [], [1:3], [2:4], [3:5], [1:3; 2:4], [1:3; 3:5], [2:4; 3:5], [1:3; 2:4; 3:5]}));
 %! p = sort (cellstr (powerset ([1:3;2:4;3:5], "rows")));
-%!assert (p,c);
+%! assert (p,c);
+
 %!assert (powerset([]), {});  # always return a cell array
 
+%% Test input validation
+%!error powerset ()
+%!error powerset (1,2,3)
+%!error <expecting second argument to be "rows"> powerset (1, "cols")
+%!error <"rows" not valid for cell arrays> powerset ({1}, "rows")
+%!error <cell arrays can only be used for character> powerset ({1})
+%!error <not implemented for more than 32 elements> powerset (1:33)
+
--- a/scripts/set/private/validargs.m	Fri Feb 06 08:31:09 2015 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,58 +0,0 @@
-## Copyright (C) 2000-2013 Paul Kienzle
-## Copyright (C) 2009-2010 Jaroslav Hajek
-##
-## 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/>.
-
-## Validate arguments for binary set operation.
-function [x, y] = validargs (caller, x, y, byrows_arg)
-
-  if (nargin == 3)
-    icx = iscellstr (x);
-    icy = iscellstr (y);
-    if (icx || icy)
-      if (icx && ischar (y))
-        y = cellstr (y);
-      elseif (icy && ischar (x))
-        x = cellstr (x);
-      elseif (! (icx && icy))
-        error ("%s: cell array of strings cannot be combined with a nonstring value", caller);
-      endif
-    elseif (! (ismatrix (x) && ismatrix (y)))
-      error ("%s: input arguments must be arrays or cell arrays of strings", caller);
-    endif
-  elseif (nargin == 4)
-    if (strcmpi (byrows_arg, "rows"))
-      if (iscell (x) || iscell (y))
-        error ('%s: cells not supported with "rows"', caller);
-      elseif (! (ismatrix (x) && ismatrix (y)))
-        error ("%s: input arguments must be arrays or cell arrays of strings", caller);
-      else
-        if (ndims (x) > 2 || ndims (y) > 2)
-          error ('%s: need 2-dimensional matrices for "rows"', caller);
-        elseif (columns (x) != columns (y) && ! (isempty (x) || isempty (y)))
-          error ("%s: number of columns must match", caller);
-        endif
-      endif
-    else
-      error ("%s: invalid option: %s", caller, byrows_arg);
-    endif
-  else
-    print_usage (caller);
-  endif
-
-endfunction
-
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/set/private/validsetargs.m	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,59 @@
+## Copyright (C) 2000-2013 Paul Kienzle
+## Copyright (C) 2009-2010 Jaroslav Hajek
+##
+## 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/>.
+
+## Validate arguments for binary set operation.
+
+function [x, y] = validsetargs (caller, x, y, byrows_arg)
+
+  if (nargin == 3)
+    icx = iscellstr (x);
+    icy = iscellstr (y);
+    if (icx || icy)
+      if (icx && ischar (y))
+        y = cellstr (y);
+      elseif (icy && ischar (x))
+        x = cellstr (x);
+      elseif (! (icx && icy))
+        error ("%s: cell array of strings cannot be combined with a nonstring value", caller);
+      endif
+    elseif (! (ismatrix (x) && ismatrix (y)))
+      error ("%s: A and B must be arrays or cell arrays of strings", caller);
+    endif
+  elseif (nargin == 4)
+    if (! strcmpi (byrows_arg, "rows"))
+      error ("%s: invalid option: %s", caller, byrows_arg);
+    endif
+
+    if (iscell (x) || iscell (y))
+      error ('%s: cells not supported with "rows"', caller);
+    elseif (! (ismatrix (x) && ismatrix (y)))
+      error ("%s: A and B must be arrays or cell arrays of strings", caller);
+    else
+      if (ndims (x) > 2 || ndims (y) > 2)
+        error ('%s: A and B must be 2-dimensional matrices for "rows"', caller);
+      elseif (columns (x) != columns (y) && ! (isempty (x) || isempty (y)))
+        error ("%s: number of columns in A and B must match", caller);
+      endif
+    endif
+  endif
+
+endfunction
+
+
+## %!tests for function are in union.m
--- a/scripts/set/setdiff.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/set/setdiff.m	Fri Feb 06 08:31:49 2015 -0800
@@ -18,72 +18,81 @@
 ## <http://www.gnu.org/licenses/>.
 
 ## -*- texinfo -*-
-## @deftypefn  {Function File} {} setdiff (@var{a}, @var{b})
-## @deftypefnx {Function File} {} setdiff (@var{a}, @var{b}, "rows")
-## @deftypefnx {Function File} {[@var{c}, @var{i}] =} setdiff (@var{a}, @var{b})
-## Return the elements in @var{a} that are not in @var{b}, sorted in
-## ascending order.  If @var{a} and @var{b} are both column vectors
-## return a column vector, otherwise return a row vector.
-## @var{a}, @var{b} may be cell arrays of string(s).
+## @deftypefn  {Function File} {@var{c} =} setdiff (@var{a}, @var{b})
+## @deftypefnx {Function File} {@var{c} =} setdiff (@var{a}, @var{b}, "rows")
+## @deftypefnx {Function File} {[@var{c}, @var{ia}] =} setdiff (@dots{})
+## Return the elements in @var{a} that are not in @var{b} sorted in
+## ascending order.
 ##
-## Given the optional third argument @qcode{"rows"}, return the rows in
-## @var{a} that are not in @var{b}, sorted in ascending order by rows.
+## If @var{a} and @var{b} are both column vectors return a column vector;
+## Otherwise, return a row vector.  The inputs may also be cell arrays of
+## strings.
 ##
-## If requested, return @var{i} such that @code{c = a(i)}.
+## If the optional input @qcode{"rows"} is given then return the rows in
+## @var{a} that are not in @var{b}.  The inputs must be 2-D matrices to use
+## this option.
+##
+## If requested, return the index vector @var{ia} such that
+## @code{@var{c} = @var{a}(@var{ia})}.
 ## @seealso{unique, union, intersect, setxor, ismember}
 ## @end deftypefn
 
 ## Author: Paul Kienzle
 ## Adapted-by: jwe
 
-function [c, i] = setdiff (a, b, varargin)
+function [c, ia] = setdiff (a, b, varargin)
 
   if (nargin < 2 || nargin > 3)
     print_usage ();
   endif
 
-  [a, b] = validargs ("setdiff", a, b, varargin{:});
+  [a, b] = validsetargs ("setdiff", a, b, varargin{:});
 
-  if (nargin > 2)
+  by_rows = nargin == 3;
+  iscol = isvector (a) && isvector (b) && iscolumn (a) && iscolumn (b);
+
+  if (by_rows)
     if (nargout > 1)
-      [c, i] = unique (a, "rows");
+      [c, ia] = unique (a, "rows");
     else
       c = unique (a, "rows");
     endif
     if (! isempty (c) && ! isempty (b))
-      ## Form a and b into combined set.
+      ## Form A and B into combined set.
       b = unique (b, "rows");
-      [dummy, idx] = sortrows ([c; b]);
-      ## Eliminate those elements of a that are the same as in b.
-      dups = find (all (dummy(1:end-1,:) == dummy(2:end,:), 2));
+      [tmp, idx] = sortrows ([c; b]);
+      ## Eliminate those elements of A that are the same as in B.
+      dups = find (all (tmp(1:end-1,:) == tmp(2:end,:), 2));
       c(idx(dups),:) = [];
       if (nargout > 1)
-        i(idx(dups),:) = [];
+        ia(idx(dups),:) = [];
       endif
     endif
   else
     if (nargout > 1)
-      [c, i] = unique (a);
+      [c, ia] = unique (a);
     else
       c = unique (a);
     endif
     if (! isempty (c) && ! isempty (b))
       ## Form a and b into combined set.
       b = unique (b);
-      [dummy, idx] = sort ([c(:); b(:)]);
+      [tmp, idx] = sort ([c(:); b(:)]);
       ## Eliminate those elements of a that are the same as in b.
-      if (iscellstr (dummy))
-        dups = find (strcmp (dummy(1:end-1), dummy(2:end)));
+      if (iscellstr (tmp))
+        dups = find (strcmp (tmp(1:end-1), tmp(2:end)));
       else
-        dups = find (dummy(1:end-1) == dummy(2:end));
+        dups = find (tmp(1:end-1) == tmp(2:end));
       endif
       c(idx(dups)) = [];
       if (nargout > 1)
-        i(idx(dups)) = [];
+        ia(idx(dups)) = [];
       endif
-      ## Reshape if necessary.
-      if (rows (c) != 1 && rows (b) == 1)
-        c = c.';
+      ## Reshape if necessary for Matlab compatibility.
+      if (iscol)
+        c = c(:);
+      else
+        c = c(:).';
       endif
     endif
   endif
@@ -100,8 +109,22 @@
 %!assert (setdiff ({"one","two";"three","four"}, {"one","two";"three","six"}), {"four"})
 
 %!test
-%! a = [3, 1, 4, 1, 5];  b = [1, 2, 3, 4];
-%! [y, i] = setdiff (a, b.');
-%! assert (y, [5]);
-%! assert (y, a(i));
+%! a = [3, 1, 4, 1, 5];
+%! b = [1, 2, 3, 4];
+%! [c, ia] = setdiff (a, b');
+%! assert (c, [5]);
+%! assert (c, a(ia));
 
+%% 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
+%! a = rand (3,3,3);
+%! b = a(1);
+%! assert (setdiff (a, b), sort (a(2:end)));
+
--- a/scripts/set/setxor.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/set/setxor.m	Fri Feb 06 08:31:49 2015 -0800
@@ -1,3 +1,4 @@
+## Copyright (C) 2014 Julien Bect
 ## Copyright (C) 2008-2013 Jaroslav Hajek
 ## Copyright (C) 2000, 2006-2007 Paul Kienzle
 ##
@@ -18,18 +19,24 @@
 ## <http://www.gnu.org/licenses/>.
 
 ## -*- texinfo -*-
-## @deftypefn  {Function File} {} setxor (@var{a}, @var{b})
-## @deftypefnx {Function File} {} setxor (@var{a}, @var{b}, "rows")
-## @deftypefnx {Function File} {[@var{c}, @var{ia}, @var{ib}] =} setxor (@var{a}, @var{b})
+## @deftypefn  {Function File} {@var{c} =} setxor (@var{a}, @var{b})
+## @deftypefnx {Function File} {@var{c} =} setxor (@var{a}, @var{b}, "rows")
+## @deftypefnx {Function File} {[@var{c}, @var{ia}, @var{ib}] =} setxor (@dots{})
+##
+## Return the elements exclusive to sets @var{a} or @var{b} sorted in
+## ascending order.
 ##
-## Return the elements exclusive to @var{a} or @var{b}, sorted in ascending
-## order.  If @var{a} and @var{b} are both column vectors return a column
-## vector, otherwise return a row vector.
-## @var{a}, @var{b} may be cell arrays of string(s).
+## If @var{a} and @var{b} are both column vectors return a column vector;
+## Otherwise, return a row vector.  The inputs may also be cell arrays of
+## strings.
 ##
-## With three output arguments, return index vectors @var{ia} and @var{ib}
-## such that @code{a(ia)} and @code{b(ib)} are disjoint sets whose union
-## is @var{c}.
+## If the optional input @qcode{"rows"} is given then return the rows exclusive
+## to sets @var{a} and @var{b}.  The inputs must be 2-D matrices to use this
+## option.
+##
+## If requested, return index vectors @var{ia} and @var{ib} such that
+## @code{@var{a}(@var{ia})} and @code{@var{b}(@var{ib})} are disjoint sets
+## whose union is @var{c}.
 ##
 ## @seealso{unique, union, intersect, setdiff, ismember}
 ## @end deftypefn
@@ -40,7 +47,10 @@
     print_usage ();
   endif
 
-  [a, b] = validargs ("setxor", a, b, varargin{:});
+  [a, b] = validsetargs ("setxor", a, b, varargin{:});
+
+  by_rows = nargin == 3;
+  iscol = isvector (a) && isvector (b) && iscolumn (a) && iscolumn (b);
 
   ## Form A and B into sets.
   if (nargout > 1)
@@ -57,8 +67,8 @@
     c = a;
   else
     ## Reject duplicates.
-    if (nargin > 2)
-      na = rows (a); nb = rows (b);
+    if (by_rows)
+      na = rows (a);  nb = rows (b);
       [c, i] = sortrows ([a; b]);
       n = rows (c);
       idx = find (all (c(1:n-1, :) == c(2:n, :), 2));
@@ -67,7 +77,7 @@
         i([idx, idx+1],:) = [];
       endif
     else
-      na = numel (a); nb = numel (b);
+      na = numel (a);  nb = numel (b);
       [c, i] = sort ([a(:); b(:)]);
       n = length (c);
       if (iscell (c))
@@ -79,31 +89,81 @@
         c([idx, idx+1]) = [];
         i([idx, idx+1]) = [];
       endif
-      if (rows (a) == 1 || rows (b) == 1)
+
+      ## Adjust output orientation for Matlab compatibility
+      if (! iscol)
         c = c.';
       endif
     endif
-  endif
-  if (nargout > 1)
-    ia = ia(i(i <= na));
-    ib = ib(i(i > na) - na);
+
+    if (nargout > 1)
+      ia = ia(i(i <= na));
+      ib = ib(i(i > na) - na);
+    endif
   endif
 
 endfunction
 
 
-%!assert (setxor ([1,2,3],[2,3,4]),[1,4])
+%!assert (setxor ([1,2,3], [2,3,4]), [1,4])
 %!assert (setxor ({'a'}, {'a', 'b'}), {'b'})
 
 %!test
-%! a = [3, 1, 4, 1, 5];  b = [1, 2, 3, 4];
+%! a = [3, 1, 4, 1, 5];
+%! b = [1, 2, 3, 4];
 %! [c, ia, ib] = setxor (a, b.');
 %! assert (c, [2, 5]);
 %! assert (c, sort ([a(ia), b(ib)]));
 
 %!test
-%! a = [1 2; 4 5; 1 3];  b = [1 1; 1 2; 4 5; 2 10];
+%! a = [1 2; 4 5; 1 3];
+%! b = [1 1; 1 2; 4 5; 2 10];
 %! [c, ia, ib] = setxor (a, b, "rows");
 %! assert (c, [1 1; 1 3; 2 10]);
 %! assert (c, sortrows ([a(ia,:); b(ib,:)]));
 
+%!assert (setxor (1, []), 1)
+%!assert (setxor ([], 1), 1)
+
+%!test
+%! [c, ia, ib] = setxor (1, []);
+%! assert (c, 1);
+%! assert (ia, 1);
+%! assert (isempty (ib));
+
+%!test
+%! [c, ia, ib] = setxor ([], 1);
+%! assert (c, 1);
+%! assert (isempty (ia));
+%! assert (ib, 1);
+
+%!test
+%! a = [2 1; 4 3];  b = [];
+%! [c, ia, ib] = setxor (a, b);
+%! assert (c, [1; 2; 3; 4]);
+%! assert (ia, [3; 1; 4; 2]);
+%! assert (isempty (ib));
+
+%!test
+%! a = [];  b = [2 1; 4 3];
+%! [c, ia, ib] = setxor (a, b);
+%! assert (c, [1; 2; 3; 4]);
+%! assert (isempty (ia));
+%! assert (ib, [3; 1; 4; 2]);
+## Test orientation of output
+%!shared x,y
+%! x = 1:3;
+%! y = 2:5;
+
+%!assert (size (setxor (x, y)), [1 3])
+%!assert (size (setxor (x', y)), [1 3])
+%!assert (size (setxor (x, y')), [1 3])
+%!assert (size (setxor (x', y')), [3 1])
+
+## Test multi-dimensional arrays
+%!test
+%! a = rand (3,3,3);
+%! b = a;
+%! b(1,1,1) = 2;
+%! assert (intersect (a, b), sort (a(2:end)));
+
--- a/scripts/set/union.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/set/union.m	Fri Feb 06 08:31:49 2015 -0800
@@ -18,38 +18,26 @@
 ## <http://www.gnu.org/licenses/>.
 
 ## -*- texinfo -*-
-## @deftypefn  {Function File} {} union (@var{a}, @var{b})
-## @deftypefnx {Function File} {} union (@var{a}, @var{b}, "rows")
-## @deftypefnx {Function File} {[@var{c}, @var{ia}, @var{ib}] =} union (@var{a}, @var{b})
+## @deftypefn  {Function File} {@var{c} =} union (@var{a}, @var{b})
+## @deftypefnx {Function File} {@var{c} =} union (@var{a}, @var{b}, "rows")
+## @deftypefnx {Function File} {[@var{c}, @var{ia}, @var{ib}] =} union (@dots{})
 ##
-## Return the set of elements that are in either of the sets @var{a} and
-## @var{b}.  @var{a}, @var{b} may be cell arrays of strings.
-## For example:
+## Return the elements that are in either @var{a} or @var{b} sorted in
+## ascending order with duplicates removed.
 ##
-## @example
-## @group
-## union ([1, 2, 4], [2, 3, 5])
-##     @result{} [1, 2, 3, 4, 5]
-## @end group
-## @end example
+## If @var{a} and @var{b} are both column vectors return a column vector;
+## Otherwise, return a row vector.  The inputs may also be cell arrays of
+## strings.
 ##
-## If the optional third input argument is the string @qcode{"rows"} then
-## each row of the matrices @var{a} and @var{b} will be considered as a
-## single set element.  For example:
-##
-## @example
-## @group
-## union ([1, 2; 2, 3], [1, 2; 3, 4], "rows")
-##    @result{}  1   2
-##        2   3
-##        3   4
-## @end group
-## @end example
+## If the optional input @qcode{"rows"} is given then return rows that are in
+## either @var{a} or @var{b}.  The inputs must be 2-D matrices to use this
+## option.
 ##
 ## The optional outputs @var{ia} and @var{ib} are index vectors such that
-## @code{a(ia)} and @code{b(ib)} are disjoint sets whose union is @var{c}.
+## @code{@var{a}(@var{ia})} and @code{@var{b}(@var{ib})} are disjoint sets
+## whose union is @var{c}.
 ##
-## @seealso{intersect, setdiff, unique}
+## @seealso{unique, intersect, setdiff, setxor, ismember}
 ## @end deftypefn
 
 ## Author: jwe
@@ -60,40 +48,59 @@
     print_usage ();
   endif
 
-  [a, b] = validargs ("union", a, b, varargin{:});
+  [a, b] = validsetargs ("union", a, b, varargin{:});
+
+  by_rows = nargin == 3;
+  iscol = isvector (a) && isvector (b) && iscolumn (a) && iscolumn (b);
 
-  if (nargin == 2)
+  if (by_rows)
+    y = [a; b];
+  else
     y = [a(:); b(:)];
-    na = numel (a); nb = numel (b);
-    if (rows (a) == 1 || rows (b) == 1)
+    ## Adjust output orientation for Matlab compatibility
+    if (! iscol)
       y = y.';
     endif
-  else
-    y = [a; b];
-    na = rows (a); nb = rows (b);
   endif
 
-  if (nargout == 1)
+  if (nargout <= 1)
     y = unique (y, varargin{:});
   else
-    [y, i] = unique (y, varargin{:});
-    ia = i(i <= na);
-    ib = i(i > na) - na;
+    [y, idx] = unique (y, varargin{:});
+    na = numel (a);
+    ia = idx(idx <= na);
+    ib = idx(idx > na) - na;
   endif
 
 endfunction
 
 
-%!assert (union ([1, 2, 4], [2, 3, 5]), [1, 2, 3, 4, 5]);
-%!assert (union ([1; 2; 4], [2, 3, 5]), [1, 2, 3, 4, 5]);
-%!assert (union ([1, 2, 3], [5; 7; 9]), [1, 2, 3, 5, 7, 9]);
+%!assert (union ([1, 2, 4], [2, 3, 5]), [1, 2, 3, 4, 5])
+%!assert (union ([1; 2; 4], [2, 3, 5]), [1, 2, 3, 4, 5])
+%!assert (union ([1; 2; 4], [2; 3; 5]), [1; 2; 3; 4; 5])
+%!assert (union ([1, 2, 3], [5; 7; 9]), [1, 2, 3, 5, 7, 9])
+
+## Test multi-dimensional arrays
+%!test
+%! a = rand (3,3,3);
+%! b = a;
+%! b(1,1,1) = 2;
+%! assert (union (a, b), sort ([a(1:end), 2]));
 
 %!test
-%! a = [3, 1, 4, 1, 5];  b = [1, 2, 3, 4];
+%! a = [3, 1, 4, 1, 5];
+%! b = [1, 2, 3, 4];
 %! [y, ia, ib] = union (a, b.');
 %! assert (y, [1, 2, 3, 4, 5]);
 %! assert (y, sort ([a(ia), b(ib)]));
 
-%!error union (1)
-%!error union (1, 2, 3)
 
+%% Test common input validation for set routines contained in validsetargs
+%!error <cell array of strings cannot be combined> union ({"a"}, 1)
+%!error <A and B must be arrays or cell arrays> union (@sin, 1)
+%!error <invalid option: columns> union (1, 2, "columns")
+%!error <cells not supported with "rows"> union ({"a"}, {"b"}, "rows")
+%!error <A and B must be arrays or cell arrays> union (@sin, 1, "rows")
+%!error <A and B must be 2-dimensional matrices> union (rand(2,2,2), 1, "rows")
+%!error <number of columns in A and B must match> union ([1 2], 1, "rows")
+
--- a/scripts/set/unique.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/set/unique.m	Fri Feb 06 08:31:49 2015 -0800
@@ -20,20 +20,20 @@
 ## -*- texinfo -*-
 ## @deftypefn  {Function File} {} unique (@var{x})
 ## @deftypefnx {Function File} {} unique (@var{x}, "rows")
-## @deftypefnx {Function File} {} unique (@dots{}, "first")
-## @deftypefnx {Function File} {} unique (@dots{}, "last")
 ## @deftypefnx {Function File} {[@var{y}, @var{i}, @var{j}] =} unique (@dots{})
-## Return the unique elements of @var{x}, sorted in ascending order.
-## If the input @var{x} is a vector then the output is also a vector with the
-## same orientation (row or column) as the input.  For a matrix input the
-## output is always a column vector.  @var{x} may also be a cell array of
-## strings.
+## @deftypefnx {Function File} {[@var{y}, @var{i}, @var{j}] =} unique (@dots{}, "first")
+## @deftypefnx {Function File} {[@var{y}, @var{i}, @var{j}] =} unique (@dots{}, "last")
+## Return the unique elements of @var{x} sorted in ascending order.
 ##
-## If the optional argument @qcode{"rows"} is supplied, return the unique
-## rows of @var{x}, sorted in ascending order.
+## If the input @var{x} is a column vector then return a column vector;
+## Otherwise, return a row vector.  @var{x} may also be a cell array of strings.
+##
+## If the optional argument @qcode{"rows"} is given then return the unique
+## rows of @var{x} sorted in ascending order.  The input must be a 2-D matrix
+## to use this option.
 ##
 ## If requested, return index vectors @var{i} and @var{j} such that
-## @code{x(i)==y} and @code{y(j)==x}.
+## @code{@var{y} = @var{x}(@var{i})} and @code{@var{x} = @var{y}(@var{j})}.
 ##
 ## Additionally, if @var{i} is a requested output then one of @qcode{"first"} or
 ## @qcode{"last"} may be given as an input.  If @qcode{"last"} is specified,
@@ -46,37 +46,35 @@
 
   if (nargin < 1)
     print_usage ();
+  elseif (! (ismatrix (x) || iscellstr (x)))
+    error ("unique: X must be a matrix or cell array of strings");
   endif
 
   if (nargin > 1)
     ## parse options
-    if (iscellstr (varargin))
-      optfirst = strcmp ("first", varargin);
-      optlast  = strcmp ("last", varargin);
-      optrows  = strcmp ("rows", varargin);
-      if (! all (optfirst | optlast | optrows))
-        error ("unique: invalid option");
-      endif
-      optfirst = any (optfirst);
-      optlast  = any (optlast);
-      optrows  = any (optrows);
-      if (optfirst && optlast)
-        error ('unique: cannot specify both "last" and "first"');
-      endif
-    else
+    if (! iscellstr (varargin))
       error ("unique: options must be strings");
     endif
 
-    if (optrows && iscell (x))
+    optrows  = any (strcmp ("rows", varargin));
+    optfirst = any (strcmp ("first", varargin));
+    optlast  = any (strcmp ("last", varargin));
+    if (optfirst && optlast)
+      error ('unique: cannot specify both "first" and "last"');
+    elseif (optfirst + optlast + optrows != nargin-1)
+      error ("unique: invalid option");
+    endif
+
+    if (optrows && iscellstr (x))
       warning ('unique: "rows" is ignored for cell arrays');
       optrows = false;
     endif
   else
+    optrows = false;
     optfirst = false;
-    optrows = false;
   endif
 
-  ## FIXME -- the operations
+  ## FIXME: The operations
   ##
   ##   match = (y(1:n-1) == y(2:n));
   ##   y(idx) = [];
@@ -87,7 +85,7 @@
 
   if (issparse (x) && ! optrows && nargout <= 1)
     if (nnz (x) < numel (x))
-      y = unique ([0; (full (nonzeros (x)))], varargin{:});
+      y = unique ([0; nonzeros(x)], varargin{:});
     else
       ## Corner case where sparse matrix is actually full
       y = unique (full (x), varargin{:});
@@ -107,7 +105,7 @@
   ## Special cases 0 and 1
   if (n == 0)
     if (! optrows && isempty (x) && any (size (x)))
-      if (iscell (y))
+      if (iscellstr (y))
         y = cell (0, 1);
       else
         y = zeros (0, 1, class (y));
@@ -127,8 +125,7 @@
       y = sortrows (y);
     endif
     match = all (y(1:n-1,:) == y(2:n,:), 2);
-    idx = find (match);
-    y(idx,:) = [];
+    y(match,:) = [];
   else
     if (! isvector (y))
       y = y(:);
@@ -138,13 +135,12 @@
     else
       y = sort (y);
     endif
-    if (iscell (y))
+    if (iscellstr (y))
       match = strcmp (y(1:n-1), y(2:n));
     else
       match = (y(1:n-1) == y(2:n));
     endif
-    idx = find (match);
-    y(idx) = [];
+    y(match) = [];
   endif
 
   if (isargout (3))
@@ -157,25 +153,25 @@
   endif
 
   if (isargout (2))
+    idx = find (match);
     if (optfirst)
-      i(idx+1) = [];
-    else
-      i(idx) = [];
+      idx += 1;   # in-place is faster than other forms of increment
     endif
+    i(idx) = [];
   endif
 
 endfunction
 
 
-%!assert (unique ([1 1 2; 1 2 1; 1 1 2]),[1;2])
-%!assert (unique ([1 1 2; 1 0 1; 1 1 2],"rows"),[1 0 1; 1 1 2])
-%!assert (unique ([]),[])
-%!assert (unique ([1]),[1])
-%!assert (unique ([1 2]),[1 2])
-%!assert (unique ([1;2]),[1;2])
-%!assert (unique ([1,NaN,Inf,NaN,Inf]),[1,Inf,NaN,NaN])
-%!assert (unique ({"Foo","Bar","Foo"}),{"Bar","Foo"})
-%!assert (unique ({"Foo","Bar","FooBar"}'),{"Bar","Foo","FooBar"}')
+%!assert (unique ([1 1 2; 1 2 1; 1 1 2]), [1;2])
+%!assert (unique ([1 1 2; 1 0 1; 1 1 2],"rows"), [1 0 1; 1 1 2])
+%!assert (unique ([]), [])
+%!assert (unique ([1]), [1])
+%!assert (unique ([1 2]), [1 2])
+%!assert (unique ([1;2]), [1;2])
+%!assert (unique ([1,NaN,Inf,NaN,Inf]), [1,Inf,NaN,NaN])
+%!assert (unique ({"Foo","Bar","Foo"}), {"Bar","Foo"})
+%!assert (unique ({"Foo","Bar","FooBar"}'), {"Bar","Foo","FooBar"}')
 %!assert (unique (zeros (1,0)), zeros (0,1))
 %!assert (unique (zeros (1,0), "rows"), zeros (1,0))
 %!assert (unique (cell (1,0)), cell (0,1))
@@ -192,6 +188,7 @@
 %!assert (unique (uint8 ([1,2,2,3,2,4]), "rows"), uint8 ([1,2,2,3,2,4]))
 %!assert (unique (uint8 ([1,2,2,3,2,4])), uint8 ([1,2,3,4]))
 %!assert (unique (uint8 ([1,2,2,3,2,4]'), "rows"), uint8 ([1,2,3,4]'))
+
 %!test
 %! [a,i,j] = unique ([1,1,2,3,3,3,4]);
 %! assert (a, [1,2,3,4]);
@@ -217,8 +214,15 @@
 %! assert (A(i,:), a);
 %! assert (a(j,:), A);
 
-%!error unique({"a", "b", "c"}, "UnknownOption")
-%!error unique({"a", "b", "c"}, "UnknownOption1", "UnknownOption2")
-%!error unique({"a", "b", "c"}, "rows", "UnknownOption2")
-%!error unique({"a", "b", "c"}, "UnknownOption1", "last")
+%% Test input validation
+%!error unique ()
+%!error <X must be a matrix or cell array of strings> unique ({1})
+%!error <options must be strings> unique (1, 2)
+%!error <cannot specify both "first" and "last"> unique (1, "first", "last")
+%!error <invalid option> unique (1, "middle")
+%!error <invalid option> unique ({"a", "b", "c"}, "UnknownOption")
+%!error <invalid option> unique ({"a", "b", "c"}, "UnknownOption1", "UnknownOption2")
+%!error <invalid option> unique ({"a", "b", "c"}, "rows", "UnknownOption2")
+%!error <invalid option> unique ({"a", "b", "c"}, "UnknownOption1", "last")
+%!warning <"rows" is ignored for cell arrays> unique ({"1"}, "rows");
 
--- a/scripts/signal/arch_fit.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/signal/arch_fit.m	Fri Feb 06 08:31:49 2015 -0800
@@ -19,7 +19,7 @@
 ## -*- texinfo -*-
 ## @deftypefn {Function File} {[@var{a}, @var{b}] =} arch_fit (@var{y}, @var{x}, @var{p}, @var{iter}, @var{gamma}, @var{a0}, @var{b0})
 ## Fit an ARCH regression model to the time series @var{y} using the
-## scoring algorithm in Engle's original ARCH paper.  The model is
+## scoring algorithm in @nospell{Engle's} original ARCH paper.  The model is
 ##
 ## @example
 ## @group
--- a/scripts/signal/bartlett.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/signal/bartlett.m	Fri Feb 06 08:31:49 2015 -0800
@@ -21,8 +21,9 @@
 ## Return the filter coefficients of a Bartlett (triangular) window of
 ## length @var{m}.
 ##
-## For a definition of the Bartlett window, see e.g., A. V. Oppenheim &
-## R. W. Schafer, @cite{Discrete-Time Signal Processing}.
+## For a definition of the Bartlett window, see e.g.,
+## @nospell{A.V. Oppenheim & R. W. Schafer},
+## @cite{Discrete-Time Signal Processing}.
 ## @end deftypefn
 
 ## Author: AW <Andreas.Weingessel@ci.tuwien.ac.at>
--- a/scripts/signal/blackman.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/signal/blackman.m	Fri Feb 06 08:31:49 2015 -0800
@@ -20,8 +20,9 @@
 ## @deftypefn {Function File} {} blackman (@var{m})
 ## Return the filter coefficients of a Blackman window of length @var{m}.
 ##
-## For a definition of the Blackman window, see e.g., A. V. Oppenheim &
-## R. W. Schafer, @cite{Discrete-Time Signal Processing}.
+## For a definition of the Blackman window, see e.g.,
+## @nospell{A.V. Oppenheim & R. W. Schafer},
+## @cite{Discrete-Time Signal Processing}.
 ## @end deftypefn
 
 ## Author: AW <Andreas.Weingessel@ci.tuwien.ac.at>
--- a/scripts/signal/diffpara.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/signal/diffpara.m	Fri Feb 06 08:31:49 2015 -0800
@@ -32,7 +32,7 @@
 ## described above is returned in @var{dd}.  The value of @var{d} is
 ## simply the mean of @var{dd}.
 ##
-## Reference: P.J. Brockwell & R.A. Davis. @cite{Time Series:
+## Reference: @nospell{P.J. Brockwell & R.A. Davis}. @cite{Time Series:
 ## Theory and Methods}. Springer 1987.
 ## @end deftypefn
 
--- a/scripts/signal/durbinlevinson.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/signal/durbinlevinson.m	Fri Feb 06 08:31:49 2015 -0800
@@ -18,7 +18,7 @@
 
 ## -*- texinfo -*-
 ## @deftypefn {Function File} {} durbinlevinson (@var{c}, @var{oldphi}, @var{oldv})
-## Perform one step of the Durbin-Levinson algorithm.
+## Perform one step of the @nospell{Durbin-Levinson} algorithm.
 ##
 ## The vector @var{c} specifies the autocovariances @code{[gamma_0, @dots{},
 ## gamma_t]} from lag 0 to @var{t}, @var{oldphi} specifies the
--- a/scripts/signal/hamming.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/signal/hamming.m	Fri Feb 06 08:31:49 2015 -0800
@@ -20,8 +20,9 @@
 ## @deftypefn {Function File} {} hamming (@var{m})
 ## Return the filter coefficients of a Hamming window of length @var{m}.
 ##
-## For a definition of the Hamming window, see e.g., A. V. Oppenheim &
-## R. W. Schafer, @cite{Discrete-Time Signal Processing}.
+## For a definition of the Hamming window, see e.g.,
+## @nospell{A.V. Oppenheim & R. W. Schafer},
+## @cite{Discrete-Time Signal Processing}.
 ## @end deftypefn
 
 ## Author: AW <Andreas.Weingessel@ci.tuwien.ac.at>
--- a/scripts/signal/hanning.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/signal/hanning.m	Fri Feb 06 08:31:49 2015 -0800
@@ -20,8 +20,9 @@
 ## @deftypefn {Function File} {} hanning (@var{m})
 ## Return the filter coefficients of a Hanning window of length @var{m}.
 ##
-## For a definition of this window type, see e.g., A. V. Oppenheim &
-## R. W. Schafer, @cite{Discrete-Time Signal Processing}.
+## For a definition of the Hanning window, see e.g.,
+## @nospell{A.V. Oppenheim & R. W. Schafer},
+## @cite{Discrete-Time Signal Processing}.
 ## @end deftypefn
 
 ## Author: AW <Andreas.Weingessel@ci.tuwien.ac.at>
--- a/scripts/signal/periodogram.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/signal/periodogram.m	Fri Feb 06 08:31:49 2015 -0800
@@ -1,5 +1,6 @@
 ## Copyright (C) 1995-2013 Friedrich Leisch
 ## Copyright (C) 2010 Alois Schloegl
+## Copyright (C) 2014 Drew Abbot
 ##
 ## This file is part of Octave.
 ##
@@ -18,43 +19,60 @@
 ## <http://www.gnu.org/licenses/>.
 
 ## -*- texinfo -*-
-## @deftypefn {Function File} {[Pxx, @var{w}] =} periodogram (@var{x})
-## For a data matrix @var{x} from a sample of size @var{n}, return the
-## periodogram.  The angular frequency is returned in @var{w}.
+## @deftypefn  {Function File} {[@var{Pxx}, @var{w}] =} periodogram (@var{x})
+## @deftypefnx {Function File} {[@var{Pxx}, @var{w}] =} periodogram (@var{x}, @var{win})
+## @deftypefnx {Function File} {[@var{Pxx}, @var{w}] =} periodogram (@var{x}, @var{win}, @var{nfft})
+## @deftypefnx {Function File} {[@var{Pxx}, @var{f}] =} periodogram (@var{x}, @var{win}, @var{nfft}, @var{Fs})
+## @deftypefnx {Function File} {[@var{Pxx}, @var{f}] =} periodogram (@dots{}, "@var{range}")
+## @deftypefnx {Function File} {} periodogram (@dots{})
 ##
-## [Pxx,w] = periodogram (@var{x}).
+## Return the periodogram (Power Spectral Density) of @var{x}.
 ##
-## [Pxx,w] = periodogram (@var{x},win).
+## The possible inputs are:
 ##
-## [Pxx,w] = periodogram (@var{x},win,nfft).
-##
-## [Pxx,f] = periodogram (@var{x},win,nfft,Fs).
+## @table @var
+## @item x
 ##
-## [Pxx,f] = periodogram (@var{x},win,nfft,Fs,"range").
+## data vector.  If @var{x} is real-valued a one-sided spectrum is estimated.
+## If @var{x} is complex-valued, or @qcode{"@var{range}"} specifies
+## @qcode{"@nospell{twosided}"}, the full spectrum is estimated.
 ##
-## @itemize
-## @item x: data; if real-valued a one-sided spectrum is estimated,
-## if complex-valued or range indicates @qcode{"@nospell{twosided}"}, the full
-## spectrum is estimated.
+## @item win
+## window weight data.  If window is empty or unspecified a default rectangular
+## window is used.  Otherwise, the window is applied to the signal
+## (@code{@var{x} .* @var{win}}) before computing the periodogram.  The window
+## data must be a vector of the same length as @var{x}.
 ##
-## @item win: weight data with window, x.*win is used for further computation,
-## if window is empty, a rectangular window is used.
+## @item nfft
+## number of frequency bins.  The default is 256 or the next higher power of
+## 2 greater than the length of @var{x}
+## (@code{max (256, 2.^nextpow2 (length (x)))}).  If @var{nfft} is greater
+## than the length of the input then @var{x} will be zero-padded to the length
+## of @var{nfft}.
 ##
-## @item nfft: number of frequency bins, default max (256, 2.^ceil (log2 (length (x)))).
-##
-## @item Fs: sampling rate, default 1.
+## @item Fs
+## sampling rate.  The default is 1.
 ##
-## @item range: @qcode{"@nospell{onesided}"} computes spectrum from [0..nfft/2+1].
-## @qcode{"@nospell{twosided}"} computes spectrum from [0..nfft-1].  These
-## strings can appear at any position in the list input arguments after
-## window.
+## @item range
+## range of spectrum.  @qcode{"@nospell{onesided}"} computes spectrum from
+## [0..nfft/2+1].  @qcode{"@nospell{twosided}"} computes spectrum from
+## [0..nfft-1].
+## @end table
 ##
-## @item @nospell{Pxx}: one-, or two-sided power spectrum.
+## The optional second output @var{w} are the normalized angular frequencies.
+## For a one-sided calculation @var{w} is in the range [0, pi] if @var{nfft}
+## is even and [0, pi) if @var{nfft} is odd.  Similarly, for a two-sided
+## calculation @var{w} is in the range [0, 2*pi] or [0, 2*pi) depending on
+## @var{nfft}.
 ##
-## @item w: angular frequency [0..2*pi) (two-sided) or [0..pi] one-sided.
+## If a sampling frequency is specified, @var{Fs}, then the output frequencies
+## @var{f} will be in the range [0, @var{Fs}/2] or [0, @var{Fs}/2) for
+## one-sided calculations.  For two-sided calculations the range will be
+## [0, @var{Fs}).
 ##
-## @item f: frequency [0..Fs) (two-sided) or [0..Fs/2] one-sided.
-## @end itemize
+## When called with no outputs the periodogram is immediately plotted in the
+## current figure window.
+## @seealso{fft}
 ## @end deftypefn
 
 ## Author: FL <Friedrich.Leisch@ci.tuwien.ac.at>
@@ -63,117 +81,113 @@
 function [pxx, f] = periodogram (x, varargin)
 
   ## check input arguments
-
   if (nargin < 1 || nargin > 5)
     print_usage ();
   endif
 
-  nfft = []; fs = []; range = []; window = [];
-  j = 1;
+  nfft = fs = range = window = [];
+  j = 2;
   for k = 1:length (varargin)
     if (ischar (varargin{k}))
       range = varargin{k};
     else
       switch (j)
-        case 1
+        case 2
           window = varargin{k};
-        case 2
+        case 3
           nfft   = varargin{k};
-        case 3
+        case 4
           fs     = varargin{k};
-        case 4
-          range  = varargin{k};
       endswitch
       j++;
     endif
   endfor
 
-  [r, c] = size (x);
-  if (r == 1)
-    r = c;
+  if (! isvector (x))
+    error ("periodogram: X must be a real or complex vector");
+  endif
+  x = x(:);  # Use column vectors from now on
+
+  n = rows (x);
+
+  if (! isempty (window))
+    if (! isvector (window) || length (window) != n)
+      error ("periodogram: WIN must be a vector of the same length as X");
+    endif
+    window = window(:);
+    x .*= window;
   endif
 
-  if (ischar (window))
-    range = window;
-    window = [];
-  endif;
-  if (ischar (nfft))
-    range = nfft;
-    nfft = [];
-  endif;
-  if (ischar (fs))
-    range = fs;
-    fs = [];
-  endif;
-
-  if (!  isempty (window))
-    if (all (size (x) == size (window)))
-      x .*= window;
-    elseif (rows (x) == rows (window) && columns (window) == 1)
-      x .*= window (:,ones (1,c));
-    endif;
+  if (isempty (nfft))
+    nfft = max (256, 2.^nextpow2 (n));
+  elseif (! isscalar (nfft))
+    error ("periodogram: NFFT must be a scalar");
   endif
 
-  if (numel (nfft)>1)
-    error ("nfft must be scalar");
-  endif
-  if (isempty (nfft))
-    nfft = max (256, 2.^ceil (log2 (r)));
+  use_w_freq = isempty (fs);
+  if (! use_w_freq && ! isscalar (fs))
+    error ("periodogram: FS must be a scalar");
   endif
 
-  if (strcmp (range, "onesided"))
+  if (strcmpi (range, "onesided"))
     range = 1;
-  elseif (strcmp (range, "twosided"))
+  elseif (strcmpi (range, "twosided"))
     range = 2;
+  elseif (strcmpi (range, "centered"))
+    error ('periodogram: "centered" range type is not implemented');
   else
     range = 2-isreal (x);
   endif
 
   ## compute periodogram
 
-  if (r>nfft)
+  if (n > nfft)
     Pxx = 0;
     rr = rem (length (x), nfft);
     if (rr)
-      x = [x(:); (zeros (nfft-rr, 1))];
+      x = [x(:); zeros(nfft-rr, 1)];
     endif
     x = sum (reshape (x, nfft, []), 2);
   endif
 
-  if (isempty (window))
-    n = r;
-  else
+  if (! isempty (window))
     n = sumsq (window);
-  end;
-  Pxx = (abs (fft (x, nfft))) .^ 2 / n ;
+  endif;
+  Pxx = (abs (fft (x, nfft))) .^ 2 / n;
 
-  if (nargin<4)
+  if (use_w_freq)
     Pxx /= 2*pi;
-  elseif (! isempty (fs))
+  else
     Pxx /= fs;
   endif
 
   ## generate output arguments
 
   if (range == 1)  # onesided
-    Pxx = Pxx(1:nfft/2+1) + [0; Pxx(end:-1:(nfft/2+2)); 0];
+    if (! rem (nfft,2))  # nfft is even
+      psd_len = nfft/2+1;
+      Pxx = Pxx(1:psd_len) + [0; Pxx(nfft:-1:psd_len+1); 0];
+    else                 # nfft is odd
+      psd_len = (nfft+1)/2;
+      Pxx = Pxx(1:psd_len) + [0; Pxx(nfft:-1:psd_len+1)];
+    endif
   endif
 
   if (nargout != 1)
     if (range == 1)
-      f = (0:nfft/2)'/nfft;
+      f = (0:nfft/2)' / nfft;
     elseif (range == 2)
-      f = (0:nfft-1)'/nfft;
+      f = (0:nfft-1)' / nfft;
     endif
-    if (nargin<4)
-      f *= 2*pi; # generate w=2*pi*f
-    elseif (! isempty (fs))
+    if (use_w_freq)
+      f *= 2*pi;  # generate w=2*pi*f
+    else
       f *= fs;
     endif
   endif
 
   if (nargout == 0)
-    if (nargin<4)
+    if (use_w_freq)
       plot (f/(2*pi), 10*log10 (Pxx));
       xlabel ("normalized frequency [x pi rad]");
       ylabel ("Power density [dB/rad/sample]");
@@ -190,3 +204,17 @@
 
 endfunction
 
+
+## FIXME: Need some functional tests
+
+
+%% Test input validation
+%!error periodogram ()
+%!error periodogram (1,2,3,4,5,6)
+%!error <X must be a real or complex vector> periodogram (ones (2,2))
+%!error <WIN must be a vector.*same length> periodogram (1:5, ones (2,2))
+%!error <WIN must be a vector.*same length> periodogram (1:5, 1:6)
+%!error <NFFT must be a scalar> periodogram (1:5, 1:5, 1:5)
+%!error <FS must be a scalar> periodogram (1:5, [], [], 1:5)
+%!error <"centered" range type is not implemented> periodogram (1:5, "centered")
+
--- a/scripts/sparse/colperm.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/sparse/colperm.m	Fri Feb 06 08:31:49 2015 -0800
@@ -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/eigs.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/sparse/eigs.m	Fri Feb 06 08:31:49 2015 -0800
@@ -183,9 +183,9 @@
 ## of the convergence.  If @var{flag} is 0 then all eigenvalues have converged.
 ## Any other value indicates a failure to converge.
 ##
-## This function is based on the @sc{arpack} package, written by R. Lehoucq,
-## K. Maschhoff, D. Sorensen, and C. Yang.  For more information see
-## @url{http://www.caam.rice.edu/software/ARPACK/}.
+## This function is based on the @sc{arpack} package, written by
+## @nospell{R. Lehoucq, K. Maschhoff, D. Sorensen, and C. Yang}.  For more
+## information see @url{http://www.caam.rice.edu/software/ARPACK/}.
 ##
 ## @seealso{eig, svds}
 ## @end deftypefn
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/sparse/ichol.m	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,470 @@
+## Copyright (C) 2014 Eduardo Ramos Fernández <eduradical951@gmail.com>
+## Copyright (C) 2013 Kai T. Ohlhus <k.ohlhus@gmail.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} {@var{L} =} ichol (@var{A})
+## @deftypefnx {Function File} {@var{L} =} ichol (@var{A}, @var{opts})
+##
+## Compute the incomplete Cholesky factorization of the sparse square matrix
+## @var{A}.
+##
+## By default, @code{ichol} uses only the lower triangle of @var{A} and
+## produces a lower triangular factor @var{L} such that @tcode{L*L'}
+## approximates @var{A}.
+##
+## The factor given by this routine may be useful as a preconditioner for a
+## system of linear equations being solved by iterative methods such as
+## PCG (Preconditioned Conjugate Gradient).
+##
+## The factorization may be modified by passing options in a structure
+## @var{opts}.  The option name is a field of the structure and the setting
+## is the value of field.  Names and specifiers are case sensitive.
+##
+## @table @asis
+## @item type
+## Type of factorization.
+##
+## @table @asis
+## @item @qcode{"nofill"} (default)
+## Incomplete Cholesky factorization with no fill-in (@nospell{IC(0)}).
+##
+## @item @qcode{"ict"}
+## Incomplete Cholesky factorization with threshold dropping (@nospell{ICT}).
+## @end table
+##
+## @item diagcomp
+## A non-negative scalar @var{alpha} for incomplete Cholesky factorization of
+## @code{@var{A} + @var{alpha} * diag (diag (@var{A}))} instead of @var{A}.
+## This can be useful when @var{A} is not positive definite.  The default value
+## is 0.
+##
+## @item droptol
+## A non-negative scalar specifying the drop tolerance for factorization if
+## performing @nospell{ICT}@.  The default value is 0 which produces the
+## complete Cholesky factorization.
+##
+## Non-diagonal entries of @var{L} are set to 0 unless
+##
+## @code{abs (@var{L}(i,j)) >= droptol * norm (@var{A}(j:end, j), 1)}.
+##
+## @item michol
+## Modified incomplete Cholesky factorization:
+##
+## @table @asis
+## @item @qcode{"off"} (default)
+## Row and column sums are not necessarily preserved.
+##
+## @item @qcode{"on"}
+## The diagonal of @var{L} is modified so that row (and column) sums are
+## preserved even when elements have been dropped during the factorization.
+## The relationship preserved is: @code{@var{A} * e = @var{L} * @var{L}' * e},
+## where e is a vector of ones.
+## @end table
+##
+## @item shape
+##
+## @table @asis
+## @item @qcode{"lower"} (default)
+## Use only the lower triangle of @var{A} and return a lower triangular
+## factor @var{L} such that @tcode{L*L'} approximates @var{A}.
+##
+## @item @qcode{"upper"}
+## Use only the upper triangle of @var{A} and return an upper triangular
+## factor @var{U} such that @code{U'*U} approximates @var{A}.
+## @end table
+## @end table
+##
+## EXAMPLES
+##
+## The following problem demonstrates how to factorize a sample symmetric
+## positive definite matrix with the full Cholesky decomposition and with the
+## incomplete one.
+##
+## @example
+## @group
+## A = [ 0.37, -0.05,  -0.05,  -0.07;
+##      -0.05,  0.116,  0.0,   -0.05;
+##      -0.05,  0.0,    0.116, -0.05;
+##      -0.07, -0.05,  -0.05,   0.202];
+## A = sparse (A);
+## nnz (tril (A))
+## ans =  9
+## L = chol (A, "lower");
+## nnz (L)
+## ans =  10
+## norm (A - L * L', "fro") / norm (A, "fro")
+## ans =  1.1993e-16
+## opts.type = "nofill";
+## L = ichol (A, opts);
+## nnz (L)
+## ans =  9
+## norm (A - L * L', "fro") / norm (A, "fro")
+## ans =  0.019736
+## @end group
+## @end example
+##
+## Another example for decomposition is a finite difference matrix used to
+## solve a boundary value problem on the unit square.
+##
+## @example
+## @group
+## nx = 400; ny = 200;
+## hx = 1 / (nx + 1); hy = 1 / (ny + 1);
+## Dxx = spdiags ([ones(nx, 1), -2*ones(nx, 1), ones(nx, 1)],
+##                [-1 0 1 ], nx, nx) / (hx ^ 2);
+## Dyy = spdiags ([ones(ny, 1), -2*ones(ny, 1), ones(ny, 1)],
+##                [-1 0 1 ], ny, ny) / (hy ^ 2);
+## A = -kron (Dxx, speye (ny)) - kron (speye (nx), Dyy);
+## nnz (tril (A))
+## ans =  239400
+## opts.type = "nofill";
+## L = ichol (A, opts);
+## nnz (tril (A))
+## ans =  239400
+## norm (A - L * L', "fro") / norm (A, "fro")
+## ans =  0.062327
+## @end group
+## @end example
+##
+## References for implemented algorithms:
+##
+## [1] @nospell{Y. Saad}. "Preconditioning Techniques." @cite{Iterative
+## Methods for Sparse Linear Systems}, @nospell{PWS} Publishing Company, 1996.
+##
+## [2] @nospell{M. Jones, P. Plassmann}: @cite{An Improved Incomplete
+## Cholesky Factorization}, 1992.
+## @seealso{chol, ilu, pcg}
+## @end deftypefn
+
+function L = ichol (A, opts = struct ())
+
+  if (nargin < 1 || nargin > 2 || nargout > 1)
+    print_usage ();
+  endif
+
+  if (! (issparse (A) && issquare (A)))
+    error ("ichol: A must be a sparse square matrix");
+  endif
+
+  if (! isstruct (opts))
+    error ("ichol: OPTS must be a structure.");
+  endif
+
+  ## If A is empty then return empty L for Matlab compatibility
+  if (isempty (A))
+    L = A;
+    return;
+  endif
+
+  ## Parse input options
+  if (! isfield (opts, "type"))
+    opts.type = "nofill";  # set default
+  else
+    type = tolower (getfield (opts, "type"));
+    if (! strcmp (type, "nofill") && ! strcmp (type, "ict"))
+      error ('ichol: TYPE must be "nofill" or "ict"');
+    endif
+    opts.type = type;
+  endif
+
+  if (! isfield (opts, "droptol"))
+    opts.droptol = 0;      # set default
+  else
+    if (! (isreal (opts.droptol) && isscalar (opts.droptol)
+           && opts.droptol >= 0))
+      error ("ichol: DROPTOL must be a non-negative real scalar");
+    endif
+  endif
+
+  michol = "";
+  if (! isfield (opts, "michol"))
+    opts.michol = "off";   # set default
+  else
+    michol = tolower (getfield (opts, "michol"));
+    if (! strcmp (michol, "off") && ! strcmp (michol, "on"))
+      error ('ichol: MICHOL must be "on" or "off"');
+    endif
+    opts.michol = michol;
+  endif
+
+  if (! isfield (opts, "diagcomp"))
+    opts.diagcomp = 0;     # set default
+  else
+    if (! (isreal (opts.diagcomp) && isscalar (opts.diagcomp)
+           && opts.diagcomp >= 0))
+      error ("ichol: DIAGCOMP must be a non-negative real scalar");
+    endif
+  endif
+
+  if (! isfield (opts, "shape"))
+    opts.shape = "lower";  # set default
+  else
+    shape = tolower (getfield (opts, "shape"));
+    if (! strcmp (shape, "lower") && ! strcmp (shape, "upper"))
+      error ('ichol: SHAPE must be "lower" or "upper"');
+    endif
+    opts.shape = shape;
+  endif
+
+  ## Prepare input for specialized ICHOL
+  A_in = [];
+  if (opts.diagcomp > 0)
+    A += opts.diagcomp * diag (diag (A));
+  endif
+  if (strcmp (opts.shape, "upper"))
+    A_in = triu (A);
+    A_in = A_in';
+  else
+    A_in = tril (A);
+  endif
+
+  ## Delegate to specialized ICHOL
+  switch (opts.type)
+    case "nofill"
+      L  = __ichol0__ (A_in, opts.michol);
+    case "ict"
+      L = __icholt__ (A_in, opts.droptol, opts.michol);
+  endswitch
+
+  if (strcmp (opts.shape, "upper"))
+    L = L';
+  endif
+
+endfunction
+
+
+%!shared A1, A2, A3, A4, A5, A6, A7
+%! A1 = [ 0.37, -0.05,  -0.05,  -0.07;
+%!       -0.05,  0.116,  0.0,   -0.05;
+%!       -0.05,  0.0,    0.116, -0.05;
+%!       -0.07, -0.05,  -0.05,   0.202];
+%! A1 = sparse (A1);
+%! A2 = gallery ("poisson", 30);
+%! A3 = gallery ("tridiag", 50);
+%! nx = 400; ny = 200;
+%! hx = 1 / (nx + 1); hy = 1 / (ny + 1);
+%! Dxx = spdiags ([ones(nx, 1), -2*ones(nx, 1), ones(nx, 1)],
+%!                [-1 0 1 ], nx, nx) / (hx ^ 2);
+%! Dyy = spdiags ([ones(ny, 1), -2*ones(ny, 1), ones(ny, 1)],
+%!                [-1 0 1 ], ny, ny) / (hy ^ 2);
+%! A4 = -kron (Dxx, speye (ny)) - kron (speye (nx), Dyy);
+%! A5 = [ 0.37, -0.05,         -0.05,  -0.07;
+%!       -0.05,  0.116,         0.0,   -0.05 + 0.05i;
+%!       -0.05,  0.0,           0.116, -0.05;
+%!       -0.07, -0.05 - 0.05i, -0.05,   0.202];
+%! A5 = sparse (A5);
+%! A6 = [ 0.37,     -0.05 - i, -0.05,  -0.07;
+%!       -0.05 + i,  0.116,     0.0,   -0.05;
+%!       -0.05,      0.0,       0.116, -0.05;
+%!       -0.07,     -0.05,     -0.05,   0.202];
+%! A6 = sparse (A6);
+%! A7 = A5;
+%! A7(1) = 2i;
+
+## ICHOL0 tests
+
+%!test
+%! opts.type = "nofill";
+%! opts.michol = "off";
+%! assert (nnz (tril (A1)), nnz (ichol (A1, opts)));
+%! assert (nnz (tril (A2)), nnz (ichol (A2, opts)));
+%! assert (nnz (tril (A3)), nnz (ichol (A3, opts)));
+%! assert (nnz (tril (A4)), nnz (ichol (A4, opts)));
+%! assert (nnz (tril (A5)), nnz (ichol (A5, opts)));
+%!
+%!test
+%! opts.type = "nofill";
+%! opts.michol = "off";
+%! L = ichol (A1, opts);
+%! assert (norm (A1 - L * L', "fro") / norm (A1, "fro"), 0.0197, 1e-4);
+%! opts.shape = "upper";
+%! U = ichol (A1, opts);
+%! assert (norm (A1 - U' * U, "fro") / norm (A1, "fro"), 0.0197, 1e-4);
+%! opts.shape = "lower";
+%! L = ichol (A1, opts);
+%! assert (norm (A1 - L * L', "fro") / norm (A1, "fro"), 0.0197, 1e-4);
+%!
+%!test
+%! opts.michol = "on";
+%! opts.shape = "lower";
+%! opts.type = "nofill";
+%! L = ichol (A1, opts);
+%! assert (norm (A1 - L * L', "fro") / norm (A1, "fro"), 0.0279, 1e-4);
+%! opts.shape = "upper";
+%! U = ichol (A1, opts);
+%! assert (norm (A1 - U' * U, "fro") / norm (A1, "fro"), 0.0279, 1e-4);
+%! opts.shape = "lower";
+%! opts.diagcomp = 3e-3;
+%! L = ichol (A1, opts);
+%! assert (norm (A1 - L * L', "fro") / norm (A1, "fro"), 0.0272, 1e-4);
+%!
+%!test
+%! opts.type = "nofill";
+%! opts.michol = "off";
+%! L = ichol (A2, opts);
+%! assert (norm (A2 - L*L', "fro") / norm (A2, "fro"), 0.0893, 1e-4)
+%! opts.michol = "on";
+%! L = ichol (A2, opts);
+%! assert (norm (A2 - L*L', "fro") / norm (A2, "fro"), 0.2377, 1e-4)
+%!
+%!test
+%! opts.type = "nofill";
+%! opts.michol = "off";
+%! L = ichol (A3, opts);
+%! assert (norm (A3 - L*L', "fro") / norm (A3, "fro"), eps, eps);
+%! opts.michol = "on";
+%! L = ichol (A3, opts);
+%! assert (norm (A3 - L*L', "fro") / norm (A3, "fro"), eps, eps);
+%!
+%!test
+%! opts.type = "nofill";
+%! opts.michol = "off";
+%! L = ichol (A4, opts);
+%! assert (norm (A4 - L*L', "fro") / norm (A4, "fro"), 0.0623, 1e-4);
+%! opts.michol = "on";
+%! L = ichol (A4, opts);
+%! assert (norm (A4 - L*L', "fro") / norm (A4, "fro"), 0.1664, 1e-4);
+%!
+%!test
+%! opts.type = "nofill";
+%! opts.michol = "off";
+%! L = ichol (A5, opts);
+%! assert (norm (A5 - L*L', "fro") / norm (A5, "fro"), 0.0195, 1e-4);
+%! opts.michol = "on";
+%! L = ichol (A5, opts);
+%! assert (norm (A5 - L*L', "fro") / norm (A5, "fro"), 0.0276, 1e-4);
+
+## Negative pivot
+%!error <negative pivot> ichol (A6)
+%!error ichol (A6)
+## Complex entry in the diagonal
+%!error <non-real pivot> ichol (A7)
+
+## ICHOLT tests
+
+%%!test
+%! opts.type = "ict";
+%! opts.droptol = 1e-1;
+%! opts.michol = "off";
+%! L = ichol (A1, opts);
+%! assert (norm (A1 - L * L', "fro") / norm (A1, "fro"), 0.2065, 1e-4);
+%! opts.shape = "upper";
+%! U = ichol (A1, opts);
+%! assert (norm (A1 - U' * U, "fro") / norm (A1, "fro"), 0.2065, 1e-4);
+%! opts.shape = "lower";
+%! L = ichol (A1, opts);
+%! assert (norm (A1 - L * L', "fro") / norm (A1, "fro"), 0.2065, 1e-4);
+%!
+%%!test
+%! opts.type = "ict";
+%! opts.droptol = 1e-1;
+%! opts.michol = "on";
+%! L = ichol (A1, opts);
+%! assert (norm (A1 - L * L', "fro") / norm (A1, "fro"), 0.3266, 1e-4);
+%! opts.shape = "upper";
+%! U = ichol (A1, opts);
+%! assert (norm (A1 - U' * U, "fro") / norm (A1, "fro"), 0.3266, 1e-4);
+%! opts.shape = "lower";
+%! opts.diagcomp = 3e-3;
+%! L = ichol (A1, opts);
+%! assert (norm (A1 - L * L', "fro") / norm (A1, "fro"), 0.3266, 1e-4);
+%!
+%!test
+%! opts.type = "ict";
+%! opts.droptol = 1e-1;
+%! opts.michol = "off";
+%! L = ichol (A2, opts);
+%! assert (norm (A2 - L*L', "fro") / norm (A2, "fro"),  0.0893, 1e-4)
+%! opts.michol = "on";
+%! L = ichol (A2, opts);
+%! assert (norm (A2 - L*L', "fro") / norm (A2, "fro"), 0.2377, 1e-4)
+%!
+%!test
+%! opts.type = "ict";
+%! opts.droptol = 1e-1;
+%! opts.michol = "off";
+%! L = ichol (A3, opts);
+%! assert (norm (A3 - L*L', "fro") / norm (A3, "fro"), eps, eps);
+%! opts.michol = "on";
+%! L = ichol (A3, opts);
+%! assert (norm (A3 - L*L', "fro") / norm (A3, "fro"), eps, eps);
+%!
+%!test
+%! opts.type = "ict";
+%! opts.droptol = 1e-1;
+%! opts.michol = "off";
+%! L = ichol (A4, opts);
+%! assert (norm (A4 - L*L', "fro") / norm (A4, "fro"), 0.1224, 1e-4);
+%! opts.michol = "on";
+%! L = ichol (A4, opts);
+%! assert (norm (A4 - L*L', "fro") / norm (A4, "fro"), 0.2118, 1e-4);
+%!
+%!test
+%! opts.type = "ict";
+%! opts.droptol = 1e-1;
+%! opts.michol = "off";
+%! L = ichol (A5, opts);
+%! assert (norm (A5 - L*L', "fro") / norm (A5, "fro"), 0.2044, 1e-4);
+%! opts.michol = "on";
+%! L = ichol (A5, opts);
+%! assert (norm (A5 - L*L', "fro") / norm (A5, "fro"), 0.3231, 1e-4);
+
+%% Input validation tests
+
+%!error <A must be a sparse square matrix> ichol ([])
+%!error <A must be a sparse square matrix> ichol (0)
+%!error <pivot equal to 0> ichol (sparse (0))
+%!error <pivot equal to 0> ichol (sparse (-0))
+%!error <negative pivot> ichol (sparse (-1))
+%!test
+%! opts.type = "foo";
+%! fail ("ichol (A1, opts)", 'TYPE must be "nofill"');
+%! opts.type = 1;
+%! fail ("ichol (A1, opts)", 'TYPE must be "nofill"');
+%! opts.type = [];
+%! fail ("ichol (A1, opts)", 'TYPE must be "nofill"');
+%!test
+%! opts.droptol = -1;
+%! fail ("ichol (A1, opts)", "DROPTOL must be a non-negative real scalar");
+%! opts.droptol = 0.5i;
+%! fail ("ichol (A1, opts)", "DROPTOL must be a non-negative real scalar");
+%! opts.droptol = [];
+%! fail ("ichol (A1, opts)", "DROPTOL must be a non-negative real scalar");
+%!test
+%! opts.michol = "foo";
+%! fail ("ichol (A1, opts)", 'MICHOL must be "on"');
+%! opts.michol = 1;
+%! fail ("ichol (A1, opts)", 'MICHOL must be "on"');
+%! opts.michol = [];
+%! fail ("ichol (A1, opts)", 'MICHOL must be "on"');
+%!test
+%! opts.diagcomp = -1;
+%! fail ("ichol (A1, opts)", "DIAGCOMP must be a non-negative real scalar");
+%! opts.diagcomp = 0.5i;
+%! fail ("ichol (A1, opts)", "DIAGCOMP must be a non-negative real scalar");
+%! opts.diagcomp = [];
+%! fail ("ichol (A1, opts)", "DIAGCOMP must be a non-negative real scalar");
+%!test
+%! opts.shape = "foo";
+%! fail ("ichol (A1, opts)", 'SHAPE must be "lower"');
+%! opts.shape = 1;
+%! fail ("ichol (A1, opts)", 'SHAPE must be "lower"');
+%! opts.shape = [];
+%! fail ("ichol (A1, opts)", 'SHAPE must be "lower"');
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/sparse/ilu.m	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,536 @@
+## Copyright (C) 2014 Eduardo Ramos Fernández <eduradical951@gmail.com>
+## Copyright (C) 2013 Kai T. Ohlhus <k.ohlhus@gmail.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} {} ilu (@var{A})
+## @deftypefnx {Function File} {} ilu (@var{A}, @var{opts})
+## @deftypefnx {Function File} {[@var{L}, @var{U}] =} ilu (@dots{})
+## @deftypefnx {Function File} {[@var{L}, @var{U}, @var{P}] =} ilu (@dots{})
+##
+## Compute the incomplete LU factorization of the sparse square matrix @var{A}.
+##
+## @code{ilu} returns a unit lower triangular matrix @var{L}, an upper
+## triangular matrix @var{U}, and optionally a permutation matrix @var{P}, such
+## that @code{@var{L}*@var{U}} approximates @code{@var{P}*@var{A}}.
+##
+## The factors given by this routine may be useful as preconditioners for a
+## system of linear equations being solved by iterative methods such as BICG
+## (BiConjugate Gradients) or GMRES (Generalized Minimum Residual Method).
+##
+## The factorization may be modified by passing options in a structure
+## @var{opts}.  The option name is a field of the structure and the setting
+## is the value of field.  Names and specifiers are case sensitive.
+##
+## @table @code
+## @item type
+## Type of factorization.
+##
+## @table @asis
+## @item @qcode{"nofill"}
+## ILU factorization with no fill-in (ILU(0)).
+##
+## Additional supported options: @code{milu}.
+##
+## @item @qcode{"crout"}
+## Crout version of ILU factorization (@nospell{ILUC}).
+##
+## Additional supported options: @code{milu}, @code{droptol}.
+##
+## @item @qcode{"ilutp"} (default)
+## ILU factorization with threshold and pivoting.
+##
+## Additional supported options: @code{milu}, @code{droptol}, @code{udiag},
+## @code{thresh}.
+## @end table
+##
+## @item droptol
+## A non-negative scalar specifying the drop tolerance for factorization.  The
+## default value is 0 which produces the complete LU factorization.
+##
+## Non-diagonal entries of @var{U} are set to 0 unless
+##
+## @code{abs (@var{U}(i,j)) >= droptol * norm (@var{A}(:,j))}.
+##
+## Non-diagonal entries of @var{L} are set to 0 unless
+##
+## @code{abs (@var{L}(i,j)) >= droptol * norm (@var{A}(:,j))/@var{U}(j,j)}.
+##
+## @item milu
+## Modified incomplete LU factorization:
+##
+## @table @asis
+## @item @qcode{"row"}
+## Row-sum modified incomplete LU factorization.
+## The factorization preserves row sums:
+## @code{@var{A} * e = @var{L} * @var{U} * e}, where e is a vector of ones.
+##
+## @item @qcode{"col"}
+## Column-sum modified incomplete LU factorization.
+## The factorization preserves column sums:
+## @code{e' * @var{A} = e' * @var{L} * @var{U}}.
+##
+## @item @qcode{"off"} (default)
+## Row and column sums are not necessarily preserved.
+## @end table
+##
+## @item udiag
+## If true, any zeros on the diagonal of the upper triangular factor are
+## replaced by the local drop tolerance
+## @code{droptol * norm (@var{A}(:,j))/@var{U}(j,j)}.  The default is false.
+##
+## @item thresh
+## Pivot threshold for factorization.  It can range between 0 (diagonal
+## pivoting) and 1 (default), where the maximum magnitude entry in the column
+## is chosen to be the pivot.
+## @end table
+##
+## If @code{ilu} is called with just one output, the returned matrix is
+## @code{@var{L} + @var{U} - speye (size (@var{A}))}, where @var{L} is unit
+## lower triangular and @var{U} is upper triangular.
+##
+## With two outputs, @code{ilu} returns a unit lower triangular matrix @var{L}
+## and an upper triangular matrix @var{U}.  For @var{opts}.type ==
+## @qcode{"ilutp"}, one of the factors is permuted based on the value of
+## @var{opts}.milu.  When @var{opts}.milu == @qcode{"row"}, @var{U} is a
+## column permuted upper triangular factor.  Otherwise, @var{L} is a
+## row-permuted unit lower triangular factor.
+##
+## If there are three named outputs and @var{opts}.milu != @qcode{"row"},
+## @var{P} is returned such that @var{L} and @var{U} are incomplete factors
+## of @code{@var{P}*@var{A}}.  When @var{opts}.milu == @qcode{"row"}, @var{P}
+## is returned such that @var{L} and @var{U} are incomplete factors of
+## @code{@var{A}*@var{P}}.
+##
+## EXAMPLES
+##
+## @example
+## @group
+## A = gallery ("neumann", 1600) + speye (1600);
+## opts.type = "nofill";
+## nnz (A)
+## ans = 7840
+##
+## nnz (lu (A))
+## ans = 126478
+##
+## nnz (ilu (A, opts))
+## ans = 7840
+## @end group
+## @end example
+##
+## This shows that @var{A} has 7,840 nonzeros, the complete LU factorization has
+## 126,478 nonzeros, and the incomplete LU factorization, with 0 level of
+## fill-in, has 7,840 nonzeros, the same amount as @var{A}.  Taken from:
+## http://www.mathworks.com/help/matlab/ref/ilu.html
+##
+## @example
+## @group
+## A = gallery ("wathen", 10, 10);
+## b = sum (A, 2);
+## tol = 1e-8;
+## maxit = 50;
+## opts.type = "crout";
+## opts.droptol = 1e-4;
+## [L, U] = ilu (A, opts);
+## x = bicg (A, b, tol, maxit, L, U);
+## norm (A * x - b, inf)
+## @end group
+## @end example
+##
+## This example uses ILU as preconditioner for a random FEM-Matrix, which has a
+## large condition number.  Without @var{L} and @var{U} BICG would not converge.
+##
+## @seealso{lu, ichol, bicg, gmres}
+## @end deftypefn
+
+function [L, U, P] = ilu (A, opts = struct ())
+
+  if (nargin < 1 || nargin > 2 || (nargout > 3))
+    print_usage ();
+  endif
+
+  if (! (issparse (A) && issquare (A)))
+    error ("ichol: A must be a sparse square matrix");
+  endif
+
+  if (! isstruct (opts))
+    error ("ichol: OPTS must be a structure.");
+  endif
+
+  ## If A is empty then return empty L, U and P for Matlab compatibility
+  if (isempty (A))
+    L = U = P = A;
+    return;
+  endif
+
+  ## Parse input options
+  if (! isfield (opts, "type"))
+    opts.type = "nofill";  # set default
+  else
+    type = tolower (getfield (opts, "type"));
+    if (! any (strcmp (type, {"nofill", "crout", "ilutp"})))
+      error ("ilu: invalid TYPE specified");
+    endif
+    opts.type = type;
+  endif
+
+  if (! isfield (opts, "droptol"))
+    opts.droptol = 0;      # set default
+  else
+    if (! (isreal (opts.droptol) && isscalar (opts.droptol)
+           && opts.droptol >= 0))
+      error ("ilu: DROPTOL must be a non-negative real scalar");
+    endif
+  endif
+
+  if (! isfield (opts, "milu"))
+    opts.milu = "off";     # set default
+  else
+    milu = tolower (getfield (opts, "milu"));
+    if (! any (strcmp (milu, {"off", "col", "row"})))
+      error ('ilu: MILU must be one of "off", "col", or "row"');
+    endif
+    opts.milu = milu;
+  endif
+
+  if (! isfield (opts, "udiag"))
+    opts.udiag = 0;        # set default
+  else
+    if (! isscalar (opts.udiag) || (opts.udiag != 0 && opts.udiag != 1))
+      error ("ilu: UDIAG must be 0 or 1");
+    endif
+  endif
+
+  if (! isfield (opts, "thresh"))
+    opts.thresh = 1;       # set default
+  else
+    if (! (isreal (opts.thresh) && isscalar (opts.thresh))
+        || opts.thresh < 0 || opts.thresh > 1)
+      error ("ilu: THRESH must be a scalar in the range [0, 1]");
+    endif
+  endif
+
+  n = length (A);
+
+  ## Delegate to specialized ILU
+  switch (opts.type)
+    case "nofill"
+        [L, U] = __ilu0__ (A, opts.milu);
+        if (nargout == 3)
+          P = speye (length (A));
+        endif
+    case "crout"
+        [L, U] = __iluc__ (A, opts.droptol, opts.milu);
+        if (nargout == 3)
+          P = speye (length (A));
+        endif
+    case "ilutp"
+        if (nargout == 2)
+          [L, U]  = __ilutp__ (A, opts.droptol, opts.thresh,
+                                  opts.milu, opts.udiag);
+        elseif (nargout == 3)
+          [L, U, P]  = __ilutp__ (A, opts.droptol, opts.thresh,
+                                     opts.milu, opts.udiag);
+        endif
+  endswitch
+
+  if (nargout == 1)
+    L = L + U - speye (n);
+  endif
+
+endfunction
+
+
+%!shared n, dtol, A
+%! n = 1600;
+%! dtol = 0.1;
+%! A = gallery ("neumann", n) + speye (n);
+%!test
+%! opts.type = "nofill";
+%! assert (nnz (ilu (A, opts)), 7840);
+## This test has been verified in both Matlab and Octave.
+%!test
+%! opts.type = "crout";
+%! opts.milu = "row";
+%! opts.droptol = dtol;
+%! [L, U] = ilu (A, opts);
+%! e = ones (size (A, 2),1);
+%! assert (norm (A*e - L*U*e), 1e-14, 1e-14);
+%!test
+%! opts.type = "crout";
+%! opts.droptol = dtol;
+%! [L, U] = ilu (A, opts);
+%! assert (norm (A - L * U, "fro") / norm (A, "fro"), 0.05, 1e-2);
+
+## Check if the elements in U satisfy the non-dropping condition.
+%!test
+%! opts.type = "crout";
+%! opts.droptol = dtol;
+%! [L, U] = ilu (A, opts);
+%! for j = 1:n
+%!   cmp_value = dtol * norm (A(:, j));
+%!   non_zeros = nonzeros (U(:, j));
+%!   assert (abs (non_zeros) >= cmp_value);
+%! endfor
+%!test
+%! opts.type = "ilutp";
+%! opts.droptol = dtol;
+%! [L, U] = ilu (A, opts);
+%! for j = 1:n
+%!   cmp_value = dtol * norm (A(:, j));
+%!   non_zeros = nonzeros (U(:, j));
+%!   assert (abs (non_zeros) >= cmp_value);
+%! endfor
+
+## Check that the complete LU factorisation with crout and ilutp algorithms
+## produce the same result.
+%!test
+%! opts.type = "crout";
+%! opts.droptol = 0;
+%! [L1, U1] = ilu (A, opts);
+%! opts.type = "ilutp";
+%! opts.thresh = 0;
+%! [L2, U2] = ilu (A, opts);
+%! assert (norm (L1 - L2, "fro") / norm (L1, "fro"), 0, eps);
+%! assert (norm (U1 - U2, "fro") / norm (U1, "fro"), 0, eps);
+
+## Tests for real matrices of different sizes for ilu0, iluc and ilutp.
+## The difference A - L*U should be not greater than eps because with droptol
+## equaling 0, the LU complete factorization is performed.
+%!shared n_tiny, n_small, n_medium, n_large, A_tiny, A_small, A_medium, A_large
+%! n_tiny = 5;
+%! n_small = 40;
+%! n_medium = 600;
+%! n_large = 10000;
+%! A_tiny = spconvert ([1 4 2 3 3 4 2 5; 1 1 2 3 4 4 5 5; 1 2 3 4 5 6 7 8]');
+%! A_small = sprand (n_small, n_small, 1/n_small) + speye (n_small);
+%! A_medium = sprand (n_medium, n_medium, 1/n_medium) + speye (n_medium);
+%! A_large = sprand (n_large, n_large, 1/n_large/10) + speye (n_large);
+%!
+%!test
+%! opts.type = "nofill";
+%! [L, U] = ilu (A_tiny);
+%! assert (norm (A_tiny - L*U, "fro") / norm (A_tiny, "fro"), 0, n_tiny * eps);
+%!test
+%! opts.type = "nofill";
+%! [L, U] = ilu (A_small);
+%! assert (norm (A_small - L*U, "fro") / norm (A_small, "fro"), 0, 1);
+%!test
+%! opts.type = "nofill";
+%! [L, U] = ilu (A_medium);
+%! assert (norm (A_medium - L*U, "fro") / norm (A_medium, "fro"), 0, 1);
+%!test
+%! opts.type = "nofill";
+%! [L, U] = ilu (A_large);
+%! assert (norm (A_large - L*U, "fro") / norm (A_large, "fro"), 0, 1);
+%!
+%!test
+%! opts.type = "crout";
+%! [L, U] = ilu (A_tiny, opts);
+%! assert (norm (A_tiny - L*U, "fro") / norm (A_tiny, "fro"), eps, eps);
+%!test
+%! opts.type = "crout";
+%! [L, U] = ilu (A_small, opts);
+%! assert (norm (A_small - L*U, "fro") / norm (A_small, "fro"), eps, eps);
+%!test
+%! opts.type = "crout";
+%! [L, U] = ilu (A_medium, opts);
+%! assert (norm (A_medium - L*U, "fro") / norm (A_medium, "fro"), eps, eps);
+%!test
+%! opts.type = "crout";
+%! [L, U] = ilu (A_large, opts);
+%! assert (norm (A_large - L*U, "fro") / norm (A_large, "fro"), eps, eps);
+%!
+%!test
+%! opts.type = "ilutp";
+%! opts.droptol = 0;
+%! opts.thresh = 0;
+%! [L, U] = ilu (A_tiny, opts);
+%! assert (norm (A_tiny - L*U, "fro") / norm (A_tiny, "fro"), eps, eps);
+%!test
+%! opts.type = "ilutp";
+%! opts.droptol = 0;
+%! opts.thresh = 0;
+%! [L, U] = ilu (A_small, opts);
+%! assert (norm (A_small - L*U, "fro") / norm (A_small, "fro"), eps, eps);
+%!test
+%! opts.type = "ilutp";
+%! opts.droptol = 0;
+%! opts.thresh = 0;
+%! [L, U] = ilu (A_medium, opts);
+%! assert (norm (A_medium - L*U, "fro") / norm (A_medium, "fro"), eps, eps);
+%!test
+%! opts.type = "ilutp";
+%! opts.droptol = 0;
+%! opts.thresh = 0;
+%! [L, U] = ilu (A_large, opts);
+%! assert (norm (A_large - L*U, "fro") / norm (A_large, "fro"), eps, eps);
+
+## Tests for complex matrices of different sizes for ilu0, iluc and ilutp.
+%!shared n_tiny, n_small, n_medium, n_large, A_tiny, A_small, A_medium, A_large
+%! n_tiny = 5;
+%! n_small = 40;
+%! n_medium = 600;
+%! n_large = 10000;
+%! A_tiny = spconvert ([1 4 2 3 3 4 2 5; 1 1 2 3 4 4 5 5; 1 2 3 4 5 6 7 8]');
+%! A_tiny(1,1) += 1i;
+%! A_small = sprand (n_small, n_small, 1/n_small) + ...
+%!   i * sprand (n_small, n_small, 1/n_small) + speye (n_small);
+%! A_medium = sprand (n_medium, n_medium, 1/n_medium) + ...
+%!   i * sprand (n_medium, n_medium, 1/n_medium) + speye (n_medium);
+%! A_large = sprand (n_large, n_large, 1/n_large/10) + ...
+%!   i * sprand (n_large, n_large, 1/n_large/10) + speye (n_large);
+%!
+%!test
+%! opts.type = "nofill";
+%! [L, U] = ilu (A_tiny);
+%! assert (norm (A_tiny - L*U, "fro") / norm (A_tiny, "fro"), 0, n_tiny * eps);
+%!test
+%! opts.type = "nofill";
+%! [L, U] = ilu (A_small);
+%! assert (norm (A_small - L*U, "fro") / norm (A_small, "fro"), 0, 1);
+%!test
+%! opts.type = "nofill";
+%! [L, U] = ilu (A_medium);
+%! assert (norm (A_medium - L*U, "fro") / norm (A_medium, "fro"), 0, 1);
+%!test
+%! opts.type = "nofill";
+%! [L, U] = ilu (A_large);
+%! assert (norm (A_large - L*U, "fro") / norm (A_large, "fro"), 0, 1);
+%!
+%!test
+%! opts.type = "crout";
+%! [L, U] = ilu (A_tiny, opts);
+%! assert (norm (A_tiny - L*U, "fro") / norm (A_tiny, "fro"), eps, eps);
+%!test
+%! opts.type = "crout";
+%! [L, U] = ilu (A_small, opts);
+%! assert (norm (A_small - L*U, "fro") / norm (A_small, "fro"), eps, eps);
+%!test
+%! opts.type = "crout";
+%! [L, U] = ilu (A_medium, opts);
+%! assert (norm (A_medium - L*U, "fro") / norm (A_medium, "fro"), eps, eps);
+%!test
+%! opts.type = "crout";
+%! [L, U] = ilu (A_large, opts);
+%! assert (norm (A_large - L*U, "fro") / norm (A_large, "fro"), eps, eps);
+%!
+%!test
+%! opts.type = "ilutp";
+%! opts.droptol = 0;
+%! opts.thresh = 0;
+%! [L, U] = ilu (A_tiny, opts);
+%! assert (norm (A_tiny - L*U, "fro") / norm (A_tiny, "fro"), eps, eps);
+%!test
+%! opts.type = "ilutp";
+%! opts.droptol = 0;
+%! opts.thresh = 0;
+%! [L, U] = ilu (A_small, opts);
+%! assert (norm (A_small - L*U, "fro") / norm (A_small, "fro"), eps, eps);
+%!test
+%! opts.type = "ilutp";
+%! opts.droptol = 0;
+%! opts.thresh = 0;
+%! [L, U] = ilu (A_medium, opts);
+%! assert (norm (A_medium - L*U, "fro") / norm (A_medium, "fro"), eps, eps);
+%!test
+%! opts.type = "ilutp";
+%! opts.droptol = 0;
+%! opts.thresh = 0;
+%! [L, U] = ilu (A_large, opts);
+%! assert (norm (A_large - L*U, "fro") / norm (A_large, "fro"), eps, eps);
+
+## Specific tests for ilutp
+
+%!shared a1, a2
+%! a1 = sparse ([0 0 4 3 1; 5 1 2.3 2 4.5; 0 0 0 2 1;0 0 8 0 2.2; 0 0 9 9 1 ]);
+%! a2 = sparse ([3 1 0 0 4; 3 1 0 0 -2;0 0 8 0 0; 0 4 0 4 -4.5; 0 -1 0 0 1]);
+%!test
+%! opts.udiag = 1;
+%! opts.type = "ilutp";
+%! opts.droptol = 0.2;
+%! [L, U, P] = ilu (a1, opts);
+%! assert (norm (U, "fro"), 17.4577, 1e-4);
+%! assert (norm (L, "fro"), 2.4192, 1e-4);
+%! opts.udiag = 0;
+%! #fail ("ilu (a1, opts)");
+%!
+%!test
+%! opts.type = "ilutp";
+%! opts.droptol = 0;
+%! opts.thresh = 0;
+%! opts.milu = "row";
+%! #fail ("ilu (a2, opts)");
+
+%% Tests for input validation
+%!shared A_tiny
+%! A_tiny = spconvert ([1 4 2 3 3 4 2 5; 1 1 2 3 4 4 5 5; 1 2 3 4 5 6 7 8]');
+
+%!test
+%! [L, U] = ilu (sparse ([]));
+%! assert (isempty (L));
+%! assert (isempty (U));
+%! opts.type = "crout";
+%! [L, U] = ilu (sparse ([]), opts);
+%! assert (isempty (L));
+%! assert (isempty (U));
+%! opts.type = "ilutp";
+%! [L, U] = ilu (sparse ([]), opts);
+%! assert (isempty (L));
+%! assert (isempty (U));
+%!error <A must be a sparse square matrix> ilu (0)
+%!error <A must be a sparse square matrix> ilu ([])
+%!error <zero on the diagonal> ilu (sparse (0))
+
+%!test
+%! opts.type = "foo";
+%! fail ("ilu (A_tiny, opts)", "invalid TYPE specified");
+%! opts.type = 1;
+%! fail ("ilu (A_tiny, opts)", "invalid TYPE specified");
+%! opts.type = [];
+%! fail ("ilu (A_tiny, opts)", "invalid TYPE specified");
+%!test
+%! opts.droptol = -1;
+%! fail ("ilu (A_tiny, opts)", "DROPTOL must be a non-negative real scalar");
+%! opts.droptol = 0.5i;
+%! fail ("ilu (A_tiny, opts)", "DROPTOL must be a non-negative real scalar");
+%! opts.droptol = [];
+%! fail ("ilu (A_tiny, opts)", "DROPTOL must be a non-negative real scalar");
+%!test
+%! opts.milu = "foo";
+%! fail ("ilu (A_tiny, opts)", 'MILU must be one of "off"');
+%! opts.milu = 1;
+%! fail ("ilu (A_tiny, opts)", 'MILU must be one of "off"');
+%! opts.milu = [];
+%! fail ("ilu (A_tiny, opts)", 'MILU must be one of "off"');
+%!test
+%! opts.udiag = -1;
+%! fail ("ilu (A_tiny, opts)", "UDIAG must be 0 or 1");
+%! opts.udiag = 0.5i;
+%! fail ("ilu (A_tiny, opts)", "UDIAG must be 0 or 1");
+%! opts.udiag = [];
+%! fail ("ilu (A_tiny, opts)", "UDIAG must be 0 or 1");
+%!test
+%! opts.thresh = -1;
+%! fail ("ilu (A_tiny, opts)", "THRESH must be a scalar");
+%! opts.thresh = 0.5i;
+%! fail ("ilu (A_tiny, opts)", "THRESH must be a scalar");
+%! opts.thresh = [];
+%! fail ("ilu (A_tiny, opts)", "THRESH must be a scalar");
+
--- a/scripts/sparse/module.mk	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/sparse/module.mk	Fri Feb 06 08:31:49 2015 -0800
@@ -12,9 +12,12 @@
   sparse/etreeplot.m \
   sparse/gmres.m \
   sparse/gplot.m \
+  sparse/ichol.m \
+  sparse/ilu.m \
   sparse/nonzeros.m \
   sparse/pcg.m \
   sparse/pcr.m \
+  sparse/qmr.m \
   sparse/spaugment.m \
   sparse/spconvert.m \
   sparse/spdiags.m \
--- a/scripts/sparse/nonzeros.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/sparse/nonzeros.m	Fri Feb 06 08:31:49 2015 -0800
@@ -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/pcg.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/sparse/pcg.m	Fri Feb 06 08:31:49 2015 -0800
@@ -124,7 +124,7 @@
 ## n = 10;
 ## A = diag (sparse (1:n));
 ## b = rand (n, 1);
-## [l, u, p, q] = luinc (A, 1.e-3);
+## [l, u, p] = ilu (A, struct ("droptol", 1.e-3));
 ## @end group
 ## @end example
 ##
@@ -203,7 +203,7 @@
 ## SIAM, 1995. (the base PCG algorithm)
 ##
 ## @item
-## Y. Saad, @cite{Iterative Methods for Sparse Linear Systems},
+## @nospell{Y. Saad}, @cite{Iterative Methods for Sparse Linear Systems},
 ## @nospell{PWS} 1996. (condition number estimate from PCG)
 ## Revised version of this book is available online at
 ## @url{http://www-users.cs.umn.edu/~saad/books.html}
--- a/scripts/sparse/pcr.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/sparse/pcr.m	Fri Feb 06 08:31:49 2015 -0800
@@ -162,8 +162,8 @@
 ##
 ## References:
 ##
-##      [1] W. Hackbusch, @cite{Iterative Solution of Large Sparse Systems of
-##      Equations}, section 9.5.4; Springer, 1994
+## [1] @nospell{W. Hackbusch}, @cite{Iterative Solution of Large Sparse
+## Systems of Equations}, section 9.5.4; Springer, 1994
 ##
 ## @seealso{sparse, pcg}
 ## @end deftypefn
--- a/scripts/sparse/private/__sprand_impl__.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/sparse/private/__sprand_impl__.m	Fri Feb 06 08:31:49 2015 -0800
@@ -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
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/sparse/qmr.m	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,324 @@
+## Copyright (C) 2014 Nathan Podlich
+##
+## 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; If not, see <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn  {Function File} {@var{x} =} qmr (@var{A}, @var{b}, @var{rtol}, @var{maxit}, @var{M1}, @var{M2}, @var{x0})
+## @deftypefnx {Function File} {@var{x} =} qmr (@var{A}, @var{b}, @var{rtol}, @var{maxit}, @var{P})
+## @deftypefnx {Function File} {[@var{x}, @var{flag}, @var{relres}, @var{iter}, @var{resvec}] =} qmr (@var{A}, @var{b}, @dots{})
+## Solve @code{A x = b} using the Quasi-Minimal Residual iterative
+## method (without look-ahead).
+##
+## @itemize @minus
+## @item @var{rtol} is the relative tolerance, if not given
+## or set to [] the default value 1e-6 is used.
+##
+## @item @var{maxit} the maximum number of outer iterations,
+## if not given or set to [] the default value
+## @code{min (20, numel (b))} is used.
+##
+## @item @var{x0} the initial guess, if not given or set to []
+## the default value @code{zeros (size (b))} is used.
+## @end itemize
+##
+## @var{A} can be passed as a matrix or as a function handle or
+## inline function @code{f} such that @code{f(x, "notransp") = A*x}
+## and @code{f(x, "transp") = A'*x}.
+##
+## The preconditioner @var{P} is given as @code{P = M1 * M2}.
+## Both @var{M1} and @var{M2} can be passed as a matrix or as
+## a function handle or inline function @code{g} such that
+## @code{g(x, "notransp") = M1 \ x} or @code{g(x, "notransp") = M2 \ x} and
+## @code{g(x, "transp") = M1' \ x} or @code{g(x, "transp") = M2' \ x}.
+##
+## If called with more than one output parameter
+##
+## @itemize @minus
+## @item @var{flag} indicates the exit status:
+##
+## @itemize @minus
+## @item 0: iteration converged to the within the chosen tolerance
+##
+## @item 1: the maximum number of iterations was reached before convergence
+##
+## @item 3: the algorithm reached stagnation
+## @end itemize
+##
+## (the value 2 is unused but skipped for compatibility).
+##
+## @item @var{relres} is the final value of the relative residual.
+##
+## @item @var{iter} is the number of iterations performed.
+##
+## @item @var{resvec} is a vector containing the residual norms at each
+##       iteration.
+## @end itemize
+##
+## References:
+##
+## @enumerate
+## @item
+## R. Freund and N. Nachtigal, @cite{QMR: a quasi-minimal residual
+## method for non-Hermitian linear systems}, Numerische Mathematik,
+## 1991, 60, pp. 315-339.
+##
+## @item
+## R. Barrett, M. Berry, T. Chan, J. Demmel, J. Donato, J. Dongarra,
+## V. Eijkhour, R. Pozo, C. Romine, and H. van der Vorst,
+## @cite{Templates for the solution of linear systems: Building blocks
+## for iterative methods}, SIAM, 2nd ed., 1994.
+## @end enumerate
+##
+## @seealso{bicg, bicgstab, cgs, gmres}
+## @end deftypefn
+
+## Author: Nathan Podlich <nathan.podlich@gmail.com>
+
+function [x, flag, relres, iter, resvec] = qmr (A, b, tol, maxit, M1, M2, x0)
+
+  if (nargin >= 2 && isvector (full (b)))
+
+    if (ischar (A))
+      fun = str2func (A);
+      Ax  = @(x) feval (fun, x, "notransp");
+      Atx = @(x) feval (fun, x, "transp");
+    elseif (isa (A, "function_handle"))
+      Ax  = @(x) feval (A, x, "notransp");
+      Atx = @(x) feval (A, x, "transp");
+    elseif (ismatrix (A))
+      Ax  = @(x) A  * x;
+      Atx = @(x) A' * x;
+    else
+      error (["qmr: first argument is expected to " ...
+                "be a function or a square matrix"]);
+    endif
+
+    if (nargin < 3 || isempty (tol))
+      tol = 1e-6;
+    endif
+
+    if (nargin < 4 || isempty (maxit))
+      maxit = min (rows (b), 20);
+    endif
+
+    if (nargin < 5 || isempty (M1))
+      M1m1x = @(x, ignore) x;
+      M1tm1x = M1m1x;
+    elseif (ischar (M1))
+      fun = str2func (M1);
+      M1m1x  = @(x) feval (fun, x, "notransp");
+      M1tm1x = @(x) feval (fun, x, "transp");
+    elseif (isa (M1, "function_handle"))
+      M1m1x  = @(x) feval (M1, x, "notransp");
+      M1tm1x = @(x) feval (M1, x, "transp");
+    elseif (ismatrix (M1))
+      M1m1x  = @(x) M1  \ x;
+      M1tm1x = @(x) M1' \ x;
+    else
+      error (["qmr: preconditioner is expected to " ...
+                "be a function or matrix"]);
+    endif
+
+    if (nargin < 6 || isempty (M2))
+      M2m1x = @(x, ignore) x;
+      M2tm1x = M2m1x;
+    elseif (ischar (M2))
+      fun = str2func (M2);
+      M2m1x  = @(x) feval (fun, x, "notransp");
+      M2tm1x = @(x) feval (fun, x, "transp");
+    elseif (isa (M2, "function_handle"))
+      M2m1x  = @(x) feval (M2, x, "notransp");
+      M2tm1x = @(x) feval (M2, x, "transp");
+    elseif (ismatrix (M2))
+      M2m1x  = @(x) M2  \ x;
+      M2tm1x = @(x) M2' \ x;
+    else
+      error (["qmr: preconditioner is expected to " ...
+                "be a function or matrix"]);
+    endif
+
+
+    if (nargin < 7 || isempty (x0))
+      x = zeros (size (b));
+    else
+      x = x0;
+    endif
+
+    r = b - Ax (x);
+
+    bnorm = norm (b);
+    res0 = norm (r);
+    if (nargout > 4)
+      resvec(1) = res0;
+    endif
+    vt = r;
+
+    y = M1m1x (vt);
+
+    rho0 = norm (y);
+    wt = r;
+
+    z = M2tm1x (wt);
+
+    xi1 = norm (z);
+    gamma0 = 1;
+    eta0 = -1;
+    flag = 1;
+    for iter=1:1:maxit
+      ## If rho0 == 0 or xi1 == 0, method fails.
+      v = vt / rho0;
+      y = y / rho0;
+      w = wt / xi1;
+      z = z / xi1;
+
+      delta1 = z' * y; ## If delta1 == 0, method fails.
+
+      yt = M2m1x (y);
+      zt = M1tm1x (z);
+
+      if (iter == 1)
+        p = yt;
+        q = zt;
+      else
+        p = yt - (xi1*delta1/eps0) * p;
+        q = zt - (rho0*delta1/eps0) * q;
+      endif
+      pt = Ax (p);
+
+      eps0 = q' * pt; ## If eps0 == 0, method fails.
+      beta1 = eps0 / delta1; ## If beta1 == 0, method fails.
+      vt = pt - beta1 * v;
+
+      y = M1m1x (vt);
+      rho1 = norm(y);
+      wt = Atx (q) - beta1 * w;
+      z = M2tm1x (wt);
+
+      xi1 = norm(z);
+      theta1 = rho1 / (gamma0 * abs(beta1));
+      gamma1 = 1 / sqrt(1 + theta1^2); ## If gamma1 == 0, method fails.
+      eta1 = -eta0 * rho0 * gamma1^2 / (beta1 * gamma0^2);
+
+      if (iter == 1)
+        d = eta1 * p;
+        s = eta1 * pt;
+      else
+        d = eta1 * p + (theta0*gamma1)^2 * d;
+        s = eta1 * pt + (theta0 * gamma1)^2 * s;
+      endif
+      x += d;
+      r -= s;
+
+      res1 = norm (r) / bnorm;
+      if (nargout > 4)
+        resvec(iter + 1, 1) = norm (r);
+      end
+
+      if (res1 < tol)
+        ## Convergence achieved.
+        flag = 0;
+        break;
+      elseif (res0 <= res1)
+        ## Stagnation encountered.
+        flag = 3;
+        break;
+      endif
+      theta0 = theta1;
+      eta0 = eta1;
+      gamma0 = gamma1;
+      rho0 = rho1;
+    endfor
+
+    relres = res1;
+    if (flag == 1)
+      if (nargout < 2)
+        printf ("qmr stopped at iteration %i ", iter);
+        printf ("without converging to the desired tolerance %e\n", tol);
+        printf ("because the maximum number of iterations was reached. ");
+        printf ("The iterate returned (number %i) has ", maxit);
+        printf ("relative residual %e\n", res1);
+      endif
+    elseif (flag == 3)
+      if (nargout < 2)
+        printf ("qmr stopped at iteration %i ", iter);
+        printf (" without converging to the desired tolerance %e\n", tol);
+        printf ("because the method stagnated.\n");
+        printf ("The iterate returned (number %i) ", iter);
+        printf ("has relative residual %e\n", res1);
+      endif
+    elseif (nargout < 2)
+      printf ("qmr converged at iteration %i ", iter);
+      printf ("to a solution with relative residual %e\n", res1);
+    endif
+  else
+    print usage();
+  endif
+endfunction
+
+
+%!demo
+%! % Solve system of A*x=b
+%! A = [5 -1 3;-1 2 -2;3 -2 3];
+%! b = [7;-1;4];
+%! [x, flag, relres, iter, resvec] = qmr (A, b)
+
+%!test
+%! n = 100;
+%! A = spdiags ([-2*ones(n,1) 4*ones(n,1) -ones(n,1)], -1:1, n, n);
+%! b = sum (A, 2);
+%! tol = 1e-8;
+%! maxit = 15;
+%! M1 = spdiags ([ones(n,1)/(-2) ones(n,1)],-1:0, n, n);
+%! M2 = spdiags ([4*ones(n,1) -ones(n,1)], 0:1, n, n);
+%! [x, flag, relres, iter, resvec] = qmr (A, b, tol, maxit, M1, M2);
+%! assert (x, ones (size (b)), 1e-7);
+
+%!function y = afun (x, t, a)
+%!  switch (t)
+%!    case "notransp"
+%!      y = a * x;
+%!    case "transp"
+%!      y = a' * x;
+%!  endswitch
+%!endfunction
+%!
+%!test
+%! n = 100;
+%! A = spdiags ([-2*ones(n,1) 4*ones(n,1) -ones(n,1)], -1:1, n, n);
+%! b = sum (A, 2);
+%! tol = 1e-8;
+%! maxit = 15;
+%! M1 = spdiags ([ones(n,1)/(-2) ones(n,1)],-1:0, n, n);
+%! M2 = spdiags ([4*ones(n,1) -ones(n,1)], 0:1, n, n);
+%!
+%! [x, flag, relres, iter, resvec] = qmr (@(x, t) afun (x, t, A),
+%!                                         b, tol, maxit, M1, M2);
+%! assert (x, ones (size (b)), 1e-7);
+
+%!test
+%! n = 100;
+%! tol = 1e-8;
+%! a = sprand (n, n, .1);
+%! A = a' * a + 100 * eye (n);
+%! b = sum (A, 2);
+%! [x, flag, relres, iter, resvec] = qmr (A, b, tol, [], diag (diag (A)));
+%! assert (x, ones (size (b)), 1e-7);
+
+%!test
+%! A = [1 + 1i, 1 + 1i; 2 - 1i, 2 + 1i];
+%! b = A * [1; 1];
+%! [x, flag, relres, iter, resvec] = qmr (A, b);
+%! assert (x, [1; 1], 1e-6);
--- a/scripts/sparse/spdiags.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/sparse/spdiags.m	Fri Feb 06 08:31:49 2015 -0800
@@ -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 Feb 06 08:31:09 2015 -0800
+++ b/scripts/sparse/spfun.m	Fri Feb 06 08:31:49 2015 -0800
@@ -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 Feb 06 08:31:09 2015 -0800
+++ b/scripts/sparse/spones.m	Fri Feb 06 08:31:49 2015 -0800
@@ -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 Feb 06 08:31:09 2015 -0800
+++ b/scripts/sparse/sprand.m	Fri Feb 06 08:31:49 2015 -0800
@@ -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 Feb 06 08:31:09 2015 -0800
+++ b/scripts/sparse/sprandn.m	Fri Feb 06 08:31:49 2015 -0800
@@ -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 Feb 06 08:31:09 2015 -0800
+++ b/scripts/sparse/sprandsym.m	Fri Feb 06 08:31:49 2015 -0800
@@ -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 Feb 06 08:31:09 2015 -0800
+++ b/scripts/sparse/spstats.m	Fri Feb 06 08:31:49 2015 -0800
@@ -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 Feb 06 08:31:09 2015 -0800
+++ b/scripts/sparse/svds.m	Fri Feb 06 08:31:49 2015 -0800
@@ -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 Feb 06 08:31:09 2015 -0800
+++ b/scripts/sparse/treeplot.m	Fri Feb 06 08:31:49 2015 -0800
@@ -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/bessel.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/specfun/bessel.m	Fri Feb 06 08:31:49 2015 -0800
@@ -31,24 +31,21 @@
 ##
 ## @item bessely
 ## Bessel functions of the second kind.  If the argument @var{opt} is supplied,
-## the result is multiplied by @code{exp (-abs (imag (x)))}.
+## the result is multiplied by @w{@code{exp (-abs (imag (x)))}}.
 ##
 ## @item besseli
 ## Modified Bessel functions of the first kind.  If the argument @var{opt} is
-## supplied,
-## the result is multiplied by @code{exp (-abs (real (x)))}.
+## supplied, the result is multiplied by @w{@code{exp (-abs (real (x)))}}.
 ##
 ## @item besselk
 ## Modified Bessel functions of the second kind.  If the argument @var{opt} is
-## supplied,
-## the result is multiplied by @code{exp (x)}.
+## supplied, the result is multiplied by @w{@code{exp (x)}}.
 ##
 ## @item besselh
-## Compute Hankel functions of the first (@var{k} = 1) or second (@var{k}
-## = 2) kind.  If the argument @var{opt} is supplied, the result is multiplied
-## by
-## @code{exp (-I*@var{x})} for @var{k} = 1 or @code{exp (I*@var{x})} for
-## @var{k} = 2.
+## Compute Hankel functions of the first (@var{k} = 1) or second (@var{k} = 2)
+## kind.  If the argument @var{opt} is supplied, the result is multiplied by
+## @w{@code{exp (-I*@var{x})}} for @var{k} = 1 or @w{@code{exp (I*@var{x})}}
+## for @var{k} = 2.
 ## @end table
 ##
 ## If @var{alpha} is a scalar, the result is the same size as @var{x}.
@@ -58,11 +55,10 @@
 ## @code{length (@var{alpha})} columns.  Otherwise, @var{alpha} and
 ## @var{x} must conform and the result will be the same size.
 ##
-## The value of @var{alpha} must be real.  The value of @var{x} may be
-## complex.
+## The value of @var{alpha} must be real.  The value of @var{x} may be complex.
 ##
-## If requested, @var{ierr} contains the following status information
-## and is the same size as the result.
+## If requested, @var{ierr} contains the following status information and is
+## the same size as the result.
 ##
 ## @enumerate 0
 ## @item
@@ -75,8 +71,8 @@
 ## Overflow, return @code{Inf}.
 ##
 ## @item
-## Loss of significance by argument reduction results in less than
-## half of machine accuracy.
+## Loss of significance by argument reduction results in less than half of
+## machine accuracy.
 ##
 ## @item
 ## Complete loss of significance by argument reduction, return @code{NaN}.
@@ -88,7 +84,7 @@
 ## @end deftypefn
 
 function bessel ()
-  error ("bessel: you must use besselj, bessely, besseli, or besselk");
+  error ("bessel: you must use besselj, bessely, besseli, besselk, or besselh");
 endfunction
 
 
--- a/scripts/specfun/beta.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/specfun/beta.m	Fri Feb 06 08:31:49 2015 -0800
@@ -18,7 +18,9 @@
 
 ## -*- texinfo -*-
 ## @deftypefn {Mapping Function} {} beta (@var{a}, @var{b})
-## For real inputs, return the Beta function,
+## Compute the Beta function for real inputs @var{a} and @var{b}.
+##
+## The Beta function definition is
 ## @tex
 ## $$
 ##  B (a, b) = {\Gamma (a) \Gamma (b) \over \Gamma (a + b)}.
@@ -31,7 +33,12 @@
 ## @end example
 ##
 ## @end ifnottex
-## @seealso{betaln, betainc}
+##
+## The Beta function can grow quite large and it is often more useful to work
+## with the logarithm of the output rather than the function directly.
+## @xref{XREFbetaln,,betaln}, for computing the logarithm of the Beta function
+## in an efficient manner.
+## @seealso{betaln, betainc, betaincinv}
 ## @end deftypefn
 
 ## Author: KH <Kurt.Hornik@wu-wien.ac.at>
@@ -44,12 +51,10 @@
     print_usage ();
   endif
 
-  if (any (size (a) != size (b)) && numel (a) != 1 && numel (b) != 1)
-    error ("beta: inputs A and B have inconsistent sizes");
-  endif
-
   if (! isreal (a) || ! isreal (b))
-    error ("beta: inputs A and B must be real");
+    error ("beta: A and B must be real");
+  elseif (! size_equal (a, b) && numel (a) != 1 && numel (b) != 1)
+    error ("beta: A and B must have consistent sizes");
   endif
 
   retval = real (exp (gammaln (a) + gammaln (b) - gammaln (a+b)));
@@ -60,8 +65,8 @@
 %!test
 %! a = [1, 1.5, 2, 3];
 %! b = [4, 3, 2, 1];
-%! v1 = beta (a,b);
-%! v2 = beta (b,a);
+%! v1 = beta (a, b);
+%! v2 = beta (b, a);
 %! v3 = gamma (a).*gamma (b) ./ gamma (a+b);
 %! assert (v1, v2, sqrt (eps));
 %! assert (v2, v3, sqrt (eps));
@@ -82,4 +87,10 @@
 
 %!error beta ()
 %!error beta (1)
+%!error beta (1,2,3)
+%!error <A and B must be real> beta (1i, 2)
+%!error <A and B must be real> beta (2, 1i)
+%!error <A and B must have consistent sizes> beta ([1 2], [1 2 3])
+%!error <A and B must have consistent sizes> beta ([1 2 3], [1 2])
+%!error <A and B must have consistent sizes> beta ([1 2 3], [1 2 3]')
 
--- a/scripts/specfun/betaln.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/specfun/betaln.m	Fri Feb 06 08:31:49 2015 -0800
@@ -18,7 +18,10 @@
 
 ## -*- texinfo -*-
 ## @deftypefn {Mapping Function} {} betaln (@var{a}, @var{b})
-## Return the natural logarithm of the Beta function,
+## Compute the natural logarithm of the Beta function for real inputs @var{a}
+## and @var{b}.
+##
+## @code{betaln} is defined as
 ## @tex
 ## $$
 ##  {\rm betaln} (a, b) = \ln (B (a,b)) \equiv \ln ({\Gamma (a) \Gamma (b) \over \Gamma (a + b)}).
@@ -31,8 +34,11 @@
 ## @end example
 ##
 ## @end ifnottex
-## calculated in a way to reduce the occurrence of underflow.
-## @seealso{beta, betainc, gammaln}
+## and is calculated in a way to reduce the occurrence of underflow.
+##
+## The Beta function can grow quite large and it is often more useful to work
+## with the logarithm of the output rather than the function directly.
+## @seealso{beta, betainc, betaincinv, gammaln}
 ## @end deftypefn
 
 ## Author:   Nicol N. Schraudolph <nic@idsia.ch>
@@ -45,6 +51,12 @@
     print_usage ();
   endif
 
+  if (! isreal (a) || ! isreal (b))
+    error ("betaln: A and B must be real");
+  elseif (! size_equal (a, b) && numel (a) != 1 && numel (b) != 1)
+    error ("betaln: A and B must have consistent sizes");
+  endif
+
   retval = gammaln (a) + gammaln (b) - gammaln (a + b);
 
 endfunction
@@ -53,6 +65,12 @@
 %!assert (betaln (3,4), log (beta (3,4)), eps)
 
 %% Test input validation
-%!error (betaln (1))
-%!error (betaln (1,2,3))
+%!error betaln ()
+%!error betaln (1)
+%!error betaln (1,2,3)
+%!error <A and B must be real> betaln (1i, 2)
+%!error <A and B must be real> betaln (2, 1i)
+%!error <A and B must have consistent sizes> betaln ([1 2], [1 2 3])
+%!error <A and B must have consistent sizes> betaln ([1 2 3], [1 2])
+%!error <A and B must have consistent sizes> betaln ([1 2 3], [1 2 3]')
 
--- a/scripts/specfun/ellipke.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/specfun/ellipke.m	Fri Feb 06 08:31:49 2015 -0800
@@ -27,13 +27,58 @@
 ##
 ## @var{m} must be a scalar or real array with -Inf @leq{} @var{m} @leq{} 1.
 ##
-## The optional input @var{tol} is currently ignored (@sc{matlab} uses this
-## to allow a faster, less accurate approximation).
+## The optional input @var{tol} controls the stopping tolerance of the
+## algorithm and defaults to @code{eps (class (@var{m}))}.  The tolerance can
+## be increased to compute a faster, less accurate approximation.
 ##
-## Called with only one output, elliptic integrals of the first kind are
+## When called with one output only elliptic integrals of the first kind are
 ## returned.
 ##
-## Reference: Milton Abramowitz and Irene A. Stegun,
+## Mathematical Note:
+##
+## Elliptic integrals of the first kind are defined as
+##
+## @tex
+## $$
+## {\rm K} (m) = \int_0^1 {dt \over \sqrt{(1 - t^2) (1 - m^2 t^2)}}
+## $$
+## @end tex
+## @ifnottex
+##
+## @example
+## @group
+##          1
+##         /               dt
+## K (m) = | ------------------------------
+##         / sqrt ((1 - t^2)*(1 - m^2*t^2))
+##        0
+## @end group
+## @end example
+##
+## @end ifnottex
+##
+## Elliptic integrals of the second kind are defined as
+##
+## @tex
+## $$
+## {\rm E} (m) = \int_0^1 {\sqrt{1 - m^2 t^2} \over \sqrt{1 - t^2}} dt
+## $$
+## @end tex
+## @ifnottex
+##
+## @example
+## @group
+##          1
+##         /  sqrt (1 - m^2*t^2)
+## E (m) = |  ------------------ dt
+##         /  sqrt (1 - t^2)
+##        0
+## @end group
+## @end example
+##
+## @end ifnottex
+##
+## Reference: Milton @nospell{Abramowitz} and Irene A. @nospell{Stegun},
 ## @cite{Handbook of Mathematical Functions}, Chapter 17, Dover, 1965.
 ## @seealso{ellipj}
 ## @end deftypefn
@@ -42,12 +87,13 @@
 ## Author: Paul Kienzle <pkienzle@users.sf.net>
 ## Author: Jaakko Ruohio
 
-function [k, e] = ellipke (m)
+function [k, e] = ellipke (m, tol = [])
 
   if (nargin < 1 || nargin > 2)
     print_usage ();
   endif
 
+  sz = size (m);
   m = m(:);
   if (! isreal (m))
     error ("ellipke: M must be real");
@@ -55,7 +101,13 @@
     error ("ellipke: M must be <= 1");
   endif
 
-  k = e = zeros (size (m));
+  if (isempty (tol))
+    tol = eps (class (m));
+  elseif (! (isreal (tol) && isscalar (tol) && tol > 0))
+    error ("ellipke: TOL must be a real scalar > 0")
+  endif
+
+  k = e = zeros (sz);
 
   ## Handle extreme values
   idx_1 = (m == 1);
@@ -84,11 +136,11 @@
     do
       t = (a + b)/2;
       c = (a - b)/2;
-      b = sqrt (a.*b);
+      b = sqrt (a .* b);
       a = t;
       f *= 2;
       sum += f*c.^2;
-    until (all (c./a < eps) || (++n > Nmax))
+    until (all (c./a < tol) || (++n > Nmax))
     if (n >= Nmax)
       error ("ellipke: algorithm did not converge in %d iterations", Nmax);
     endif
@@ -104,23 +156,17 @@
 ## Test complete elliptic functions of first and second kind
 ## against "exact" solution from Mathematica 3.0
 %!test
-%! m = [0.0; 0.01; 0.1; 0.5; 0.9; 0.99; 1.0];
+%! m = [0.0, 0.01; 0.1, 0.5; 0.9, 0.99; 1.0, 0.0];
 %! [k,e] = ellipke (m);
 %!
-%! k_exp = [1.5707963267948966192;
-%!          1.5747455615173559527;
-%!          1.6124413487202193982;
-%!          1.8540746773013719184;
-%!          2.5780921133481731882;
-%!          3.6956373629898746778;
-%!          Inf ];
-%! e_exp = [1.5707963267948966192;
-%!          1.5668619420216682912;
-%!          1.5307576368977632025;
-%!          1.3506438810476755025;
-%!          1.1047747327040733261;
-%!          1.0159935450252239356;
-%!          1.0 ];
+%! k_exp = [1.5707963267948966192, 1.5747455615173559527
+%!          1.6124413487202193982, 1.8540746773013719184
+%!          2.5780921133481731882, 3.6956373629898746778
+%!          Inf                  , 1.5707963267948966192 ];
+%! e_exp = [1.5707963267948966192, 1.5668619420216682912
+%!          1.5307576368977632025, 1.3506438810476755025
+%!          1.1047747327040733261, 1.0159935450252239356
+%!          1.0                  , 1.5707963267948966192 ];
 %! assert (k, k_exp, 8*eps);
 %! assert (e, e_exp, 8*eps);
 
@@ -175,4 +221,9 @@
 ## Test input validation
 %!error ellipke ()
 %!error ellipke (1,2,3)
+%!error <M must be real> ellipke (1i)
+%!error <M must be .= 1> ellipke (2)
+%!error <TOL must be a real scalar . 0> ellipke (1, i)
+%!error <TOL must be a real scalar . 0> ellipke (1, [1 1])
+%!error <TOL must be a real scalar . 0> ellipke (1, -1)
 
--- a/scripts/specfun/factor.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/specfun/factor.m	Fri Feb 06 08:31:49 2015 -0800
@@ -17,20 +17,20 @@
 ## <http://www.gnu.org/licenses/>.
 
 ## -*- texinfo -*-
-## @deftypefn  {Function File} {@var{p} =} factor (@var{q})
-## @deftypefnx {Function File} {[@var{p}, @var{n}] =} factor (@var{q})
-##
-## Return the prime factorization of @var{q}.  That is,
-## @code{prod (@var{p}) == @var{q}} and every element of @var{p} is a prime
-## number.  If @code{@var{q} == 1}, return 1.
+## @deftypefn  {Function File} {@var{pf} =} factor (@var{q})
+## @deftypefnx {Function File} {[@var{pf}, @var{n}] =} factor (@var{q})
+## Return the prime factorization of @var{q}.
 ##
-## With two output arguments, return the unique primes @var{p} and
-## their multiplicities.  That is, @code{prod (@var{p} .^ @var{n}) ==
-## @var{q}}.
+## The prime factorization is defined as @code{prod (@var{pf}) == @var{q}}
+## where every element of @var{pf} is a prime number.  If @code{@var{q} == 1},
+## return 1.
 ##
-## Implementation Note: The input @var{q} must not be greater than
+## With two output arguments, return the unique prime factors @var{pf} and
+## their multiplicities.  That is, @code{prod (@var{pf} .^ @var{n}) == @var{q}}.
+##
+## Implementation Note: The input @var{q} must be less than
 ## @code{bitmax} (9.0072e+15) in order to factor correctly.
-## @seealso{gcd, lcm, isprime}
+## @seealso{gcd, lcm, isprime, primes}
 ## @end deftypefn
 
 ## Author: Paul Kienzle
@@ -40,29 +40,29 @@
 ## * return multiplicity as suggested by Dirk Laurie
 ## * add error handling
 
-function [x, n] = factor (q)
+function [pf, n] = factor (q)
 
-  if (nargin < 1)
+  if (nargin != 1)
     print_usage ();
   endif
 
-  if (! isscalar (q) || q != fix (q))
-    error ("factor: Q must be a scalar integer");
+  if (! isreal (q) || ! isscalar (q) || q != fix (q))
+    error ("factor: Q must be a real integer");
   endif
 
   ## Special case of no primes less than sqrt(q).
   if (q < 4)
-    x = q;
+    pf = q;
     n = 1;
     return;
   endif
 
   q = double (q);  # For the time being, calcs rely on double precision var.
   qorig = q;
-  x = [];
+  pf = [];
   ## There is at most one prime greater than sqrt(q), and if it exists,
   ## it has multiplicity 1, so no need to consider any factors greater
-  ## than sqrt(q) directly. [If there were two factors p1, p2 > sqrt(q),
+  ## than sqrt(q) directly.  [If there were two factors p1, p2 > sqrt(q),
   ## then q >= p1*p2 > sqrt(q)*sqrt(q) == q. Contradiction.]
   p = primes (sqrt (q));
   while (q > 1)
@@ -72,24 +72,24 @@
       ## Can't be reduced further, so q must itself be a prime.
       p = q;
     endif
-    x = [x, p];
+    pf = [pf, p];
     ## Reduce q.
     q /= prod (p);
   endwhile
-  x = sort (x);
+  pf = sort (pf);
 
   ## Verify algorithm was succesful
-  q = prod (x);
+  q = prod (pf);
   if (q != qorig)
-    error ("factor: Input Q too large to factor");
+    error ("factor: Q too large to factor");
   elseif (q > bitmax)
-    warning ("factor: Input Q too large.  Answer is unreliable");
+    warning ("factor: Q too large.  Answer is unreliable");
   endif
 
   ## Determine muliplicity.
   if (nargout > 1)
-    idx = find ([0, x] != [x, 0]);
-    x = x(idx(1:length (idx)-1));
+    idx = find ([0, pf] != [pf, 0]);
+    pf = pf(idx(1:length (idx)-1));
     n = diff (idx);
   endif
 
@@ -99,16 +99,18 @@
 %!assert (factor (1), 1)
 %!test
 %! for i = 2:20
-%!   p = factor (i);
-%!   assert (prod (p), i);
-%!   assert (all (isprime (p)));
-%!   [p,n] = factor (i);
-%!   assert (prod (p.^n), i);
-%!   assert (all ([0,p] != [p,0]));
+%!   pf = factor (i);
+%!   assert (prod (pf), i);
+%!   assert (all (isprime (pf)));
+%!   [pf, n] = factor (i);
+%!   assert (prod (pf.^n), i);
+%!   assert (all ([0,pf] != [pf,0]));
 %! endfor
 
 %% Test input validation
 %!error factor ()
-%!error <Q must be a scalar integer> factor ([1,2])
-%!error <Q must be a scalar integer> factor (1.5)
+%!error factor (1,2)
+%!error <Q must be a real integer> factor (6i)
+%!error <Q must be a real integer> factor ([1,2])
+%!error <Q must be a real integer> factor (1.5)
 
--- a/scripts/specfun/factorial.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/specfun/factorial.m	Fri Feb 06 08:31:49 2015 -0800
@@ -18,28 +18,48 @@
 
 ## -*- texinfo -*-
 ## @deftypefn {Function File} {} factorial (@var{n})
-## Return the factorial of @var{n} where @var{n} is a positive integer.  If
-## @var{n} is a scalar, this is equivalent to @code{prod (1:@var{n})}.  For
+## Return the factorial of @var{n} where @var{n} is a real non-negative integer.
+##
+## If @var{n} is a scalar, this is equivalent to @code{prod (1:@var{n})}.  For
 ## vector or matrix arguments, return the factorial of each element in the
-## array.  For non-integers see the generalized factorial function
-## @code{gamma}.
-## @seealso{prod, gamma}
+## array.
+##
+## For non-integers see the generalized factorial function @code{gamma}.
+## Note that the factorial function grows large quite quickly, and even
+## with double precision values overflow will occur if @var{n} > 171.  For
+## such cases consider @code{gammaln}.
+## @seealso{prod, gamma, gammaln}
 ## @end deftypefn
 
 function x = factorial (n)
+
   if (nargin != 1)
     print_usage ();
-  elseif (any (n(:) < 0 | n(:) != fix (n(:))))
-    error ("factorial: N must all be non-negative integers");
+  elseif (! isreal (n) || any (n(:) < 0 | n(:) != fix (n(:))))
+    error ("factorial: all N must be real non-negative integers");
   endif
+
   x = round (gamma (n+1));
+
+  ## FIXME: Matlab returns an output of the same type as the input.
+  ## This doesn't seem particularly worth copying--for example uint8 would
+  ## saturate for n > 5.  If desired, however, the following code could be
+  ## uncommented.
+  # if (! isfloat (x))
+  #   x = cast (x, class (n));
+  # endif
+
 endfunction
 
 
 %!assert (factorial (5), prod (1:5))
 %!assert (factorial ([1,2;3,4]), [1,2;6,24])
 %!assert (factorial (70), exp (sum (log (1:70))), -128*eps)
+%!assert (factorial (0), 1)
 
-%!fail ("factorial (5.5)", "must all be non-negative integers")
-%!fail ("factorial (-3)", "must all be non-negative integers")
+%!error factorial ()
+%!error factorial (1,2)
+%!error <must be real non-negative integers> factorial (2i)
+%!error <must be real non-negative integers> factorial (-3)
+%!error <must be real non-negative integers> factorial (5.5)
 
--- a/scripts/specfun/isprime.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/specfun/isprime.m	Fri Feb 06 08:31:49 2015 -0800
@@ -22,8 +22,21 @@
 ## Return a logical array which is true where the elements of @var{x} are
 ## prime numbers and false where they are not.
 ##
-## If the maximum value in @var{x} is very large, then you should be using
-## special purpose factorization code.
+## A prime number is conventionally defined as a positive integer greater than
+## 1 (e.g., 2, 3, @dots{}) which is divisible only by itself and 1.  Octave
+## extends this definition to include both negative integers and complex
+## values.  A negative integer is prime if its positive counterpart is prime.
+## This is equivalent to @code{isprime (abs (x))}.
+##
+## If @code{class (@var{x})} is complex, then primality is tested in the domain
+## of Gaussian integers (@url{http://en.wikipedia.org/wiki/Gaussian_integer}).
+## Some non-complex integers are prime in the ordinary sense, but not in the
+## domain of Gaussian integers.  For example, @math{5 = (1+2i)*(1-2i)} shows
+## that 5 is not prime because it has a factor other than itself and 1.
+## Exercise caution when testing complex and real values together in the same
+## matrix.
+##
+## Examples:
 ##
 ## @example
 ## @group
@@ -31,59 +44,129 @@
 ##     @result{} [0, 1, 1, 0, 1, 0]
 ## @end group
 ## @end example
+##
+## @example
+## @group
+## isprime ([i, 2, 3, 5])
+##     @result{} [0, 0, 1, 0]
+## @end group
+## @end example
+##
+## Programming Note: @code{isprime} is appropriate if the maximum value in
+## @var{x} is not too large (< 1e15).  For larger values special purpose
+## factorization code should be used.
+##
+## Compatibility Note: @var{matlab} does not extend the definition of prime
+## numbers and will produce an error if given negative or complex inputs.
 ## @seealso{primes, factor, gcd, lcm}
 ## @end deftypefn
 
 function t = isprime (x)
 
-  if (nargin == 1)
-    if (any ((x != floor (x) | x < 0)(:)))
-      error ("isprime: needs positive integers");
-    endif
-    maxn = max (x(:));
-    ## generate prime table of suitable length.
-    maxp = min (maxn, max (sqrt (maxn), 1e7)); # FIXME: threshold not optimized.
-    pr = primes (maxp);
-    ## quick search for table matches.
-    t = lookup (pr, x, "b");
-    ## take the rest.
-    m = x(x > maxp);
-    if (! isempty (m))
-      ## there are still possible primes. filter them out by division.
-      if (maxn <= intmax ("uint32"))
-        m = uint32 (m);
-      elseif (maxn <= intmax ("uint64"))
-        m = uint64 (m);
-      else
-        warning ("isprime: too large integers being tested");
-      endif
-      pr = cast (pr(pr <= sqrt (maxn)), class (m));
-      for p = pr
-        m = m(rem (m, p) != 0);
-        if (length (m) < length (pr) / 10)
-          break;
-        endif
-      endfor
-      pr = pr(pr > p);
-      mm = arrayfun (@(x) all (rem (x, pr)), m);
-      m = m(mm);
-      if (! isempty (m))
-        m = cast (sort (m), class (x));
-        t |= lookup (m, x, "b");
-      endif
+  if (nargin != 1)
+    print_usage ();
+  elseif (any (fix (x) != x))
+    error ("isprime: X contains non-integer entries");
+  endif
+
+  if (isempty (x))
+    t = x;
+    return;
+  endif
+
+  if (iscomplex (x))
+    t = isgaussianprime (x);
+    return;
+  endif
+
+  ## Code strategy is to build a table with the list of possible primes
+  ## and then quickly compare entries in x with the table of primes using
+  ## lookup().  The table size is limited to save memory and computation
+  ## time during its creation.  All entries larger than the maximum in the
+  ## table are checked by straightforward division.
+
+  x = abs (x);              # handle negative entries
+  maxn = max (x(:));
+  ## generate prime table of suitable length.
+  ## 1e7 threshold requires ~0.15 seconds of computation, 1e8 requires 1.8.
+  maxp = min (maxn, max (sqrt (maxn), 1e7));
+  pr = primes (maxp);
+  t = lookup (pr, x, "b");  # quick search for table matches.
+
+  ## process any remaining large entries
+  m = x(x > maxp);
+  if (! isempty (m))
+    if (maxn <= intmax ("uint32"))
+      m = uint32 (m);
+    elseif (maxn <= intmax ("uint64"))
+      m = uint64 (m);
+    else
+      warning ("isprime: X contains integers too large to be tested");
     endif
 
-  else
-    print_usage ();
+    ## Start by dividing through by the small primes until the remaining
+    ## list of entries is small (and most likely prime themselves).
+    pr = cast (pr(pr <= sqrt (maxn)), class (m));
+    for p = pr
+      m = m(rem (m, p) != 0);
+      if (numel (m) < numel (pr) / 10)
+        break;
+      endif
+    endfor
+
+    ## Check the remaining list of possible primes against the
+    ## remaining prime factors which were not tested in the for loop.
+    ## This is just an optimization to use arrayfun over for loo
+    pr = pr(pr > p);
+    mm = arrayfun (@(x) all (rem (x, pr)), m);
+    m = m(mm);
+
+    ## Add any remaining entries, which are truly prime, to the results.
+    if (! isempty (m))
+      m = cast (sort (m), class (x));
+      t |= lookup (m, x, "b");
+    endif
   endif
 
 endfunction
 
+function t = isgaussianprime (z)
+  ## Assume prime unless proven otherwise
+  t = true (size (z));
+
+  x = real (z);
+  y = imag (z);
+
+  ## If purely real or purely imaginary, ordinary prime test for
+  ## that complex part if that part is 3 mod 4.
+  xidx = y==0 & mod (x, 4) == 3;
+  yidx = x==0 & mod (y, 4) == 3;
+
+  t(xidx) &= isprime (x(xidx));
+  t(yidx) &= isprime (y(yidx));
+
+  ## Otherwise, prime if x^2 + y^2 is prime
+  zidx = ! (xidx | yidx);          # Skip entries that were already evaluated
+  zabs = x(zidx).^2 + y(zidx).^2;
+  t(zidx) &= isprime (zabs);
+endfunction
+
 
 %!assert (isprime (3), true)
 %!assert (isprime (4), false)
+%!assert (isprime (5i), false)
+%!assert (isprime (7i), true)
+%!assert (isprime ([1+2i, (2+3i)*(-1+2i)]), [true, false])
+%!assert (isprime (-2), true)
+%!assert (isprime (complex (-2)), false)
+%!assert (isprime (2i), false)
+%!assert (isprime ([i, 2, 3, 5]), [false, false, true, false])
+%!assert (isprime (0), false)
 %!assert (isprime (magic (3)), logical ([0, 0, 0; 1, 1, 1; 0, 0, 1]))
 
+%% Test input validation
 %!error isprime ()
 %!error isprime (1, 2)
+%!error <X contains non-integer entries> isprime (0.5i)
+%!error <X contains non-integer entries> isprime (0.5)
 
--- a/scripts/specfun/lcm.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/specfun/lcm.m	Fri Feb 06 08:31:49 2015 -0800
@@ -19,10 +19,11 @@
 ## -*- texinfo -*-
 ## @deftypefn  {Mapping Function} {} lcm (@var{x}, @var{y})
 ## @deftypefnx {Mapping Function} {} lcm (@var{x}, @var{y}, @dots{})
-## Compute the least common multiple of @var{x} and @var{y},
-## or of the list of all arguments.  All elements must be the same size or
-## scalar.
-## @seealso{factor, gcd}
+## Compute the least common multiple of @var{x} and @var{y}, or of the list of
+## all arguments.
+##
+## All elements must be numeric and of the same size or scalar.
+## @seealso{factor, gcd, isprime}
 ## @end deftypefn
 
 ## Author: KH <Kurt.Hornik@wu-wien.ac.at>
@@ -31,31 +32,31 @@
 
 function l = lcm (varargin)
 
-  if (nargin > 1)
-    if (common_size (varargin{:}) != 0)
-      error ("lcm: all args must be of the same size or scalar");
-    elseif (! all (cellfun ("isnumeric", varargin)))
-      error ("lcm: all arguments must be numeric");
-    endif
-
-    l = varargin{1};
-    for i = 2:nargin
-      x = varargin{i};
-      msk = l == 0 & x == 0;
-      l .*= x ./ gcd (l, x);
-      l(msk) = 0;
-    endfor
-  else
+  if (nargin < 2)
     print_usage ();
   endif
 
+  if (common_size (varargin{:}) != 0)
+    error ("lcm: all args must be the same size or scalar");
+  elseif (! all (cellfun ("isnumeric", varargin)))
+    error ("lcm: all arguments must be numeric");
+  endif
+
+  l = varargin{1};
+  for i = 2:nargin
+    x = varargin{i};
+    msk = (l == 0 & x == 0);
+    l .*= x ./ gcd (l, x);
+    l(msk) = 0;
+  endfor
+
 endfunction
 
 
 %!assert (lcm (3, 5, 7, 15), 105)
 
-%!error lcm ();
-%!test
-%! s.a = 1;
-%! fail ("lcm (s)");
+%!error lcm ()
+%!error lcm (1)
+%!error <same size or scalar> lcm ([1 2], [1 2 3])
+%!error <arguments must be numeric> lcm ([1 2], {1 2})
 
--- a/scripts/specfun/legendre.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/specfun/legendre.m	Fri Feb 06 08:31:49 2015 -0800
@@ -21,15 +21,19 @@
 ## @deftypefn  {Function File} {@var{l} =} legendre (@var{n}, @var{x})
 ## @deftypefnx {Function File} {@var{l} =} legendre (@var{n}, @var{x}, @var{normalization})
 ## Compute the Legendre function of degree @var{n} and order
-## @var{m} = 0 @dots{} N@.  The optional argument, @var{normalization},
-## may be one of @qcode{"unnorm"}, @qcode{"sch"}, or @qcode{"norm"}.
-## The default is @qcode{"unnorm"}.  The value of @var{n} must be a
-## non-negative scalar integer.
+## @var{m} = 0 @dots{} @var{n}.
+##
+## The value @var{n} must be a real non-negative integer.  @var{x} is a
+## vector with real-valued elements in the range [-1, 1].
 ##
-## If the optional argument @var{normalization} is missing or is
-## @qcode{"unnorm"}, compute the Legendre function of degree @var{n} and
-## order @var{m} and return all values for @var{m} = 0 @dots{} @var{n}.
-## The return value has one dimension more than @var{x}.
+## The optional argument @var{normalization} may be one of @qcode{"unnorm"},
+## @qcode{"sch"}, or @qcode{"norm"}.  The default if no normalization is given
+## is @qcode{"unnorm"}.
+##
+## When the optional argument @var{normalization} is @qcode{"unnorm"}, compute
+## the Legendre function of degree @var{n} and order @var{m} and return all
+## values for @var{m} = 0 @dots{} @var{n}.  The return value has one dimension
+## more than @var{x}.
 ##
 ## The Legendre Function of degree @var{n} and order @var{m}:
 ##
@@ -42,7 +46,7 @@
 ##
 ## @example
 ## @group
-##  m        m       2  m/2   d^m
+##  m         m      2  m/2   d^m
 ## P(x) = (-1) * (1-x  )    * ----  P(x)
 ##  n                         dx^m   n
 ## @end group
@@ -84,12 +88,12 @@
 ## @end group
 ## @end example
 ##
-## If the optional argument @code{normalization} is @qcode{"sch"},
+## When the optional argument @code{normalization} is @qcode{"sch"},
 ## compute the Schmidt semi-normalized associated Legendre function.
 ## The Schmidt semi-normalized associated Legendre function is related
 ## to the unnormalized Legendre functions by the following:
 ##
-## For Legendre functions of degree n and order 0:
+## For Legendre functions of degree @var{n} and order 0:
 ##
 ## @tex
 ## $$
@@ -127,7 +131,7 @@
 ##
 ## @end ifnottex
 ##
-## If the optional argument @var{normalization} is @qcode{"norm"},
+## When the optional argument @var{normalization} is @qcode{"norm"},
 ## compute the fully normalized associated Legendre function.
 ## The fully normalized associated Legendre function is related
 ## to the unnormalized Legendre functions by the following:
@@ -162,11 +166,9 @@
     print_usage ();
   endif
 
-  if (!isscalar (n) || n < 0 || n != fix (n))
-    error ("legendre: N must be a non-negative scalar integer");
-  endif
-
-  if (!isreal (x) || any (x(:) < -1 | x(:) > 1))
+  if (! isreal (n) || ! isscalar (n) || n < 0 || n != fix (n))
+    error ("legendre: N must be a real non-negative integer");
+  elseif (! isreal (x) || any (x(:) < -1 | x(:) > 1))
     error ("legendre: X must be real-valued vector in the range -1 <= X <= 1");
   endif
 
@@ -176,15 +178,17 @@
     normalization = "unnorm";
   endif
 
+  unnorm = false;
   switch (normalization)
+    case "unnorm"
+      scale = 1;
+      unnorm = true;
     case "norm"
       scale = sqrt (n+0.5);
     case "sch"
       scale = sqrt (2);
-    case "unnorm"
-      scale = 1;
     otherwise
-      error ('legendre: expecting NORMALIZATION option to be "norm", "sch", or "unnorm"');
+      error ('legendre: NORMALIZATION option must be "unnorm", "norm", or "sch"');
   endswitch
 
   scale = scale * ones (size (x));
@@ -204,11 +208,11 @@
     for k = m+1:n
       lpm3a = (2*k-1) .* x .* lpm2;
       lpm3b = (k+m-2) .* lpm1;
-      lpm3 = (lpm3a - lpm3b)/(k-m+1);
+      lpm3 = (lpm3a - lpm3b) / (k-m+1);
       lpm1 = lpm2;
       lpm2 = lpm3;
       if (! warned_overflow)
-        if (any (abs (lpm3a) > realmax)
+        if (   any (abs (lpm3a) > realmax)
             || any (abs (lpm3b) > realmax)
             || any (abs (lpm3)  > realmax))
           overflow = true;
@@ -216,24 +220,23 @@
       endif
     endfor
     retval(m,:) = lpm3(:);
-    if (strcmp (normalization, "unnorm"))
-      scale = -scale * (2*m-1);
-    else
-      ## normalization == "sch" or normalization == "norm"
-      scale = scale / sqrt ((n-m+1)*(n+m))*(2*m-1);
+    if (unnorm)
+      scale *= -(2*m-1);
+    else  # normalization = "sch" or "norm"
+      scale *= (2*m-1) / sqrt ((n-m+1)*(n+m));
     endif
-    scale = scale .* sqrt (1-x.^2);
+    scale .*= sqrt (1-x.^2);
   endfor
 
   retval(n+1,:) = scale(:);
 
   if (isvector (x))
-  ## vector case is special
+    ## vector case is special
     retval = reshape (retval, n + 1, length (x));
   endif
 
   if (strcmp (normalization, "sch"))
-    retval(1,:) = retval(1,:) / sqrt (2);
+    retval(1,:) ./= sqrt (2);
   endif
 
   if (overflow && ! warned_overflow)
@@ -289,8 +292,8 @@
 %! assert (result, full (ones (1,11)));
 
 %!test
+%! ## Test matrix input
 %! result = legendre (3, [-1,0,1;1,0,-1]);
-%! ## Test matrix input
 %! expected(:,:,1) = [-1,1;0,0;0,0;0,0];
 %! expected(:,:,2) = [0,0;1.5,1.5;0,0;-15,-15];
 %! expected(:,:,3) = [1,-1;0,0;0,0;0,0];
@@ -306,11 +309,12 @@
 %!error legendre ()
 %!error legendre (1)
 %!error legendre (1,2,3,4)
-%!error legendre ([1, 2], [-1, 0, 1])
-%!error legendre (-1, [-1, 0, 1])
-%!error legendre (1.1, [-1, 0, 1])
-%!error legendre (1, [-1+i, 0, 1])
-%!error legendre (1, [-2, 0, 1])
-%!error legendre (1, [-1, 0, 2])
-%!error legendre (1, [-1, 0, 1], "badnorm")
+%!error <must be a real non-negative integer> legendre (i, [-1, 0, 1])
+%!error <must be a real non-negative integer> legendre ([1, 2], [-1, 0, 1])
+%!error <must be a real non-negative integer> legendre (-1, [-1, 0, 1])
+%!error <must be a real non-negative integer> legendre (1.1, [-1, 0, 1])
+%!error <must be real-valued vector> legendre (1, [-1+i, 0, 1])
+%!error <in the range -1 .= X .= 1> legendre (1, [-2, 0, 1])
+%!error <in the range -1 .= X .= 1> legendre (1, [-1, 0, 2])
+%!error <NORMALIZATION option must be> legendre (1, [-1, 0, 1], "badnorm")
 
--- a/scripts/specfun/nchoosek.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/specfun/nchoosek.m	Fri Feb 06 08:31:49 2015 -0800
@@ -21,7 +21,8 @@
 ## @deftypefn  {Function File} {@var{c} =} nchoosek (@var{n}, @var{k})
 ## @deftypefnx {Function File} {@var{c} =} nchoosek (@var{set}, @var{k})
 ##
-## Compute the binomial coefficient or all combinations of a set of items.
+## Compute the binomial coefficient of @var{n} or list all possible
+## combinations of a @var{set} of items.
 ##
 ## If @var{n} is a scalar then calculate the binomial coefficient
 ## of @var{n} and @var{k} which is defined as
@@ -75,10 +76,10 @@
 ## @end group
 ## @end example
 ##
-## @code{nchoosek} works only for non-negative, integer arguments.  Use
-## @code{bincoeff} for non-integer and negative scalar arguments, or for
-## computing many binomial coefficients at once with vector inputs
-## for @var{n} or @var{k}.
+## Programming Note: When calculating the binomial coefficient @code{nchoosek}
+## works only for non-negative, integer arguments.  Use @code{bincoeff} for
+## non-integer and negative scalar arguments, or for computing many binomial
+## coefficients at once with vector inputs for @var{n} or @var{k}.
 ##
 ## @seealso{bincoeff, perms}
 ## @end deftypefn
@@ -87,16 +88,17 @@
 ## Author: Paul Kienzle <pkienzle@users.sf.net>
 ## Author: Jaroslav Hajek
 
-function A = nchoosek (v, k)
+function C = nchoosek (v, k)
 
   if (nargin != 2
-      || !isnumeric (k) || !isnumeric (v)
-      || !isscalar (k) || ! (isscalar (v) || isvector (v)))
+      || ! (isreal (k) && isscalar (k))
+      || ! (isnumeric (v) && isvector (v)))
     print_usage ();
   endif
-  if (k < 0 || k != fix (k)
-      || (isscalar (v) && (v < k || v < 0 || v != fix (v))))
-    error ("nchoosek: args are non-negative integers with V not less than K");
+  if (k < 0 || k != fix (k))
+    error ("nchoosek: K must be an integer >= 0");
+  elseif (isscalar (v) && (iscomplex (v) || v < k || v < 0 || v != fix (v)))
+    error ("nchoosek: N must be a non-negative integer >= K");
   endif
 
   n = length (v);
@@ -104,54 +106,60 @@
   if (n == 1)
     ## Improve precision at next step.
     k = min (k, v-k);
-    A = round (prod ((v-k+1:v)./(1:k)));
-    if (A*2*k*eps >= 0.5)
-      warning ("nchoosek", "nchoosek: possible loss of precision");
+    C = round (prod ((v-k+1:v)./(1:k)));
+    if (C*2*k*eps >= 0.5)
+      warning ("nchoosek: possible loss of precision");
     endif
   elseif (k == 0)
-    A = [];
+    C = zeros (1,0);
   elseif (k == 1)
-    A = v(:);
+    C = v(:);
   elseif (k == n)
-    A = v(:).';
+    C = v(:).';
   elseif (k > n)
-    A = zeros (0, k, class (v));
+    C = zeros (0, k, class (v));
   elseif (k == 2)
     ## Can do it without transpose.
     x = repelems (v(1:n-1), [1:n-1; n-1:-1:1]).';
     y = cat (1, cellslices (v(:), 2:n, n*ones (1, n-1)){:});
-    A = [x, y];
+    C = [x, y];
   elseif (k < n)
     v = v(:).';
-    A = v(k:n);
+    C = v(k:n);
     l = 1:n-k+1;
     for j = 2:k
-      c = columns (A);
-      cA = cellslices (A, l, c*ones (1, n-k+1), 2);
+      c = columns (C);
+      cA = cellslices (C, l, c*ones (1, n-k+1), 2);
       l = c-l+1;
       b = repelems (v(k-j+1:n-j+1), [1:n-k+1; l]);
-      A = [b; cA{:}];
+      C = [b; cA{:}];
       l = cumsum (l);
       l = [1, 1 + l(1:n-k)];
     endfor
-    clear cA b;
-    A = A.';
+    C = C.';
   endif
+
 endfunction
 
 
 %!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);
+%!error nchoosek ()
+%!error nchoosek (1)
+%!error nchoosek (1,2,3)
+
+%!error nchoosek (100, 2i)
+%!error nchoosek (100, [2 3])
 %!error nchoosek ("100", 45)
-%!error nchoosek (100, "45")
-%!error nchoosek (100, ones (2,2))
-%!error nchoosek (repmat (100, [2 2]), 45)
-%!error nchoosek (100, -45)
-%!error nchoosek (100, 45.5)
-%!error nchoosek (100, 145)
-%!error nchoosek (-100, 45)
-%!error nchoosek (100.5, 45)
+%!error nchoosek (100*ones (2, 2), 45)
+%!error <K must be an integer .= 0> nchoosek (100, -45)
+%!error <K must be an integer .= 0> nchoosek (100, 45.5)
+%!error <N must be a non-negative integer .= K> nchoosek (100i, 2)
+%!error <N must be a non-negative integer .= K> nchoosek (100, 145)
+%!error <N must be a non-negative integer .= K> nchoosek (-100, 45)
+%!error <N must be a non-negative integer .= K> nchoosek (100.5, 45)
+%!warning <possible loss of precision> nchoosek (100, 45);
 
--- a/scripts/specfun/nthroot.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/specfun/nthroot.m	Fri Feb 06 08:31:49 2015 -0800
@@ -23,8 +23,13 @@
 ## -*- texinfo -*-
 ## @deftypefn {Function File} {} nthroot (@var{x}, @var{n})
 ##
-## Compute the n-th root of @var{x}, returning real results for real
-## components of @var{x}.  For example:
+## Compute the real (non-complex) @var{n}-th root of @var{x}.
+##
+## @var{x} must have all real entries and @var{n} must be a scalar.
+## If @var{n} is an even integer and @var{x} has negative entries then
+## @code{nthroot} aborts and issues an error.
+##
+## Example:
 ##
 ## @example
 ## @group
@@ -34,10 +39,6 @@
 ## @result{} 0.50000 - 0.86603i
 ## @end group
 ## @end example
-##
-## @var{x} must have all real entries.  @var{n} must be a scalar.
-## If @var{n} is an even integer and @var{X} has negative entries, an
-## error is produced.
 ## @seealso{realsqrt, sqrt, cbrt}
 ## @end deftypefn
 
@@ -47,12 +48,12 @@
     print_usage ();
   endif
 
-  if (any (iscomplex (x(:))))
+  if (iscomplex (x))
     error ("nthroot: X must not contain complex values");
   endif
 
-  if (! isscalar (n) || n == 0)
-    error ("nthroot: N must be a nonzero scalar");
+  if (! isreal (n) || ! isscalar (n) || n == 0)
+    error ("nthroot: N must be a real nonzero scalar");
   endif
 
   if (n == 3)
@@ -63,37 +64,48 @@
     y = 1 ./ nthroot (x, -n);
   else
     ## Compute using power.
-    if (n == fix (n) && mod (n, 2) == 1)
+    integer_n = n == fix (n);
+    if (integer_n && mod (n, 2) == 1)
       y = abs (x) .^ (1/n) .* sign (x);
     elseif (any (x(:) < 0))
-      error ("nthroot: if X contains negative values, N must be an odd integer");
+      error ("nthroot: N must be an odd integer if X contains negative values");
     else
       y = x .^ (1/n);
     endif
 
-    if (finite (n) && n > 0 && n == fix (n))
-      ## Correction.
-      y = ((n-1)*y + x ./ (y.^(n-1))) / n;
-      y = merge (finite (y), y, x);
+    if (integer_n && n > 0 && isfinite (n))
+      if (isscalar (y) && y == 0)
+        ## Don't apply correction which leads to division by zero (bug #43492)
+      else
+        ## FIXME: What is this correction for?
+        y = ((n-1)*y + x ./ (y.^(n-1))) / n;
+        y = merge (isfinite (y), y, x);
+      endif
     endif
-
   endif
 
 endfunction
 
 
-%!assert (nthroot (-32,5), -2);
-%!assert (nthroot (81,4), 3);
-%!assert (nthroot (Inf,4), Inf);
-%!assert (nthroot (-Inf,7), -Inf);
-%!assert (nthroot (-Inf,-7), 0);
+%!assert (nthroot (-32, 5), -2)
+%!assert (nthroot (81, 4), 3)
+%!assert (nthroot (Inf, 4), Inf)
+%!assert (nthroot (-Inf, 7), -Inf)
+%!assert (nthroot (-Inf, -7), 0)
+
+## Bug #43492.  This should not generate a division by zero warning
+%!test
+%! warnmsg = lastwarn ();
+%! assert (nthroot (0, 2), 0);
+%! assert (lastwarn (), warnmsg);
 
 %% Test input validation
-%!error (nthroot ())
-%!error (nthroot (1))
-%!error (nthroot (1,2,3))
-%!error (nthroot (1+j,2))
-%!error (nthroot (1,[1 2]))
-%!error (nthroot (1,0))
-%!error (nthroot (-1,2))
+%!error nthroot ()
+%!error nthroot (1)
+%!error nthroot (1,2,3)
+%!error <X must not contain complex values> nthroot (1+j, 2)
+%!error <N must be a real nonzero scalar> nthroot (1, i)
+%!error <N must be a real nonzero scalar> nthroot (1, [1 2])
+%!error <N must be a real nonzero scalar> nthroot (1, 0)
+%!error <N must be an odd integer> nthroot (-1, 2)
 
--- a/scripts/specfun/perms.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/specfun/perms.m	Fri Feb 06 08:31:49 2015 -0800
@@ -19,15 +19,17 @@
 
 ## -*- texinfo -*-
 ## @deftypefn {Function File} {} perms (@var{v})
+## Generate all permutations of @var{v} with one row per permutation.
 ##
-## Generate all permutations of @var{v}, one row per permutation.  The
-## result has size @code{factorial (@var{n}) * @var{n}}, where @var{n}
+## The result has size @code{factorial (@var{n}) * @var{n}}, where @var{n}
 ## is the length of @var{v}.
 ##
-## As an example, @code{perms ([1, 2, 3])} returns the matrix
+## Example
 ##
 ## @example
 ## @group
+## perms ([1, 2, 3])
+## @result{}
 ##   1   2   3
 ##   2   1   3
 ##   1   3   2
@@ -36,12 +38,18 @@
 ##   3   2   1
 ## @end group
 ## @end example
+##
+## Programming Note: The maximum length of @var{v} should be less than or
+## equal to 10 to limit memory consumption.
+## @seealso{permute, randperm, nchoosek}
 ## @end deftypefn
 
 function A = perms (v)
+
   if (nargin != 1)
     print_usage ();
   endif
+
   vidx = uint8 ([1:length(v)]');
   n = length (vidx);
 
@@ -62,7 +70,9 @@
       endfor
     endfor
   endif
+
   A = v(p);
+
 endfunction
 
 
--- a/scripts/specfun/pow2.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/specfun/pow2.m	Fri Feb 06 08:31:49 2015 -0800
@@ -17,9 +17,9 @@
 ## <http://www.gnu.org/licenses/>.
 
 ## -*- texinfo -*-
-## @deftypefn  {Mapping Function} {} pow2 (@var{x})
-## @deftypefnx {Mapping Function} {} pow2 (@var{f}, @var{e})
-## With one argument, computes
+## @deftypefn  {Function File} {} pow2 (@var{x})
+## @deftypefnx {Function File} {} pow2 (@var{f}, @var{e})
+## With one input argument, compute
 ## @tex
 ## $2^x$
 ## @end tex
@@ -28,14 +28,14 @@
 ## @end ifnottex
 ## for each element of @var{x}.
 ##
-## With two arguments, returns
+## With two input arguments, return
 ## @tex
 ## $f \cdot 2^e$.
 ## @end tex
 ## @ifnottex
 ## f .* (2 .^ e).
 ## @end ifnottex
-## @seealso{log2, nextpow2}
+## @seealso{log2, nextpow2, power}
 ## @end deftypefn
 
 ## Author: AW <Andreas.Weingessel@ci.tuwien.ac.at>
@@ -67,4 +67,5 @@
 %! assert (pow2 (x,y), z, sqrt (eps));
 
 %!error pow2 ()
+%!error pow2 (1,2,3)
 
--- a/scripts/specfun/primes.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/specfun/primes.m	Fri Feb 06 08:31:49 2015 -0800
@@ -18,12 +18,13 @@
 
 ## -*- texinfo -*-
 ## @deftypefn {Function File} {} primes (@var{n})
-##
 ## Return all primes up to @var{n}.
 ##
-## The algorithm used is the Sieve of Eratosthenes.
+## The output data class (double, single, uint32, etc.) is the same as
+## the input class of @var{n}.  The algorithm used is the Sieve of
+## Eratosthenes.
 ##
-## Note that if you need a specific number of primes you can use the
+## Notes: If you need a specific number of primes you can use the
 ## fact that the distance from one prime to the next is, on average,
 ## proportional to the logarithm of the prime.  Integrating, one finds
 ## that there are about @math{k} primes less than
@@ -33,6 +34,9 @@
 ## @ifnottex
 ## k*log (5*k).
 ## @end ifnottex
+##
+## See also @code{list_primes} if you need a specific number @var{n} of
+## primes.
 ## @seealso{list_primes, isprime}
 ## @end deftypefn
 
@@ -40,7 +44,7 @@
 ## Author: Francesco Potortì
 ## Author: Dirk Laurie
 
-function x = primes (n)
+function p = primes (n)
 
   if (nargin != 1)
     print_usage ();
@@ -50,9 +54,9 @@
     error ("primes: N must be a scalar");
   endif
 
-  if (n > 100000)
+  if (n > 100e3)
     ## Optimization: 1/6 less memory, and much faster (asymptotically)
-    ## 100000 happens to be the cross-over point for Paul's machine;
+    ## 100K happens to be the cross-over point for Paul's machine;
     ## below this the more direct code below is faster.  At the limit
     ## of memory in Paul's machine, this saves .7 seconds out of 7 for
     ## n = 3e6.  Hardly worthwhile, but Dirk reports better numbers.
@@ -71,8 +75,8 @@
         sievem(5*i+1:6*i+1:lenm) = false;
       endif
     endfor
-    x = sort ([2, 3, 6*find(sievem)-1, 6*find(sievep)+1]);
-  elseif (n > 352)                # nothing magical about 352; must be >2
+    p = sort ([2, 3, 6*find(sievem)-1, 6*find(sievep)+1]);
+  elseif (n > 352)                # nothing magical about 352; must be > 2
     len = floor ((n-1)/2);        # length of the sieve
     sieve = true (1, len);        # assume every odd number is prime
     for i = 1:(sqrt (n)-1)/2      # check up to sqrt (n)
@@ -80,7 +84,7 @@
         sieve(3*i+1:2*i+1:len) = false; # do it
       endif
     endfor
-    x = [2, 1+2*find(sieve)];     # primes remaining after sieve
+    p = [2, 1+2*find(sieve)];     # primes remaining after sieve
   else
     a = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, ...
          53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, ...
@@ -88,7 +92,11 @@
          173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, ...
          233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 283, ...
          293, 307, 311, 313, 317, 331, 337, 347, 349];
-    x = a(a <= n);
+    p = a(a <= n);
+  endif
+
+  if (! isa (n, "double"))
+    cast (p, class (n));
   endif
 
 endfunction
@@ -99,4 +107,5 @@
 
 %!error primes ()
 %!error primes (1, 2)
+%!error <N must be a scalar> primes (ones (2,2))
 
--- a/scripts/specfun/reallog.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/specfun/reallog.m	Fri Feb 06 08:31:49 2015 -0800
@@ -18,12 +18,15 @@
 
 ## -*- texinfo -*-
 ## @deftypefn {Function File} {} reallog (@var{x})
-## Return the real-valued natural logarithm of each element of @var{x}.  Report
-## an error if any element results in a complex return value.
+## Return the real-valued natural logarithm of each element of @var{x}.
+##
+## If any element results in a complex return value @code{reallog} aborts
+## and issues an error.
 ## @seealso{log, realpow, realsqrt}
 ## @end deftypefn
 
 function y = reallog (x)
+
   if (nargin != 1)
     print_usage ();
   elseif (iscomplex (x) || any (x(:) < 0))
@@ -31,13 +34,17 @@
   else
     y = log (x);
   endif
+
 endfunction
 
 
-%!assert (log (1:5), reallog (1:5))
+%!assert (reallog (1:5), log (1:5))
 %!test
-%! x = rand (10,10);
-%! assert (log (x),reallog (x));
+%! x = rand (10, 10);
+%! assert (reallog (x), log (x));
 
+%!error reallog ()
+%!error reallog (1,2)
+%!error <produced complex result> reallog (2i)
 %!error <produced complex result> reallog (-1)
 
--- a/scripts/specfun/realpow.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/specfun/realpow.m	Fri Feb 06 08:31:49 2015 -0800
@@ -18,31 +18,37 @@
 
 ## -*- texinfo -*-
 ## @deftypefn {Function File} {} realpow (@var{x}, @var{y})
-## Compute the real-valued, element-by-element power operator.  This is
-## equivalent to @w{@code{@var{x} .^ @var{y}}}, except that @code{realpow}
-## reports an error if any return value is complex.
-## @seealso{reallog, realsqrt}
+## Compute the real-valued, element-by-element power operator.
+##
+## This is equivalent to @w{@code{@var{x} .^ @var{y}}}, except that
+## @code{realpow} reports an error if any return value is complex.
+## @seealso{power, reallog, realsqrt}
 ## @end deftypefn
 
 function z = realpow (x, y)
+
   if (nargin != 2)
     print_usage ();
-  else
-    z = x .^ y;
-    if (iscomplex (z))
-      error ("realpow: produced complex result");
-    endif
   endif
+
+  z = x .^ y;
+  if (iscomplex (z))
+    error ("realpow: produced complex result");
+  endif
+
 endfunction
 
 
-%!assert (power (1:10, 0.5:0.5:5), realpow (1:10, 0.5:0.5:5))
-%!assert ([1:10] .^ [0.5:0.5:5], realpow (1:10, 0.5:0.5:5))
+%!assert (realpow (1:10, 0.5:0.5:5), power (1:10, 0.5:0.5:5))
+%!assert (realpow (1:10, 0.5:0.5:5), [1:10] .^ [0.5:0.5:5])
 %!test
-%! x = rand (10,10);
-%! y = randn (10,10);
+%! x = rand (10, 10);
+%! y = randn (10, 10);
 %! assert (x.^y, realpow (x,y));
 %!assert (realpow (1i,2), -1)
 
+%!error realpow ()
+%!error realpow (1)
+%!error realpow (1,2,3)
 %!error <produced complex result> realpow (-1, 1/2)
 
--- a/scripts/specfun/realsqrt.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/specfun/realsqrt.m	Fri Feb 06 08:31:49 2015 -0800
@@ -18,12 +18,15 @@
 
 ## -*- texinfo -*-
 ## @deftypefn {Function File} {} realsqrt (@var{x})
-## Return the real-valued square root of each element of @var{x}.  Report an
-## error if any element results in a complex return value.
+## Return the real-valued square root of each element of @var{x}.
+##
+## If any element results in a complex return value @code{realsqrt} aborts
+## and issues an error.
 ## @seealso{sqrt, realpow, reallog}
 ## @end deftypefn
 
 function y = realsqrt (x)
+
   if (nargin != 1)
     print_usage ();
   elseif (iscomplex (x) || any (x(:) < 0))
@@ -31,13 +34,16 @@
   else
     y = sqrt (x);
   endif
+
 endfunction
 
 
-%!assert (sqrt (1:5), realsqrt (1:5))
+%!assert (realsqrt (1:5), sqrt (1:5))
 %!test
-%! x = rand (10,10);
-%! assert (sqrt (x), realsqrt (x));
+%! x = rand (10, 10);
+%! assert (realsqrt (x), sqrt (x));
 
+%!error realsqrt ()
+%!error realsqrt (1,2)
 %!error <produced complex result> realsqrt (-1)
 
--- a/scripts/special-matrix/gallery.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/special-matrix/gallery.m	Fri Feb 06 08:31:49 2015 -0800
@@ -83,7 +83,7 @@
 ## @deftypefn  {Function File} {[@var{c}, @var{d}, @var{e}] =} gallery ("dorr", @var{n})
 ## @deftypefnx {Function File} {[@var{c}, @var{d}, @var{e}] =} gallery ("dorr", @var{n}, @var{theta})
 ## @deftypefnx {Function File} {@var{a} =} gallery ("dorr", @dots{})
-## Create a diagonally dominant, ill conditioned, tridiagonal matrix.
+## Create a diagonally dominant, ill-conditioned, tridiagonal matrix.
 ##
 ## @end deftypefn
 ##
@@ -94,20 +94,20 @@
 ## @end deftypefn
 ##
 ## @deftypefn {Function File} {@var{a} =} gallery ("fiedler", @var{c})
-## Create a symmetric Fiedler matrix.
+## Create a symmetric @nospell{Fiedler} matrix.
 ##
 ## @end deftypefn
 ##
 ## @deftypefn  {Function File} {@var{a} =} gallery ("forsythe", @var{n})
 ## @deftypefnx {Function File} {@var{a} =} gallery ("forsythe", @var{n}, @var{alpha})
 ## @deftypefnx {Function File} {@var{a} =} gallery ("forsythe", @var{n}, @var{alpha}, @var{lambda})
-## Create a Forsythe matrix (a perturbed Jordan block).
+## Create a @nospell{Forsythe} matrix (a perturbed Jordan block).
 ##
 ## @end deftypefn
 ##
 ## @deftypefn  {Function File} {@var{f} =} gallery ("frank", @var{n})
 ## @deftypefnx {Function File} {@var{f} =} gallery ("frank", @var{n}, @var{k})
-## Create a Frank matrix (ill conditioned eigenvalues).
+## Create a Frank matrix (ill-conditioned eigenvalues).
 ##
 ## @end deftypefn
 ##
@@ -194,13 +194,13 @@
 ## @deftypefn  {Function File} {@var{u} =} gallery ("kahan", @var{n})
 ## @deftypefnx {Function File} {@var{u} =} gallery ("kahan", @var{n}, @var{theta})
 ## @deftypefnx {Function File} {@var{u} =} gallery ("kahan", @var{n}, @var{theta}, @var{pert})
-## Create a Kahan matrix (upper trapezoidal).
+## Create a @nospell{Kahan} matrix (upper trapezoidal).
 ##
 ## @end deftypefn
 ##
 ## @deftypefn  {Function File} {@var{a} =} gallery ("kms", @var{n})
 ## @deftypefnx {Function File} {@var{a} =} gallery ("kms", @var{n}, @var{rho})
-## Create a Kac-Murdock-Szego Toeplitz matrix.
+## Create a @nospell{Kac-Murdock-Szego} Toeplitz matrix.
 ##
 ## @end deftypefn
 ##
@@ -213,12 +213,12 @@
 ##
 ## @deftypefn  {Function File} {@var{a} =} gallery ("lauchli", @var{n})
 ## @deftypefnx {Function File} {@var{a} =} gallery ("lauchli", @var{n}, @var{mu})
-## Create a Lauchli matrix (rectangular).
+## Create a @nospell{Lauchli} matrix (rectangular).
 ##
 ## @end deftypefn
 ##
 ## @deftypefn {Function File} {@var{a} =} gallery ("lehmer", @var{n})
-## Create a Lehmer matrix (symmetric positive definite).
+## Create a @nospell{Lehmer} matrix (symmetric positive definite).
 ##
 ## @end deftypefn
 ##
@@ -228,7 +228,7 @@
 ## @end deftypefn
 ##
 ## @deftypefn {Function File} {@var{a} =} gallery ("lotkin", @var{n})
-## Create a Lotkin matrix.
+## Create a @nospell{Lotkin} matrix.
 ##
 ## @end deftypefn
 ##
@@ -239,7 +239,7 @@
 ##
 ## @deftypefn  {Function File} {@var{a} =} gallery ("moler", @var{n})
 ## @deftypefnx {Function File} {@var{a} =} gallery ("moler", @var{n}, @var{alpha})
-## Create a Moler matrix (symmetric positive definite).
+## Create a @nospell{Moler} matrix (symmetric positive definite).
 ##
 ## @end deftypefn
 ##
@@ -274,7 +274,8 @@
 ## @end deftypefn
 ##
 ## @deftypefn {Function File} {@var{a} =} gallery ("parter", @var{n})
-## Create a Parter matrix (a Toeplitz matrix with singular values near pi).
+## Create a @nospell{Parter} matrix (a Toeplitz matrix with singular values
+## near pi).
 ##
 ## @end deftypefn
 ##
@@ -316,8 +317,8 @@
 ## @end deftypefn
 ##
 ## @deftypefn {Function File} {@var{a} =} gallery ("redheff", @var{n})
-## Create a zero and ones matrix of Redheffer associated with the Riemann
-## hypothesis.
+## Create a zero and ones matrix of @nospell{Redheffer} associated with the
+## Riemann hypothesis.
 ##
 ## @end deftypefn
 ##
@@ -365,7 +366,8 @@
 ## @deftypefn  {Function File} {@var{t} =} gallery ("triw", @var{n})
 ## @deftypefnx {Function File} {@var{t} =} gallery ("triw", @var{n}, @var{alpha})
 ## @deftypefnx {Function File} {@var{t} =} gallery ("triw", @var{n}, @var{alpha}, @var{k})
-## Create an upper triangular matrix discussed by Kahan, Golub and Wilkinson.
+## Create an upper triangular matrix discussed by
+## @nospell{Kahan, Golub, and Wilkinson}.
 ##
 ## @end deftypefn
 ##
@@ -390,7 +392,7 @@
 ##
 ## @deftypefn  {Function File} {@var{a} =} gallery ("wathen", @var{nx}, @var{ny})
 ## @deftypefnx {Function File} {@var{a} =} gallery ("wathen", @var{nx}, @var{ny}, @var{k})
-## Create the Wathen matrix.
+## Create the @nospell{Wathen} matrix.
 ##
 ## @end deftypefn
 ##
@@ -1214,9 +1216,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 +2522,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 +2558,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.
@@ -2853,3 +2855,15 @@
   endif
 endfunction
 
+
+## BIST testing for just a few functions to verify that the main gallery
+## dispatch function works.
+%assert (gallery ("clement", 3), [0 1 0; 2 0 2; 0 1 0])
+%assert (gallery ("invhess", 2), [1 -1; 1 2])
+
+## Test input validation of main dispatch function only
+%!error gallery ()
+%!error <NAME must be a string> gallery (123)
+%!error <matrix binomial not implemented> gallery ("binomial")
+%!error <unknown matrix with NAME foobar> gallery ("foobar")
+
--- a/scripts/special-matrix/invhilb.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/special-matrix/invhilb.m	Fri Feb 06 08:31:49 2015 -0800
@@ -63,7 +63,7 @@
 ## The validity of this formula can easily be checked by expanding
 ## the binomial coefficients in both formulas as factorials.  It can
 ## be derived more directly via the theory of Cauchy matrices.
-## See J. W. Demmel, @cite{Applied Numerical Linear Algebra}, p. 92.
+## See @nospell{J. W. Demmel}, @cite{Applied Numerical Linear Algebra}, p. 92.
 ##
 ## Compare this with the numerical calculation of @code{inverse (hilb (n))},
 ## which suffers from the ill-conditioning of the Hilbert matrix, and the
--- a/scripts/startup/inputrc	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/startup/inputrc	Fri Feb 06 08:31:49 2015 -0800
@@ -24,3 +24,8 @@
 ## \C-q should still be available for quoted insert.
 
 "\C-v": ""
+
+## In windows, disable audiable bell which is enabled by default
+$if term=cygwin
+   set bell-style none
+$endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/statistics/base/lscov.m	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,188 @@
+## Copyright (C) 2014 Nir Krakauer
+##
+## This program is free software; you can redistribute it and/or modify
+## it under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or
+## (at your option) any later version.
+##
+## This program is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+## GNU General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with this program; If not, see <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn  {Function File} {@var{x} =} lscov (@var{A}, @var{b})
+## @deftypefnx {Function File} {@var{x} =} lscov (@var{A}, @var{b}, @var{V})
+## @deftypefnx {Function File} {@var{x} =} lscov (@var{A}, @var{b}, @var{V}, @var{alg})
+## @deftypefnx {Function File} {[@var{x}, @var{stdx}, @var{mse}, @var{S}] =} lscov (@dots{})
+##
+## Compute a generalized linear least squares fit.
+## Estimate @var{x} under the model @var{b} = @var{A}@var{x} + @var{w},
+## where the noise @var{w} is assumed to follow a normal distribution
+## with covariance matrix @math{{\sigma^2} V}.
+##
+## If the size of the coefficient matrix @var{A} is n-by-p, the
+## size of the vector/array of constant terms @var{b} must be n-by-k.
+##
+## The optional input argument @var{V} may be a n-by-1 vector of positive
+## weights (inverse variances), or a n-by-n symmetric positive
+## semidefinite matrix representing the covariance of @var{b}.  If
+## @var{V} is not supplied, the ordinary least squares solution is
+## returned.
+##
+## The @var{alg} input argument, a guidance on solution method to use,
+## is currently ignored.
+##
+## Besides the least-squares estimate matrix @var{x} (p-by-k), the
+## function also returns @var{stdx} (p-by-k), the error standard
+## deviation of estimated @var{x}; @var{mse} (k-by-1), the estimated
+## data error covariance scale factors (@math{\sigma^2}); and @var{S}
+## (p-by-p, or p-by-p-by-k if k > 1), the error covariance of @var{x}.
+##
+## Reference: @nospell{Golub and Van Loan} (1996),
+## Matrix Computations (3rd Ed.), Johns Hopkins, Section 5.6.3
+##
+## @end deftypefn
+## @seealso{ols, gls, lsqnonneg}
+
+## Author: Nir Krakauer
+
+function [x, stdx, mse, S] = lscov (A, b, V = [], alg)
+
+  if (nargin < 2 || (rows (A) != rows (b)))
+    print_usage ();
+  endif
+
+  n = rows (A);
+  p = columns (A);
+  k = columns (b);
+
+  if (! isempty (V))
+    if (rows (V) != n || ! any (columns (V) == [1 n]))
+      error ("lscov: V should be a square matrix or a vector with the same number of rows as A");
+    endif
+
+    if (isvector (V))
+      ## n-by-1 vector of inverse variances
+      v = diag (sqrt (V));
+      A = v * A;
+      b = v * b;
+    else
+      ## n-by-n covariance matrix
+      try
+        ## ordinarily V will be positive definite
+        B = chol (V)';
+      catch
+        ## if V is only positive semidefinite, use its
+        ## eigendecomposition to find a factor B such that V = B*B'
+        [B, lambda] = eig (V);
+        image_dims = (diag (lambda) > 0);
+        B = B(:, image_dims) * sqrt (lambda(image_dims, image_dims));
+      end_try_catch
+      A = B \ A;
+      b = B \ b;
+    endif
+  endif
+
+  pinv_A = pinv (A); #pseudoinverse
+
+  x = pinv_A * b;
+
+  if (isargout (3))
+    dof = n - p; #degrees of freedom remaining after fit
+    SSE = sumsq (b - A * x);
+    mse = SSE / dof;
+  endif
+
+  s = pinv_A * pinv_A';
+
+  stdx = sqrt (diag (s) * mse);
+
+  if (isargout (4))
+    if (k == 1)
+      S = mse * s;
+    else
+      S = nan (p, p, k);
+      for i = 1:k
+        S(:, :, i) = mse(i) * s;
+      endfor
+    endif
+  endif
+endfunction
+
+%!test
+%! ## Longley data from the NIST Statistical Reference Dataset
+%! Z = [  60323    83.0   234289   2356     1590    107608  1947
+%!        61122    88.5   259426   2325     1456    108632  1948
+%!        60171    88.2   258054   3682     1616    109773  1949
+%!        61187    89.5   284599   3351     1650    110929  1950
+%!        63221    96.2   328975   2099     3099    112075  1951
+%!        63639    98.1   346999   1932     3594    113270  1952
+%!        64989    99.0   365385   1870     3547    115094  1953
+%!        63761   100.0   363112   3578     3350    116219  1954
+%!        66019   101.2   397469   2904     3048    117388  1955
+%!        67857   104.6   419180   2822     2857    118734  1956
+%!        68169   108.4   442769   2936     2798    120445  1957
+%!        66513   110.8   444546   4681     2637    121950  1958
+%!        68655   112.6   482704   3813     2552    123366  1959
+%!        69564   114.2   502601   3931     2514    125368  1960
+%!        69331   115.7   518173   4806     2572    127852  1961
+%!        70551   116.9   554894   4007     2827    130081  1962 ];
+%! ## Results certified by NIST using 500 digit arithmetic
+%! ## b and standard error in b
+%! V = [  -3482258.63459582         890420.383607373
+%!         15.0618722713733         84.9149257747669
+%!        -0.358191792925910E-01    0.334910077722432E-01
+%!        -2.02022980381683         0.488399681651699
+%!        -1.03322686717359         0.214274163161675
+%!        -0.511041056535807E-01    0.226073200069370
+%!         1829.15146461355         455.478499142212 ];
+%! rsd =  304.854073561965;
+%! y = Z(:,1); X = [ones(rows(Z),1), Z(:,2:end)];
+%! alpha = 0.05;
+%! [b, stdb, mse] = lscov (X, y);
+%! assert(b, V(:,1), 3e-6);
+%! assert(stdb, V(:,2), -1.e-5);
+%! assert(sqrt (mse), rsd, -1E-6);
+
+%!test
+%! ## Adapted from example in Matlab documentation
+%! x1 = [.2 .5 .6 .8 1.0 1.1]';
+%! x2 = [.1 .3 .4 .9 1.1 1.4]';
+%! X = [ones(size(x1)) x1 x2];
+%! y = [.17 .26 .28 .23 .27 .34]';
+%! [b, se_b, mse, S] = lscov(X, y);
+%! assert(b, [0.1203 0.3284 -0.1312]', 1E-4);
+%! assert(se_b, [0.0643 0.2267 0.1488]', 1E-4);
+%! assert(mse, 0.0015, 1E-4);
+%! assert(S, [0.0041 -0.0130 0.0075; -0.0130 0.0514 -0.0328; 0.0075 -0.0328 0.0221], 1E-4);
+%! w = [1 1 1 1 1 .1]';
+%! [bw, sew_b, msew] = lscov (X, y, w);
+%! assert(bw, [0.1046 0.4614 -0.2621]', 1E-4);
+%! assert(sew_b, [0.0309 0.1152 0.0814]', 1E-4);
+%! assert(msew, 3.4741e-004, -1E-4);
+%! V = .2*ones(length(x1)) + .8*diag(ones(size(x1)));
+%! [bg, sew_b, mseg] = lscov (X, y, V);
+%! assert(bg, [0.1203 0.3284 -0.1312]', 1E-4);
+%! assert(sew_b, [0.0672 0.2267 0.1488]', 1E-4);
+%! assert(mseg, 0.0019, 1E-4);
+%! y2 = [y 2*y];
+%! [b2, se_b2, mse2, S2] = lscov (X, y2);
+%! assert(b2, [b 2*b], eps)
+%! assert(se_b2, [se_b 2*se_b], eps)
+%! assert(mse2, [mse 4*mse], eps)
+%! assert(S2(:, :, 1), S, eps)
+%! assert(S2(:, :, 2), 4*S, eps)
+
+%!test
+%! ## Artificial example with positive semidefinite weight matrix
+%! x = (0:0.2:2)';
+%! y = round(100*sin(x) + 200*cos(x));
+%! X = [ones(size(x)) sin(x) cos(x)];
+%! V = eye(numel(x));
+%! V(end, end-1) = V(end-1, end) = 1;
+%! [b, seb, mseb, S] = lscov (X, y, V);
+%! assert(b, [0 100 200]', 0.2);
--- a/scripts/statistics/base/module.mk	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/statistics/base/module.mk	Fri Feb 06 08:31:49 2015 -0800
@@ -11,6 +11,7 @@
   statistics/base/kendall.m \
   statistics/base/kurtosis.m \
   statistics/base/logit.m \
+  statistics/base/lscov.m \
   statistics/base/mahalanobis.m \
   statistics/base/mean.m \
   statistics/base/meansq.m \
--- a/scripts/statistics/base/moment.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/statistics/base/moment.m	Fri Feb 06 08:31:49 2015 -0800
@@ -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 Feb 06 08:31:09 2015 -0800
+++ b/scripts/statistics/base/prctile.m	Fri Feb 06 08:31:49 2015 -0800
@@ -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 Feb 06 08:31:09 2015 -0800
+++ b/scripts/statistics/base/qqplot.m	Fri Feb 06 08:31:49 2015 -0800
@@ -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 Feb 06 08:31:09 2015 -0800
+++ b/scripts/statistics/base/quantile.m	Fri Feb 06 08:31:49 2015 -0800
@@ -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
@@ -75,17 +73,17 @@
 ## @var{x} is normally distributed.
 ## @end enumerate
 ##
-## Hyndman and Fan (1996) recommend method 8.  Maxima, S, and R
+## @nospell{Hyndman and Fan} (1996) recommend method 8.  Maxima, S, and R
 ## (versions prior to 2.0.0) use 7 as their default.  Minitab and SPSS
 ## use method 6.  @sc{matlab} uses method 5.
 ##
 ## References:
 ##
 ## @itemize @bullet
-## @item Becker, R. A., Chambers, J. M. and Wilks, A. R. (1988) The New
-## S Language.  Wadsworth & Brooks/Cole.
+## @item @nospell{Becker, R. A., Chambers, J. M. and Wilks, A. R.} (1988)
+## The New S Language.  Wadsworth & Brooks/Cole.
 ##
-## @item Hyndman, R. J. and Fan, Y. (1996) Sample quantiles in
+## @item @nospell{Hyndman, R. J. and Fan, Y.} (1996) Sample quantiles in
 ## statistical packages, American Statistician, 50, 361--365.
 ##
 ## @item R: A Language and Environment for Statistical Computing;
@@ -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/betapdf.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/statistics/distributions/betapdf.m	Fri Feb 06 08:31:49 2015 -0800
@@ -57,26 +57,26 @@
   if (isscalar (a) && isscalar (b))
     pdf(k) = exp ((a - 1) * log (x(k))
                   + (b - 1) * log (1 - x(k))
-                  + lgamma (a + b) - lgamma (a) - lgamma (b));
+                  + gammaln (a + b) - gammaln (a) - gammaln (b));
   else
     pdf(k) = exp ((a(k) - 1) .* log (x(k))
                   + (b(k) - 1) .* log (1 - x(k))
-                  + lgamma (a(k) + b(k)) - lgamma (a(k)) - lgamma (b(k)));
+                  + gammaln (a(k) + b(k)) - gammaln (a(k)) - gammaln (b(k)));
   endif
 
   ## Most important special cases when the density is finite.
   k = (x == 0) & (a == 1) & (b > 0) & (b != 1);
   if (isscalar (a) && isscalar (b))
-    pdf(k) = exp (lgamma (a + b) - lgamma (a) - lgamma (b));
+    pdf(k) = exp (gammaln (a + b) - gammaln (a) - gammaln (b));
   else
-    pdf(k) = exp (lgamma (a(k) + b(k)) - lgamma (a(k)) - lgamma (b(k)));
+    pdf(k) = exp (gammaln (a(k) + b(k)) - gammaln (a(k)) - gammaln (b(k)));
   endif
 
   k = (x == 1) & (b == 1) & (a > 0) & (a != 1);
   if (isscalar (a) && isscalar (b))
-    pdf(k) = exp (lgamma (a + b) - lgamma (a) - lgamma (b));
+    pdf(k) = exp (gammaln (a + b) - gammaln (a) - gammaln (b));
   else
-    pdf(k) = exp (lgamma (a(k) + b(k)) - lgamma (a(k)) - lgamma (b(k)));
+    pdf(k) = exp (gammaln (a(k) + b(k)) - gammaln (a(k)) - gammaln (b(k)));
   endif
 
   k = (x >= 0) & (x <= 1) & (a == 1) & (b == 1);
--- a/scripts/statistics/distributions/empirical_pdf.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/statistics/distributions/empirical_pdf.m	Fri Feb 06 08:31:49 2015 -0800
@@ -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 Feb 06 08:31:09 2015 -0800
+++ b/scripts/statistics/distributions/normrnd.m	Fri Feb 06 08:31:49 2015 -0800
@@ -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 Feb 06 08:31:09 2015 -0800
+++ b/scripts/statistics/tests/cor_test.m	Fri Feb 06 08:31:49 2015 -0800
@@ -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 Feb 06 08:31:09 2015 -0800
+++ b/scripts/statistics/tests/hotelling_test_2.m	Fri Feb 06 08:31:49 2015 -0800
@@ -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/statistics/tests/kruskal_wallis_test.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/statistics/tests/kruskal_wallis_test.m	Fri Feb 06 08:31:49 2015 -0800
@@ -18,7 +18,7 @@
 
 ## -*- texinfo -*-
 ## @deftypefn {Function File} {[@var{pval}, @var{k}, @var{df}] =} kruskal_wallis_test (@var{x1}, @dots{})
-## Perform a Kruskal-Wallis one-factor analysis of variance.
+## Perform a @nospell{Kruskal-Wallis} one-factor analysis of variance.
 ##
 ## Suppose a variable is observed for @var{k} > 1 different groups, and
 ## let @var{x1}, @dots{}, @var{xk} be the corresponding data vectors.
@@ -36,7 +36,7 @@
 ## where @var{sum_ties} is the sum of @var{t}^2 - @var{t} over each group
 ## of ties where @var{t} is the number of ties in the group and @var{n}
 ## is the total number of values in the input data.  For more info on
-## this adjustment see William H. Kruskal and W. Allen Wallis,
+## this adjustment see @nospell{William H. Kruskal and W. Allen Wallis},
 ## @cite{Use of Ranks in One-Criterion Variance Analysis},
 ## Journal of the American Statistical Association, Vol. 47,
 ## No. 260 (Dec 1952).
--- a/scripts/statistics/tests/manova.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/statistics/tests/manova.m	Fri Feb 06 08:31:49 2015 -0800
@@ -28,7 +28,7 @@
 ## and columns are variables.  The vector @var{g} specifies the
 ## corresponding group labels (e.g., numbers from 1 to @var{k}).
 ##
-## The LR test statistic (Wilks' Lambda) and approximate p-values are
+## The LR test statistic (@nospell{Wilks' Lambda}) and approximate p-values are
 ## computed and displayed.
 ## @end deftypefn
 
--- a/scripts/statistics/tests/mcnemar_test.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/statistics/tests/mcnemar_test.m	Fri Feb 06 08:31:49 2015 -0800
@@ -19,8 +19,8 @@
 ## -*- texinfo -*-
 ## @deftypefn {Function File} {[@var{pval}, @var{chisq}, @var{df}] =} mcnemar_test (@var{x})
 ## For a square contingency table @var{x} of data cross-classified on
-## the row and column variables, McNemar's test can be used for testing
-## the null hypothesis of symmetry of the classification probabilities.
+## the row and column variables, @nospell{McNemar's} test can be used for
+## testing the null hypothesis of symmetry of the classification probabilities.
 ##
 ## Under the null, @var{chisq} is approximately distributed as chisquare
 ## with @var{df} degrees of freedom.
--- a/scripts/statistics/tests/t_test.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/statistics/tests/t_test.m	Fri Feb 06 08:31:49 2015 -0800
@@ -82,3 +82,34 @@
 
 endfunction
 
+
+%!test
+%! ## Two-sided (also the default option)
+%! x = rand (10,1); n = length (x);
+%! u0 = 0.5; # true mean
+%! xbar = mean (x);
+%! pval = t_test (x, u0, "!=");
+%! if (xbar >= u0)
+%!   tval = abs (tinv (0.5*pval, n-1));
+%! else
+%!   tval = -abs (tinv (0.5*pval, n-1));
+%! endif
+%! unew = tval * std(x)/sqrt(n) + u0;
+%! assert (xbar, unew, 100*eps);
+
+%!test
+%! x = rand (10,1); n = length (x);
+%! u0 = 0.5;
+%! pval = t_test (x, u0, ">");
+%! tval = tinv (1-pval, n-1);
+%! unew = tval * std(x)/sqrt(n) + u0;
+%! assert (mean (x), unew, 100*eps);
+
+%!test
+%! x = rand (10,1); n = length (x);
+%! u0 = 0.5;
+%! pval = t_test (x, u0, "<");
+%! tval = tinv (pval, n-1);
+%! unew = tval * std(x)/sqrt(n) + u0;
+%! assert (mean (x), unew, 100*eps);
+
--- a/scripts/statistics/tests/z_test.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/statistics/tests/z_test.m	Fri Feb 06 08:31:49 2015 -0800
@@ -86,3 +86,33 @@
 
 endfunction
 
+
+%!test
+%! ## Two-sided (also the default option)
+%! x = rand (10,1); n = length (x);
+%! u0 = 0.5; v = 1/12; # true mean, var
+%! pval = z_test (x, u0, v, "!=");
+%! if (mean (x) >= u0)
+%!   zval = abs (norminv (0.5*pval));
+%! else
+%!   zval = -abs (norminv (0.5*pval));
+%! endif
+%! unew = zval * sqrt (v/n) + u0;
+%! assert (mean (x), unew, 100*eps);
+
+%!test
+%! x = rand (10,1); n = length (x);
+%! u0 = 0.5; v = 1/12;
+%! pval = z_test (x, u0, v, ">");
+%! zval = norminv (1-pval);
+%! unew = zval * sqrt (v/n) + u0;
+%! assert (mean (x), unew, 100*eps);
+
+%!test
+%! x = rand (10,1); n = length (x);
+%! u0 = 0.5; v = 1/12;
+%! pval = z_test (x, u0, v, "<");
+%! zval = norminv (pval);
+%! unew = zval * sqrt (v/n) + u0;
+%! assert (mean (x), unew, 100*eps);
+
--- a/scripts/strings/findstr.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/strings/findstr.m	Fri Feb 06 08:31:49 2015 -0800
@@ -35,7 +35,7 @@
 ##
 ## @strong{Caution:} @code{findstr} is scheduled for deprecation.  Use
 ## @code{strfind} in all new code.
-## @seealso{strfind, strmatch, strcmp, strncmp, strcmpi, strncmpi, find}
+## @seealso{strfind, strcmp, strncmp, strcmpi, strncmpi, find}
 ## @end deftypefn
 
 ## Note that this implementation swaps the strings if second one is longer
--- a/scripts/strings/module.mk	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/strings/module.mk	Fri Feb 06 08:31:49 2015 -0800
@@ -23,7 +23,6 @@
   strings/strchr.m \
   strings/strjoin.m \
   strings/strjust.m \
-  strings/strmatch.m \
   strings/strsplit.m \
   strings/strtok.m \
   strings/strtrim.m \
--- a/scripts/strings/strmatch.m	Fri Feb 06 08:31:09 2015 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,119 +0,0 @@
-## Copyright (C) 2000-2013 Paul Kienzle
-## Copyright (C) 2003 Alois Schloegl
-## Copyright (C) 2010 VZLU Prague
-##
-## 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} {} strmatch (@var{s}, @var{A})
-## @deftypefnx {Function File} {} strmatch (@var{s}, @var{A}, "exact")
-## Return indices of entries of @var{A} which begin with the string @var{s}.
-## The second argument @var{A} must be a string, character matrix, or a cell
-## array of strings.  If the third argument @qcode{"exact"} is not given, then
-## @var{s} only needs to match @var{A} up to the length of @var{s}.
-## Trailing spaces and nulls in @var{s} and @var{A} are ignored when matching.
-##
-## For example:
-##
-## @example
-## @group
-## strmatch ("apple", "apple juice")
-##      @result{} 1
-##
-## strmatch ("apple", ["apple  "; "apple juice"; "an apple"])
-##      @result{} [1; 2]
-##
-## strmatch ("apple", ["apple  "; "apple juice"; "an apple"], "exact")
-##      @result{} [1]
-## @end group
-## @end example
-##
-## @strong{Caution:} @code{strmatch} is scheduled for deprecation.  Use
-## @code{strncmp} (normal case), or @code{strcmp} (@qcode{"exact"} case), or
-## @code{regexp} in all new code.
-## @seealso{strfind, findstr, strcmp, strncmp, strcmpi, strncmpi, find}
-## @end deftypefn
-
-## Author: Paul Kienzle, Alois Schloegl
-## Adapted-by: jwe
-
-function idx = strmatch (s, A, exact)
-
-  if (nargin < 2 || nargin > 3)
-    print_usage ();
-  endif
-
-  if (! ischar (s) || (! isempty (s) && ! isvector (s)))
-    error ("strmatch: S must be a string");
-  elseif (! (ischar (A) || iscellstr (A)))
-    error ("strmatch: A must be a string or cell array of strings");
-  endif
-
-  ## Trim blanks and nulls from search string
-  s = regexprep (s, "[ \\0]+$", '');
-  len = length (s);
-
-  exact = nargin == 3 && ischar (exact) && strcmp (exact, "exact");
-
-  if (ischar (A))
-    [nr, nc] = size (A);
-    if (len > nc)
-      idx = [];
-    else
-      match = all (bsxfun (@eq, A(:,1:len), s), 2);
-      if (exact)
-        AA = A(:,len+1:nc);
-        match &= all (AA == " " | AA == "\0", 2);
-      endif
-      idx = find (match);
-    endif
-  else
-    if (len > 0)
-      idx = find (strncmp (s, A, len));
-    else
-      idx = find (strcmp (s, A));
-    endif
-    if (exact)
-      ## We can't just use strcmp, because we need to ignore spaces at end.
-      B = regexprep (A(idx), "[ \\0]+$", '');
-      idx = idx(strcmp (s, B));
-    endif
-  endif
-
-endfunction
-
-
-%!assert (strmatch ("a", {"aaa", "bab", "bbb"}), 1)
-%!assert (strmatch ("apple", "apple juice"), 1)
-%!assert (strmatch ("apple", ["apple pie"; "apple juice"; "an apple"]), [1; 2])
-%!assert (strmatch ("apple", {"apple pie"; "apple juice"; "tomato"}), [1; 2])
-%!assert (strmatch ("apple pie", "apple"), [])
-%!assert (strmatch ("a ", "a"), 1)
-%!assert (strmatch ("a", "a \0", "exact"), 1)
-%!assert (strmatch ("a b", {"a b", "a c", "c d"}), 1)
-%!assert (strmatch ("", {"", "foo", "bar", ""}), [1, 4])
-%!assert (strmatch ('', { '', '% comment', 'var a = 5', ''}, 'exact'), [1,4])
-
-%% Test input validation
-%!error <Invalid call to strmatch> strmatch ()
-%!error <Invalid call to strmatch> strmatch ("a")
-%!error <Invalid call to strmatch> strmatch ("a", "aaa", "exact", 1)
-%!error <S must be a string> strmatch (1, "aaa")
-%!error <S must be a string> strmatch (char ("a", "bb"), "aaa")
-%!error <A must be a string> strmatch ("a", 1)
-%!error <A must be a string> strmatch ("a", {"hello", [1]})
-
--- a/scripts/strings/validatestring.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/strings/validatestring.m	Fri Feb 06 08:31:49 2015 -0800
@@ -53,7 +53,7 @@
 ## @end group
 ## @end smallexample
 ##
-## @seealso{strcmp, strcmpi}
+## @seealso{strcmp, strcmpi, validateattributes, inputParser}
 ## @end deftypefn
 
 ## Author: Bill Denney <bill@denney.ws>
@@ -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/__have_feature__.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/testfun/__have_feature__.m	Fri Feb 06 08:31:49 2015 -0800
@@ -33,3 +33,7 @@
   endif
 endfunction
 
+
+## No test coverage for internal function.  It is tested through calling fcn.
+%!assert (1)
+
--- a/scripts/testfun/__printf_assert__.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/testfun/__printf_assert__.m	Fri Feb 06 08:31:49 2015 -0800
@@ -26,3 +26,7 @@
   _assert_printf = cat (2, _assert_printf, sprintf (varargin{:}));
 endfunction
 
+
+## No test coverage for internal function.  It is tested through calling fcn.
+%!assert (1)
+
--- a/scripts/testfun/__prog_output_assert__.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/testfun/__prog_output_assert__.m	Fri Feb 06 08:31:49 2015 -0800
@@ -33,3 +33,7 @@
   _assert_printf = "";
 endfunction
 
+
+## No test coverage for internal function.  It is tested through calling fcn.
+%!assert (1)
+
--- a/scripts/testfun/__run_test_suite__.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/testfun/__run_test_suite__.m	Fri Feb 06 08:31:49 2015 -0800
@@ -40,95 +40,102 @@
   global topsrcdir = fcnfiledir;
   global topbuilddir = testsdir;
   pso = page_screen_output ();
-  warn_state = warning ("query", "quiet");
-  warning ("on", "quiet");
+  orig_wstate = warning ();
   logfile = make_absolute_filename ("fntests.log");
-  try
+  unwind_protect
     page_screen_output (false);
+    warning ("on", "quiet");
     warning ("off", "Octave:deprecated-function");
-    fid = fopen (logfile, "wt");
-    if (fid < 0)
-      error ("could not open %s for writing", logfile);
-    endif
-    test ("", "explain", fid);
-    dp = dn = dxf = dsk = 0;
-    puts ("\nIntegrated test scripts:\n\n");
-    for i = 1:length (fcndirs)
-      [p, n, xf, sk] = run_test_script (fid, fcndirs{i});
-      dp += p;
-      dn += n;
-      dxf += xf;
-      dsk += sk;
-    endfor
-    puts ("\nFixed test scripts:\n\n");
-    for i = 1:length (fixedtestdirs)
-      [p, n, xf, sk] = run_test_dir (fid, fixedtestdirs{i});
-      dp += p;
-      dn += n;
-      dxf += xf;
-      dsk += sk;
-    endfor
-    puts ("\nSummary:\n\n");
-    nfail = dn - dp;
-    printf ("  PASS    %6d\n", dp);
-    printf ("  FAIL    %6d\n", nfail);
-    if (dxf > 0)
-      printf ("  XFAIL   %6d\n", dxf);
-    endif
-    if (dsk > 0)
-      printf ("  SKIPPED %6d\n", dsk);
-    endif
-    puts ("\n");
-    printf ("See the file %s for additional details.\n", logfile);
-    if (dxf > 0)
+    try
+      fid = fopen (logfile, "wt");
+      if (fid < 0)
+        error ("could not open %s for writing", logfile);
+      endif
+      test ("", "explain", fid);
+      dp = dn = dxf = dsk = 0;
+      puts ("\nIntegrated test scripts:\n\n");
+      for i = 1:length (fcndirs)
+        [p, n, xf, sk] = run_test_script (fid, fcndirs{i});
+        dp += p;
+        dn += n;
+        dxf += xf;
+        dsk += sk;
+      endfor
+      puts ("\nFixed test scripts:\n\n");
+      for i = 1:length (fixedtestdirs)
+        [p, n, xf, sk] = run_test_dir (fid, fixedtestdirs{i});
+        dp += p;
+        dn += n;
+        dxf += xf;
+        dsk += sk;
+      endfor
+      puts ("\nSummary:\n\n");
+      nfail = dn - dp - dxf;
+      printf ("  PASS    %6d\n", dp);
+      printf ("  FAIL    %6d\n", nfail);
+      if (dxf > 0)
+        printf ("  XFAIL   %6d\n", dxf);
+      endif
+      if (dsk > 0)
+        printf ("  SKIPPED %6d\n", dsk);
+      endif
       puts ("\n");
-      puts ("Expected failures (listed as XFAIL above) are known bugs.\n");
-      puts ("Please help improve Octave by contributing fixes for them.\n");
-    endif
-    if (dsk > 0)
-      puts ("\n");
-      puts ("Tests are most often skipped because the features they require\n");
-      puts ("have been disabled.  Features are most often disabled because\n");
-      puts ("they require dependencies that were not present when Octave\n");
-      puts ("was built.  The configure script should have printed a summary\n");
-      puts ("at the end of its run indicating which dependencies were not found.\n");
-    endif
+      printf ("See the file %s for additional details.\n", logfile);
+      if (dxf > 0)
+        puts ("\n");
+        puts ("Expected failures (listed as XFAIL above) are known bugs.\n");
+        puts ("Please help improve Octave by contributing fixes for them.\n");
+      endif
+      if (dsk > 0)
+        puts ("\n");
+        puts ("Tests are most often skipped because the features they require\n");
+        puts ("have been disabled.  Features are most often disabled because\n");
+        puts ("they require dependencies that were not present when Octave\n");
+        puts ("was built.  The configure script should have printed a summary\n");
+        puts ("at the end of its run indicating which dependencies were not found.\n");
+      endif
 
-    ## Weed out deprecated and private functions
-    weed_idx = cellfun (@isempty, regexp (files_with_tests, '\<deprecated\>|\<private\>', 'once'));
-    files_with_tests = files_with_tests(weed_idx);
-    weed_idx = cellfun (@isempty, regexp (files_with_no_tests, '\<deprecated\>|\<private\>', 'once'));
-    files_with_no_tests = files_with_no_tests(weed_idx);
+      ## Weed out deprecated and private functions
+      weed_idx = cellfun (@isempty, regexp (files_with_tests, '\<deprecated\>|\<private\>', 'once'));
+      files_with_tests = files_with_tests(weed_idx);
+      weed_idx = cellfun (@isempty, regexp (files_with_no_tests, '\<deprecated\>|\<private\>', 'once'));
+      files_with_no_tests = files_with_no_tests(weed_idx);
 
-    report_files_with_no_tests (files_with_tests, files_with_no_tests, ".m");
+      report_files_with_no_tests (files_with_tests, files_with_no_tests, ".m");
 
-    puts ("\nPlease help improve Octave by contributing tests for these files\n");
-    printf ("(see the list in the file %s).\n\n", logfile);
+      puts ("\nPlease help improve Octave by contributing tests for these files\n");
+      printf ("(see the list in the file %s).\n\n", logfile);
 
-    fprintf (fid, "\nFiles with no tests:\n\n%s",
-                  list_in_columns (files_with_no_tests, 80));
-    fclose (fid);
-
+      fprintf (fid, "\nFiles with no tests:\n\n%s",
+                    list_in_columns (files_with_no_tests, 80));
+      fclose (fid);
+    catch
+      disp (lasterr ());
+    end_try_catch
+  unwind_protect_cleanup
+    warning ("off", "all");
+    warning (orig_wstate);
     page_screen_output (pso);
-    warning (warn_state.state, "quiet");
-  catch
-    page_screen_output (pso);
-    warning (warn_state.state, "quiet");
-    disp (lasterr ());
-  end_try_catch
+  end_unwind_protect
 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");
@@ -184,7 +191,7 @@
   endfor
   saved_dir = pwd ();
   unwind_protect
-    chdir (d);
+    cd (d);
     for i = 1:length (lst)
       nm = lst(i).name;
       if (length (nm) > 4 && strcmpi (nm((end-3):end), ".tst"))
@@ -193,7 +200,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;
@@ -205,7 +212,7 @@
       endif
     endfor
   unwind_protect_cleanup
-    chdir (saved_dir);
+    cd (saved_dir);
   end_unwind_protect
 endfunction
 
@@ -244,7 +251,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;
@@ -272,3 +279,7 @@
   printf ("\n%d (of %d) %s files have no tests.\n", n_without, n_tot, typ);
 endfunction
 
+
+## No test coverage for internal function.  It is tested through calling fcn.
+%!assert (1)
+
--- a/scripts/testfun/assert.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/testfun/assert.m	Fri Feb 06 08:31:49 2015 -0800
@@ -18,21 +18,24 @@
 
 ## -*- texinfo -*-
 ## @deftypefn  {Function File} {} assert (@var{cond})
+## @deftypefnx {Function File} {} assert (@var{cond}, @var{errmsg})
 ## @deftypefnx {Function File} {} assert (@var{cond}, @var{errmsg}, @dots{})
 ## @deftypefnx {Function File} {} assert (@var{cond}, @var{msg_id}, @var{errmsg}, @dots{})
 ## @deftypefnx {Function File} {} assert (@var{observed}, @var{expected})
 ## @deftypefnx {Function File} {} assert (@var{observed}, @var{expected}, @var{tol})
 ##
-## Produce an error if the specified condition is not met.  @code{assert} can
-## be called in three different ways.
+## Produce an error if the specified condition is not met.
+##
+## @code{assert} can be called in three different ways.
 ##
 ## @table @code
 ## @item  assert (@var{cond})
+## @itemx assert (@var{cond}, @var{errmsg})
 ## @itemx assert (@var{cond}, @var{errmsg}, @dots{})
 ## @itemx assert (@var{cond}, @var{msg_id}, @var{errmsg}, @dots{})
 ## Called with a single argument @var{cond}, @code{assert} produces an
-## error if @var{cond} is zero.  When called with more than one argument the
-## additional arguments are passed to the @code{error} function.
+## error if @var{cond} is false (numeric zero).  Any additional arguments are
+## passed to the @code{error} function for processing.
 ##
 ## @item assert (@var{observed}, @var{expected})
 ## Produce an error if observed is not the same as expected.  Note that
@@ -46,12 +49,13 @@
 ## an error if @code{abs (@var{observed} - @var{expected}) > abs (@var{tol})}.
 ## If @var{tol} is negative then it is a relative tolerance which will produce
 ## an error if @code{abs (@var{observed} - @var{expected}) >
-## abs (@var{tol} * @var{expected})}.  If @var{expected} is zero @var{tol} will
-## always be interpreted as an absolute tolerance.  If @var{tol} is not scalar
-## its dimensions must agree with those of @var{observed} and @var{expected}
-## and tests are performed on an element-wise basis.
+## abs (@var{tol} * @var{expected})}.
+## If @var{expected} is zero @var{tol} will always be interpreted as an
+## absolute tolerance.  If @var{tol} is not scalar its dimensions must agree
+## with those of @var{observed} and @var{expected} and tests are performed on
+## an element-by-element basis.
 ## @end table
-## @seealso{test, fail, error}
+## @seealso{fail, test, error, isequal}
 ## @end deftypefn
 
 function assert (cond, varargin)
@@ -162,7 +166,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) ")"];
--- a/scripts/testfun/demo.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/testfun/demo.m	Fri Feb 06 08:31:49 2015 -0800
@@ -25,12 +25,14 @@
 ## Run example code block @var{n} associated with the function @var{name}.
 ## If @var{n} is not specified, all examples are run.
 ##
-## Examples are stored in the script file, or in a file with the same
-## name but no extension located on Octave's load path.  To keep examples
-## separate from regular script code, all lines are prefixed by @code{%!}.  Each
-## example must also be introduced by the keyword @qcode{"demo"} flush left
-## to the prefix with no intervening spaces.  The remainder of the example
-## can contain arbitrary Octave code.  For example:
+## The preferred location for example code blocks is embedded within the script
+## m-file immediately following the code that it exercises.  Alternatively,
+## the examples may be stored in a file with the same name but no extension
+## located on Octave's load path.  To separate examples from regular script
+## code all lines are prefixed by @code{%!}.  Each example must also be
+## introduced by the keyword @qcode{"demo"} flush left to the prefix with no
+## intervening spaces.  The remainder of the example can contain arbitrary
+## Octave code.  For example:
 ##
 ## @example
 ## @group
@@ -38,78 +40,84 @@
 ## %! t = 0:0.01:2*pi;
 ## %! x = sin (t);
 ## %! plot (t, x);
-## %! %-------------------------------------------------
-## %! % the figure window shows one cycle of a sine wave
+## %! title ("one cycle of a sine wave");
+## %! #-------------------------------------------------
+## %! # the figure window shows one cycle of a sine wave
 ## @end group
 ## @end example
 ##
-## Note that the code is displayed before it is executed, so a simple
-## comment at the end suffices for labeling what is being shown.  It is
-## generally not necessary to use @code{disp} or @code{printf} within the demo.
+## Note that the code is displayed before it is executed so that a simple
+## comment at the end suffices for labeling what is being shown.  For plots,
+## labeling can also be done with @code{title} or @code{text}.  It is generally
+## @strong{not} necessary to use @code{disp} or @code{printf} within the demo.
 ##
-## Demos are run in a function environment with no access to external
-## variables.  This means that every demo must have separate initialization
-## code.  Alternatively, all demos can be combined into a single large demo
-## with the code
+## Demos are run in a stand-alone function environment with no access to
+## external variables.  This means that every demo must have separate
+## initialization code.  Alternatively, all demos can be combined into a single
+## large demo with the code
 ##
 ## @example
-## %! input("Press <enter> to continue: ","s");
+## %! input ("Press <enter> to continue: ", "s");
 ## @end example
 ##
 ## @noindent
-## between the sections, but this is discouraged.  Other techniques
+## between the sections, but this usage is discouraged.  Other techniques
 ## to avoid multiple initialization blocks include using multiple plots
 ## with a new @code{figure} command between each plot, or using @code{subplot}
 ## to put multiple plots in the same window.
 ##
-## Also, because demo evaluates within a function context, you cannot
-## define new functions inside a demo.  If you must have function blocks,
-## rather than just anonymous functions or inline functions, you will have to
-## use @code{eval (example ("function",n))} to see them.  Because eval only
-## evaluates one line, or one statement if the statement crosses
-## multiple lines, you must wrap your demo in @qcode{"if 1 <demo stuff> endif"}
-## with the @qcode{"if"} on the same line as @qcode{"demo"}.  For example:
+## Finally, because @code{demo} evaluates within a function context it is
+## not possible to define new functions within the code.  Anonymous functions
+## make a good substitute in most instances.  If function blocks
+## @strong{must} be used then the code @code{eval (example ("function", n))}
+## will allow Octave to see them.  This has its own problems, however, as
+## @code{eval} only evaluates one line or statement at a time.  In this case
+## the function declaration must be wrapped with
+## @qcode{"if 1 <demo stuff> endif"} where @qcode{"if"} is on the same line
+## as @qcode{"demo"}.  For example:
 ##
 ## @example
 ## @group
 ## %!demo if 1
-## %!  function y=f(x)
-## %!    y=x;
+## %!  function y = f(x)
+## %!    y = x;
 ## %!  endfunction
 ## %!  f(3)
 ## %! endif
 ## @end group
 ## @end example
 ##
-## @seealso{test, example}
+## @seealso{rundemos, example, test}
 ## @end deftypefn
 
 ## FIXME: modify subplot so that gnuplot_has_multiplot == 0 causes it to
 ## use the current figure window but pause if not plotting in the
 ## first subplot.
 
-function demo (name, n)
+function demo (name, n = 0)
 
   if (nargin < 1 || nargin > 2)
     print_usage ();
   endif
 
-  if (nargin < 2)
-    n = 0;
-  elseif (ischar (n))
+  if (ischar (n))
     n = str2double (n);
   endif
 
+  if (! (isreal (n) && isscalar (n) && n == fix (n)))
+    error ("demo: N must be a scalar integer");
+  endif
+
   [code, idx] = test (name, "grabdemo");
 
   if (idx == -1)
-    warning ("no function %s found", name);
+    warning ("demo: no function %s found", name);
     return;
   elseif (isempty (idx))
-    warning ("no demo available for %s", name);
+    warning ("demo: no demo available for %s", name);
     return;
   elseif (n >= length (idx))
-    warning ("only %d demos available for %s", length (idx) - 1, name);
+    warning ("demo: only %d demos available for %s", length (idx) - 1, name);
     return;
   endif
 
@@ -128,7 +136,7 @@
     try
       block = code(idx(doidx(i)):idx(doidx(i)+1)-1);
       ## Use an environment without variables
-      eval (["function __demo__()\n" block "\nendfunction"]);
+      eval (["function __demo__ ()\n" block "\nendfunction"]);
       ## Display the code that will be executed before executing it
       printf ("%s example %d:%s\n\n", name, doidx(i), block);
       __demo__;
@@ -146,9 +154,15 @@
 %! t = 0:0.01:2*pi;
 %! x = sin (t);
 %! plot (t, x);
-%! %-------------------------------------------------
-%! % the figure window shows one cycle of a sine wave
+%! title ("one cycle of a sine wave");
+%! #-------------------------------------------------
+%! # the figure window shows one cycle of a sine wave
 
 %!error demo ()
 %!error demo (1, 2, 3)
+%!error <N must be a scalar integer> demo ("demo", {1})
+%!error <N must be a scalar integer> demo ("demo", ones (2,2))
+%!error <N must be a scalar integer> demo ("demo", 1.5)
+%!warning <no function .* found> demo ("_%NOT_A_FUNCTION%_");
+%!warning <only 1 demos available for demo> demo ("demo", 10);
 
--- a/scripts/testfun/example.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/testfun/example.m	Fri Feb 06 08:31:49 2015 -0800
@@ -35,31 +35,46 @@
 ## @seealso{demo, test}
 ## @end deftypefn
 
-function [code_r, idx_r] = example (name, n)
+function [ex_code, ex_idx] = example (name, n = 0)
 
   if (nargin < 1 || nargin > 2)
     print_usage ();
   endif
 
-  if (nargin < 2)
-    n = 0;
-  elseif (ischar (n))
+  if (ischar (n))
     n = str2double (n);
   endif
 
+  if (! (isreal (n) && isscalar (n) && n == fix (n)))
+    error ("example: N must be a scalar integer");
+  endif
+
   [code, idx] = test (name, "grabdemo");
+
+  if (idx == -1)
+    warning ("example: no function %s found", name);
+    return;
+  elseif (isempty (idx))
+    warning ("example: no example available for %s", name);
+    return;
+  elseif (n >= length (idx))
+    warning ("example: only %d examples available for %s",
+             length (idx) - 1, name);
+    return;
+  endif
+
   if (nargout > 0)
     if (n > 0)
       if (n <= length (idx))
-        code_r = code(idx(n):idx(n+1)-1);
-        idx_r = [1, length(code_r)+1];
+        ex_code = code(idx(n):idx(n+1)-1);
+        ex_idx = [1, length(ex_code)+1];
       else
-        code_r = "";
-        idx_r = [];
+        ex_code = "";
+        ex_idx = [];
       endif
     else
-      code_r = code;
-      idx_r = idx;
+      ex_code = code;
+      ex_idx = idx;
     endif
   else
     if (n > 0)
@@ -67,13 +82,6 @@
     else
       doidx = 1:length (idx) - 1;
     endif
-    if (isempty (idx))
-      warning ("no example available for %s", name);
-      return;
-    elseif (n >= length (idx))
-      warning ("only %d examples available for %s", length (idx) - 1, name);
-      return;
-    endif
 
     for i = 1:length (doidx)
       block = code(idx(doidx(i)):idx(doidx(i)+1)-1);
@@ -90,17 +98,24 @@
 
 %!demo
 %! clf;
-%! t = 0:0.01:2*pi;  x = sin (t);
+%! t = 0:0.01:2*pi;
+%! x = sin (t);
 %! plot (t,x)
 
-%!assert (example ("example",1), "\n example (\"example\");");
+%!assert (example ("example", 1), "\n example (\"example\");");
+
 %!test
 %! [code, idx] = example ("example");
 %! assert (code, ...
-%!         "\n example (\"example\");\n clf;\n t = 0:0.01:2*pi;  x = sin (t);\n plot (t,x)")
+%!         "\n example (\"example\");\n clf;\n t = 0:0.01:2*pi;\n x = sin (t);\n plot (t,x)");
 %! assert (idx, [1, 23, 73]);
 
 %% Test input validation
-%!error example
+%!error example ()
 %!error example ("example", 3, 5)
+%!error <N must be a scalar integer> example ("example", {1})
+%!error <N must be a scalar integer> example ("example", ones (2,2))
+%!error <N must be a scalar integer> example ("example", 1.5)
+%!warning <no function .* found> example ("_%NOT_A_FUNCTION%_");
+%!warning <only 2 examples available for example> example ("example", 10);
 
--- a/scripts/testfun/fail.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/testfun/fail.m	Fri Feb 06 08:31:49 2015 -0800
@@ -22,51 +22,51 @@
 ## -*- texinfo -*-
 ## @deftypefn  {Function File} {} fail (@var{code})
 ## @deftypefnx {Function File} {} fail (@var{code}, @var{pattern})
+## @deftypefnx {Function File} {} fail (@var{code}, "warning")
 ## @deftypefnx {Function File} {} fail (@var{code}, "warning", @var{pattern})
 ##
 ## Return true if @var{code} fails with an error message matching
-## @var{pattern}, otherwise produce an error.  Note that @var{code}
-## is a string and if @var{code} runs successfully, the error produced is:
+## @var{pattern}, otherwise produce an error.
+##
+## @var{code} must be in the form of a string that is passed to the Octave
+## interpreter via the @code{evalin} function, i.e., a (quoted) string constant
+## or a string variable.
+##
+## Note that if @var{code} runs successfully, rather than failing, the error
+## printed is:
 ##
 ## @example
 ##           expected error <.> but got none
 ## @end example
 ##
-##
-## Code must be in the form of a string that may be passed by
-## @code{fail} to the Octave interpreter via the @code{evalin} function,
-## that is, a (quoted) string constant or a string variable.
-##
-## If called with two arguments, the behavior is similar to
-## @code{fail (@var{code})}, except the return value will only be true if
-## code fails with an error message containing pattern (case sensitive).
-## If the code fails with a different error to that given in pattern,
-## the message produced is:
+## If called with two arguments, the return value will be true only if
+## @var{code} fails with an error message containing @var{pattern}
+## (case sensitive).  If the code fails with a different error than the one
+## specified in @var{pattern} then the message produced is:
 ##
 ## @example
 ## @group
-##           expected <pattern>
+##           expected <@var{pattern}>
 ##           but got <text of actual error>
 ## @end group
 ## @end example
 ##
 ## The angle brackets are not part of the output.
 ##
-## Called with three arguments, the behavior is similar to
-## @code{fail (@var{code}, @var{pattern})}, but produces an error if no
-## warning is given during code execution or if the code fails.
-## @seealso{assert}
+## When called with the @qcode{"warning"} option @code{fail} will produce
+## an error if executing the code produces no warning.
+## @seealso{assert, error}
 ## @end deftypefn
 
 ## Author: Paul Kienzle <pkienzle@users.sf.net>
 
-function ret = fail (code, pattern, warning_pattern)
+function retval = fail (code, pattern, warning_pattern)
 
   if (nargin < 1 || nargin > 3)
     print_usage ();
   endif
 
-  ## sort out arguments
+  ## Parse input arguments
   test_warning = (nargin > 1 && strcmp (pattern, "warning"));
   if (nargin == 3)
     pattern = warning_pattern;
@@ -74,52 +74,50 @@
     pattern = "";
   endif
 
-  ## match any nonempty message
+  ## Match any nonempty message
   if (isempty (pattern))
     pattern = ".";
   endif
 
-  ## allow assert (fail ())
+  ## Allow assert (fail ())
   if (nargout)
-    ret = 1;
+    retval = true;
   endif
 
   if (test_warning)
     ## Perform the warning test.
     ## Clear old warnings.
-    lastwarn ();
+    lastwarn ("");
     ## Make sure warnings are turned on.
     state = warning ("query", "quiet");
     warning ("on", "quiet");
     try
-      ## printf ("lastwarn before %s: %s\n",code,lastwarn);
-      evalin ("caller", sprintf ("%s;", code));
-      ## printf ("lastwarn after %s: %s\n",code,lastwarn);
+      evalin ("caller", [code ";"]);
       ## Retrieve new warnings.
-      err = lastwarn ();
+      warn = lastwarn ();
       warning (state.state, "quiet");
-      if (isempty (err))
+      if (isempty (warn))
         msg = sprintf ("expected warning <%s> but got none", pattern);
       else
         ## Transform "warning: ...\n" to "...".
-        err([1:9, end]) = [];
-        if (! isempty (regexp (err, pattern, "once")))
+        warn([1:9, end]) = [];
+        if (! isempty (regexp (warn, pattern, "once")))
           return;
         endif
-        msg = sprintf ("expected warning <%s>\nbut got <%s>", pattern, err);
+        msg = sprintf ("expected warning <%s>\nbut got <%s>", pattern, warn);
       endif
     catch
       warning (state.state, "quiet");
       err = lasterr;
       ## Transform "error: ...\n", to "...".
-      err([1:7, end]) = [];
-      msg = sprintf ("expected warning <%s> but got error <%s>", pattern, err);
+      err([1:6, end]) = [];
+      msg = sprintf ("expected warning <%s>\nbut got error <%s>", pattern, err);
     end_try_catch
 
   else
     ## Perform the error test.
     try
-      evalin ("caller", sprintf ("%s;", code));
+      evalin ("caller", [code ";"]);
       msg = sprintf ("expected error <%s> but got none", pattern);
     catch
       err = lasterr ();
@@ -147,8 +145,12 @@
 ##% !fail ("warning ('next test')",'warning','next test');  ## only allowed one warning test?!?
 
 %% Test that fail() itself will generate an error
-%!error fail ("1")
-%!error <undefined> fail ("a*[2;3]", "nonconformant")
-%!error <expected error>  fail ("a*[2,3]", "usage:")
+%!error <expected error> fail ("1")
+%!error <'a' undefined> fail ("a*[2;3]", "nonconformant")
+%!error <expected error .usage:>  fail ("a*[2,3]", "usage:")
 %!error <warning failure> fail ("warning ('warning failure')", "warning", "success")
 
+%% Test input validation
+%!error fail ()
+%!error fail (1,2,3,4)
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/testfun/private/compare_plot_demos.m	Fri Feb 06 08:31:49 2015 -0800
@@ -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 Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,187 @@
+## 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}
+##   @qcode{"dump.m"}
+##
+##   @item @var{fmt}
+##   @qcode{"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 Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,135 @@
+## 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 Feb 06 08:31:49 2015 -0800
@@ -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 Feb 06 08:31:09 2015 -0800
+++ b/scripts/testfun/rundemos.m	Fri Feb 06 08:31:49 2015 -0800
@@ -19,13 +19,14 @@
 ## -*- texinfo -*-
 ## @deftypefn  {Function File} {} rundemos ()
 ## @deftypefnx {Function File} {} rundemos (@var{directory})
-## Execute built-in demos for all function files in the specified directory.
-## Also executes demos in any C++ source files found in the directory, for
-## use with dynamically linked functions.
+## Execute built-in demos for all m-files in the specified @var{directory}.
+##
+## Demo blocks in any C++ source files (@file{*.cc}) will also be executed
+## for use with dynamically linked oct-file functions.
 ##
 ## If no directory is specified, operate on all directories in Octave's
 ## search path for functions.
-## @seealso{runtests, path}
+## @seealso{demo, runtests, path}
 ## @end deftypefn
 
 ## Author: jwe
@@ -36,20 +37,17 @@
     dirs = ostrsplit (path (), pathsep ());
     do_class_dirs = true;
   elseif (nargin == 1)
-    if (is_absolute_filename (directory))
-      dirs = {directory};
-    elseif (is_rooted_relative_filename (directory))
-      dirs = {canonicalize_file_name(directory)};
-    else
-      if (directory(end) == filesep ())
-        directory = directory(1:end-1);
+    dirs = {canonicalize_file_name(directory)};
+    if (isempty (dirs{1}))
+      ## Search for directory name in path
+      if (directory(end) == '/' || directory(end) == '\')
+        directory(end) = [];
       endif
-      fullname = find_dir_in_path (directory);
-      if (! isempty (fullname))
-        dirs = {fullname};
-      else
+      fullname = dir_in_loadpath (directory);
+      if (isempty (fullname))
         error ("rundemos: DIRECTORY argument must be a valid pathname");
       endif
+      dirs = {fullname};
     endif
     do_class_dirs = false;
   else
@@ -75,7 +73,7 @@
         try
           demo (f);
         catch
-          printf ("error: %s\n\n", lasterror().message);
+          printf ("error: %s\n\n", lasterror ().message);
         end_try_catch
         if (i != numel (flist))
           input ("Press <enter> to continue: ", "s");
--- a/scripts/testfun/runtests.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/testfun/runtests.m	Fri Feb 06 08:31:49 2015 -0800
@@ -19,13 +19,14 @@
 ## -*- texinfo -*-
 ## @deftypefn  {Function File} {} runtests ()
 ## @deftypefnx {Function File} {} runtests (@var{directory})
-## Execute built-in tests for all function files in the specified directory.
-## Also executes tests in any C++ source files found in the directory, for
-## use with dynamically linked functions.
+## Execute built-in tests for all m-files in the specified @var{directory}.
+##
+## Test blocks in any C++ source files (@file{*.cc}) will also be executed
+## for use with dynamically linked oct-file functions.
 ##
 ## If no directory is specified, operate on all directories in Octave's
 ## search path for functions.
-## @seealso{rundemos, path}
+## @seealso{rundemos, test, path}
 ## @end deftypefn
 
 ## Author: jwe
@@ -36,20 +37,17 @@
     dirs = ostrsplit (path (), pathsep ());
     do_class_dirs = true;
   elseif (nargin == 1)
-    if (is_absolute_filename (directory))
-      dirs = {directory};
-    elseif (is_rooted_relative_filename (directory))
-      dirs = {canonicalize_file_name(directory)};
-    else
-      if (directory(end) == filesep ())
-        directory = directory(1:end-1);
+    dirs = {canonicalize_file_name(directory)};
+    if (isempty (dirs{1}))
+      ## Search for directory name in path
+      if (directory(end) == '/' || directory(end) == '\')
+        directory(end) = [];
       endif
-      fullname = find_dir_in_path (directory);
-      if (! isempty (fullname))
-        dirs = {fullname};
-      else
+      fullname = dir_in_loadpath (directory);
+      if (isempty (fullname))
         error ("runtests: DIRECTORY argument must be a valid pathname");
       endif
+      dirs = {fullname};
     endif
     do_class_dirs = false;
   else
--- a/scripts/testfun/test.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/testfun/test.m	Fri Feb 06 08:31:49 2015 -0800
@@ -20,125 +20,174 @@
 ## @deftypefn  {Command} {} test @var{name}
 ## @deftypefnx {Command} {} test @var{name} quiet|normal|verbose
 ## @deftypefnx {Function File} {} test ("@var{name}", "quiet|normal|verbose", @var{fid})
-## @deftypefnx {Function File} {} test ([], "explain", @var{fid})
+## @deftypefnx {Function File} {} test ("@var{name}", "quiet|normal|verbose", @var{fname})
 ## @deftypefnx {Function File} {@var{success} =} test (@dots{})
-## @deftypefnx {Function File} {[@var{n}, @var{max}] =} test (@dots{})
+## @deftypefnx {Function File} {[@var{n}, @var{nmax}, @var{nxfail}, @var{nskip}] =} test (@dots{})
 ## @deftypefnx {Function File} {[@var{code}, @var{idx}] =} test ("@var{name}", "grabdemo")
+## @deftypefnx {Function File} {} test ([], "explain", @var{fid})
+## @deftypefnx {Function File} {} test ([], "explain", @var{fname})
+##
+## Perform built-in self-tests from the first file in the loadpath matching
+## @var{name}.
+##
+## @code{test} can be called in either command or functional form.  The exact
+## operation of test is determined by a combination of mode (interactive or
+## batch), reporting level (@qcode{"quiet"}, @qcode{"normal"},
+## @qcode{"verbose"}), and whether a logfile or summary output variable is
+## used.
 ##
-## Perform tests from the first file in the loadpath matching @var{name}.
-## @code{test} can be called as a command or as a function.  Called with
-## a single argument @var{name}, the tests are run interactively and stop
-## after the first error is encountered.
+## The default mode when @code{test} is called from the command line is
+## interactive.  In this mode, tests will be run until the first error is
+## encountered, or all tests complete successfully.  In batch mode, all tests
+## are run regardless of any failures, and the results are collected for
+## reporting.  Tests which require user interaction, i.e., demo blocks,
+## are never run in batch mode.
 ##
-## With a second argument the tests which are performed and the amount of
-## output is selected.
+## Batch mode is enabled by either 1) specifying a logfile using the third
+## argument @var{fname} or @var{fid}, or 2) requesting an output argument
+## such as @var{success}, @var{n}, etc.
+##
+## The optional second argument determines the amount of output to generate and
+## which types of tests to run.  The default value is @qcode{"normal"}.
+## Requesting an output argument will suppress printing the final summary
+## message and any intermediate warnings, unless verbose reporting is
+## enabled.
 ##
 ## @table @asis
 ## @item @qcode{"quiet"}
-##  Don't report all the tests as they happen, just the errors.
+## Print a summary message when all tests pass, or print an error with the
+## results of the first bad test when a failure occurs.  Don't run tests which
+## require user interaction.
 ##
 ## @item @qcode{"normal"}
-## Report all tests as they happen, but don't do tests which require
-## user interaction.
+## Display warning messages about skipped tests or failing xtests during test
+## execution.
+## Print a summary message when all tests pass, or print an error with the
+## results of the first bad test when a failure occurs.  Don't run tests which
+## require user interaction.
 ##
 ## @item @qcode{"verbose"}
-## Do tests which require user interaction.
+## Display tests before execution.  Print all warning messages.  In interactive
+## mode, run all tests including those which require user interaction.
 ## @end table
 ##
-## The argument @var{fid} can be used to allow batch processing.  Errors
-## can be written to the already open file defined by @var{fid}, and
-## hopefully when Octave crashes this file will tell you what was happening
-## when it did.  You can use @code{stdout} if you want to see the results as
-## they happen.  You can also give a file name rather than an @var{fid}, in
-## which case the contents of the file will be replaced with the log from
-## the current test.
+## The optional third input argument specifies a logfile where results of the
+## tests should be written.  The logfile may be a character string
+## (@var{fname}) or an open file descriptor ID (@var{fid}).  To enable batch
+## processing, but still print the results to the screen, use @code{stdout} for
+## @var{fid}.
+##
+## When called with just a single output argument @var{success}, @code{test}
+## returns true if all of the tests were successful.  If called with more
+## than one output argument then the number of successful tests (@var{n}),
+## the total number of tests in the file (@var{nmax}), the number of xtest
+## failures (@var{nxfail}), and the number of skipped tests (@var{nskip} are
+## returned.
+##
+## Example
 ##
-## Called with a single output argument @var{success}, @code{test} returns
-## true if all of the tests were successful.  Called with two output arguments
-## @var{n} and @var{max}, the number of successful tests and the total number
-## of tests in the file @var{name} are returned.
+## @example
+## @group
+## test sind
+## @result{}
+## PASSES 5 out of 5 tests
+##
+## [n, nmax] = test ("sind")
+## @result{}
+## n =  5
+## nmax =  5
+## @end group
+## @end example
+##
+## Additional Calling Syntaxes
 ##
 ## If the second argument is the string @qcode{"grabdemo"}, the contents of
-## the demo blocks are extracted but not executed.  Code for all code blocks
-## is concatenated and returned as @var{code} with @var{idx} being a vector
-## of positions of the ends of the demo blocks.
+## any built-in demo blocks are extracted but not executed.  The text for all
+## code blocks is concatenated and returned as @var{code} with @var{idx} being
+## a vector of positions of the ends of each demo block.  For an easier way to
+## extract demo blocks from files, @xref{XREFexample,,example}.
 ##
-## If the second argument is @qcode{"explain"}, then @var{name} is ignored
-## and an explanation of the line markers used is written to the file
-## @var{fid}.
-## @seealso{assert, fail, error, demo, example}
+## If the second argument is @qcode{"explain"} then @var{name} is ignored and
+## an explanation of the line markers used in @code{test} output reports is
+## written to the file specified by @var{fname} or @var{fid}.
+##
+## @seealso{assert, fail, demo, example, error}
 ## @end deftypefn
 
-## FIXME: * Consider using keyword fail rather then error?  This allows us
-## to make a functional form of error blocks, which means we
-## can include them in test sections which means that we can use
-## octave flow control for both kinds of tests.
+## Programming Note: All variables for test() must use the internal prefix "__".
+## Shared variables are eval'ed into the current workspace and therefore might
+## collide with the names used in the test.m function itself.
 
-function [__ret1, __ret2, __ret3, __ret4] = test (__name, __flag, __fid)
-  ## Information from test will be introduced by "key".
-  persistent __signal_fail =  "!!!!! ";
+function [__n, __nmax, __nxfail, __nskip] = test (__name, __flag = "normal", __fid = [])
+
+  ## Output from test is prefixed by a "key" to quickly understand the issue.
+  persistent __signal_fail  = "!!!!! ";
   persistent __signal_empty = "????? ";
-  persistent __signal_block = "  ***** ";
-  persistent __signal_file =  ">>>>> ";
-  persistent __signal_skip = "----- ";
-
-  __xfail = 0;
-  __xskip = 0;
+  persistent __signal_block = "***** ";
+  persistent __signal_file  = ">>>>> ";
+  persistent __signal_skip  = "----- ";
 
-  if (nargin < 2 || isempty (__flag))
-    __flag = "quiet";
-  endif
-  if (nargin < 3)
-    __fid = [];
-  endif
-  if (nargin < 1 || nargin > 3
-      || (! ischar (__name) && ! isempty (__name)) || ! ischar (__flag))
+  if (nargin < 1 || nargin > 3)
+    print_usage ();
+  elseif (! isempty (__name) && ! ischar (__name))
+    error ("test: NAME must be a string");
+  elseif (! ischar (__flag))
+    error ("test: second argument must be a string");
+  elseif (isempty (__name) && (nargin != 3 || ! strcmp (__flag, "explain")))
     print_usage ();
   endif
-  if (isempty (__name) && (nargin != 3 || ! strcmp (__flag, "explain")))
-    print_usage ();
-  endif
-  __batch = (! isempty (__fid));
 
   ## Decide if error messages should be collected.
-  __close_fid = 0;
-  if (__batch)
+  __logfile = ! isempty (__fid);
+  __batch = __logfile || nargout > 0;
+  __close_fid = false;
+  if (__logfile)
     if (ischar (__fid))
-      __fid = fopen (__fid, "wt");
+      __fname = __fid;
+      __fid = fopen (__fname, "wt");
       if (__fid < 0)
-        error ("test: could not open log file");
+        error ("test: could not open log file %s", __fname);
       endif
-      __close_fid = 1;
+      __close_fid = true;
     endif
-    fprintf (__fid, "%sprocessing %s\n", __signal_file, __name);
-    fflush (__fid);
+    if (! strcmp (__flag, "explain"))
+      fprintf (__fid, "%sprocessing %s\n", __signal_file, __name);
+      fflush (__fid);
+    endif
   else
     __fid = stdout;
   endif
 
   if (strcmp (__flag, "normal"))
-    __grabdemo = 0;
-    __rundemo = 0;
-    __verbose = __batch;
+    __grabdemo = false;
+    __rundemo  = false;
+    if (__logfile)
+      __verbose = 1;
+    elseif (__batch)
+      __verbose = -1;
+    else
+      __verbose = 0;
+    endif
   elseif (strcmp (__flag, "quiet"))
-    __grabdemo = 0;
-    __rundemo = 0;
-    __verbose = 0;
+    __grabdemo = false;
+    __rundemo  = false;
+    __verbose  = -1;
   elseif (strcmp (__flag, "verbose"))
-    __grabdemo = 0;
-    __rundemo = 1;
-    __verbose = 1;
+    __grabdemo = false;
+    __rundemo  = true;
+    __verbose  = 1;
   elseif (strcmp (__flag, "grabdemo"))
-    __grabdemo = 1;
-    __rundemo = 0;
-    __verbose = 0;
+    __grabdemo = true;
+    __rundemo  = false;
+    __verbose  = -1;
     __demo_code = "";
     __demo_idx = [];
   elseif (strcmp (__flag, "explain"))
     fprintf (__fid, "# %s new test file\n", __signal_file);
     fprintf (__fid, "# %s no tests in file\n", __signal_empty);
     fprintf (__fid, "# %s test had an unexpected result\n", __signal_fail);
-    fprintf (__fid, "# %s code for the test\n", __signal_block);
+    fprintf (__fid, "# %s test was skipped\n", __signal_skip);
+    fprintf (__fid, "# %s code for the test\n\n", __signal_block);
     fprintf (__fid, "# Search for the unexpected results in the file\n");
     fprintf (__fid, "# then page back to find the file name which caused it.\n");
     fprintf (__fid, "# The result may be an unexpected failure (in which\n");
@@ -162,17 +211,16 @@
     __file = file_in_loadpath ([__name ".cc"], "all");
   endif
   if (iscell (__file))
-      ## If repeats, return first in path.
     if (isempty (__file))
       __file = "";
     else
-      __file = __file{1};
+      __file = __file{1};  # If repeats, return first in path.
     endif
   endif
   if (isempty (__file))
     if (__grabdemo)
-      __ret1 = "";
-      __ret2 = -1;
+      __n = "";
+      __nmax = -1;
     else
       ftype = exist (__name);
       if (ftype == 3)
@@ -188,7 +236,11 @@
       endif
       fflush (__fid);
       if (nargout > 0)
-        __ret1 = __ret2 = 0;
+        if (nargout == 1)
+          __n = false;
+        else
+          __n = __nmax = 0;
+        endif
       endif
     endif
     if (__close_fid)
@@ -202,13 +254,17 @@
 
   if (isempty (__body))
     if (__grabdemo)
-      __ret1 = "";
-      __ret2 = [];
+      __n = "";
+      __nmax = [];
     else
       fprintf (__fid, "%s%s has no tests available\n", __signal_empty, __file);
       fflush (__fid);
       if (nargout > 0)
-        __ret1 = __ret2 = 0;
+        if (nargout == 1)
+          __n = false;
+        else
+          __n = __nmax = 0;
+        endif
       endif
     endif
     if (__close_fid)
@@ -217,10 +273,10 @@
     return;
   else
     ## Add a dummy comment block to the end for ease of indexing.
-    if (__body (length (__body)) == "\n")
-      __body = sprintf ("\n%s#", __body);
+    if (__body(end) == "\n")
+      __body = ["\n" __body "#"];
     else
-      __body = sprintf ("\n%s\n#", __body);
+      __body = ["\n" __body "\n#"];
     endif
   endif
 
@@ -228,354 +284,368 @@
   __lineidx = find (__body == "\n");
   __blockidx = __lineidx(find (! isspace (__body(__lineidx+1))))+1;
 
-  ## Ready to start tests ... if in batch mode, tell us what is happening.
-  if (__verbose)
+  ## Ready to start tests.
+  ## If in batch mode, with a logfile, report what is happening.
+  if (__verbose > 0)
     disp ([__signal_file, __file]);
   endif
 
   ## Assume all tests will pass.
-  __all_success = 1;
+  __all_success = true;
 
   ## Process each block separately, initially with no shared variables.
   __tests = __successes = 0;
+  __xfail = __xskip = 0;
   __shared = " ";
   __shared_r = " ";
-  __clear = "";
-  for __i = 1:length (__blockidx)-1
-
-    ## Extract the block.
-    __block = __body(__blockidx(__i):__blockidx(__i+1)-2);
+  __clearfcn = "";
+  for __i = 1:numel (__blockidx)-1
 
-    ## Let the user/logfile know what is happening.
-    if (__verbose)
-      fprintf (__fid, "%s%s\n", __signal_block, __block);
-      fflush (__fid);
-    endif
+    ## FIXME: Should other global settings be similarly saved and restored?
+    orig_wstate = warning ();
+    unwind_protect
+
+      ## Extract the block.
+      __block = __body(__blockidx(__i):__blockidx(__i+1)-2);
 
-    ## Split __block into __type and __code.
-    __idx = find (! isletter (__block));
-    if (isempty (__idx))
-      __type = __block;
-      __code = "";
-    else
-      __type = __block(1:__idx(1)-1);
-      __code = __block(__idx(1):length (__block));
-    endif
+      ## Print the code block before execution if in verbose mode.
+      if (__verbose > 0)
+        fprintf (__fid, "%s%s\n", __signal_block, __block);
+        fflush (__fid);
+      endif
 
-    ## Assume the block will succeed.
-    __success = 1;
-    __msg = [];
+      ## Split __block into __type and __code.
+      __idx = find (! isletter (__block));
+      if (isempty (__idx))
+        __type = __block;
+        __code = "";
+      else
+        __type = __block(1:__idx(1)-1);
+        __code = __block(__idx(1):length (__block));
+      endif
+
+      ## Assume the block will succeed.
+      __success = true;
+      __msg = [];
+      __isxtest = false;
 
 ### DEMO
 
-    ## If in __grabdemo mode, then don't process any other block type.
-    ## So that the other block types don't have to worry about
-    ## this __grabdemo mode, the demo block processor grabs all block
-    ## types and skips those which aren't demo blocks.
+      ## If in __grabdemo mode, then don't process any other block type.
+      ## So that the other block types don't have to worry about
+      ## this __grabdemo mode, the demo block processor grabs all block
+      ## types and skips those which aren't demo blocks.
+
+      __isdemo = strcmp (__type, "demo");
+      if (__grabdemo || __isdemo)
+        __istest = false;
 
-    __isdemo = strcmp (__type, "demo");
-    if (__grabdemo || __isdemo)
-      __istest = 0;
+        if (__grabdemo && __isdemo)
+          if (isempty (__demo_code))
+            __demo_code = __code;
+            __demo_idx = [1, length(__demo_code)+1];
+          else
+            __demo_code = [__demo_code, __code];
+            __demo_idx = [__demo_idx, length(__demo_code)+1];
+          endif
 
-      if (__grabdemo && __isdemo)
-        if (isempty (__demo_code))
-          __demo_code = __code;
-          __demo_idx = [1, length(__demo_code)+1];
-        else
-          __demo_code = [__demo_code, __code];
-          __demo_idx = [__demo_idx, length(__demo_code)+1];
+        elseif (__rundemo && __isdemo)
+          try
+            ## process the code in an environment without variables
+            eval (sprintf ("function __test__ ()\n%s\nendfunction", __code));
+            __test__;
+            input ("Press <enter> to continue: ", "s");
+          catch
+            __success = false;
+            __msg = [__signal_fail "demo failed\n" lasterr()];
+          end_try_catch
+          clear __test__;
+
         endif
-
-      elseif (__rundemo && __isdemo)
-        try
-          ## process the code in an environment without variables
-          eval (sprintf ("function __test__ ()\n%s\nendfunction", __code));
-          __test__;
-          input ("Press <enter> to continue: ", "s");
-        catch
-          __success = 0;
-          __msg = sprintf ("%sdemo failed\n%s",  __signal_fail, lasterr ());
-        end_try_catch
-        clear __test__;
-
-      endif
-      ## Code already processed.
-      __code = "";
+        ## Code already processed.
+        __code = "";
 
 ### SHARED
 
-    elseif (strcmp (__type, "shared"))
-      __istest = 0;
+      elseif (strcmp (__type, "shared"))
+        __istest = false;
 
-      ## Separate initialization code from variables.
-      __idx = find (__code == "\n");
-      if (isempty (__idx))
-        __vars = __code;
-        __code = "";
-      else
-        __vars = __code (1:__idx(1)-1);
-        __code = __code (__idx(1):length (__code));
-      endif
+        ## Separate initialization code from variables.
+        __idx = find (__code == "\n");
+        if (isempty (__idx))
+          __vars = __code;
+          __code = "";
+        else
+          __vars = __code (1:__idx(1)-1);
+          __code = __code (__idx(1):length (__code));
+        endif
 
-      ## Strip comments off the variables.
-      __idx = find (__vars == "%" | __vars == "#");
-      if (! isempty (__idx))
-        __vars = __vars(1:__idx(1)-1);
-      endif
+        ## Strip comments off the variables.
+        __idx = find (__vars == "%" | __vars == "#");
+        if (! isempty (__idx))
+          __vars = __vars(1:__idx(1)-1);
+        endif
 
-      ## Assign default values to variables.
-      try
-        __vars = deblank (__vars);
-        if (! isempty (__vars))
-          eval ([strrep(__vars, ",", "=[];"), "=[];"]);
-          __shared = __vars;
-          __shared_r = ["[ ", __vars, "] = "];
-        else
-          __shared = " ";
-          __shared_r = " ";
-        endif
-      catch
-        ## Couldn't declare, so don't initialize.
-        __code = "";
-        __success = 0;
-        __msg = sprintf ("%sshared variable initialization failed\n",
-                         __signal_fail);
-      end_try_catch
+        ## Assign default values to variables.
+        try
+          __vars = deblank (__vars);
+          if (! isempty (__vars))
+            eval ([strrep(__vars, ",", "=[];"), "=[];"]);
+            __shared = __vars;
+            __shared_r = ["[ " __vars "] = "];
+          else
+            __shared = " ";
+            __shared_r = " ";
+          endif
+        catch
+          ## Couldn't declare, so don't initialize.
+          __code = "";
+          __success = false;
+          __msg = [__signal_fail "shared variable initialization failed\n"];
+        end_try_catch
 
-      ## Initialization code will be evaluated below.
+        ## Initialization code will be evaluated below.
 
 ### FUNCTION
 
-    elseif (strcmp (__type, "function"))
-      __istest = 0;
-      persistent __fn = 0;
-      __name_position = function_name (__block);
-      if (isempty (__name_position))
-        __success = 0;
-        __msg = sprintf ("%stest failed: missing function name\n",
-                         __signal_fail);
-      else
-        __name = __block(__name_position(1):__name_position(2));
-        __code = __block;
-        try
-          eval (__code);  # Define the function
-          __clear = sprintf ("%sclear %s;\n", __clear, __name);
-        catch
-          __success = 0;
-          __msg = sprintf ("%stest failed: syntax error\n%s",
-                           __signal_fail, lasterr ());
-        end_try_catch
-      endif
-      __code = "";
+      elseif (strcmp (__type, "function"))
+        __istest = false;
+        persistent __fn = 0;
+        __name_position = function_name (__block);
+        if (isempty (__name_position))
+          __success = false;
+          __msg = [__signal_fail "test failed: missing function name\n"];
+        else
+          __name = __block(__name_position(1):__name_position(2));
+          __code = __block;
+          try
+            eval (__code);  # Define the function
+            __clearfcn = sprintf ("%sclear %s;\n", __clearfcn, __name);
+          catch
+            __success = false;
+            __msg = [__signal_fail "test failed: syntax error\n" lasterr()];
+          end_try_catch
+        endif
+        __code = "";
 
 ### ENDFUNCTION
 
-    elseif (strcmp (__type, "endfunction"))
-      ## endfunction simply declares the end of a previous function block.
-      ## There is no processing to be done here, just skip to next block.
-      __istest = 0;
-      __code = "";
+      elseif (strcmp (__type, "endfunction"))
+        ## endfunction simply declares the end of a previous function block.
+        ## There is no processing to be done here, just skip to next block.
+        __istest = false;
+        __code = "";
 
 ### ASSERT/FAIL
 
-    elseif (strcmp (__type, "assert") || strcmp (__type, "fail"))
-      __istest = 1;
-      ## Put the keyword back on the code.
-      __code = __block;
-      ## The code will be evaluated below as a test block.
+      elseif (strcmp (__type, "assert") || strcmp (__type, "fail"))
+        __istest = true;
+        ## Put the keyword back on the code.
+        __code = __block;
+        ## The code will be evaluated below as a test block.
 
 ### ERROR/WARNING
 
-    elseif (strcmp (__type, "error") || strcmp (__type, "warning"))
-      __istest = 1;
-      __warning = strcmp (__type, "warning");
-      [__pattern, __id, __code] = getpattern (__code);
-      if (__id)
-        __patstr = ["id=",__id];
-      else
-        if (! strcmp (__pattern, '.'))
-          __patstr = ["<",__pattern,">"];
+      elseif (strcmp (__type, "error") || strcmp (__type, "warning"))
+        __istest = true;
+        __iswarning = strcmp (__type, "warning");
+        [__pattern, __id, __code] = getpattern (__code);
+        if (__id)
+          __patstr = ["id=" __id];
         else
-          __patstr = ifelse (__warning, "a warning", "an error");
+          if (! strcmp (__pattern, '.'))
+            __patstr = ["<" __pattern ">"];
+          else
+            __patstr = ifelse (__iswarning, "a warning", "an error");
+          endif
         endif
-      endif
-      try
-        eval (sprintf ("function __test__(%s)\n%s\nendfunction",
-                       __shared, __code));
-      catch
-        __success = 0;
-        __msg = sprintf ("%stest failed: syntax error\n%s",
-                         __signal_fail, lasterr ());
-      end_try_catch
+        try
+          eval (sprintf ("function __test__(%s)\n%s\nendfunction",
+                         __shared, __code));
+        catch
+          __success = false;
+          __msg = [__signal_fail "test failed: syntax error\n" lasterr()];
+        end_try_catch
 
-      if (__success)
-        __success = 0;
-        __warnstate = warning ("query", "quiet");
-        warning ("on", "quiet");
-        ## Clear error and warning strings before starting
-        lasterr ("");
-        lastwarn ("");
-        try
-          ## FIXME: lastwarn () must be called once from *WITHIN* the try block
-          ##        or subsequent warning/lastwarn statements may fail.
-          ##        Likely this is something to do with the specialness of
-          ##        the try block which is disabling normal errors.
-          lastwarn ();
-          eval (sprintf ("__test__(%s);", __shared));
-          if (! __warning)
-            __msg = sprintf ("%serror failed.\nExpected %s but got no error\n",
-                             __signal_fail, __patstr);
-          else
+        if (__success)
+          __success = false;
+          __warnstate = warning ("query", "quiet");
+          warning ("on", "quiet");
+          ## Clear error and warning strings before starting
+          lasterr ("");
+          lastwarn ("");
+          try
+            eval (sprintf ("__test__(%s);", __shared));
+            if (! __iswarning)
+              __msg = [__signal_fail "error failed.\n" ...
+                                     "Expected " __patstr ", but got no error\n"];
+            else
+              if (! isempty (__id))
+                [~, __err] = lastwarn ();
+                __mismatch = ! strcmp (__err, __id);
+              else
+                __err = trimerr (lastwarn (), "warning");
+                __mismatch = isempty (regexp (__err, __pattern, "once"));
+              endif
+              warning (__warnstate.state, "quiet");
+              if (isempty (__err))
+                __msg = [__signal_fail "warning failed.\n" ...
+                                       "Expected " __patstr ", but got no warning\n"];
+              elseif (__mismatch)
+                __msg = [__signal_fail "warning failed.\n" ...
+                                       "Expected " __patstr ", but got <" __err ">\n"];
+              else
+                __success = true;
+              endif
+            endif
+
+          catch
             if (! isempty (__id))
-              [~, __err] = lastwarn ();
+              [~, __err] = lasterr ();
               __mismatch = ! strcmp (__err, __id);
             else
-              __err = trimerr (lastwarn (), "warning");
+              __err = trimerr (lasterr (), "error");
               __mismatch = isempty (regexp (__err, __pattern, "once"));
             endif
             warning (__warnstate.state, "quiet");
-            if (isempty (__err))
-              __msg = sprintf (["%swarning failed.\n" ...
-                                "Expected %s but got no warning\n"],
-                               __signal_fail, __patstr);
+            if (__iswarning)
+              __msg = [__signal_fail "warning failed.\n" ...
+                                     "Expected warning " __patstr ...
+                                     ", but got error <" __err ">\n"];
             elseif (__mismatch)
-              __msg = sprintf ("%swarning failed.\nExpected %s but got <%s>\n",
-                               __signal_fail, __patstr, __err);
+              __msg = [__signal_fail "error failed.\n" ...
+                                     "Expected " __patstr ", but got <" __err ">\n"];
             else
-              __success = 1;
+              __success = true;
             endif
+          end_try_catch
+          clear __test__;
+        endif
+        ## Code already processed.
+        __code = "";
+
+### TESTIF
+
+      elseif (strcmp (__type, "testif"))
+        __e = regexp (__code, '.$', 'lineanchors', 'once');
+        ## Strip any comment from testif line before looking for features
+        __feat_line = strtok (__code(1:__e), '#%');
+        __feat = regexp (__feat_line, '\w+', 'match');
+        __feat = strrep (__feat, "HAVE_", "");
+        __have_feat = __have_feature__ (__feat);
+        if (__have_feat)
+          __istest = true;
+          __code = __code(__e + 1 : end);
+        else
+          __xskip++;
+          __istest = false;
+          __code = ""; # Skip the code.
+          __msg = [__signal_skip "skipped test\n"];
+        endif
+
+### TEST
+
+      elseif (strcmp (__type, "test"))
+        __istest = true;
+        ## Code will be evaluated below.
+
+### XTEST
+
+      elseif (strcmp (__type, "xtest"))
+        __istest = false;
+        __isxtest = true;
+        ## Code will be evaluated below.
+
+### Comment block.
+
+      elseif (strcmp (__block(1:1), "#"))
+        __istest = false;
+        __code = ""; # skip the code
+
+### Unknown block.
+
+      else
+        __istest = true;
+        __success = false;
+        __msg = [__signal_fail "unknown test type!\n"];
+        __code = ""; # skip the code
+      endif
+
+      ## evaluate code for test, shared, and assert.
+      if (! isempty(__code))
+        try
+          ## FIXME: Must check for embedded test functions, which cause
+          ## segfaults, until issues with subfunctions in functions are resolved.
+          embed_func = regexp (__code, '^\s*function ', 'once', 'lineanchors');
+          if (isempty (embed_func))
+            eval (sprintf ("function %s__test__(%s)\n%s\nendfunction",
+                           __shared_r, __shared, __code));
+            eval (sprintf ("%s__test__(%s);", __shared_r, __shared));
+          else
+            error (["Functions embedded in %!test blocks are not allowed.\n", ...
+                    "Use the %!function/%!endfunction syntax instead to define shared functions for testing.\n"]);
           endif
-
         catch
-          if (! isempty (__id))
-            [~, __err] = lasterr ();
-            __mismatch = ! strcmp (__err, __id);
+          if (strcmp (__type, "xtest"))
+            __msg = [__signal_fail "known failure\n" lasterr()];
+            __xfail++;
+            __success = false;
           else
-            __err = trimerr (lasterr (), "error");
-            __mismatch = isempty (regexp (__err, __pattern, "once"));
+            __msg = [__signal_fail "test failed\n" lasterr()];
+            __success = false;
           endif
-          warning (__warnstate.state, "quiet");
-          if (__warning)
-            __msg = sprintf (["%swarning failed.\n" ...
-                              "Expected warning %s but got error <%s>\n"],
-                             __signal_fail, __patstr, __err);
-          elseif (__mismatch)
-            __msg = sprintf ("%serror failed.\nExpected %s but got <%s>\n",
-                             __signal_fail, __patstr, __err);
-          else
-            __success = 1;
+          if (isempty (lasterr ()))
+            error ("empty error text, probably Ctrl-C --- aborting");
           endif
         end_try_catch
         clear __test__;
       endif
-      ## Code already processed.
-      __code = "";
-
-### TESTIF
-
-    elseif (strcmp (__type, "testif"))
-      __e = regexp (__code, '.$', 'lineanchors', 'once');
-      ## Strip comment any comment from testif line before looking for features
-      __feat_line = strtok (__code(1:__e), '#%');
-      __feat = regexp (__feat_line, '\w+', 'match');
-      __feat = strrep (__feat, "HAVE_", "");
-      __have_feat = __have_feature__ (__feat);
-      if (__have_feat)
-        __istest = 1;
-        __code = __code(__e + 1 : end);
-      else
-        __xskip++;
-        __istest = 0;
-        __code = ""; # Skip the code.
-        __msg = sprintf ("%sskipped test\n", __signal_skip);
-      endif
-
-### TEST
-
-    elseif (strcmp (__type, "test") || strcmp (__type, "xtest"))
-      __istest = 1;
-      ## Code will be evaluated below.
-
-### Comment block.
-
-    elseif (strcmp (__block(1:1), "#"))
-      __istest = 0;
-      __code = ""; # skip the code
-
-### Unknown block.
-
-    else
-      __istest = 1;
-      __success = 0;
-      __msg = sprintf ("%sunknown test type!\n", __signal_fail);
-      __code = ""; # skip the code
-    endif
 
-    ## evaluate code for test, shared, and assert.
-    if (! isempty(__code))
-      try
-        ## FIXME: need to check for embedded test functions, which cause
-        ## segfaults, until issues with subfunctions in functions are resolved.
-        embed_func = regexp (__code, '^\s*function ', 'once', 'lineanchors');
-        if (isempty (embed_func))
-          eval (sprintf ("function %s__test__(%s)\n%s\nendfunction",
-                         __shared_r,__shared, __code));
-          eval (sprintf ("%s__test__(%s);", __shared_r, __shared));
-        else
-          error (["Functions embedded in %!test blocks are not allowed.\n", ...
-                  "Use the %!function/%!endfunction syntax instead to define shared functions for testing.\n"]);
+      ## All done.  Remember if we were successful and print any messages.
+      if (! isempty (__msg) && (__verbose >= 0 || __logfile))
+        ## Make sure the user knows what caused the error.
+        if (__verbose < 1)
+          fprintf (__fid, "%s%s\n", __signal_block, __block);
+          fflush (__fid);
+        endif
+        fprintf (__fid, "%s\n", __msg);
+        fflush (__fid);
+        ## Show the variable context.
+        if (! strcmp (__type, "error") && ! strcmp (__type, "testif")
+            && ! all (__shared == " "))
+          fputs (__fid, "shared variables ");
+          eval (sprintf ("fdisp(__fid,var2struct(%s));", __shared));
+          fflush (__fid);
         endif
-      catch
-        if (strcmp (__type, "xtest"))
-           __msg = sprintf ("%sknown failure\n%s", __signal_fail, lasterr ());
-           __xfail++;
-        else
-           __msg = sprintf ("%stest failed\n%s", __signal_fail, lasterr ());
-           __success = 0;
+      endif
+      if (! __success && ! __isxtest)
+        __all_success = false;
+        ## Stop after 1 error if not in batch mode or only pass/fail requested.
+        if (! __batch || nargout == 1)
+          if (nargout > 0)
+            if (nargout == 1)
+              __n = false;
+            else
+              __n = __nmax = 0;
+            endif
+          endif
+          if (__close_fid)
+            fclose (__fid);
+          endif
+          return;
         endif
-        if (isempty (lasterr ()))
-          error ("empty error text, probably Ctrl-C --- aborting");
-        endif
-      end_try_catch
-      clear __test__;
-    endif
+      endif
+      __tests += (__istest || __isxtest);
+      __successes += __success && (__istest || __isxtest);
 
-    ## All done.  Remember if we were successful and print any messages.
-    if (! isempty (__msg))
-      ## Make sure the user knows what caused the error.
-      if (! __verbose)
-        fprintf (__fid, "%s%s\n", __signal_block, __block);
-        fflush (__fid);
-      endif
-      fputs (__fid, __msg);
-      fputs (__fid, "\n");
-      fflush (__fid);
-      ## Show the variable context.
-      if (! strcmp (__type, "error") && ! strcmp (__type, "testif")
-          && ! all (__shared == " "))
-        fputs (__fid, "shared variables ");
-        eval (sprintf ("fdisp(__fid,bundle(%s));", __shared));
-        fflush (__fid);
-      endif
-    endif
-    if (__success == 0)
-      __all_success = 0;
-      ## Stop after one error if not in batch mode.
-      if (! __batch)
-        if (nargout > 0)
-          __ret1 = __ret2 = 0;
-        endif
-        if (__close_fid)
-          fclose (__fid);
-        endif
-        return;
-      endif
-    endif
-    __tests += __istest;
-    __successes += __success * __istest;
+    unwind_protect_cleanup
+      warning ("off", "all");
+      warning (orig_wstate);
+    end_unwind_protect
   endfor
-  ## Clear any test functions created
-  eval (__clear, "");
+
+  ## Clear any functions created during test run
+  eval (__clearfcn, "");
 
   if (nargout == 0)
     if (__tests || __xfail || __xskip)
@@ -595,20 +665,22 @@
       printf ("%s%s has no tests available\n", __signal_empty, __file);
     endif
   elseif (__grabdemo)
-    __ret1 = __demo_code;
-    __ret2 = __demo_idx;
+    __n    = __demo_code;
+    __nmax = __demo_idx;
   elseif (nargout == 1)
-    __ret1 = __all_success;
+    __n = __all_success;
   else
-    __ret1 = __successes;
-    __ret2 = __tests;
-    __ret3 = __xfail;
-    __ret4 = __xskip;
+    __n      = __successes;
+    __nmax   = __tests;
+    __nxfail = __xfail;
+    __nskip  = __xskip;
   endif
+
 endfunction
 
+
 ## Create structure with fieldnames the name of the input variables.
-function s = varstruct (varargin)
+function s = var2struct (varargin)
   for i = 1:nargin
     s.(deblank (argn(i,:))) = varargin{i};
   endfor
@@ -670,25 +742,13 @@
   str = str(idx:end);
 endfunction
 
-## Make a structure out of the named variables
-## (based on Etienne Grossmann's tar function).
-function s = bundle (varargin)
-  for i = 1:nargin
-    s.(deblank (argn(i,:))) = varargin{i};
-  endfor
-endfunction
-
 function body = __extract_test_code (nm)
   fid = fopen (nm, "rt");
-  body = [];
+  body = "";
   if (fid >= 0)
-    while (! feof (fid))
-      ln = fgetl (fid);
-      if (length (ln) >= 2 && strcmp (ln(1:2), "%!"))
-        body = [body, "\n"];
-        if (length (ln) > 2)
-          body = [body, ln(3:end)];
-        endif
+    while (ischar (ln = fgets (fid)))
+      if (strncmp (ln, "%!", 2))
+        body = [body, ln(3:end)];
       endif
     endwhile
     fclose (fid);
@@ -696,23 +756,24 @@
 endfunction
 
 
-### example from toeplitz
+## example from toeplitz
 %!shared msg1,msg2
-%! msg1="C must be a vector";
-%! msg2="C and R must be vectors";
-%!fail ('toeplitz ([])', msg1);
-%!fail ('toeplitz ([1,2;3,4])', msg1);
-%!fail ('toeplitz ([1,2],[])', msg2);
-%!fail ('toeplitz ([1,2],[1,2;3,4])', msg2);
-%!fail ('toeplitz ([1,2;3,4],[1,2])', msg2);
-% !fail ('toeplitz','usage: toeplitz'); # usage doesn't generate an error
-% !fail ('toeplitz (1, 2, 3)', 'usage: toeplitz');
-%!test  assert (toeplitz ([1,2,3], [1,4]), [1,4; 2,1; 3,2]);
-%!demo  toeplitz ([1,2,3,4],[1,5,6])
+%! msg1 = "C must be a vector";
+%! msg2 = "C and R must be vectors";
+%!fail ("toeplitz ([])", msg1)
+%!fail ("toeplitz ([1,2;3,4])", msg1)
+%!fail ("toeplitz ([1,2],[])", msg2)
+%!fail ("toeplitz ([1,2],[1,2;3,4])", msg2)
+%!fail ("toeplitz ([1,2;3,4],[1,2])", msg2)
+%!test fail ("toeplitz", "Invalid call to toeplitz")
+%!fail ("toeplitz (1, 2, 3)", "Invalid call to toeplitz")
+%!test assert (toeplitz ([1,2,3], [1,4]), [1,4; 2,1; 3,2])
+%!assert (toeplitz ([1,2,3], [1,4]), [1,4; 2,1; 3,2])
+%!demo toeplitz ([1,2,3,4],[1,5,6])
 
-### example from kron
-%!#error kron  # FIXME suppress these until we can handle output
-%!#error kron(1,2,3)
+## example from kron
+%!error <Invalid call to kron> kron ()
+%!error <Invalid call to kron> kron (1)
 %!test assert (isempty (kron ([], rand (3, 4))))
 %!test assert (isempty (kron (rand (3, 4), [])))
 %!test assert (isempty (kron ([], [])))
@@ -732,101 +793,110 @@
 %!assert (kron ([1, 2; 3, 4], A), [ A, 2*A; 3*A, 4*A ])
 %!test
 %! res = [1,-1,2,-2,3,-3; 2,-2,4,-4,6,-6; 4,-4,5,-5,6,-6; 8,-8,10,-10,12,-12];
-%! assert (kron (A, B), res)
+%! assert (kron (A, B), res);
+%!shared  # clear out shared variables
+
+## Now verify test() itself
 
-### an extended demo from specgram
-%!#demo
-%! ## Speech spectrogram
-%! [x, Fs] = auload (file_in_loadpath ("sample.wav")); # audio file
-%! step = fix (5*Fs/1000);     # one spectral slice every 5 ms
-%! window = fix (40*Fs/1000);  # 40 ms data window
-%! fftn = 2^nextpow2 (window); # next highest power of 2
-%! [S, f, t] = specgram (x, fftn, Fs, window, window-step);
-%! S = abs (S (2:fftn*4000/Fs,:)); # magnitude in range 0<f<=4000 Hz.
-%! S = S/max(max(S));          # normalize magnitude so that max is 0 dB.
-%! S = max (S, 10^(-40/10));   # clip below -40 dB.
-%! S = min (S, 10^(-3/10));    # clip above -3 dB.
-%! imagesc (flipud (20*log10 (S)), 1);
-%! % you should now see a spectrogram in the image window
-
-
-## now test 'test' itself
-
-## usage and error testing
-% !fail ('test','usage.*test')           # no args, generates usage()
-% !fail ('test (1,2,3,4)','usage.*test') # too many args, generates usage()
-%!fail ('test ("test", "bogus")','unknown flag')  # incorrect args
+## Test 'fail' keyword
+%!fail ("test", "Invalid call to test")  # no args, generates usage()
+%!fail ("test (1,2,3,4)", "usage.*test") # too many args, generates usage()
+%!fail ('test ("test", "bogus")', "unknown flag")  # incorrect args
 %!fail ('garbage','garbage.*undefined')  # usage on nonexistent function should be
 
-%!error test                     # no args, generates usage()
-%!error test (1,2,3,4)           # too many args, generates usage()
-%!error <unknown flag> test ("test", 'bogus'); # incorrect args, generates error()
-%!error <garbage' undefined> garbage           # usage on nonexistent function should be
-
-%!error test ("test", 'bogus');  # test without pattern
+## Test 'error' keyword
+%!error test              # no args, generates usage()
+%!error test (1,2,3,4)    # too many args, generates usage()
+%!error <unknown flag> test ("test", "bogus"); # incorrect args
+%!error test ("test", "bogus");  # test without pattern
+%!error <'garbage' undefined> garbage; # usage on nonexistent function is error
 
-%!test
-%! lastwarn();            # clear last warning just in case
-
-%!warning <warning message> warning ('warning message');
+## Test 'warning' keyword
+%!warning warning ("warning message");   # no pattern
+%!warning <warning message> warning ("warning message");   # with pattern
 
-## test of shared variables
+## Test 'shared' keyword
 %!shared a                # create a shared variable
-%!test   a=3;             # assign to a shared variable
-%!test   assert (a,3)     # variable should equal 3
+%!test a = 3;             # assign to a shared variable
+%!test assert (a, 3)      # variable should equal 3
 %!shared b,c              # replace shared variables
 %!test assert (!exist ("a", "var"));  # a no longer exists
 %!test assert (isempty (b));   # variables start off empty
 %!shared a,b,c            # recreate a shared variable
 %!test assert (isempty (a));   # value is empty even if it had a previous value
 %!test a=1; b=2; c=3;   # give values to all variables
-%!test assert ([a,b,c],[1,2,3]); # test all of them together
-%!test c=6;             # update a value
-%!test assert ([a, b, c],[1, 2, 6]); # show that the update sticks
-%!shared                     # clear all shared variables
+%!test assert ([a,b,c], [1,2,3]); # test all of them together
+%!test c=6;               # update a value
+%!test assert ([a,b,c], [1,2,6]); # show that the update sticks
+%!shared                  # clear all shared variables
 %!test assert (!exist ("a", "var")) # show that they are cleared
-%!shared a,b,c               # support for initializer shorthand
+%!shared a,b,c            # support for initializer shorthand
 %! a=1; b=2; c=4;
+%!shared                  # clear all shared variables for remainder of tests
 
+## Test 'function' keyword
 %!function x = __test_a (y)
 %! x = 2*y;
 %!endfunction
-%!assert (__test_a (2),4);       # Test a test function
+%!assert (__test_a (2), 4)  # Test a test function
 
 %!function __test_a (y)
 %! x = 2*y;
 %!endfunction
 %!test
-%! __test_a (2);                # Test a test function with no return value
+%! __test_a (2);            # Test a test function with no return value
 
 %!function [x,z] = __test_a (y)
 %! x = 2*y;
 %! z = 3*y;
 %!endfunction
-%!test                   # Test a test function with multiple returns
-%! [x,z] = __test_a (3);
+%!test
+%! [x,z] = __test_a (3);    # Test a test function with multiple returns
 %! assert (x,6);
 %! assert (z,9);
 
-## test of assert block
-%!assert (isempty ([]))      # support for test assert shorthand
+## Test 'assert' keyword
+%!assert (isempty ([]))     # support for test assert shorthand
+%!assert (size (ones (1,2,3)), [1 2 3])
 
-## demo blocks
-%!demo                   # multiline demo block
+## Test 'demo' keyword
+%!demo                      # multiline demo block
 %! t = [0:0.01:2*pi]; x = sin (t);
 %! plot (t,x);
 %! % you should now see a sine wave in your figure window
-%!demo a=3               # single line demo blocks work too
+
+%!demo a=3                  # single line demo blocks work too
+
+%!test
+%! [code, idx] = test ("test", "grabdemo");
+%! assert (numel (idx), 4);
+%! assert (code(idx(3):end),
+%!         " a=3                  # single line demo blocks work too");
 
-## this is a comment block. it can contain anything.
+## Test 'testif' keyword
+%!testif HAVE_BOGUS_FEATURE
+%! error ("testif executed code despite not having feature");
+
+## Test 'xtest' keyword
+%!xtest
+%! assert (1, 1);      # Test passes
+%!xtest
+%! assert (0, 1);      # Test fails
+
+## Test comment block. it can contain anything.
 %!##
 %! it is the "#" as the block type that makes it a comment
 %! and it stays as a comment even through continuation lines
 %! which means that it works well with commenting out whole tests
 
-% !# failure tests.  All the following should fail. These tests should
-% !# be disabled unless you are developing test() since users don't
-% !# like to be presented with expected failures.  I use % ! to disable.
+%% Test test() input validation
+%!error <NAME must be a string> test (1)
+%!error <second argument must be a string> test ("ls", 1)
+%!error test ([], "normal")
+
+## All of the following tests should fail.  These tests should
+## be disabled unless you are developing test() since users don't
+## like to be presented with expected failures.  I use '% !' to disable.
 % !test   error("---------Failure tests.  Use test('test','verbose',1)");
 % !test   assert([a,b,c],[1,3,6]);   # variables have wrong values
 % !bogus                     # unknown block type
@@ -839,10 +909,10 @@
 % !demo   with syntax error  # syntax errors in demo fail properly
 % !shared a,b,c
 % !demo                      # shared variables not available in demo
-% ! assert(exist("a", "var"))
+% ! assert (exist ("a", "var"))
 % !error
-% ! test('/etc/passwd');
-% ! test("nonexistent file");
+% ! test ('/etc/passwd');
+% ! test ("nonexistent file");
 % ! ## These don't signal an error, so the test for an error fails. Note
 % ! ## that the call doesn't reference the current fid (it is unavailable),
 % ! ## so of course the informational message is not printed in the log.
--- a/scripts/time/datestr.m	Fri Feb 06 08:31:09 2015 -0800
+++ b/scripts/time/datestr.m	Fri Feb 06 08:31:49 2015 -0800
@@ -37,16 +37,16 @@
 ##
 ## @multitable @columnfractions 0.1 0.45 0.35
 ## @headitem Code @tab Format @tab Example
-## @item 0 @tab dd-mmm-yyyy HH:MM:SS   @tab 07-Sep-2000 15:38:09
-## @item 1 @tab dd-mmm-yyyy            @tab 07-Sep-2000
-## @item 2 @tab mm/dd/yy               @tab 09/07/00
-## @item 3 @tab mmm                    @tab Sep
-## @item 4 @tab m                      @tab S
-## @item 5 @tab mm                     @tab 09
-## @item 6 @tab mm/dd                  @tab 09/07
-## @item 7 @tab dd                     @tab 07
-## @item 8 @tab ddd                    @tab Thu
-## @item 9 @tab d                      @tab T
+## @item 0 @tab dd-mmm-yyyy HH:MM:SS    @tab 07-Sep-2000 15:38:09
+## @item 1 @tab dd-mmm-yyyy             @tab 07-Sep-2000
+## @item 2 @tab mm/dd/yy                @tab 09/07/00
+## @item 3 @tab mmm                     @tab Sep
+## @item 4 @tab m                       @tab S
+## @item 5 @tab mm                      @tab 09
+## @item 6 @tab mm/dd                   @tab 09/07
+## @item 7 @tab dd                      @tab 07
+## @item 8 @tab ddd                     @tab Thu
+## @item 9 @tab d                       @tab T
 ## @item 10 @tab yyyy                   @tab 2000
 ## @item 11 @tab yy                     @tab 00
 ## @item 12 @tab mmmyy                  @tab Sep00
@@ -193,7 +193,7 @@
     endif
   endif
 
-  retval = [];
+  retval = "";
   for i = 1 : rows (v)
 
     if (isempty (f))
@@ -213,8 +213,8 @@
     endif
 
     df_orig = df;
-    df = strrep (df, 'AM', "%p");
-    df = strrep (df, 'PM', "%p");
+    df = strrep (df, "AM", "%p");
+    df = strrep (df, "PM", "%p");
     if (strcmp (df, df_orig))
       ## PM not set.
       df = strrep (df, "HH", "%H");
@@ -222,20 +222,20 @@
       df = strrep (df, "HH", sprintf ("%2d", v(i,4)));
     endif
 
-    df = regexprep (df, '[Yy][Yy][Yy][Yy]', "%Y");
+    df = regexprep (df, "[Yy][Yy][Yy][Yy]", "%Y");
 
-    df = regexprep (df, '[Yy][Yy]', "%y");
+    df = regexprep (df, "[Yy][Yy]", "%y");
 
-    df = regexprep (df, '[Dd][Dd][Dd][Dd]', "%A");
+    df = regexprep (df, "[Dd][Dd][Dd][Dd]", "%A");
 
-    df = regexprep (df, '[Dd][Dd][Dd]', "%a");
+    df = regexprep (df, "[Dd][Dd][Dd]", "%a");
 
-    df = regexprep (df, '[Dd][Dd]', "%d");
+    df = regexprep (df, "[Dd][Dd]", "%d");
 
     wday = weekday (datenum (v(i,1), v(i,2), v(i,3)));
     tmp = names_d{wday};
-    df = regexprep (df, '([^%])[Dd]', sprintf ("$1%s", tmp));
-    df = regexprep (df, '^[Dd]', sprintf ("%s", tmp));
+    df = regexprep (df, "([^%])[Dd]", sprintf ("$1%s", tmp));
+    df = regexprep (df, "^[Dd]", sprintf ("%s", tmp));
 
     df = strrep (df, "mmmm", "%B");
 
@@ -244,17 +244,18 @@
     df = strrep (df, "mm", "%m");
 
     tmp = names_m{v(i,2)};
-    pos = regexp (df, '[^%]m') + 1;
+    pos = regexp (df, "[^%]m") + 1;
     df(pos) = tmp;
-    df = regexprep (df, '^m', tmp);
+    df = regexprep (df, "^m", tmp);
 
     df = strrep (df, "MM", "%M");
 
-    df = regexprep (df, '[Ss][Ss]', "%S");
+    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)));
+    df = strrep (df, "QQ", sprintf ("Q%d", fix ((v(i,2) + 2) / 3)));
 
     vi = v(i,:);
     tm.year = vi(1) - 1900;
@@ -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 Feb 06 08:31:09 2015 -0800
+++ b/scripts/time/datevec.m	Fri Feb 06 08:31:49 2015 -0800
@@ -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,10 +319,15 @@
 %!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);
@@ -317,3 +335,9 @@
 %!assert (double (datevec (int64 (datenum ([2014 6 1])))), datevec (datenum ([2014 6 1])))
 %!assert (double (datevec (int64 (datenum ([2014 6 18])))), datevec (datenum ([2014 6 18])))
 
+%% 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 Feb 06 08:31:09 2015 -0800
+++ b/src/main.in.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -493,14 +493,22 @@
 {
   int retval = 0;
 
-  bool start_gui = false;
-  bool gui_libs = false;
+  bool start_gui = true;
+  bool gui_libs = true;
 
   std::string octave_bindir = get_octave_bindir ();
   std::string octave_archlibdir = get_octave_archlibdir ();
 
+#if defined (HAVE_OCTAVE_GUI)
+  // The Octave version number is already embedded in the
+  // octave_archlibdir directory name so we don't need to append it to
+  // the octave-gui file name.
+
+  std::string file = octave_archlibdir + dir_sep_char + "octave-gui";
+#else
   std::string file
-    = octave_bindir + dir_sep_char + "octave-cli-" OCTAVE_VERSION;;
+    = octave_bindir + dir_sep_char + "octave-cli-" OCTAVE_VERSION;
+#endif
 
   char **new_argv = new char * [argc + 1];
 
@@ -510,22 +518,7 @@
 
   for (int i = 1; i < argc; i++)
     {
-      if (! strcmp (argv[i], "--force-gui"))
-        {
-          start_gui = true;
-          gui_libs = true;
-#if defined (HAVE_OCTAVE_GUI)
-          // The Octave version number is already embedded in the
-          // octave_archlibdir directory name so we don't need to
-          // append it to the octave-gui file name.
-
-          file = octave_archlibdir + dir_sep_char + "octave-gui";
-#else
-          file = octave_bindir + dir_sep_char + "octave-cli-" OCTAVE_VERSION;
-#endif
-          new_argv[k++] = argv[i];
-        }
-      else if (! strcmp (argv[i], "--no-gui-libs"))
+      if (! strcmp (argv[i], "--no-gui-libs"))
         {
           // Run the version of Octave that is not linked with any GUI
           // libraries.  It may not be possible to do plotting or any
@@ -533,7 +526,9 @@
           // require less memory.  Don't pass the --no-gui-libs option
           // on as that option is not recognized by Octave.
 
-          // This is the default for 3.8 release.
+          start_gui = false;
+          gui_libs = false;
+          file = octave_bindir + dir_sep_char + "octave-cli";
         }
       else if (! strcmp (argv[i], "--no-gui"))
         {
@@ -543,10 +538,11 @@
           // even if the --no-gui option is given, we may be asked to do
           // some plotting or ui* calls.
 
-          // This option calls the cli executable for the 3.8 release.
+          start_gui = false;
+          new_argv[k++] = argv[i];
         }
-      else if (! strcmp (argv[i], "--silent") || ! strcmp (argv[i], "-q")
-               || ! strcmp (argv[i], "--quiet"))
+      else if (! strcmp (argv[i], "--silent") || ! strcmp (argv[i], "--quiet")
+               || ! strcmp (argv[i], "-q"))
         {
           warn_display = false;
           new_argv[k++] = argv[i];
@@ -607,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 Feb 06 08:31:09 2015 -0800
+++ b/src/mkoctfile.in.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -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/src/octave-config.in.cc	Fri Feb 06 08:31:09 2015 -0800
+++ b/src/octave-config.in.cc	Fri Feb 06 08:31:49 2015 -0800
@@ -56,23 +56,24 @@
 "  -p VAR, --print VAR   Print the value of the given configuration\n"
 "                        variable VAR.  Recognized variables are:\n"
 "\n"
-"                          API_VERSION            LOCALAPIOCTFILEDIR\n"
-"                          ARCHLIBDIR             LOCALARCHLIBDIR\n"
-"                          BINDIR                 LOCALFCNFILEDIR\n"
-"                          CANONICAL_HOST_TYPE    LOCALOCTFILEDIR\n"
-"                          DATADIR                LOCALSTARTUPFILEDIR\n"
-"                          DATAROOTDIR            LOCALVERARCHLIBDIR\n"
-"                          DEFAULT_PAGER          LOCALVERFCNFILEDIR\n"
-"                          EXEC_PREFIX            LOCALVEROCTFILEDIR\n"
-"                          FCNFILEDIR             MAN1DIR\n"
-"                          IMAGEDIR               MAN1EXT\n"
-"                          INCLUDEDIR             MANDIR\n"
+"                          API_VERSION            LOCALARCHLIBDIR\n"
+"                          ARCHLIBDIR             LOCALFCNFILEDIR\n"
+"                          BINDIR                 LOCALOCTFILEDIR\n"
+"                          CANONICAL_HOST_TYPE    LOCALSTARTUPFILEDIR\n"
+"                          DATADIR                LOCALVERARCHLIBDIR\n"
+"                          DATAROOTDIR            LOCALVERFCNFILEDIR\n"
+"                          DEFAULT_PAGER          LOCALVEROCTFILEDIR\n"
+"                          EXEC_PREFIX            MAN1DIR\n"
+"                          FCNFILEDIR             MAN1EXT\n"
+"                          IMAGEDIR               MANDIR\n"
+"                          INCLUDEDIR             OCTDATADIR\n"
 "                          INFODIR                OCTFILEDIR\n"
 "                          INFOFILE               OCTINCLUDEDIR\n"
 "                          LIBDIR                 OCTLIBDIR\n"
 "                          LIBEXECDIR             PREFIX\n"
 "                          LOCALAPIARCHLIBDIR     STARTUPFILEDIR\n"
 "                          LOCALAPIFCNFILEDIR     VERSION\n"
+"                          LOCALAPIOCTFILEDIR\n"
 "\n"
 "  -v, --version         Print the Octave version number.\n"
 "\n";
@@ -113,6 +114,7 @@
   vars["LOCALVEROCTFILEDIR"] = subst_octave_home (%OCTAVE_LOCALVEROCTFILEDIR%);
   vars["MAN1DIR"] = subst_octave_home (%OCTAVE_MAN1DIR%);
   vars["MANDIR"] = subst_octave_home (%OCTAVE_MANDIR%);
+  vars["OCTDATADIR"] = subst_octave_home (%OCTAVE_OCTDATADIR%);
   vars["OCTFILEDIR"] = subst_octave_home (%OCTAVE_OCTFILEDIR%);
   vars["OCTINCLUDEDIR"] = subst_octave_home (%OCTAVE_OCTINCLUDEDIR%);
   vars["OCTLIBDIR"] = subst_octave_home (%OCTAVE_OCTLIBDIR%);
--- a/test/Makefile.am	Fri Feb 06 08:31:09 2015 -0800
+++ b/test/Makefile.am	Fri Feb 06 08:31:49 2015 -0800
@@ -25,6 +25,8 @@
   args.tst \
   bug-31371.tst \
   bug-38576.tst \
+  colormaps.tst \
+  complex.tst \
   diag-perm.tst \
   error.tst \
   eval-catch.tst \
@@ -56,6 +58,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 +73,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 Feb 06 08:31:09 2015 -0800
+++ b/test/build-sparse-tests.sh	Fri Feb 06 08:31:49 2015 -0800
@@ -464,7 +464,7 @@
 print_mapper_test cos
 print_mapper_test cosh
 print_mapper_test exp
-print_mapper_test finite
+print_mapper_test isfinite
 print_mapper_test fix
 print_mapper_test floor
 print_mapper_test imag
@@ -508,19 +508,18 @@
 print_real_mapper_test isspace 0
 print_real_mapper_test isupper 0
 print_real_mapper_test isxdigit 0
-#print_real_mapper_test lgamma 1
+#print_real_mapper_test gammaln 1
 
 # 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");
 
@@ -856,7 +855,7 @@
 %!assert (as(idx'), sparse (af(idx')));
 %!assert (as(flipud (idx(:))), sparse (af(flipud (idx(:)))))
 %!assert (as([idx,idx]), sparse (af([idx,idx])))
-%!error (as(reshape ([idx;idx], [1,length(idx),2])))
+%!assert (as(reshape ([idx;idx], [1,length(idx),2])), sparse(af(reshape ([idx;idx], [1,length(idx),2]))))
 
 %% Slice tests
 %!assert (as(ridx,cidx), sparse (af(ridx,cidx)))
@@ -915,7 +914,7 @@
 gen_save_tests() {
     cat >>$TESTS <<EOF
 %!test # save ascii
-%! savefile = tmpnam ();
+%! savefile = tempname ();
 %! as_save = as;
 %! save ("-text", savefile, "bf", "as_save", "af");
 %! clear as_save;
@@ -923,7 +922,7 @@
 %! unlink (savefile);
 %! assert (as_save, sparse (af));
 %!test # save binary
-%! savefile = tmpnam ();
+%! savefile = tempname ();
 %! as_save = as;
 %! save ("-binary", savefile, "bf", "as_save", "af");
 %! clear as_save;
@@ -931,7 +930,7 @@
 %! unlink (savefile);
 %! assert (as_save, sparse (af));
 %!testif HAVE_HDF5   # save hdf5
-%! savefile = tmpnam ();
+%! savefile = tempname ();
 %! as_save = as;
 %! save ("-hdf5", savefile, "bf", "as_save", "af");
 %! clear as_save;
@@ -942,7 +941,7 @@
 ## saving sparse matrices to MAT files when using 64-bit indexing since
 ## that is not implemented yet.
 %!test # save matlab
-%! savefile = tmpnam ();
+%! savefile = tempname ();
 %! as_save = as;
 %! save ("-mat", savefile, "bf", "as_save", "af");
 %! clear as_save;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/classdef/classdef.tst	Fri Feb 06 08:31:49 2015 -0800
@@ -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 Feb 06 08:31:49 2015 -0800
@@ -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 Feb 06 08:31:49 2015 -0800
@@ -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 Feb 06 08:31:49 2015 -0800
@@ -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 Feb 06 08:31:49 2015 -0800
@@ -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)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/colormaps.tst	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,37 @@
+## Copyright (C) 2015 Carnë Draug
+##
+## 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
+%! all_colormaps = colormap ("list");
+%!
+%! assert (numel (all_colormaps) > 0)
+%!
+%! for i = 1:numel (all_colormaps)
+%!   f = str2func (all_colormaps{i});
+%!
+%!   assert (iscolormap (f (1)))
+%!   assert (iscolormap (f (12)))
+%!   assert (iscolormap (f (200)))
+%!
+%!   ## bug #44070
+%!   assert (class (f (uint8 (12))), "double")
+%!   assert (iscolormap (f (uint8 (12))))
+%!
+%!   assert (f (0), zeros (0, 3))
+%! endfor
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/command.tst	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,154 @@
+## Don't alter the spacing in the command_test lines.  These are
+## specifically testing for possible differences in things like
+##   A(X) or A( X ) or A (X) or A ( X )
+
+%!function command_test (varargin)
+%!  assignin ('caller', 'cmd_out', ['|', sprintf('%s|', varargin{:})]);
+%!endfunction
+
+%!function gobble_command (varargin)
+%!endfunction
+
+## 0, 1, 2, 3 simple arguments
+%!test
+%! command_test
+%! assert (cmd_out, '|')
+%!test
+%! command_test a
+%! assert (cmd_out, '|a|')
+%!test
+%! command_test aa     b
+%! assert (cmd_out, '|aa|b|')
+%!test
+%! command_test aaa  bb    c
+%! assert (cmd_out, '|aaa|bb|c|')
+
+## continuation
+%!test
+%! command_test a...
+%!  bb ccc
+%! assert (cmd_out, '|a|bb|ccc|')
+%!test
+%! command_test a ...
+%!  bb ccc
+%! assert (cmd_out, '|a|bb|ccc|')
+%!test
+%! command_test aa(...
+%!  bb cc
+%! assert (cmd_out, '|aa(|bb|cc|')
+%!test
+%! command_test aa(   ...
+%!  bb cc
+%! assert (cmd_out, '|aa(   |bb|cc|')
+
+## comments
+%!test
+%! command_test aa bb cc%comment
+%! assert (cmd_out, '|aa|bb|cc|')
+%!test
+%! command_test aa bb cc#comment
+%! assert (cmd_out, '|aa|bb|cc|')
+%!test
+%! command_test aa bb cc   %comment
+%! assert (cmd_out, '|aa|bb|cc|')
+%!test
+%! command_test aa bb cc   #comment
+%! assert (cmd_out, '|aa|bb|cc|')
+%!test
+%! command_test aa bb cc(  %comment
+%! assert (cmd_out, '|aa|bb|cc(  |')
+%!test
+%! command_test aa bb cc(  #comment
+%! assert (cmd_out, '|aa|bb|cc(  |')
+
+## semicolons and commas; multiple commands
+%!test
+%! command_test aa bb, gobble_command cc
+%! assert (cmd_out, '|aa|bb|')
+%!test
+%! command_test aa bb ; gobble_command cc
+%! assert (cmd_out, '|aa|bb|')
+%!test
+%! command_test aa bb ; command_test cc dd
+%! assert (cmd_out, '|cc|dd|')
+%!test
+%! command_test aa bb
+%!test
+%! command_test cc dd
+%! assert (cmd_out, '|cc|dd|')
+
+## parenthesis matching
+%!test
+%! command_test aa(bb,cc,dd) ee(ff,gg) hh
+%! assert (cmd_out, '|aa(bb,cc,dd)|ee(ff,gg)|hh|')
+%!test
+%! command_test aa([bb,cc)]
+%! assert (cmd_out, '|aa([bb,cc)]|')
+%!test
+%! command_test aa(,@!$@"bb"'cc'
+%! assert (cmd_out, '|aa(,@!$@"bb"''cc''|')
+%!test
+%! command_test aa(bb,cc,dd)
+%! assert (cmd_out, '|aa(bb,cc,dd)|')
+%!test
+%! command_test aa( bb,cc,dd )
+%! assert (cmd_out, '|aa( bb,cc,dd )|')
+%!test
+%! command_test aa (bb,cc,dd)
+%! assert (cmd_out, '|aa|(bb,cc,dd)|')
+%!test
+%! command_test aa ( bb,cc,dd )
+%! assert (cmd_out, '|aa|( bb,cc,dd )|')
+%!test
+%! command_test aa(bb, cc, dd)
+%! assert (cmd_out, '|aa(bb, cc, dd)|')
+%!test
+%! command_test aa( bb, cc, dd )
+%! assert (cmd_out, '|aa( bb, cc, dd )|')
+%!test
+%! command_test aa (bb, cc, dd)
+%! assert (cmd_out, '|aa|(bb, cc, dd)|')
+%!test
+%! command_test aa ( bb, cc, dd )
+%! assert (cmd_out, '|aa|( bb, cc, dd )|')
+
+## single and double quotes
+%!test
+%! command_test "aa" 'bb' cc
+%! assert (cmd_out, '|aa|bb|cc|')
+%!test
+%! command_test "aa"'bb'cc
+%! assert (cmd_out, '|aabbcc|')
+%!test
+%! command_test aa'bb'"cc"
+%! assert (cmd_out, '|aabbcc|')
+%!test
+%! command_test "aa"bb'cc'
+%! assert (cmd_out, '|aabbcc|')
+
+## CVX-inspired
+%!test
+%! command_test Z(n,n) hermitian toeplitz
+%! assert (cmd_out, '|Z(n,n)|hermitian|toeplitz|')
+%!test
+%! command_test X( n, n ) symmetric
+%! assert (cmd_out, '|X( n, n )|symmetric|')
+%!test
+%! command_test xw( nm-1, nv );
+%! assert (cmd_out, '|xw( nm-1, nv )|')
+%!test
+%! command_test x( sx ) y( sx ) z( sx )
+%! assert (cmd_out, '|x( sx )|y( sx )|z( sx )|')
+%!test
+%! command_test coeffs(deg+1) complex;
+%! assert (cmd_out, '|coeffs(deg+1)|complex|')
+%!test
+%! command_test w( 1, npairs * nv ) v( 1, npairs * nv )
+%! assert (cmd_out, '|w( 1, npairs * nv )|v( 1, npairs * nv )|')
+%!test
+%! command_test w(m,1)   % edge weights
+%! assert (cmd_out, '|w(m,1)|')
+%!test
+%! command_test x2( size( x ) )
+%! assert (cmd_out, '|x2( size( x ) )|')
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/complex.tst	Fri Feb 06 08:31:49 2015 -0800
@@ -0,0 +1,44 @@
+## Copyright (C) 2015 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/>.
+
+## Test ordering of complex values by magnitude and then by phase
+%!test
+%! x = [0 i 1+i 2 3i 3+4i];
+%! assert (sort (x, "descend"), fliplr (x));
+
+%!test
+%! x = [1, -1, i, -i];
+%! xs = [-i, 1, i, -1];
+%! assert (sort (x), xs);
+%! assert (sort (x, "descend"), fliplr (xs));
+
+## bug #44071, issorted incorrect because it uses different sort routine.
+%!assert (issorted ([1, -1, i, -i]), false)
+
+## bug #43313, -1 is both '>' and '==' to (-1 - 0i)
+%!test
+%! assert (complex(-1,0) == complex(-1,-0), true);
+%! assert (complex(-1,0) > complex(-1,-0), false);
+%! assert (complex(-1,0) < complex(-1,-0), false);
+
+## Test that sort and issorted both agree on boundary case
+%!test
+%! x = [complex(-1,0), complex(-1,-0), i, -i, 1];
+%! xs = sort (x);
+%! assert (issorted (xs));
+
--- a/test/error.tst	Fri Feb 06 08:31:09 2015 -0800
+++ b/test/error.tst	Fri Feb 06 08:31:49 2015 -0800
@@ -59,6 +59,36 @@
 %! assert (warning ("query", "backtrace"), st);
 %! warning (ws.state, "backtrace");
 
+%!shared t1_opts, t2_opts, t1_id, t1_state, saved_opts, saved_id, saved_state
+%! saved_opts = warning ();
+%! saved_id = {saved_opts.identifier};
+%! saved_state = {saved_opts.state};
+%! warning ("off", "all");
+%! assert (warning (), struct ("identifier", {"all"}, "state", {"off"}));
+%! warning ("off", "all");
+%! warning (saved_opts);
+%! t1_opts = struct ("identifier", {"foo:bar"}, "state", {"off"});
+%! t1_id = {t1_opts.identifier};
+%! t1_state = {t1_opts.state};
+%! warning (t1_opts);
+%! t2_opts = struct ("identifier", [saved_id, t1_id], "state", [saved_state, t1_state]);
+%! assert (warning (), t2_opts);
+%! warning ("off", "all");
+%! warning (saved_opts);
+
+## Bug 36393
+
+%!test
+%! w0 = warning;
+%! warnoffId = "MATLAB:singularMatrix";
+%! warnstat = warning ("query", warnoffId);
+%! warnoff = warnstat;
+%! warnoff.state = "off";
+%! warning (warnoff); %update warning status
+%! warning (warnstat); %reset warning status
+%! w = warning;
+%! assert (w, w0);
+
 ## Test usage() function
 
 %!function g ()
--- a/test/fcn-handle-derived-resolution/@derived/derived.m	Fri Feb 06 08:31:09 2015 -0800
+++ /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 Feb 06 08:31:49 2015 -0800
@@ -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 Feb 06 08:31:49 2015 -0800
@@ -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 Feb 06 08:31:49 2015 -0800
@@ -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 Feb 06 08:31:49 2015 -0800
@@ -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 Feb 06 08:31:49 2015 -0800
@@ -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 Feb 06 08:31:49 2015 -0800
@@ -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 Feb 06 08:31:49 2015 -0800
@@ -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 Feb 06 08:31:09 2015 -0800
+++ /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 Feb 06 08:31:09 2015 -0800
+++ /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 Feb 06 08:31:09 2015 -0800
+++ /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 Feb 06 08:31:09 2015 -0800
+++ /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 Feb 06 08:31:09 2015 -0800
+++ /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 Feb 06 08:31:09 2015 -0800
+++ /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 Feb 06 08:31:09 2015 -0800
+++ b/test/fcn-handle-derived-resolution/fcn-handle-derived-resolution.tst	Fri Feb 06 08:31:49 2015 -0800
@@ -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 Feb 06 08:31:09 2015 -0800
+++ b/test/fcn-handle-derived-resolution/module.mk	Fri Feb 06 08:31:49 2015 -0800
@@ -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/io.tst	Fri Feb 06 08:31:09 2015 -0800
+++ b/test/io.tst	Fri Feb 06 08:31:49 2015 -0800
@@ -74,7 +74,9 @@
 %!
 %!  ret = 0;
 %!
-%!  files = {"text.mat", "binary.mat", "mat5.mat", "mat7.mat"};
+%!  files = cellfun (@fullfile, {P_tmpdir},
+%!                   {"text.mat", "binary.mat", "mat5.mat", "mat7.mat"},
+%!                   "UniformOutput", false);
 %!  opts = {"-z -text", "-z -binary", "-z -mat", "-v7"};
 %!  tols = {2*eps, 0, 0, 0};
 %!
@@ -197,8 +199,9 @@
 %! STR.struct_fld.x = 0;
 %! STR.struct_fld.y = 1;
 %!
-%! save struct.dat -struct STR;
-%! STR = load ("struct.dat");
+%! struct_dat = fullfile (P_tmpdir, "struct.dat");
+%! save (struct_dat, "-struct", "STR");
+%! STR = load (struct_dat);
 %!
 %! assert (STR.scalar_fld == 1 && ...
 %!         STR.matrix_fld == [1.1,2;3,4] && ...
@@ -207,8 +210,9 @@
 %!         STR.struct_fld.y == 1 );
 %!
 %!
-%! save -binary struct.dat -struct STR matrix_fld str*_fld;
-%! STR = load ("struct.dat");
+%! save ("-binary", struct_dat,
+%!       "-struct", "STR", "matrix_fld", "str*_fld");
+%! STR =  load (struct_dat);
 %!
 %! assert (!isfield (STR,"scalar_fld") && ...
 %!         STR.matrix_fld == [1.1,2;3,4] && ...
@@ -216,15 +220,16 @@
 %!         STR.struct_fld.x == 0 && ...
 %!         STR.struct_fld.y == 1);
 %!
-%! delete struct.dat;
+%! delete (struct_dat);
 
 %!test
 %! matrix1 = rand (100, 2);
-%! save -ascii matrix.ascii matrix1
-%! matrix2 = load ("matrix.ascii");
+%! matrix_ascii = fullfile (P_tmpdir, "matrix.ascii");
+%! save ("-ascii", matrix_ascii, "matrix1")
+%! matrix2 = load (matrix_ascii);
 %! assert (matrix1, matrix2, 1e-9);
 %!
-%! delete matrix.ascii;
+%! delete (matrix_ascii);
 
 %!error <unable to find file> load ("")
 
@@ -290,7 +295,7 @@
 
 %% Note use fprintf so output not sent to stdout
 %!test
-%! nm = tmpnam ();
+%! nm = tempname ();
 %! fid1 = fopen (nm,"w");
 %! x = fprintf (fid1, "%s: %d\n", "test", 1);
 %! fclose (fid1);
@@ -335,7 +340,7 @@
 %!     elseif (j == 4)
 %!       mode_list = {"W+"; "R+"; "A+"};
 %!     endif
-%!     nm = tmpnam ();
+%!     nm = tempname ();
 %!     for k = 1:3
 %!       mode = mode_list{k};
 %!       [id, err] = fopen (nm, mode, arch);
@@ -392,12 +397,12 @@
 %!error fclose (0)
 %!error <Invalid call to fclose> fclose (1, 2)
 
-%!assert (ischar (tmpnam ()))
+%!assert (ischar (tempname ()))
 
-%!warning tmpnam (1);
-%!warning tmpnam ("foo", 1);
+%!error <DIR must be a string> tempname (1);
+%!error <PREFIX must be a string> tempname ("foo", 1);
 
-%!error <Invalid call to tmpnam> tmpnam (1, 2, 3)
+%!error <Invalid call to tempname> tempname (1, 2, 3)
 
 %!test
 %! type_list = ["char"; "char*1"; "integer*1"; "int8";
@@ -408,7 +413,7 @@
 %! "real*8"; "int16"; "integer*2"; "int32"; "integer*4"];
 %!
 %! n = rows (type_list);
-%! nm = tmpnam ();
+%! nm = tempname ();
 %! id = fopen (nm, "wb");
 %! if (id > 0)
 %!   for i = 1:n
@@ -435,7 +440,7 @@
 
 %!test
 %! x = char (128:255)';
-%! nm = tmpnam ();
+%! nm = tempname ();
 %! id = fopen (nm, "wb");
 %! fwrite (id, x);
 %! fclose (id);
@@ -446,7 +451,7 @@
 %! assert (x, y);
 
 %!test
-%! nm = tmpnam ();
+%! nm = tempname ();
 %! id = fopen (nm, "wb");
 %! if (id > 0)
 %!   fprintf (id, "%d\n", 1:100);
--- a/test/jit.tst	Fri Feb 06 08:31:09 2015 -0800
+++ b/test/jit.tst	Fri Feb 06 08:31:49 2015 -0800
@@ -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,12 @@
 %! endfor
 %! assert (a, 2000);
 %! assert (b, 1);
+%! assert (jit_failure_count, 0);
 
-%!testif HAVE_LLVM
+%!xtest
+%! ## FIXME: No support for functions with complex input prototypes
+%! ## testif HAVE_LLVM
+%! jit_failure_count (0)
 %! a = [1+1i 1+2i];
 %! b = 0;
 %! while (1)
@@ -392,6 +547,7 @@
 %!   break;
 %! endwhile
 %! assert (b, a(1));
+%! assert (jit_failure_count, 0);
 
 %!function test_undef ()
 %!  for i=1:1e7
@@ -400,26 +556,34 @@
 %!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
+%!xtest
+%! ## FIXME: No support for functions with complex input prototypes
+%! ## 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 Feb 06 08:31:09 2015 -0800
+++ b/test/null-assign.tst	Fri Feb 06 08:31:49 2015 -0800
@@ -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
--- a/test/parser.tst	Fri Feb 06 08:31:09 2015 -0800
+++ b/test/parser.tst	Fri Feb 06 08:31:49 2015 -0800
@@ -19,6 +19,7 @@
 ## Tests for parser problems belong in this file.
 ## We need many more tests here!
 
+## Test cell construction operator {}
 %!assert ({1 2 {3 4}}, {1,2,{3,4}})
 %!assert ({1, 2 {3 4}}, {1,2,{3,4}})
 %!assert ({1 2, {3 4}}, {1,2,{3,4}})
@@ -28,6 +29,14 @@
 %!assert ({1 2,{3,4}}, {1,2,{3,4}})
 %!assert ({1,2,{3 4}}, {1,2,{3,4}})
 
+## bug #43113 using null comma-separated list in constructor
+%!test
+%! z = cell (1,2,3,0,5);
+%! assert ({1, z{:}, 2}, {1, 2});
+%! assert ({1; z{:}; 2}, {1; 2});
+%! assert ({1 2; z{:}; 3 4}, {1, 2; 3 4});
+%! assert ({1 2; 5 z{:} 6; 3 4}, {1, 2; 5 6; 3 4});
+
 ## Tests for operator precedence as documented in section 8.8 of manual
 ## There are 13 levels of precedence from "parentheses and indexing" (highest)
 ## down to "statement operators" (lowest).
--- a/test/prefer.tst	Fri Feb 06 08:31:09 2015 -0800
+++ b/test/prefer.tst	Fri Feb 06 08:31:49 2015 -0800
@@ -66,16 +66,16 @@
 %! warning (wsn.state, "Octave:str-to-num");
 
 %!test
-%! wir = warning ("query", "Ocave:imag-to-real");
-%! warning ("off", "Ocave:imag-to-real");
+%! wir = warning ("query", "Octave:imag-to-real");
+%! warning ("off", "Octave:imag-to-real");
 %! assert (eye (1+i), 1);
-%! warning (wir.state, "Ocave:imag-to-real");
+%! warning (wir.state, "Octave:imag-to-real");
 
 %!test
-%! wir = warning ("query", "Ocave:imag-to-real");
-%! warning ("on", "Ocave:imag-to-real");
+%! wir = warning ("query", "Octave:imag-to-real");
+%! warning ("on", "Octave:imag-to-real");
 %! fail ("eye (1+i)", "warning");
-%! warning (wir.state, "Ocave:imag-to-real");
+%! warning (wir.state, "Octave:imag-to-real");
 
 %!test
 %! wrre = warning ("query", "Octave:resize-on-range-error");
@@ -115,7 +115,7 @@
 %! sp = save_precision ();
 %! save_precision (1);
 %! x = pi;
-%! nm = tmpnam ();
+%! nm = tempname ();
 %! save ("-text", nm, "x");
 %! clear x;
 %! load (nm);
@@ -127,7 +127,7 @@
 %! sp = save_precision ();
 %! save_precision (5);
 %! x = pi;
-%! nm = tmpnam ();
+%! nm = tempname ();
 %! save ("-text", nm, "x");
 %! clear x;
 %! load (nm);
@@ -160,7 +160,7 @@
 %!test
 %! wndz = warning ("query", "Octave:neg-dim-as-zero");
 %! warning ("on", "Octave:neg-dim-as-zero");
-%! fail ("eye (-1) == []", "warning");
+%! fail ("eye (-1) == []", "warning", "converting negative dimension");
 %! warning (wndz.state, "Octave:neg-dim-as-zero");
 
 %!test
@@ -171,14 +171,8 @@
 
 %!test
 %! watv = warning ("query", "Octave:assign-as-truth-value");
-%! warning ("off", "Octave:assign-as-truth-value");
-%! if (x = 1) 1; endif
-%! warning (watv.state, "Octave:assign-as-truth-value");
-
-%!test
-%! watv = warning ("query", "Octave:assign-as-truth-value");
 %! warning ("on", "Octave:assign-as-truth-value");
-%! fail ("if (x = 1) 1; endif", "warning");
+%! fail ("if (x = 1) 1; endif", "warning", "assignment used as truth value");
 %! warning (watv.state, "Octave:assign-as-truth-value");
 
 %!test
@@ -192,6 +186,6 @@
 %! warning ("on", "Octave:divide-by-zero");
 %! a = 1;
 %! b = 0;
-%! fail ("isinf (a/b);", "warning")
+%! fail ("isinf (a/b);", "warning", "division by zero");
 %! warning (wdbz.state, "Octave:divide-by-zero");
 
--- a/test/system.tst	Fri Feb 06 08:31:09 2015 -0800
+++ b/test/system.tst	Fri Feb 06 08:31:49 2015 -0800
@@ -58,8 +58,8 @@
 %!error <Invalid call to usleep> usleep (1, 2)
 
 %!test
-%! from = tmpnam ();
-%! to = tmpnam ();
+%! from = tempname ();
+%! to = tempname ();
 %! id = fopen (from, "wb");
 %! if (id > 0 && fclose (id) == 0)
 %!   [s, e] = stat (from);
@@ -79,7 +79,7 @@
 %!error <Invalid call to rename> rename ("foo", "bar", 1)
 
 %!test
-%! nm = tmpnam ();
+%! nm = tempname ();
 %! if ((id = fopen (nm, "wb")) > 0)
 %!   [s, err] = stat (nm);
 %!   if (! err && fclose (id) == 0 && unlink (nm) == 0)
@@ -90,6 +90,7 @@
 
 %!error <Invalid call to unlink> unlink ()
 %!error <Invalid call to unlink> unlink ("foo", 1)
+%!error <FILE must be a string> unlink ({})
 
 %!test
 %! [files, status, msg] = readdir (filesep);
@@ -99,7 +100,7 @@
 %!error <Invalid call to readdir> readdir ("foo", 1)
 
 %!test
-%! nm = tmpnam ();
+%! nm = tempname ();
 %! e1 = mkdir (nm);
 %! [s2, e2] = stat (nm);
 %! e3 = rmdir (nm);
@@ -120,14 +121,14 @@
 %! ## Test makes no sense on Windows systems
 %! if (isunix () || ismac ())
 %!   orig_umask = umask (0);
-%!   nm = tmpnam ();
+%!   nm = tempname ();
 %!   id = fopen (nm, "wb");
 %!   s1 = stat (nm);
 %!   fclose (id);
 %!   unlink (nm);
 %!
 %!   umask (777);
-%!   nm = tmpnam ();
+%!   nm = tempname ();
 %!   id = fopen (nm, "wb");
 %!   s2 = stat (nm);
 %!   fclose (id);
@@ -180,22 +181,48 @@
 %!error <Invalid call to lstat> lstat ()
 %!error <Invalid call to lstat> lstat ("foo", 1)
 
+%!test
+%! if (isunix ())
+%!   assert (S_ISCHR (stat ("/dev/null").mode));
+%!   if (exist ("/dev/initctl"))
+%!     assert (S_ISFIFO (stat ("/dev/initctl").mode));
+%!   endif
+%!   assert (S_ISLNK (lstat ("/dev/core").mode));
+%! endif
+%! nm = tempname ();
+%! fid = fopen (nm, "wb");
+%! fclose (fid);
+%! r = [ S_ISREG(stat(nm).mode)
+%!       S_ISDIR(stat(nm).mode)
+%!       S_ISCHR(stat(nm).mode)
+%!       S_ISBLK(stat(nm).mode)
+%!       S_ISFIFO(stat(nm).mode)
+%!       S_ISLNK(lstat(nm).mode)
+%!       S_ISSOCK(stat(nm).mode) ];
+%! unlink (nm);
+%! assert (r(:), [true; false; false; false; false; false; false]);
+
+%!error <octave_base_value::double_value> S_ISREG ({})
+%!error <octave_base_value::double_value> S_ISDIR ({})
+%!error <octave_base_value::double_value> S_ISCHR ({})
+%!error <octave_base_value::double_value> S_ISBLK ({})
+%!error <octave_base_value::double_value> S_ISFIFO ({})
+%!error <octave_base_value::double_value> S_ISLNK ({})
+%!error <octave_base_value::double_value> S_ISSOCK ({})
+
+%!error <Invalid call to S_ISREG> S_ISREG ()
+%!error <Invalid call to S_ISDIR> S_ISDIR ()
+%!error <Invalid call to S_ISCHR> S_ISCHR ()
+%!error <Invalid call to S_ISBLK> S_ISBLK ()
+%!error <Invalid call to S_ISFIFO> S_ISFIFO ()
+%!error <Invalid call to S_ISLNK> S_ISLNK ()
+%!error <Invalid call to S_ISSOCK> S_ISSOCK ()
+
 %!assert (iscell (glob ([filesep "*"])))
 
 %!error <Invalid call to glob> glob ()
 %!error <Invalid call to glob> glob ("foo", 1)
 
-%!test
-%! string_fill_char = char (0);
-%! assert ((fnmatch ("a*a", {"aba"; "xxxba"; "aa"}) == [1; 0; 1]
-%! && fnmatch ({"a*a"; "b*b"}, "bob")
-%! && fnmatch ("x[0-5]*", {"x1"; "x6"}) == [1; 0]
-%! && fnmatch ("x[0-5]*", {"x1"; "x6"; "x001"}) == [1; 0; 1]
-%! && fnmatch ("x???y", {"xabcy"; "xy"}) == [1; 0]));
-
-%!error <Invalid call to fnmatch> fnmatch ()
-%!error <Invalid call to fnmatch> fnmatch ("foo", "bar", 3)
-
 %!assert (ischar (file_in_path (path (), "date.m")))
 
 %!error <invalid option> file_in_path ("foo", "bar", 1)
@@ -253,17 +280,13 @@
 %! warning (wns.state, "Octave:num-to-str");
 
 %!test
-%! putenv ("foobar", "baz");
+%! setenv ("foobar", "baz");
 %! assert (getenv ("foobar"), "baz");
 
-%!error <Invalid call to putenv> putenv ()
-%!error <Invalid call to putenv> putenv ("foo", "bar", 1)
+%!error <Invalid call to setenv> setenv ()
+%!error <Invalid call to setenv> setenv ("foo", "bar", 1)
 
-%!test
-%! wns = warning ("query", "Octave:num-to-str");
-%! warning ("on", "Octave:num-to-str");
-%! fail ("putenv (1, 2)","warning");
-%! warning (wns.state, "Octave:num-to-str");
+%!error <VAR must be a string> setenv (1, 2)
 
 %!test
 %! xdir = pwd ();
@@ -370,4 +393,3 @@
 %!assert (isstruct (octave_config_info ()))
 
 %!assert (isstruct (getrusage ()))
-