diff --git a/manual/luatex-backend.tex b/manual/luatex-backend.tex
index ed9edeea75d0647328ab525f988466c299b58471..771c1cac72b613b3661d6f5748e5ce7e5afd1fe2 100644
--- a/manual/luatex-backend.tex
+++ b/manual/luatex-backend.tex
@@ -52,6 +52,11 @@ The version is frozen in the binary but you can set the minor version. What mino
 version you set depends on what \PDF\ features you use. This is out of control
 of \LUATEX.
 
+\subsection{\type {getcreationdate}}
+
+This function returns a string with the date in the format that ends up in the
+\PDF\ file, in this case it's: {\tttf \cldcontext{pdf.getcreationdate()}}.
+
 \subsection{\type {[set|get]inclusionerrorlevel}, \type {[set|get]ignoreunknownimages}}
 
 These variable control how error in included image are treated. They are modeled
diff --git a/manual/luatex-nodes.tex b/manual/luatex-nodes.tex
index 21ef0232d58de011fcc8eed9d3fb94720eaa4093..8d32ab287d36b49ea18ddde501def08b41e64640 100644
--- a/manual/luatex-nodes.tex
+++ b/manual/luatex-nodes.tex
@@ -882,212 +882,6 @@ Valid window types are:
 \NC attr        \NC node     \NC list of attributes \NC \NR
 \stoptabulate
 
