diff --git a/src/base-lu.cc b/src/base-lu.cc
new file mode 100644
index 0000000..c27d868
--- /dev/null
+++ b/src/base-lu.cc
@@ -0,0 +1,191 @@
+/*
+
+Copyright (C) 1996-2015 John W. Eaton
+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/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "base-lu.h"
+
+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.transpose ().col_perm_vec ())
+{
+  if (l.columns () != u.rows ())
+    (*current_liboctave_error_handler) ("lu: dimension mismatch");
+}
+
+template <class lu_type>
+bool
+base_lu <lu_type> :: packed (void) const
+{
+  return l_fact.dims () == dim_vector ();
+}
+
+template <class lu_type>
+void
+base_lu <lu_type> :: unpack (void)
+{
+  if (packed ())
+    {
+      l_fact = L ();
+      a_fact = U (); // FIXME: sub-optimal
+      ipvt = getp ();
+    }
+}
+
+template <class lu_type>
+lu_type
+base_lu <lu_type> :: L (void) const
+{
+  if (packed ())
+    {
+      octave_idx_type a_nr = a_fact.rows ();
+      octave_idx_type a_nc = a_fact.cols ();
+      octave_idx_type mn = (a_nr < a_nc ? a_nr : a_nc);
+
+      lu_type l (a_nr, mn, lu_elt_type (0.0));
+
+      for (octave_idx_type i = 0; i < a_nr; i++)
+        {
+          if (i < a_nc)
+            l.xelem (i, i) = 1.0;
+
+          for (octave_idx_type j = 0; j < (i < a_nc ? i : a_nc); j++)
+            l.xelem (i, j) = a_fact.xelem (i, j);
+        }
+
+      return l;
+    }
+  else
+    return l_fact;
+}
+
+template <class lu_type>
+lu_type
+base_lu <lu_type> :: U (void) const
+{
+  if (packed ())
+    {
+      octave_idx_type a_nr = a_fact.rows ();
+      octave_idx_type a_nc = a_fact.cols ();
+      octave_idx_type mn = (a_nr < a_nc ? a_nr : a_nc);
+
+      lu_type u (mn, a_nc, lu_elt_type (0.0));
+
+      for (octave_idx_type i = 0; i < mn; i++)
+        {
+          for (octave_idx_type j = i; j < a_nc; j++)
+            u.xelem (i, j) = a_fact.xelem (i, j);
+        }
+
+      return u;
+    }
+  else
+    return a_fact;
+}
+
+template <class lu_type>
+lu_type
+base_lu <lu_type> :: Y (void) const
+{
+  if (! packed ())
+    (*current_liboctave_error_handler)
+      ("lu: Y () not implemented for unpacked form");
+  return a_fact;
+}
+
+template <class lu_type>
+Array<octave_idx_type>
+base_lu <lu_type> :: getp (void) const
+{
+  if (packed ())
+    {
+      octave_idx_type a_nr = a_fact.rows ();
+
+      Array<octave_idx_type> pvt (dim_vector (a_nr, 1));
+
+      for (octave_idx_type i = 0; i < a_nr; i++)
+        pvt.xelem (i) = i;
+
+      for (octave_idx_type i = 0; i < ipvt.length (); i++)
+        {
+          octave_idx_type k = ipvt.xelem (i);
+
+          if (k != i)
+            {
+              octave_idx_type tmp = pvt.xelem (k);
+              pvt.xelem (k) = pvt.xelem (i);
+              pvt.xelem (i) = tmp;
+            }
+        }
+
+      return pvt;
+    }
+  else
+    return ipvt;
+}
+
+template <class lu_type>
+PermMatrix
+base_lu <lu_type> :: P (void) const
+{
+  return PermMatrix (getp (), false);
+}
+
+template <class lu_type>
+ColumnVector
+base_lu <lu_type> :: P_vec (void) const
+{
+  octave_idx_type a_nr = a_fact.rows ();
+
+  ColumnVector p (a_nr);
+
+  Array<octave_idx_type> pvt = getp ();
+
+  for (octave_idx_type i = 0; i < a_nr; i++)
+    p.xelem (i) = static_cast<double> (pvt.xelem (i) + 1);
+
+  return p;
+}
+
+template <class lu_type>
+bool
+base_lu<lu_type>::regular (void) const
+{
+  bool retval = true;
+
+  octave_idx_type k = std::min (a_fact.rows (), a_fact.columns ());
+
+  for (octave_idx_type i = 0; i < k; i++)
+    {
+      if (a_fact(i, i) == lu_elt_type ())
+        {
+          retval = false;
+          break;
+        }
+    }
+
+  return retval;
+}
diff --git a/src/base-lu.h b/src/base-lu.h
new file mode 100644
index 0000000..f11f625
--- /dev/null
+++ b/src/base-lu.h
@@ -0,0 +1,87 @@
+/*
+
+Copyright (C) 1996-2015 John W. Eaton
+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/>.
+
+*/
+
+#if !defined (octave_base_lu_h)
+#define octave_base_lu_h 1
+
+#include "MArray.h"
+#include "dColVector.h"
+#include "PermMatrix.h"
+
+template <class lu_type>
+class
+base_lu
+{
+public:
+
+  typedef typename lu_type::element_type lu_elt_type;
+
+  base_lu (void)
+    : a_fact (), l_fact (), ipvt () { }
+
+  base_lu (const base_lu& a)
+    : a_fact (a.a_fact), l_fact (a.l_fact), ipvt (a.ipvt) { }
+
+  base_lu (const lu_type& l, const lu_type& u,
+           const PermMatrix& p);
+
+  base_lu& operator = (const base_lu& a)
+  {
+    if (this != &a)
+      {
+        a_fact = a.a_fact;
+        l_fact = a.l_fact;
+        ipvt = a.ipvt;
+      }
+    return *this;
+  }
+
+  virtual ~base_lu (void) { }
+
+  bool packed (void) const;
+
+  void unpack (void);
+
+  lu_type L (void) const;
+
+  lu_type U (void) const;
+
+  lu_type Y (void) const;
+
+  PermMatrix P (void) const;
+
+  ColumnVector P_vec (void) const;
+
+  bool regular (void) const;
+
+protected:
+
+  Array<octave_idx_type> getp (void) const;
+
+  lu_type a_fact;
+  lu_type l_fact;
+
+  Array<octave_idx_type> ipvt;
+};
+
+#endif
diff --git a/src/galois-ops.h b/src/galois-ops.h
index e43f111..dc74837 100644
--- a/src/galois-ops.h
+++ b/src/galois-ops.h
@@ -21,6 +21,32 @@
 #if !defined (galois_octave_ops_h)
 #define galois_octave_ops_h 1
 