-\section{Two access models}
-
-Deep down in \TEX\ a node has a number which is an numeric entry in a memory
-table. In fact, this model, where \TEX\ manages memory is real fast and one of
-the reasons why plugging in callbacks that operate on nodes is quite fast too.
-Each node gets a number that is in fact an index in the memory table and that
-number often gets reported when you print node related information.
-
-There are two access models, a robust one using a so called user data object that
-provides a virtual interface to the internal nodes, and a more direct access which
-uses the node numbers directly. The first model provide key based access while
-the second always accesses fields via functions:
-
-\starttyping
-nodeobject.char
-getfield(nodenumber,"char")
-\stoptyping
-
-If you use the direct model, even if you know that you deal with numbers, you
-should not depend on that property but treat it an abstraction just like
-traditional nodes. In fact, the fact that we use a simple basic datatype has the
-penalty that less checking can be done, but less checking is also the reason why
-it's somewhat faster. An important aspect is that one cannot mix both methods,
-but you can cast both models. So, multiplying a node number makes no sense.
-
-So our advice is: use the indexed (table) approach when possible and investigate
-the direct one when speed might be an real issue. For that reason we also provide
-the \type {get*} and \type {set*} functions in the top level node namespace.
-There is a limited set of getters. When implementing this direct approach the
-regular index by key variant was also optimized, so direct access only makes
-sense when we're accessing nodes millions of times (which happens in some font
-processing for instance).
-
-We're talking mostly of getters because setters are less important. Documents
-have not that many content related nodes and setting many thousands of properties
-is hardly a burden contrary to millions of consultations.
-
-Normally you will access nodes like this:
-
-\starttyping
-local next = current.next
-if next then
-    -- do something
-end
-\stoptyping
-
-Here \type {next} is not a real field, but a virtual one. Accessing it results in
-a metatable method being called. In practice it boils down to looking up the node
-type and based on the node type checking for the field name. In a worst case you
-have a node type that sits at the end of the lookup list and a field that is last
-in the lookup chain. However, in successive versions of \LUATEX\ these lookups
-have been optimized and the most frequently accessed nodes and fields have a
-higher priority.
-
-Because in practice the \type {next} accessor results in a function call, there
-is some overhead involved. The next code does the same and performs a tiny bit
-faster (but not that much because it is still a function call but one that knows
-what to look up).
-
-\starttyping
-local next = node.next(current)
-if next then
-    -- do something
-end
-\stoptyping
-
-If performance matters you can use an function instead:
-
-\starttabulate[|T|p|]
-\NC getnext    \NC parsing nodelist always involves this one \NC \NR
-\NC getprev    \NC used less but is logical companion to \type {getnext} \NC \NR
-\NC getboth    \NC returns the next and prev pointer of a node \NC \NR
-\NC getid      \NC consulted a lot \NC \NR
-\NC getsubtype \NC consulted less but also a topper \NC \NR
-\NC getfont    \NC used a lot in \OPENTYPE\ handling (glyph nodes are consulted a lot) \NC \NR
-\NC getchar    \NC idem and also in other places \NC \NR
-\NC getdisc    \NC returns the \type {pre}, \type {post} and \type {replace} fields and
-                   optionally when true is passed also the tail fields. \NC \NR
-\NC getlist    \NC we often parse nested lists so this is a convenient one too
-                   (only works for hlist and vlist!) \NC \NR
-\NC getleader  \NC comparable to list, seldom used in \TEX\ (but needs frequent consulting
-                   like lists; leaders could have been made a dedicated node type) \NC \NR
-\NC getfield   \NC generic getter, sufficient for the rest (other field names are
-                   often shared so a specific getter makes no sense then) \NC \NR
-\stoptabulate
-
-The direct variants also have setters, where the discretionary setter takes three
-(optional) arguments plus an optional fourth indicating the subtype.
-
-It doesn't make sense to add getters for all fields, also because some are not
-unique to one node type. Profiling demonstrated that these fields can get
-accesses way more times than other fields. Even in complex documents, many node
-and fields types never get seen, or seen only a few times. Most functions in the
-\type {node} namespace have a companion in \type {node.direct}, but of course not
-the ones that don't deal with nodes themselves. The following table summarized
-this:
-
-% \startcolumns[balance=yes]
-
-\def\yes{$+$} \def\nop{$-$}
-
-\starttabulate[|T|c|c|]
-\HL
-\NC \bf function                 \NC \bf node \NC \bf direct \NC \NR
-\HL
-\NC \type {copy_list}            \NC \yes \NC \yes  \NC \NR
-\NC \type {copy}                 \NC \yes \NC \yes  \NC \NR
-\NC \type {count}                \NC \yes \NC \yes  \NC \NR
-\NC \type {current_attr}         \NC \yes \NC \yes  \NC \NR
-\NC \type {dimensions}           \NC \yes \NC \yes  \NC \NR
-\NC \type {do_ligature_n}        \NC \yes \NC \yes  \NC \NR
-\NC \type {effective_glue}       \NC \yes \NC \yes  \NC \NR
-\NC \type {end_of_math}          \NC \yes \NC \yes  \NC \NR
-\NC \type {family_font}          \NC \yes \NC \nop  \NC \NR
-\NC \type {fields}               \NC \yes \NC \nop  \NC \NR
-\NC \type {first_character}      \NC \yes \NC \nop  \NC \NR
-\NC \type {first_glyph}          \NC \yes \NC \yes  \NC \NR
-\NC \type {flush_list}           \NC \yes \NC \yes  \NC \NR
-\NC \type {flush_node}           \NC \yes \NC \yes  \NC \NR
-\NC \type {free}                 \NC \yes \NC \yes  \NC \NR
-\NC \type {getboth}              \NC \yes \NC \yes  \NC \NR
-\NC \type {getbox}               \NC \nop \NC \yes  \NC \NR
-\NC \type {getchar}              \NC \yes \NC \yes  \NC \NR
-\NC \type {getdisc}              \NC \yes \NC \yes  \NC \NR
-\NC \type {getfield}             \NC \yes \NC \yes  \NC \NR
-\NC \type {getfont}              \NC \yes \NC \yes  \NC \NR
-\NC \type {getid}                \NC \yes \NC \yes  \NC \NR
-\NC \type {getleader}            \NC \yes \NC \yes  \NC \NR
-\NC \type {getlist}              \NC \yes \NC \yes  \NC \NR
-\NC \type {getnext}              \NC \yes \NC \yes  \NC \NR
-\NC \type {getprev}              \NC \yes \NC \yes  \NC \NR
-\NC \type {getsubtype}           \NC \yes \NC \yes  \NC \NR
-\NC \type {has_attribute}        \NC \yes \NC \yes  \NC \NR
-\NC \type {get_attribute}        \NC \yes \NC \yes  \NC \NR
-\NC \type {find_attribute}       \NC \yes \NC \yes  \NC \NR
-\NC \type {has_field}            \NC \yes \NC \yes  \NC \NR
-\NC \type {has_glyph}            \NC \yes \NC \yes  \NC \NR
-\NC \type {hpack}                \NC \yes \NC \yes  \NC \NR
-\NC \type {id}                   \NC \yes \NC \nop  \NC \NR
-\NC \type {insert_after}         \NC \yes \NC \yes  \NC \NR
-\NC \type {insert_before}        \NC \yes \NC \yes  \NC \NR
-\NC \type {is_char}              \NC \yes \NC \yes  \NC \NR
-\NC \type {is_glyph}             \NC \yes \NC \yes  \NC \NR
-\NC \type {is_direct}            \NC \nop \NC \yes  \NC \NR
-\NC \type {is_node}              \NC \yes \NC \yes  \NC \NR
-\NC \type {kerning}              \NC \yes \NC \yes  \NC \NR
-\NC \type {last_node}            \NC \yes \NC \yes  \NC \NR
-\NC \type {length}               \NC \yes \NC \yes  \NC \NR
-\NC \type {ligaturing}           \NC \yes \NC \yes  \NC \NR
-\NC \type {mlist_to_hlist}       \NC \yes \NC \nop  \NC \NR
-\NC \type {new}                  \NC \yes \NC \yes  \NC \NR
-\NC \type {next}                 \NC \yes \NC \nop  \NC \NR
-\NC \type {prev}                 \NC \yes \NC \nop  \NC \NR
-\NC \type {protect_glyph}        \NC \yes \NC \yes  \NC \NR
-\NC \type {protect_glyphs}       \NC \yes \NC \yes  \NC \NR
-\NC \type {protrusion_skippable} \NC \yes \NC \yes  \NC \NR
-\NC \type {remove}               \NC \yes \NC \yes  \NC \NR
-\NC \type {set_attribute}        \NC \yes \NC \yes  \NC \NR
-\NC \type {setboth}              \NC \yes \NC \yes  \NC \NR
-\NC \type {setbox}               \NC \yes \NC \yes  \NC \NR
-\NC \type {setchar}              \NC \yes \NC \yes  \NC \NR
-\NC \type {setdisc}              \NC \yes \NC \yes  \NC \NR
-\NC \type {setfield}             \NC \yes \NC \yes  \NC \NR
-\NC \type {setlink}              \NC \yes \NC \yes  \NC \NR
-\NC \type {setnext}              \NC \yes \NC \yes  \NC \NR
-\NC \type {setprev}              \NC \yes \NC \yes  \NC \NR
-\NC \type {slide}                \NC \yes \NC \yes  \NC \NR
-\NC \type {subtype}              \NC \yes \NC \nop  \NC \NR
-\NC \type {subtypes}             \NC \yes \NC \nop  \NC \NR
-\NC \type {tail}                 \NC \yes \NC \yes  \NC \NR
-\NC \type {todirect}             \NC \yes \NC \yes  \NC \NR
-\NC \type {tonode}               \NC \yes \NC \yes  \NC \NR
-\NC \type {tostring}             \NC \yes \NC \yes  \NC \NR
-\NC \type {traverse_id}          \NC \yes \NC \yes  \NC \NR
-\NC \type {traverse_char}        \NC \yes \NC \yes  \NC \NR
-\NC \type {traverse}             \NC \yes \NC \yes  \NC \NR
-\NC \type {types}                \NC \yes \NC \nop  \NC \NR
-\NC \type {type}                 \NC \yes \NC \nop  \NC \NR
-\NC \type {unprotect_glyphs}     \NC \yes \NC \yes  \NC \NR
-\NC \type {unset_attribute}      \NC \yes \NC \yes  \NC \NR
-\NC \type {usedlist}             \NC \yes \NC \yes  \NC \NR
-\NC \type {vpack}                \NC \yes \NC \yes  \NC \NR
-\NC \type {whatsits}             \NC \yes \NC \nop  \NC \NR
-\NC \type {whatsitsubtypes}      \NC \yes \NC \nop  \NC \NR
-\NC \type {write}                \NC \yes \NC \yes  \NC \NR
-\NC \type {setglue}              \NC \yes \NC \yes  \NC \NR
-\NC \type {getglue}              \NC \yes \NC \yes  \NC \NR
-\NC \type {glue_is_zero}         \NC \yes \NC \yes  \NC \NR
-\stoptabulate
-
-% \stopcolumns
-
-The \type {node.next} and \type {node.prev} functions will stay but for
-consistency there are variants called \type {getnext} and \type {getprev}. We had
-to use \type {get} because \type {node.id} and \type {node.subtype} are already
-taken for providing meta information about nodes. Note: The getters do only basic
-checking for valid keys. You should just stick to the keys mentioned in the
-sections that describe node properties.
-
-Some nodes have indirect references. For instance a math character refers to a
-family instead of a font. In that case we provide a virtual font field as
-accessor. So, \type {getfont} and \type {.font} can be used on them. The same is
-true for the \type {width}, \type {height} and \type {depth} of glue nodes. These
-actually access the spec node properties, and here we can set as well as get the
-values.
-
 \section{The \type {node} library}
 
 The \type {node} library contains functions that facilitate dealing with (lists
@@ -1254,16 +1048,21 @@ the \TEX\ level.
 
 This function accepts string \type {id} and \type {subtype} values as well.
 
-\subsubsection{\type {node.free}}
+\subsubsection{\type {node.free} and \type {node.flush_node}}
 
 \startfunctioncall
-node.free(<node> n)
+<node> next =
+    node.free(<node> n)
+flush_node(<node> n)
 \stopfunctioncall
 
 Removes the node \type {n} from \TEX's memory. Be careful: no checks are done on
 whether this node is still pointed to from a register or some \type {next} field:
 it is up to you to make sure that the internal data structures remain correct.
 
+The \type {free} function returns the next field of the freed node, while the
+\type {flush_node} alternative returns nothing.
+
 \subsubsection{\type {node.flush_list}}
 
 \startfunctioncall
@@ -1594,6 +1393,25 @@ See the previous section for details. The change is in the local function \type
  end
 \stoptyping
 
+\subsubsection{\type {node.traverse_char}}
+
+This iterators loops over the glyph nodes in a list. Only nodes with a subtype
+less than 256 are seen.
+
+\startfunctioncall
+<node> n =
+    node.traverse_char(<node> n)
+\stopfunctioncall
+
+\subsubsection{\type {node.has_glyph}}
+
+This function returns the first glyph or disc node in the given list:
+
+\startfunctioncall
+<node> n =
+    node.has_glyph(<node> n)
+\stopfunctioncall
+
 \subsubsection{\type {node.end_of_math}}
 
 \startfunctioncall
@@ -1700,7 +1518,7 @@ Subtracts 256 from all glyph node subtypes. This and the next function are
 helpers to convert from \type {characters} to \type {glyphs} during node
 processing.
 
-\subsubsection{\type {node.protect_glyphs}}
+\subsubsection{\type {node.protect_glyphs} and \type {node.protect_glyph}}
 
 \startfunctioncall
 node.protect_glyphs(<node> n)
@@ -1708,7 +1526,8 @@ node.protect_glyphs(<node> n)
 
 Adds 256 to all glyph node subtypes in the node list starting at \type {n},
 except that if the value is 1, it adds only 255. The special handling of 1 means
-that \type {characters} will become \type {glyphs} after subtraction of 256.
+that \type {characters} will become \type {glyphs} after subtraction of 256. A
+single character can be marked by the singular call.
 
 \subsubsection{\type {node.last_node}}
 
@@ -1844,6 +1663,253 @@ attributes or attribute|-|value pairs are ignored.
 If the attribute was actually deleted, returns its old value. Otherwise, returns
 \type {nil}.
 
+\subsubsection{\type {node.slide}}
+
+This helper makes sure that the node lists is double linked and returns the found
+tail node.
+
+\startfunctioncall
+<node> tail =
+    node.slide(<node> n)
+\stopfunctioncall
+
+\subsubsection{\type {node.check_discretionary} and \type {node.check_discretionaries}}
+
+When you fool around with disc nodes you need to be aware of the fact that they
+have a special internal data structure. As long as you reassign the fields when
+you have extended the lists it's ok because then the tail pointers get updated,
+but when you add to list without reassigning you might end up in troubles when
+the linebreak routien kicks in. You can call this function to check the list for
+issues with disc nodes.
+
+\startfunctioncall
+node.check_discretionary(<node> n)
+node.check_discretionaries(<node> head)
+\stopfunctioncall
+
+The plural variant runs over all disc nodes in a list, the singular variant
+checks one node only (it also checks if the node is a disc node).
+
+\subsubsection{\type {node.family_font}}
+
+When you pass it a proper family identifier the next helper will return the font
+currently associated with it. You can normally also access the font with the normal
+font field or getter because it will resolve the family automatically for noads.
+
+\startfunctioncall
+<integer> id =
+    node.family_font(<integer> fam)
+\stopfunctioncall
+
+\section{Two access models}
+
+Deep down in \TEX\ a node has a number which is an numeric entry in a memory
+table. In fact, this model, where \TEX\ manages memory is real fast and one of
+the reasons why plugging in callbacks that operate on nodes is quite fast too.
+Each node gets a number that is in fact an index in the memory table and that
+number often gets reported when you print node related information.
+
+There are two access models, a robust one using a so called user data object that
+provides a virtual interface to the internal nodes, and a more direct access which
+uses the node numbers directly. The first model provide key based access while
+the second always accesses fields via functions:
+
+\starttyping
+nodeobject.char
+getfield(nodenumber,"char")
+\stoptyping
+
+If you use the direct model, even if you know that you deal with numbers, you
+should not depend on that property but treat it an abstraction just like
+traditional nodes. In fact, the fact that we use a simple basic datatype has the
+penalty that less checking can be done, but less checking is also the reason why
+it's somewhat faster. An important aspect is that one cannot mix both methods,
+but you can cast both models. So, multiplying a node number makes no sense.
+
+So our advice is: use the indexed (table) approach when possible and investigate
+the direct one when speed might be an real issue. For that reason we also provide
+the \type {get*} and \type {set*} functions in the top level node namespace.
+There is a limited set of getters. When implementing this direct approach the
+regular index by key variant was also optimized, so direct access only makes
+sense when we're accessing nodes millions of times (which happens in some font
+processing for instance).
+
+We're talking mostly of getters because setters are less important. Documents
+have not that many content related nodes and setting many thousands of properties
+is hardly a burden contrary to millions of consultations.
+
+Normally you will access nodes like this:
+
+\starttyping
+local next = current.next
+if next then
+    -- do something
+end
+\stoptyping
+
+Here \type {next} is not a real field, but a virtual one. Accessing it results in
+a metatable method being called. In practice it boils down to looking up the node
+type and based on the node type checking for the field name. In a worst case you
+have a node type that sits at the end of the lookup list and a field that is last
+in the lookup chain. However, in successive versions of \LUATEX\ these lookups
+have been optimized and the most frequently accessed nodes and fields have a
+higher priority.
+
+Because in practice the \type {next} accessor results in a function call, there
+is some overhead involved. The next code does the same and performs a tiny bit
+faster (but not that much because it is still a function call but one that knows
+what to look up).
+
+\starttyping
+local next = node.next(current)
+if next then
+    -- do something
+end
+\stoptyping
+
+If performance matters you can use an function instead:
+
+\starttabulate[|T|p|]
+\NC getnext    \NC parsing nodelist always involves this one \NC \NR
+\NC getprev    \NC used less but is logical companion to \type {getnext} \NC \NR
+\NC getboth    \NC returns the next and prev pointer of a node \NC \NR
+\NC getid      \NC consulted a lot \NC \NR
+\NC getsubtype \NC consulted less but also a topper \NC \NR
+\NC getfont    \NC used a lot in \OPENTYPE\ handling (glyph nodes are consulted a lot) \NC \NR
+\NC getchar    \NC idem and also in other places \NC \NR
+\NC getdisc    \NC returns the \type {pre}, \type {post} and \type {replace} fields and
+                   optionally when true is passed also the tail fields. \NC \NR
+\NC getlist    \NC we often parse nested lists so this is a convenient one too
+                   (only works for hlist and vlist!) \NC \NR
+\NC getleader  \NC comparable to list, seldom used in \TEX\ (but needs frequent consulting
+                   like lists; leaders could have been made a dedicated node type) \NC \NR
+\NC getfield   \NC generic getter, sufficient for the rest (other field names are
+                   often shared so a specific getter makes no sense then) \NC \NR
+\NC getbox     \NC gets the given box (a list node) \NC \NR
+\stoptabulate
+
+The direct variants also have setters, where the discretionary setter takes three
+(optional) arguments plus an optional fourth indicating the subtype. An additional
+setter is \type {setlink} which will link two nodes.
+
+It doesn't make sense to add getters for all fields, also because some are not
+unique to one node type. Profiling demonstrated that these fields can get
+accesses way more times than other fields. Even in complex documents, many node
+and fields types never get seen, or seen only a few times. Most functions in the
+\type {node} namespace have a companion in \type {node.direct}, but of course not
+the ones that don't deal with nodes themselves. The following table summarized
+this:
+
+% \startcolumns[balance=yes]
+
+\def\yes{$+$} \def\nop{$-$}
+
+\starttabulate[|T|c|c|]
+\HL
+\NC \bf function                 \NC \bf node \NC \bf direct \NC \NR
+\HL
+\NC \type {check_discretionaries}\NC \yes \NC \yes  \NC \NR
+\NC \type {copy_list}            \NC \yes \NC \yes  \NC \NR
+\NC \type {copy}                 \NC \yes \NC \yes  \NC \NR
+\NC \type {count}                \NC \yes \NC \yes  \NC \NR
+\NC \type {current_attr}         \NC \yes \NC \yes  \NC \NR
+\NC \type {dimensions}           \NC \yes \NC \yes  \NC \NR
+%NC \type {do_ligature_n}        \NC \yes \NC \yes  \NC \NR % was never documented and experimental
+\NC \type {effective_glue}       \NC \yes \NC \yes  \NC \NR
+\NC \type {end_of_math}          \NC \yes \NC \yes  \NC \NR
+\NC \type {family_font}          \NC \yes \NC \nop  \NC \NR
+\NC \type {fields}               \NC \yes \NC \nop  \NC \NR
+\NC \type {find_attribute}       \NC \yes \NC \yes  \NC \NR
+\NC \type {first_glyph}          \NC \yes \NC \yes  \NC \NR
+\NC \type {flush_list}           \NC \yes \NC \yes  \NC \NR
+\NC \type {flush_node}           \NC \yes \NC \yes  \NC \NR
+\NC \type {free}                 \NC \yes \NC \yes  \NC \NR
+\NC \type {get_attribute}        \NC \yes \NC \yes  \NC \NR
+\NC \type {getboth}              \NC \yes \NC \yes  \NC \NR
+\NC \type {getbox}               \NC \nop \NC \yes  \NC \NR
+\NC \type {getchar}              \NC \yes \NC \yes  \NC \NR
+\NC \type {getdisc}              \NC \yes \NC \yes  \NC \NR
+\NC \type {getfield}             \NC \yes \NC \yes  \NC \NR
+\NC \type {getfont}              \NC \yes \NC \yes  \NC \NR
+\NC \type {getglue}              \NC \yes \NC \yes  \NC \NR
+\NC \type {getid}                \NC \yes \NC \yes  \NC \NR
+\NC \type {getleader}            \NC \yes \NC \yes  \NC \NR
+\NC \type {getlist}              \NC \yes \NC \yes  \NC \NR
+\NC \type {getnext}              \NC \yes \NC \yes  \NC \NR
+\NC \type {getprev}              \NC \yes \NC \yes  \NC \NR
+\NC \type {getsubtype}           \NC \yes \NC \yes  \NC \NR
+\NC \type {has_attribute}        \NC \yes \NC \yes  \NC \NR
+\NC \type {has_field}            \NC \yes \NC \yes  \NC \NR
+\NC \type {has_glyph}            \NC \yes \NC \yes  \NC \NR
+\NC \type {hpack}                \NC \yes \NC \yes  \NC \NR
+\NC \type {id}                   \NC \yes \NC \nop  \NC \NR
+\NC \type {insert_after}         \NC \yes \NC \yes  \NC \NR
+\NC \type {insert_before}        \NC \yes \NC \yes  \NC \NR
+\NC \type {is_char}              \NC \yes \NC \yes  \NC \NR
+\NC \type {is_direct}            \NC \nop \NC \yes  \NC \NR
+\NC \type {is_glue_zero}         \NC \yes \NC \yes  \NC \NR
+\NC \type {is_glyph}             \NC \yes \NC \yes  \NC \NR
+\NC \type {is_node}              \NC \yes \NC \yes  \NC \NR
+\NC \type {kerning}              \NC \yes \NC \yes  \NC \NR
+\NC \type {last_node}            \NC \yes \NC \yes  \NC \NR
+\NC \type {length}               \NC \yes \NC \yes  \NC \NR
+\NC \type {ligaturing}           \NC \yes \NC \yes  \NC \NR
+\NC \type {mlist_to_hlist}       \NC \yes \NC \nop  \NC \NR
+\NC \type {new}                  \NC \yes \NC \yes  \NC \NR
+\NC \type {next}                 \NC \yes \NC \nop  \NC \NR
+\NC \type {prev}                 \NC \yes \NC \nop  \NC \NR
+\NC \type {protect_glyphs}       \NC \yes \NC \yes  \NC \NR
+\NC \type {protect_glyph}        \NC \yes \NC \yes  \NC \NR
+\NC \type {protrusion_skippable} \NC \yes \NC \yes  \NC \NR
+\NC \type {remove}               \NC \yes \NC \yes  \NC \NR
+\NC \type {set_attribute}        \NC \yes \NC \yes  \NC \NR
+\NC \type {setboth}              \NC \yes \NC \yes  \NC \NR
+\NC \type {setbox}               \NC \nop \NC \yes  \NC \NR
+\NC \type {setbox}               \NC \yes \NC \yes  \NC \NR
+\NC \type {setchar}              \NC \yes \NC \yes  \NC \NR
+\NC \type {setdisc}              \NC \yes \NC \yes  \NC \NR
+\NC \type {setfield}             \NC \yes \NC \yes  \NC \NR
+\NC \type {setglue}              \NC \yes \NC \yes  \NC \NR
+\NC \type {setlink}              \NC \yes \NC \yes  \NC \NR
+\NC \type {setnext}              \NC \yes \NC \yes  \NC \NR
+\NC \type {setprev}              \NC \yes \NC \yes  \NC \NR
+\NC \type {slide}                \NC \yes \NC \yes  \NC \NR
+\NC \type {subtypes}             \NC \yes \NC \nop  \NC \NR
+\NC \type {subtype}              \NC \yes \NC \nop  \NC \NR
+\NC \type {tail}                 \NC \yes \NC \yes  \NC \NR
+\NC \type {todirect}             \NC \yes \NC \yes  \NC \NR
+\NC \type {tonode}               \NC \yes \NC \yes  \NC \NR
+\NC \type {tostring}             \NC \yes \NC \yes  \NC \NR
+\NC \type {traverse_char}        \NC \yes \NC \yes  \NC \NR
+\NC \type {traverse_id}          \NC \yes \NC \yes  \NC \NR
+\NC \type {traverse}             \NC \yes \NC \yes  \NC \NR
+\NC \type {types}                \NC \yes \NC \nop  \NC \NR
+\NC \type {type}                 \NC \yes \NC \nop  \NC \NR
+\NC \type {unprotect_glyphs}     \NC \yes \NC \yes  \NC \NR
+\NC \type {unset_attribute}      \NC \yes \NC \yes  \NC \NR
+\NC \type {usedlist}             \NC \yes \NC \yes  \NC \NR
+\NC \type {vpack}                \NC \yes \NC \yes  \NC \NR
+\NC \type {whatsitsubtypes}      \NC \yes \NC \nop  \NC \NR
+\NC \type {whatsits}             \NC \yes \NC \nop  \NC \NR
+\NC \type {write}                \NC \yes \NC \yes  \NC \NR
+\stoptabulate
+
+% \stopcolumns
+
+The \type {node.next} and \type {node.prev} functions will stay but for
+consistency there are variants called \type {getnext} and \type {getprev}. We had
+to use \type {get} because \type {node.id} and \type {node.subtype} are already
+taken for providing meta information about nodes. Note: The getters do only basic
+checking for valid keys. You should just stick to the keys mentioned in the
+sections that describe node properties.
+
+Some nodes have indirect references. For instance a math character refers to a
+family instead of a font. In that case we provide a virtual font field as
+accessor. So, \type {getfont} and \type {.font} can be used on them. The same is
+true for the \type {width}, \type {height} and \type {depth} of glue nodes. These
+actually access the spec node properties, and here we can set as well as get the
+values.
+
 \stopchapter
 
 \stopcomponent
diff --git a/manual/luatex-tex.tex b/manual/luatex-tex.tex
index 74af5976fc24f7c1a0109fc871d015311a1884cc..066c5330eb0d6c7e7119c67f071263f5ad074d7b 100644
--- a/manual/luatex-tex.tex
+++ b/manual/luatex-tex.tex
@@ -697,7 +697,7 @@ Where the table for \type {mathcode} is an array of 3 numbers, like this:
 
 \starttyping
 {
-    <number> mathclass,
+    <number> class,
     <number> family,
     <number> character
 }
@@ -717,8 +717,12 @@ And the table for \type {delcode} is an array with 4 numbers, like this:
 You can also avoid the table:
 
 \startfunctioncall
+tex.setmathcode (["global"], <number> n, <number> class,
+    <number> family, <number> character)
 class, family, char =
     tex.getmathcodes (<number> n)
+tex.setdelcode (["global"], <number> n, <number> smallfam,
+    <number> smallchar, <number> largefam, <number> largechar)
 smallfam, smallchar, largefam, largechar =
     tex.getdelcodes (<number> n)
 \stopfunctioncall
@@ -770,10 +774,13 @@ called xforms in \PDF). You can (re)use the box with \type {\useboxresource} or
 by creating a rule node with subtype~2.
 
 \starttyping