+#if ! defined (CAST_BINOP_ARGS)
+#  define CAST_BINOP_ARGS(t1, t2)               \
+  t1 v1 = dynamic_cast<t1> (a1);                \
+  t2 v2 = dynamic_cast<t2> (a2)
+#endif
+
+#if ! defined (CAST_UNOP_ARG)
+#  define CAST_UNOP_ARG(t)                      \
+  t v = dynamic_cast<t> (a)
+#endif
+
+#if ! defined (BINOPDECL)
+#  define BINOPDECL(name, a1, a2)                               \
+  static octave_value                                           \
+  CONCAT2(oct_binop_, name) (const octave_base_value& a1,       \
+                             const octave_base_value& a2)
+#endif
+
+#if ! defined (CATOPDECL)
+#  define CATOPDECL(name, a1, a2)                                       \
+  static octave_value                                                   \
+  CONCAT2(oct_catop_, name) (octave_base_value& a1,                     \
+                             const octave_base_value& a2,               \
+                             const Array<octave_idx_type>& ra_idx)
+#endif
+
 // Override the operator and function definition defines from Octave
 
 #define DEFBINOP_OP_G(name, t1, t2, op) \
diff --git a/src/galois.cc b/src/galois.cc
index 43623bf..7573474 100644
--- a/src/galois.cc
+++ b/src/galois.cc
@@ -27,7 +27,7 @@
 #include "galoisfield.h"
 #include "galois-def.h"
 
-#include <octave/base-lu.cc>
+#include "base-lu.cc"
 
 galois_field_list stored_galois_fields;
 
diff --git a/src/galois.h b/src/galois.h
index ae161b3..21f8a85 100644
--- a/src/galois.h
+++ b/src/galois.h
@@ -22,10 +22,10 @@
 #define octave_galois_int_h 1
 
 #include <octave/config.h>
-#include <octave/base-lu.h>
 #include <octave/mx-base.h>
 
 #include "galoisfield.h"
+#include "base-lu.h"
 
 typedef void (*solve_singularity_handler) (double rcond);
 
diff --git a/src/ls-oct-ascii.cc b/src/ls-oct-ascii.cc
new file mode 100644
index 0000000..985d53a
--- /dev/null
+++ b/src/ls-oct-ascii.cc
@@ -0,0 +1,433 @@
+/*
+
+Copyright (C) 1996-2015 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: John W. Eaton.
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <cstring>
+#include <cctype>
+
+#include <fstream>
+#include <iomanip>
+#include <iostream>
+#include <sstream>
+#include <string>
+
+#include "byte-swap.h"
+#include "data-conv.h"
+#include "file-ops.h"
+#include "glob-match.h"
+#include "lo-mappers.h"
+#include "mach-info.h"
+#include "oct-env.h"
+#include "oct-time.h"
+#include "quit.h"
+#include "str-vec.h"
+
+#include "Cell.h"
+#include "defun.h"
+#include "error.h"
+#include "gripes.h"
+#include "load-save.h"
+#include "ls-ascii-helper.h"
+#include "ls-oct-ascii.h"
+#include "oct-obj.h"
+#include "oct-map.h"
+#include "ov-cell.h"
+#include "pager.h"
+#include "pt-exp.h"
+#include "unwind-prot.h"
+#include "utils.h"
+#include "variables.h"
+#include "version.h"
+#include "dMatrix.h"
+
+// The number of decimal digits to use when writing ascii data.
+static int Vsave_precision = 16;
+
+// Functions for reading ascii data.
+
+// Extract a KEYWORD and its value from stream IS, returning the
+// associated value in a new string.
+//
+// Input should look something like:
+//
+//  [%#][ \t]*keyword[ \t]*:[ \t]*string-value[ \t]*\n
+
+std::string
+extract_keyword (std::istream& is, const char *keyword, const bool next_only)
+{
+  std::string retval;
+
+  int ch = is.peek ();
+  if (next_only && ch != '%' && ch != '#')
+    return retval;
+
+  char c;
+  while (is.get (c))
+    {
+      if (c == '%' || c == '#')
+        {
+          std::ostringstream buf;
+
+          while (is.get (c) && (c == ' ' || c == '\t' || c == '%' || c == '#'))
+            ; // Skip whitespace and comment characters.
+
+          if (isalpha (c))
+            buf << c;
+
+          while (is.get (c) && isalpha (c))
+            buf << c;
+
+          std::string tmp = buf.str ();
+          bool match = (tmp.compare (0, strlen (keyword), keyword) == 0);
+
+          if (match)
+            {
+              std::ostringstream value;
+              while (is.get (c) && (c == ' ' || c == '\t' || c == ':'))
+                ; // Skip whitespace and the colon.
+
+              is.putback (c);
+              retval = read_until_newline (is, false);
+              break;
+            }
+          else if (next_only)
+            break;
+          else
+            skip_until_newline (is, false);
+        }
+    }
+
+  int len = retval.length ();
+
+  if (len > 0)
+    {
+      while (len)
+        {
+          c = retval[len-1];
+
+          if (c == ' ' || c == '\t')
+            len--;
+          else
+            {
+              retval.resize (len);
+              break;
+            }
+        }
+    }
+
+  return retval;
+}
+
+// Extract one value (scalar, matrix, string, etc.) from stream IS and
+// place it in TC, returning the name of the variable.  If the value
+// is tagged as global in the file, return TRUE in GLOBAL.
+//
+// Each type supplies its own function to load the data, and so this
+// function is extensible.
+//
+// FILENAME is used for error messages.
+//
+// The data is expected to be in the following format:
+//
+// The input file must have a header followed by some data.
+//
+// All lines in the header must begin with a '#' character.
+//
+// The header must contain a list of keyword and value pairs with the
+// keyword and value separated by a colon.
+//
+// Keywords must appear in the following order:
+//
+// # name: <name>
+// # type: <type>
+// # <info>
+//
+// Where, for the built in types are:
+//
+//  <name> : a valid identifier
+//
+//  <type> : <typename>
+//         | global <typename>
+//
+//  <typename> : scalar
+//             | complex scalar
+//             | matrix
+//             | complex matrix
+//             | bool
+//             | bool matrix
+//             | string
+//             | range
+//
+//  <info> : <matrix info>
+//         | <string info>
+//
+//  <matrix info> : # rows: <integer>
+//                : # columns: <integer>
+//
+//  <string info> : # elements: <integer>
+//                : # length: <integer> (once before each string)
+//
+//  For backward compatibility the type "string array" is treated as a
+// "string" type. Also "string" can have a single element with no elements
+// line such that
+//
+//  <string info> : # length: <integer>
+//
+// Formatted ASCII data follows the header.
+//
+// Example:
+//
+//  # name: foo
+//  # type: matrix
+//  # rows: 2
+//  # columns: 2
+//    2  4
+//    1  3
+//
+// Example:
+//
+//  # name: foo
+//  # type: string
+//  # elements: 5
+//  # length: 4
+//  this
+//  # length: 2
+//  is
+//  # length: 1
+//  a
+//  # length: 6
+//  string
+//  # length: 5
+//  array
+//
+// FIXME: this format is fairly rigid, and doesn't allow for
+// arbitrary comments.  Someone should fix that. It does allow arbitrary
+// types however.
+
+// Ugh.  The signature of the compare method is not standard in older
+// versions of the GNU libstdc++.  Do this instead:
+
+#define SUBSTRING_COMPARE_EQ(s, pos, n, t) (s.substr (pos, n) == t)
+
+std::string
+read_ascii_data (std::istream& is, const std::string& filename, bool& global,
+                 octave_value& tc, octave_idx_type count)
+{
+  // Read name for this entry or break on EOF.
+
+  std::string name = extract_keyword (is, "name");
+
+  if (name.empty ())
+    {
+      if (count == 0)
+        error ("load: empty name keyword or no data found in file '%s'",
+               filename.c_str ());
+
+      return std::string ();
+    }
+
+  if (! (name == ".nargin." || name == ".nargout."
+         || name == CELL_ELT_TAG || valid_identifier (name)))
+    {
+      error ("load: bogus identifier '%s' found in file '%s'",
+             name.c_str (), filename.c_str ());
+      return std::string ();
+    }
+
+  // Look for type keyword.
+
+  std::string tag = extract_keyword (is, "type");
+
+  if (! tag.empty ())
+    {
+      std::string typ;
+      size_t pos = tag.rfind (' ');
+
+      if (pos != std::string::npos)
+        {
+          global = SUBSTRING_COMPARE_EQ (tag, 0, 6, "global");
+
+          typ = global ? tag.substr (7) : tag;
+        }
+      else
+        typ = tag;
+
+      // Special case for backward compatiablity. A small bit of cruft
+      if (SUBSTRING_COMPARE_EQ (typ, 0, 12, "string array"))
+        tc = charMatrix ();
+      else
+        tc = octave_value_typeinfo::lookup_type (typ);
+
+      if (! tc.load_ascii (is))
+        error ("load: trouble reading ascii file '%s'", filename.c_str ());
+    }
+  else
+    error ("load: failed to extract keyword specifying value type");
+
+  if (error_state)
+    {
+      error ("load: reading file %s", filename.c_str ());
+      return std::string ();
+    }
+
+  return name;
+}
+
+// Save the data from TC along with the corresponding NAME, and global
+// flag MARK_AS_GLOBAL on stream OS in the plain text format described
+// above for load_ascii_data.  If NAME is empty, the name: line is not
+// generated.  PRECISION specifies the number of decimal digits to print.
+//
+// Assumes ranges and strings cannot contain Inf or NaN values.
+//
+// Returns 1 for success and 0 for failure.
+
+// FIXME: should probably write the help string here too.
+
+bool
+save_ascii_data (std::ostream& os, const octave_value& val_arg,
+                 const std::string& name, bool mark_as_global,
+                 int precision)
+{
+  bool success = true;
+
+  if (! name.empty ())
+    os << "# name: " << name << "\n";
+
+  octave_value val = val_arg;
+
+  if (mark_as_global)
+    os << "# type: global " << val.type_name () << "\n";
+  else
+    os << "# type: " << val.type_name () << "\n";
+
+  if (! precision)
+    precision = Vsave_precision;
+
+  long old_precision = os.precision ();
+  os.precision (precision);
+
+  success = val.save_ascii (os);
+
+  // Insert an extra pair of newline characters after the data so that
+  // multiple data elements may be handled separately by gnuplot (see
+  // the description of the index qualifier for the plot command in the
+  // gnuplot documentation).
+  os << "\n\n";
+
+  os.precision (old_precision);
+
+  return (os && success);
+}
+
+bool
+save_ascii_data_for_plotting (std::ostream& os, const octave_value& t,
+                              const std::string& name)
+{
+  return save_ascii_data (os, t, name, false, 6);
+}
+
+// Maybe this should be a static function in tree-plot.cc?
+
+// If TC is matrix, save it on stream OS in a format useful for
+// making a 3-dimensional plot with gnuplot.  If PARAMETRIC is
+// TRUE, assume a parametric 3-dimensional plot will be generated.
+
+bool
+save_three_d (std::ostream& os, const octave_value& tc, bool parametric)
+{
+  bool fail = false;
+
+  octave_idx_type nr = tc.rows ();
+  octave_idx_type nc = tc.columns ();
+
+  if (tc.is_real_matrix ())
+    {
+      os << "# 3-D data...\n"
+         << "# type: matrix\n"
+         << "# total rows: " << nr << "\n"
+         << "# total columns: " << nc << "\n";
+
+      long old_precision = os.precision ();
+      os.precision (6);
+
+      if (parametric)
+        {
+          octave_idx_type extras = nc % 3;
+          if (extras)
+            warning ("ignoring last %d columns", extras);
+
+          Matrix tmp = tc.matrix_value ();
+          nr = tmp.rows ();
+
+          for (octave_idx_type i = 0; i < nc-extras; i += 3)
+            {
+              os << tmp.extract (0, i, nr-1, i+2);
+              if (i+3 < nc-extras)
+                os << "\n";
+            }
+        }
+      else
+        {
+          Matrix tmp = tc.matrix_value ();
+          nr = tmp.rows ();
+
+          for (octave_idx_type i = 0; i < nc; i++)
+            {
+              os << tmp.extract (0, i, nr-1, i);
+              if (i+1 < nc)
+                os << "\n";
+            }
+        }
+
+      os.precision (old_precision);
+    }
+  else
+    {
+      ::error ("for now, I can only save real matrices in 3-D format");
+      fail = true;
+    }
+
+  return (os && ! fail);
+}
+
+DEFUN (save_precision, args, nargout,
+       "-*- texinfo -*-\n\
+@deftypefn  {Built-in Function} {@var{val} =} save_precision ()\n\
+@deftypefnx {Built-in Function} {@var{old_val} =} save_precision (@var{new_val})\n\
+@deftypefnx {Built-in Function} {} save_precision (@var{new_val}, \"local\")\n\
+Query or set the internal variable that specifies the number of digits to\n\
+keep when saving data in text format.\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\
+@end deftypefn")
+{
+  return SET_INTERNAL_VARIABLE_WITH_LIMITS (save_precision, -1,
+                                            std::numeric_limits<int>::max ());
+}
diff --git a/src/ls-oct-ascii.h b/src/ls-oct-ascii.h
new file mode 100644
index 0000000..1d6b6bf
--- /dev/null
+++ b/src/ls-oct-ascii.h
@@ -0,0 +1,189 @@
+/*
+
+Copyright (C) 2003-2015 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_ls_oct_ascii_h)
+#define octave_ls_oct_ascii_h 1
+
+#include <cfloat>
+
+#include <sstream>
+#include <string>
+
+#include "str-vec.h"
+
+#include "ls-ascii-helper.h"
+
+// Flag for cell elements
+#define CELL_ELT_TAG "<cell-element>"
+
+// Used when converting Inf to something that gnuplot can read.
+
+#ifndef OCT_RBV
+#define OCT_RBV (std::numeric_limits<double>::max () / 100.0)
+#endif
+
+extern OCTINTERP_API std::string
+extract_keyword (std::istream& is, const char *keyword,
+                 const bool next_only = false);
+
+extern OCTINTERP_API std::string
+read_ascii_data (std::istream& is, const std::string& filename, bool& global,
+                 octave_value& tc, octave_idx_type count);
+
+extern OCTINTERP_API bool
+save_ascii_data (std::ostream& os, const octave_value& val_arg,
+                 const std::string& name, bool mark_as_global, int precision);
+
+extern OCTINTERP_API bool
+save_ascii_data_for_plotting (std::ostream& os, const octave_value& t,
+                              const std::string& name);
+
+extern OCTINTERP_API bool
+save_three_d (std::ostream& os, const octave_value& t,
+              bool parametric = false);
+
+// Match KEYWORD on stream IS, placing the associated value in VALUE,
+// returning TRUE if successful and FALSE otherwise.
+//
+// Input should look something like:
+//
+//  [%#][ \t]*keyword[ \t]*int-value.*\n
+
+template <class T>
+bool
+extract_keyword (std::istream& is, const char *keyword, T& value,
+                 const bool next_only = false)
+{
+  bool status = false;
+  value = T ();
+
+  char c;
+  while (is.get (c))
+    {
+      if (c == '%' || c == '#')
+        {
+          std::ostringstream buf;
+
+          while (is.get (c) && (c == ' ' || c == '\t' || c == '%' || c == '#'))
+            ; // Skip whitespace and comment characters.
+
+          if (isalpha (c))
+            buf << c;
+
+          while (is.get (c) && isalpha (c))
+            buf << c;
+
+          std::string tmp = buf.str ();
+          bool match = (tmp.compare (0, strlen (keyword), keyword) == 0);
+
+          if (match)
+            {
+              while (is.get (c) && (c == ' ' || c == '\t' || c == ':'))
+                ; // Skip whitespace and the colon.
+
+              is.putback (c);
+              if (c != '\n' && c != '\r')
+                is >> value;
+              if (is)
+                status = true;
+              skip_until_newline (is, false);
+              break;
+            }
+          else if (next_only)
+            break;
+        }
+    }
+  return status;
+}
+
+template <class T>
+bool
+extract_keyword (std::istream& is, const std::string& kw, T& value,
+                 const bool next_only = false)
+{
+  return extract_keyword (is, kw.c_str (), value, next_only);
+}
+
+// Match one of the elements in KEYWORDS on stream IS, placing the
+// matched keyword in KW and the associated value in VALUE,
+// returning TRUE if successful and FALSE otherwise.
+//
+// Input should look something like:
+//
+//  [%#][ \t]*keyword[ \t]*int-value.*\n
+
+template <class T>
+bool
+extract_keyword (std::istream& is, const string_vector& keywords,
+                 std::string& kw, T& value, const bool next_only = false)
+{
+  bool status = false;
+  kw = "";
+  value = 0;
+
+  char c;
+  while (is.get (c))
+    {
+      if (c == '%' || c == '#')
+        {
+          std::ostringstream buf;
+
+          while (is.get (c) && (c == ' ' || c == '\t' || c == '%' || c == '#'))
+            ; // Skip whitespace and comment characters.
+
+          if (isalpha (c))
+            buf << c;
+
+          while (is.get (c) && isalpha (c))
+            buf << c;
+
+          std::string tmp = buf.str ();
+
+          for (int i = 0; i < keywords.length (); i++)
+            {
+              int match = (tmp == keywords[i]);
+
+              if (match)
+                {
+                  kw = keywords[i];
+
+                  while (is.get (c) && (c == ' ' || c == '\t' || c == ':'))
+                    ; // Skip whitespace and the colon.
+
+                  is.putback (c);
+                  if (c != '\n' && c != '\r')
+                    is >> value;
+                  if (is)
+                    status = true;
+                  skip_until_newline (is, false);
+                  return status;
+                }
+            }
+
+          if (next_only)
+            break;
+        }
+    }
+  return status;
+}
+
+#endif
diff --git a/src/ov-galois.cc b/src/ov-galois.cc
index 010d48c..64fbf24 100644
--- a/src/ov-galois.cc
+++ b/src/ov-galois.cc
@@ -24,17 +24,32 @@
 #include <octave/byte-swap.h>
 #include <octave/gripes.h>
 #include <octave/lo-ieee.h>
-#include <octave/oct-hdf5.h>
 #include <octave/oct-locbuf.h>
 #include <octave/oct-obj.h>
 #include <octave/ov.h>
 #include <octave/pr-output.h>
 
-#include <octave/ls-oct-ascii.h>
+#include "ls-oct-ascii.h"
 
 #include "galois.h"
 #include "ov-galois.h"
 
+#if defined (HAVE_HDF5)
+#  if defined (HAVE_HDF5_H)
+#    include <hdf5.h>
+#  endif
+#  include "oct-hdf5-types.h"
+#  if defined (OCTAVE_ENABLE_64)
+#    define H5T_NATIVE_IDX H5T_NATIVE_INT64
+#  else
+#    define H5T_NATIVE_IDX H5T_NATIVE_INT
+#  endif
+#endif
+
+#if ! defined (X_CAST)
+#  define X_CAST(T, E) (T) (E)
+#endif
+
 #if defined (DEFINE_OCTAVE_ALLOCATOR)
 DEFINE_OCTAVE_ALLOCATOR (octave_galois);
 #endif
diff --git a/src/ov-galois.h b/src/ov-galois.h
index e55f7d8..d16ef29 100644
--- a/src/ov-galois.h
+++ b/src/ov-galois.h
@@ -44,6 +44,10 @@ typedef int octave_hdf5_id;
 #endif
 #endif
 
+#if ! defined (OV_REP_TYPE)
+#  define OV_REP_TYPE octave_base_value
+#endif
+
 class octave_value_list;
 class tree_walker;
 
diff --git a/src/syndtable.cc b/src/syndtable.cc
index 296d4c0..0ee8675 100644
--- a/src/syndtable.cc
+++ b/src/syndtable.cc
@@ -20,8 +20,8 @@
 
 #include <octave/oct.h>
 
-#define COL_MAJ(N) (N / (SIZEOF_INT << 3))
-#define COL_MIN(N) (N % (SIZEOF_INT << 3))
+#define COL_MAJ(N) (N / (sizeof (int) << 3))
+#define COL_MIN(N) (N % (sizeof (int) << 3))
 
 Array<int>
 get_errs (const int& nmin, const int& nmax, const int &nerrs)