-local index = tex.saveboxresource(n,attributes,resources,immediate)
+local index = tex.saveboxresource(n,attributes,resources,immediate,type)
 \stoptyping
 
-The optional second and third arguments are strings, the fourth is a boolean.
+The optional second and third arguments are strings, the fourth is a boolean. The
+fifth argument is a type. When set to non|-|zero the \type {/Type} entry is
+omitted. A value of 1 or 3 still writes a \type {/BBox}, while 2 or 3 will write
+a \type {/Matrix}.
 
 You can generate the reference (a rule type) with:
 
diff --git a/manual/luatex.pdf b/manual/luatex.pdf
index 7ee0ed561865c54f71ff0bb7e4b1349e22414aac..f0b27e903d818964050d47e6da5fe7675295ae62 100644
Binary files a/manual/luatex.pdf and b/manual/luatex.pdf differ
diff --git a/manual/luatex.tex b/manual/luatex.tex
index 6bcd1c4e8ab293a8863de662cad5f85a6b9ced7f..cd67f07f29fd1015a674b25129daaa468a6781e4 100644
--- a/manual/luatex.tex
+++ b/manual/luatex.tex
@@ -3,7 +3,8 @@
 % \tex vs \type vs \syntax vs. \luatex
 % \em \it \/
 
-% "context --nodates --nocompression luatex" can be used for comparison runs
+% "context --nodates --nocompression luatex" can be used for comparison
+% runs, not that we do it
 
 \environment luatex-style
 \environment luatex-logos
@@ -11,7 +12,7 @@
 \dontcomplain
 
 \startdocument
-  [version=0.97.0,
+  [version=0.98.0,
    status=Pre-release]
 
 \component luatex-titlepage
diff --git a/source/texk/web2c/luatexdir/lang/texlang.w b/source/texk/web2c/luatexdir/lang/texlang.w
index f89ca5d4a3361347f329d64032180c7cd6ace8c1..f6dcfdb9153ad4241514d28f4c584a02cc541a39 100644
--- a/source/texk/web2c/luatexdir/lang/texlang.w
+++ b/source/texk/web2c/luatexdir/lang/texlang.w
@@ -462,7 +462,11 @@ halfword insert_character(halfword t, int c)
 void set_disc_field(halfword f, halfword t)
 {
     if (t != null) {
-        couple_nodes(f, t);
+        /*
+            couple_nodes(f, t); // better not expose f as prev pointer
+        */
+        vlink(f) = t ;
+        alink(t) = null ;
         tlink(f) = tail_of_list(t);
     } else {
         vlink(f) = null;
diff --git a/source/texk/web2c/luatexdir/lua/lnodelib.c b/source/texk/web2c/luatexdir/lua/lnodelib.c
index c4706e4333179755b3dea867e2b494362fc99afd..91d8525623090d95696abfba59633ef9c601e36f 100644
--- a/source/texk/web2c/luatexdir/lua/lnodelib.c
+++ b/source/texk/web2c/luatexdir/lua/lnodelib.c
@@ -4688,6 +4688,8 @@ static int lua_nodelib_direct_has_glyph(lua_State * L)
 
 /* this is too simplistic, but it helps Hans to get going */
 
+/*
+
 static halfword do_ligature_n(halfword prev, halfword stop, halfword lig)
 {
     vlink(lig) = vlink(stop);
@@ -4697,8 +4699,12 @@ static halfword do_ligature_n(halfword prev, halfword stop, halfword lig)
     return lig;
 }
 
+*/
+
 /* node.do_ligature_n(node prev, node last, node lig) */
 
+/*
+
 static int lua_nodelib_do_ligature_n(lua_State * L)
 {
     halfword p;
@@ -4718,8 +4724,12 @@ static int lua_nodelib_do_ligature_n(lua_State * L)
     return 1;
 }
 
+*/
+
 /* node.direct.do_ligature_n(node prev, node last, node lig) */
 
+/*
+
 static int lua_nodelib_direct_do_ligature_n(lua_State * L)
 {
     halfword p;
@@ -4742,6 +4752,8 @@ static int lua_nodelib_direct_do_ligature_n(lua_State * L)
     return 1;
 }
 
+*/
+
 /* node.usedlist */
 
 static int lua_nodelib_usedlist(lua_State * L)
@@ -6782,7 +6794,6 @@ static int lua_nodelib_effective_glue(lua_State * L)
     return 1;
 }
 
-
 static int lua_nodelib_direct_effective_glue(lua_State * L)
 {
     halfword glue = lua_tointeger(L, 1);
@@ -6807,6 +6818,70 @@ static int lua_nodelib_direct_effective_glue(lua_State * L)
     return 1;
 }
 
+/*
+    Disc nodes are kind of special in the sense that their head is not the head as we
+    see it, but a special node that has status info of which head and tail are part.
+    Normally when proper set/get functions are used this status node is all right but
+    if a macro package permits arbitrary messing around, then it can at some point
+    call the following cleaner, just before linebreaking kicks in. This one is not
+    called automatically because if significantly slows down the line break routing.
+
+*/
+
+#define check_disc(c) \
+    p = c ; \
+    if (p != null && vlink(p) != null) \
+        tlink(p) = tail_of_list(vlink(p));
+
+static int lua_nodelib_direct_check_discretionaries(lua_State * L) {
+    halfword c = lua_tointeger(L, 1);
+    halfword p ;
+    while (c != null) {
+        if (type(c) == disc_node) {
+            check_disc(no_break(c)) ;
+            check_disc(pre_break(c)) ;
+            check_disc(post_break(c)) ;
+        }
+        c = vlink(c) ;
+    }
+    return 0;
+}
+
+static int lua_nodelib_direct_check_discretionary(lua_State * L) {
+    halfword c = lua_tointeger(L, 1);
+    if (c != null && type(c) == disc_node) {
+        halfword p ;
+        check_disc(no_break(c)) ;
+        check_disc(pre_break(c)) ;
+        check_disc(post_break(c)) ;
+    }
+    return 0;
+}
+
+static int lua_nodelib_check_discretionaries(lua_State * L) {
+    halfword c = *check_isnode(L, 1);
+    halfword p ;
+    while (c != null) {
+        if (type(c) == disc_node) {
+            check_disc(no_break(c)) ;
+            check_disc(pre_break(c)) ;
+            check_disc(post_break(c)) ;
+        }
+        c = vlink(c) ;
+    }
+    return 0;
+}
+
+static int lua_nodelib_check_discretionary(lua_State * L) {
+    halfword c = *check_isnode(L, 1);
+    if (c != null && type(c) == disc_node) {
+        halfword p ;
+        check_disc(no_break(c)) ;
+        check_disc(pre_break(c)) ;
+        check_disc(post_break(c)) ;
+    }
+    return 0;
+}
 
 static const struct luaL_Reg nodelib_p[] = {
     {"__index",    lua_nodelib_get_property_t},
@@ -6836,7 +6911,7 @@ static const struct luaL_Reg direct_nodelib_f[] = {
     {"count", lua_nodelib_direct_count},
     {"current_attr", lua_nodelib_direct_currentattr},
     {"dimensions", lua_nodelib_direct_dimensions},
-    {"do_ligature_n", lua_nodelib_direct_do_ligature_n},
+ /* {"do_ligature_n", lua_nodelib_direct_do_ligature_n}, */
     {"end_of_math", lua_nodelib_direct_end_of_math},
  /* {"family_font", lua_nodelib_mfont}, */ /* no node argument */
  /* {"fields", lua_nodelib_fields}, */ /* no node argument */
@@ -6917,6 +6992,8 @@ static const struct luaL_Reg direct_nodelib_f[] = {
     {"getproperty", lua_nodelib_direct_get_property},
     {"setproperty", lua_nodelib_direct_set_property},
     {"effective_glue", lua_nodelib_direct_effective_glue},
+    {"check_discretionary", lua_nodelib_direct_check_discretionary},
+    {"check_discretionaries", lua_nodelib_direct_check_discretionaries},
     /* done */
     {NULL, NULL} /* sentinel */
 };
@@ -6929,7 +7006,7 @@ static const struct luaL_Reg nodelib_f[] = {
     {"count", lua_nodelib_count},
     {"current_attr", lua_nodelib_currentattr},
     {"dimensions", lua_nodelib_dimensions},
-    {"do_ligature_n", lua_nodelib_do_ligature_n},
+ /* {"do_ligature_n", lua_nodelib_do_ligature_n}, */
     {"end_of_math", lua_nodelib_end_of_math},
     {"family_font", lua_nodelib_mfont},
     {"fields", lua_nodelib_fields},
@@ -7004,6 +7081,8 @@ static const struct luaL_Reg nodelib_f[] = {
     {"getproperty", lua_nodelib_get_property}, /* hh experiment */
     {"setproperty", lua_nodelib_set_property}, /* hh experiment */
     {"effective_glue", lua_nodelib_effective_glue},
+    {"check_discretionary", lua_nodelib_check_discretionary},
+    {"check_discretionaries", lua_nodelib_check_discretionaries},
     /* done */
     {NULL, NULL} /* sentinel */
 };
diff --git a/source/texk/web2c/luatexdir/lua/lpdflib.c b/source/texk/web2c/luatexdir/lua/lpdflib.c
index de82be7479ebb52dc0f8f01f562c4c4b06ec5063..4037bacd81b05c3fc3e1d3443a1cba82f7d51951 100644
--- a/source/texk/web2c/luatexdir/lua/lpdflib.c
+++ b/source/texk/web2c/luatexdir/lua/lpdflib.c
@@ -907,6 +907,13 @@ static int getpdfversion(lua_State * L)
     return 1 ;
 }
 
+static int getpdfcreationdate(lua_State * L)
+{
+    initialize_start_time(static_pdf);
+    lua_pushstring(L,static_pdf->start_time_str);
+    return 1 ;
+}
+
 static int getpdfminorversion(lua_State * L)
 {
  /* lua_pushinteger(L,static_pdf->minor_version); */
@@ -1154,6 +1161,7 @@ static const struct luaL_Reg pdflib[] = {
     { "fontsize", getpdffontsize },
     { "xformname", getpdfxformname },
     { "getversion", getpdfversion },
+    { "getcreationdate", getpdfcreationdate },
     { "getminorversion", getpdfminorversion },
     { "setminorversion", setpdfminorversion },
     { "newcolorstack", newpdfcolorstack },
diff --git a/source/texk/web2c/luatexdir/lua/ltexlib.c b/source/texk/web2c/luatexdir/lua/ltexlib.c
index 0966176b1e2aee77885fc19f1c127cde6160a821..885981ae9adab28c71e320b29618e6c43e9b5ea8 100644
--- a/source/texk/web2c/luatexdir/lua/ltexlib.c
+++ b/source/texk/web2c/luatexdir/lua/ltexlib.c
@@ -1388,6 +1388,7 @@ static int getcatcode(lua_State * L)
     return 1;
 }
 
+/*
 
 static int setmathcode(lua_State * L)
 {
@@ -1426,6 +1427,52 @@ static int setmathcode(lua_State * L)
     return 0;
 }
 
+*/
+
+/*
+    [global] code { c f ch }
+    [global] code   c f ch   (a bit easier on memory, counterpart of getter)
+*/
+
+static int setmathcode(lua_State * L)
+{
+    int ch;
+    halfword cval, fval, chval;
+    int level = cur_level;
+    int f = 1;
+    if (lua_type(L,1) == LUA_TSTRING) {
+        const char *s = lua_tostring(L,1);
+        if (lua_key_eq(s,global)) {
+            level = level_one;
+            f = 2;
+        }
+    }
+    ch = luaL_checkinteger(L, f);
+    check_char_range(ch, "setmathcode", 65536*17);
+    f += 1 ;
+    if (lua_type(L,f) == LUA_TNUMBER) {
+        cval = luaL_checkinteger(L, f);
+        fval = luaL_checkinteger(L, f+1);
+        chval = luaL_checkinteger(L, f+2);
+    } else if (lua_type(L,f) == LUA_TTABLE) {
+        lua_rawgeti(L, f, 1);
+        cval = (halfword) luaL_checkinteger(L, -1);
+        lua_rawgeti(L, f, 2);
+        fval = (halfword) luaL_checkinteger(L, -1);
+        lua_rawgeti(L, f, 3);
+        chval = (halfword) luaL_checkinteger(L, -1);
+        lua_pop(L,3);
+    } else {
+        luaL_error(L, "Bad arguments for tex.setmathcode()");
+        return 0;
+    }
+    check_char_range(cval, "setmathcode", 8);
+    check_char_range(fval, "setmathcode", 256);
+    check_char_range(chval, "setmathcode", 65536*17);
+    set_math_code(ch, cval,fval, chval, (quarterword) (level));
+    return 0;
+}
+
 static int getmathcode(lua_State * L)
 {
     mathcodeval mval = { 0, 0, 0 };
@@ -1454,6 +1501,8 @@ static int getmathcodes(lua_State * L)
     return 3;
 }
 
+/*
+
 static int setdelcode(lua_State * L)
 {
     int ch;
@@ -1494,6 +1543,56 @@ static int setdelcode(lua_State * L)
     return 0;
 }
 
+*/
+
+/*
+    [global] code { c f ch }
+    [global] code   c f ch   (a bit easier on memory, counterpart of getter)
+*/
+
+static int setdelcode(lua_State * L)
+{
+    int ch;
+    halfword sfval, scval, lfval, lcval;
+    int level = cur_level;
+    int f = 1;
+    if (lua_type(L,1) == LUA_TSTRING) {
+        const char *s = lua_tostring(L,1);
+        if (lua_key_eq(s,global)) {
+            level = level_one;
+            f = 2;
+        }
+    }
+    ch = luaL_checkinteger(L, f);
+    check_char_range(ch, "setdelcode", 65536*17);
+    f += 1;
+    if (lua_type(L,f) == LUA_TNUMBER) {
+        sfval = luaL_checkinteger(L, f);
+        scval = luaL_checkinteger(L, f+1);
+        lfval = luaL_checkinteger(L, f+2);
+        lcval = luaL_checkinteger(L, f+3);
+    } else if (lua_type(L,f) == LUA_TTABLE) {
+        lua_rawgeti(L, f, 1);
+        sfval = (halfword) luaL_checkinteger(L, -1);
+        lua_rawgeti(L, f, 2);
+        scval = (halfword) luaL_checkinteger(L, -1);
+        lua_rawgeti(L, f, 3);
+        lfval = (halfword) luaL_checkinteger(L, -1);
+        lua_rawgeti(L, f, 4);
+        lcval = (halfword) luaL_checkinteger(L, -1);
+        lua_pop(L,4);
+    } else {
+        luaL_error(L, "Bad arguments for tex.setdelcode()");
+        return 0;
+    }
+    check_char_range(sfval, "setdelcode", 256);
+    check_char_range(scval, "setdelcode", 65536*17);
+    check_char_range(lfval, "setdelcode", 256);
+    check_char_range(lcval, "setdelcode", 65536*17);
+    set_del_code(ch, sfval, scval, lfval, lcval, (quarterword) (level));
+    return 0;
+}
+
 static int getdelcode(lua_State * L)
 {
     delcodeval mval = { 0, 0, 0, 0, 0 };
diff --git a/source/texk/web2c/luatexdir/luatex.c b/source/texk/web2c/luatexdir/luatex.c
index f4b2945d970a26fd49d5a8dbcfeacbd8b4d5b5d2..249afea600c842cd66cc51698339a9aa4ea4977a 100644
--- a/source/texk/web2c/luatexdir/luatex.c
+++ b/source/texk/web2c/luatexdir/luatex.c
@@ -28,10 +28,10 @@
 
 #define TeX
 
-int luatex_version = 97;        /* \.{\\luatexversion}  */
+int luatex_version = 98;        /* \.{\\luatexversion}  */
 int luatex_revision = '0';      /* \.{\\luatexrevision}  */
-int luatex_date_info = 2016060720;     /* the compile date is now hardwired */
-const char *luatex_version_string = "0.97.0";
+int luatex_date_info = 2016071717;     /* the compile date is now hardwired */
+const char *luatex_version_string = "0.98.0";
 const char *engine_name = my_name;     /* the name of this engine */
 
 #include <kpathsea/c-ctype.h>
diff --git a/source/texk/web2c/luatexdir/tex/mathcodes.w b/source/texk/web2c/luatexdir/tex/mathcodes.w
index 8c0760ae51e3fab0fde8e0640c6bacc44b119ea6..a0a357e53193f48e4e3c93be78b0b02ca77311f3 100644
--- a/source/texk/web2c/luatexdir/tex/mathcodes.w
+++ b/source/texk/web2c/luatexdir/tex/mathcodes.w
@@ -252,7 +252,7 @@ static void unsavedelcode(quarterword gl)
                 end_diagnostic(false);
             }
         }
-        (mathcode_head->stack_ptr)--;
+        (delcode_head->stack_ptr)--;
     }
 }
 
diff --git a/source/texk/web2c/luatexdir/tex/mlist.w b/source/texk/web2c/luatexdir/tex/mlist.w
index 331be47de7dc01c9a6e1d4a7e34ffc78895a3bd4..ace56be86276e70c5820203490797345afff5ed5 100644
--- a/source/texk/web2c/luatexdir/tex/mlist.w
+++ b/source/texk/web2c/luatexdir/tex/mlist.w
@@ -2430,7 +2430,6 @@ static void make_fraction(pointer q, int cur_style)
             delta1 = clr1 - ((shift_up   - depth(x) ) - (math_axis_size(cur_size) + delta));
             delta2 = clr2 - ((shift_down - height(z)) + (math_axis_size(cur_size) - delta));
         } else {
-            delta = half(thickness(q));
             clr1 = ext_xn_over_d(clr1, thickness(q), fraction_rule(cur_style));
             clr2 = ext_xn_over_d(clr2, thickness(q), fraction_rule(cur_style));
             delta1 = clr1 - ((shift_up   - depth(x) ) - (math_axis_size(cur_size) + delta));