[libfolia] 01/03: New upstream version 1.10

Maarten van Gompel proycon-guest at moszumanska.debian.org
Thu Nov 2 20:25:09 UTC 2017


This is an automated email from the git hooks/post-receive script.

proycon-guest pushed a commit to branch master
in repository libfolia.

commit dcaade5c4e11fedc5f3ffd3bd555b9c6cdb96e87
Author: proycon <proycon at anaproy.nl>
Date:   Thu Nov 2 21:18:21 2017 +0100

    New upstream version 1.10
---
 ChangeLog                         |  735 +++++++++++++++++++-
 Makefile.in                       |   16 +-
 NEWS                              |   54 +-
 README                            |   95 +--
 aclocal.m4                        |    1 -
 bootstrap.sh                      |    3 -
 config.guess                      |  137 ++--
 config.h.in                       |    3 -
 config.sub                        |   38 +-
 configure                         | 1377 ++++++++++++++++---------------------
 configure.ac                      |   68 +-
 include/Makefile.in               |   16 +-
 include/libfolia/Makefile.in      |   16 +-
 include/libfolia/folia_document.h |   87 ++-
 include/libfolia/folia_impl.h     |  389 +++++++----
 include/libfolia/folia_types.h    |    2 +-
 include/libfolia/folia_utils.h    |   40 +-
 ltmain.sh                         |    4 +-
 m4/Makefile.in                    |   16 +-
 m4/ax_icu_check.m4                |   86 ---
 m4/ax_pthread.m4                  |  550 +++++++++------
 src/Makefile.am                   |    4 +-
 src/Makefile.in                   |   20 +-
 src/folia_document.cxx            |  844 +++++++++++++++++------
 src/folia_impl.cxx                |  772 +++++++++++++++++----
 src/folia_properties.cxx          |   60 +-
 src/folia_types.cxx               |    3 -
 src/folia_utils.cxx               |   59 +-
 src/folialint.cxx                 |   63 +-
 src/simpletest.cxx                |   21 +
 30 files changed, 3645 insertions(+), 1934 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index a648aa2..4fff107 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,683 @@
+2017-10-16  Ko van der Sloot <K.vanderSloot at let.ru.nl>
+
+	* include/libfolia/folia_document.h, src/folia_document.cxx,
+	src/folialint.cxx: folialint now can warn when annotation
+	declarations are unused
+
+2017-10-16  Ko van der Sloot <K.vanderSloot at let.ru.nl>
+
+	* include/libfolia/folia_impl.h, src/folia_impl.cxx: improved and
+	simplified text-checking
+
+2017-10-12  Ko van der Sloot <K.vanderSloot at let.ru.nl>
+
+	* src/folia_impl.cxx: added exceptions for Text and Division too.
+	feels unpleaseant
+
+2017-10-12  Ko van der Sloot <K.vanderSloot at let.ru.nl>
+
+	* src/folia_impl.cxx: textchecking fix for Morphemes and Phonemes
+
+2017-10-12  Ko van der Sloot <K.vanderSloot at let.ru.nl>
+
+	* include/libfolia/folia_impl.h, src/folia_impl.cxx: cleaner code
+
+2017-10-12  Ko van der Sloot <K.vanderSloot at let.ru.nl>
+
+	* include/libfolia/folia_impl.h, src/folia_impl.cxx: some
+	cleanup/refactoring
+
+2017-10-12  Ko van der Sloot <K.vanderSloot at let.ru.nl>
+
+	* src/folia_impl.cxx: fix textchecking. still a bit shaky code
+	though
+
+2017-10-11  Ko van der Sloot <K.vanderSloot at let.ru.nl>
+
+	* src/folia_impl.cxx: attempt to fix text checking
+
+2017-10-11  Ko van der Sloot <K.vanderSloot at let.ru.nl>
+
+	* include/libfolia/folia_impl.h: added virtual members
+
+2017-10-11  Ko van der Sloot <K.vanderSloot at let.ru.nl>
+
+	* src/folia_document.cxx, src/folia_impl.cxx, src/folialint.cxx,
+	src/simpletest.cxx: changed XML parsing. 'empty' nodes inside
+	TextContent, PhonContent and Textmarkup are significant
+
+2017-10-10  Ko van der Sloot <K.vanderSloot at let.ru.nl>
+
+	* include/libfolia/folia_document.h, src/folia_document.cxx,
+	src/folialint.cxx: added some function for version checking against
+	the library version. Let folilint use it.
+
+2017-10-10  Ko van der Sloot <K.vanderSloot at let.ru.nl>
+
+	* include/libfolia/folia_document.h, src/folia_document.cxx: added
+	an update_version() function to update to the most recent library
+	version. Handle with care!
+
+2017-10-06  Ko van der Sloot <K.vanderSloot at let.ru.nl>
+
+	* include/libfolia/folia_document.h, src/folia_document.cxx: added a
+	xmlstring() serializer to Document.
+
+2017-10-05  Ko van der Sloot <K.vanderSloot at let.ru.nl>
+
+	* include/libfolia/folia_impl.h: fixed merging problem
+
+2017-10-05  Ko van der Sloot <K.vanderSloot at let.ru.nl>
+
+	* : commit 741f821d41b1501cf73d601ba9426e0e29f5bdc2 Author: Ko van
+	der Sloot <K.vanderSloot at let.ru.nl> Date:   Thu Oct 5 16:33:26 2017
+	+0200
+
+2017-10-05  Ko van der Sloot <K.vanderSloot at let.ru.nl>
+
+	* src/folia_document.cxx: better FOLIA_TEXT_CHECK environment value
+	handling
+
+2017-10-05  Ko van der Sloot <K.vanderSloot at let.ru.nl>
+
+	* src/folia_impl.cxx: handle String_t as AbstractStructure_t in
+	finddefaultreference()
+
+2017-10-05  Ko van der Sloot <K.vanderSloot at let.ru.nl>
+
+	* src/folia_document.cxx: moved environment checking to a place
+	where is is always done at least once :)
+
+2017-10-04  Ko van der Sloot <K.vanderSloot at let.ru.nl>
+
+	* src/folia_document.cxx, src/folia_impl.cxx: some fixes in messages
+
+2017-10-04  Ko van der Sloot <K.vanderSloot at let.ru.nl>
+
+	* include/libfolia/folia_document.h, include/libfolia/folia_impl.h,
+	src/folia_document.cxx, src/folia_impl.cxx: implemented ref for
+	PhonContent too
+
+2017-10-04  Ko van der Sloot <K.vanderSloot at let.ru.nl>
+
+	* include/libfolia/folia_impl.h, include/libfolia/folia_utils.h,
+	src/folia_document.cxx, src/folia_impl.cxx: implemented reference
+	resolving in TextContent
+
+2017-10-03  Ko van der Sloot <K.vanderSloot at let.ru.nl>
+
+	* include/libfolia/folia_document.h, include/libfolia/folia_impl.h,
+	src/folia_document.cxx, src/folia_impl.cxx: started implementing
+	offset checking
+
+2017-10-03  Ko van der Sloot <K.vanderSloot at let.ru.nl>
+
+	* include/libfolia/folia_utils.h, src/folia_document.cxx,
+	src/folia_impl.cxx: some XmlErrors are more specific as
+	InconstistentText now
+
+2017-10-03  Ko van der Sloot <K.vanderSloot at let.ru.nl>
+
+	* src/folia_document.cxx: fix imdi metadata when no metadata is
+	provided
+
+2017-10-02  Ko van der Sloot <K.vanderSloot at let.ru.nl>
+
+	* include/libfolia/folia_impl.h, src/folia_impl.cxx: plug a memory
+	leak
+
+2017-10-02  Ko van der Sloot <K.vanderSloot at let.ru.nl>
+
+	* src/folia_document.cxx: better cleanup
+
+2017-10-02  Ko van der Sloot <K.vanderSloot at let.ru.nl>
+
+	* include/libfolia/folia_impl.h, src/folia_impl.cxx: implemented a
+	cleartextcontent function
+
+2017-10-02  Ko van der Sloot <K.vanderSloot at let.ru.nl>
+
+	* include/libfolia/folia_impl.h, src/Makefile.am,
+	src/folia_impl.cxx: added a cleartextcontent member
+
+2017-10-02  Ko van der Sloot <K.vanderSloot at let.ru.nl>
+
+	* include/libfolia/folia_document.h, src/folia_document.cxx: some
+	cleanup in the metadata code
+
+2017-10-02  Ko van der Sloot <K.vanderSloot at let.ru.nl>
+
+	* src/folia_document.cxx: default metadatatype is "native"
+
+2017-10-02  Ko van der Sloot <K.vanderSloot at let.ru.nl>
+
+	* configure.ac: re-instate --with-icu configuration option
+
+2017-10-02  Ko van der Sloot <K.vanderSloot at let.ru.nl>
+
+	* src/folia_document.cxx: better error message
+
+2017-10-02  Ko van der Sloot <K.vanderSloot at let.ru.nl>
+
+	* configure.ac: re-instated --with-icu in configure.ac
+
+2017-09-29  Maarten van Gompel <proycon at anaproy.nl>
+
+	* src/folia_properties.cxx: regenerated foliaspec (again)
+
+2017-09-29  Maarten van Gompel <proycon at anaproy.nl>
+
+	* src/folia_properties.cxx: another foliaspec update
+
+2017-09-29  Maarten van Gompel <proycon at anaproy.nl>
+
+	* src/folia_properties.cxx: Regenerated foliaspec
+
+2017-09-28  Ko van der Sloot <K.vanderSloot at let.ru.nl>
+
+	* include/libfolia/folia_impl.h: don't throw in get_val()
+
+2017-09-28  Ko van der Sloot <K.vanderSloot at let.ru.nl>
+
+	* src/folia_document.cxx: fixed set_metadata()
+
+2017-09-28  Ko van der Sloot <K.vanderSloot at let.ru.nl>
+
+	* include/libfolia/folia_document.h, src/folia_document.cxx: cleanup
+
+2017-09-28  Ko van der Sloot <K.vanderSloot at let.ru.nl>
+
+	* include/libfolia/folia_document.h, src/folia_document.cxx: fixing
+	metadatstuff, still ugly!
+
+2017-09-28  Ko van der Sloot <K.vanderSloot at let.ru.nl>
+
+	* include/libfolia/folia_document.h, include/libfolia/folia_impl.h,
+	src/folia_document.cxx, src/folia_impl.cxx: Save current state.
+	Working but still ugly code
+
+2017-09-26  Ko van der Sloot <K.vanderSloot at let.ru.nl>
+
+	* include/libfolia/folia_document.h, include/libfolia/folia_impl.h,
+	src/folia_document.cxx, src/folia_impl.cxx: some refactoring
+
+2017-09-26  Ko van der Sloot <K.vanderSloot at let.ru.nl>
+
+	* include/libfolia/folia_impl.h, src/folia_document.cxx,
+	src/folia_impl.cxx: some additons to metadata stuff
+
+2017-09-26  Ko van der Sloot <K.vanderSloot at let.ru.nl>
+
+	* include/libfolia/folia_impl.h, src/folia_document.cxx: completing
+	submetadata stuff
+
+2017-09-26  Ko van der Sloot <K.vanderSloot at let.ru.nl>
+
+	* src/folia_impl.cxx: fixed linebreak serializing. xlink properties
+	were forgotten!
+
+2017-09-26  Ko van der Sloot <K.vanderSloot at let.ru.nl>
+
+	* include/libfolia/folia_document.h, include/libfolia/folia_impl.h,
+	include/libfolia/folia_utils.h, src/folia_document.cxx,
+	src/folia_impl.cxx, src/folia_utils.cxx: continue working on
+	metadata. getting closer
+
+2017-09-25  Ko van der Sloot <K.vanderSloot at let.ru.nl>
+
+	* : commit a9118585983269aaa3d6694e45fbef60ad23166f Author: Ko van
+	der Sloot <K.vanderSloot at let.ru.nl> Date:   Mon Sep 25 18:47:16 2017
+	+0200
+
+2017-09-25  Maarten van Gompel <proycon at anaproy.nl>
+
+	* src/folia_properties.cxx: reenerated (version revision number)
+
+2017-09-25  Ko van der Sloot <K.vanderSloot at let.ru.nl>
+
+	* src/folia_utils.cxx: typo
+
+2017-09-25  Maarten van Gompel <proycon at anaproy.nl>
+
+	* include/libfolia/folia_types.h, src/folia_properties.cxx: 
+	Regenerated with foliaspec 1.5 (METADATA attribute)
+	(proycon/folia#30)
+
+2017-09-11  Ko van der Sloot <K.vanderSloot at let.ru.nl>
+
+	* include/libfolia/folia_impl.h: allow empty argument
+
+2017-09-07  Ko van der Sloot <K.vanderSloot at let.ru.nl>
+
+	* src/folia_document.cxx: fixed stupid problem, storing 'now()'
+	instead os a reale date.
+
+2017-09-07  Ko van der Sloot <K.vanderSloot at let.ru.nl>
+
+	* src/folia_properties.cxx: added TEXTCLASS as an optional attribute
+	for Word
+
+2017-09-07  Ko van der Sloot <K.vanderSloot at let.ru.nl>
+
+	* : commit b51f5c7d1e13e79149eef74f294a107921f9e6ce Author: Ko van
+	der Sloot <K.vanderSloot at let.ru.nl> Date:   Tue Sep 5 14:38:03 2017
+	+0200
+
+2017-09-05  Ko van der Sloot <K.vanderSloot at let.ru.nl>
+
+	* include/libfolia/folia_document.h, src/folia_document.cxx,
+	src/folia_impl.cxx: aliases are associated to AnnotationType now,
+	just like the setnames
+
+2017-08-30  Ko van der Sloot <K.vanderSloot at let.ru.nl>
+
+	* configure.ac: bump version after release
+
+2017-08-30  Ko van der Sloot <K.vanderSloot at let.ru.nl>
+
+	* NEWS: NEWS for the release
+
+2017-08-30  Ko van der Sloot <K.vanderSloot at let.ru.nl>
+
+	* configure.ac: simplified config. accepting ICU 50 on the fly
+
+2017-08-30  Ko van der Sloot <K.vanderSloot at let.ru.nl>
+
+	* include/libfolia/folia_document.h, src/folia_document.cxx,
+	src/folia_impl.cxx: uses aliasses in serializing trees
+
+2017-08-30  Ko van der Sloot <K.vanderSloot at let.ru.nl>
+
+	* configure.ac: simplified configure script. allow for an older icu
+	version too
+
+2017-08-29  Ko van der Sloot <K.vanderSloot at let.ru.nl>
+
+	* src/folia_document.cxx: added checks for insane users
+
+2017-08-29  Ko van der Sloot <K.vanderSloot at let.ru.nl>
+
+	* src/Makefile.am: bump .so version again...
+
+2017-08-29  Ko van der Sloot <K.vanderSloot at let.ru.nl>
+
+	* include/libfolia/folia_document.h, src/folia_document.cxx: 
+	implemented an alias mechanism for set declarations
+
+2017-08-21  Ko van der Sloot <K.vanderSloot at let.ru.nl>
+
+	* src/folia_impl.cxx: textchecking in folia >1.5 documents is more
+	relaxed now.
+
+2017-08-18  Ko van der Sloot <K.vanderSloot at let.ru.nl>
+
+	* : commit 57137ac96ecf02dd921d093b07249c3db80b4758 Author: Ko van
+	der Sloot <K.vanderSloot at let.ru.nl> Date:   Fri Aug 18 16:42:47 2017
+	+0200
+
+2017-08-17  Ko van der Sloot <K.vanderSloot at let.ru.nl>
+
+	* include/libfolia/folia_utils.h, src/folia_utils.cxx,
+	src/simpletest.cxx: added a normalize function for UnicodeString
+
+2017-08-16  Ko van der Sloot <K.vanderSloot at let.ru.nl>
+
+	* configure.ac: Bumped version after release 1.8
+
+2017-08-16  Ko van der Sloot <K.vanderSloot at let.ru.nl>
+
+	* NEWS: NEWS about release
+
+2017-08-16  Ko van der Sloot <K.vanderSloot at let.ru.nl>
+
+	* src/Makefile.am: bump library version
+
+2017-08-15  Ko van der Sloot <K.vanderSloot at let.ru.nl>
+
+	* : commit a86e4fe432f97171339cb959ada5b5ee5554a247 Author: Ko van
+	der Sloot <K.vanderSloot at let.ru.nl> Date:   Mon Aug 14 12:58:22 2017
+	+0200
+
+2017-08-14  Ko van der Sloot <K.vanderSloot at let.ru.nl>
+
+	* include/libfolia/folia_impl.h, src/folia_impl.cxx: implemented
+	textclass attribute
+
+2017-08-14  Maarten van Gompel <proycon at anaproy.nl>
+
+	* include/libfolia/folia_types.h, src/folia_properties.cxx: 
+	Regenerated foliaspec for 1.4.3 (adds TEXTCLASS attrib)
+
+2017-07-27  Ko van der Sloot <K.vanderSloot at let.ru.nl>
+
+	* .travis.yml: updated .travis.yml
+
+2017-07-20  Ko van der Sloot <K.vanderSloot at let.ru.nl>
+
+	* src/folia_impl.cxx: fix logic
+
+2017-07-20  Ko van der Sloot <K.vanderSloot at let.ru.nl>
+
+	* .travis.yml: updated .travis.yml
+
+2017-07-20  Ko van der Sloot <K.vanderSloot at let.ru.nl>
+
+	* src/folia_impl.cxx: only do checktext() for 1.5 documents (which
+	don't exist yet)
+
+2017-07-15  Maarten van Gompel <proycon at anaproy.nl>
+
+	* src/folia_impl.cxx: More explicit error message #18
+
+2017-07-12  Maarten van Gompel <proycon at anaproy.nl>
+
+	* src/folia_properties.cxx: Regenerated foliaspec for v1.4.2
+
+2017-06-28  Ko van der Sloot <K.vanderSloot at let.ru.nl>
+
+	* src/folia_impl.cxx: more strict textchecking. No grace for
+	embedded newlines!
+
+2017-06-27  Ko van der Sloot <K.vanderSloot at let.ru.nl>
+
+	* src/folia_impl.cxx: fixed test checking by relaxing a bit on the
+	constraints.
+
+2017-06-26  Ko van der Sloot <K.vanderSloot at let.ru.nl>
+
+	* include/libfolia/folia_impl.h, src/folia_impl.cxx: added more text
+	consitency checks. might break weird documents with embedded
+	newlines.
+
+2017-06-14  Ko van der Sloot <K.vanderSloot at let.ru.nl>
+
+	* src/folia_document.cxx: fixed problem in version checking
+
+2017-05-17  Ko van der Sloot <K.vanderSloot at let.ru.nl>
+
+	* include/libfolia/folia_impl.h, src/folia_impl.cxx: small
+	refactoring.
+
+2017-05-15  Ko van der Sloot <K.vanderSloot at let.ru.nl>
+
+	* include/libfolia/folia_document.h, src/folia_document.cxx,
+	src/folia_impl.cxx: added an getmode() member to Document. the
+	FOLIA_TEXT_CKECK enverionment variable works again now
+
+2017-05-15  Ko van der Sloot <K.vanderSloot at let.ru.nl>
+
+	* include/libfolia/folia_document.h: made Document::setmode() public
+
+2017-05-15  Ko van der Sloot <K.vanderSloot at let.ru.nl>
+
+	* include/libfolia/folia_document.h, src/folia_document.cxx,
+	src/folia_impl.cxx: jugling around with document modes. added
+	'fixtext' possibility (unused yet)
+
+2017-05-10  Ko van der Sloot <K.vanderSloot at let.ru.nl>
+
+	* include/libfolia/folia_impl.h, src/folia_impl.cxx: added a
+	'override' parameter to settext*
+
+2017-05-10  Ko van der Sloot <K.vanderSloot at let.ru.nl>
+
+	* include/libfolia/folia_document.h, src/folia_document.cxx: disable
+	text checking for folia < 1.5
+
+2017-05-10  Ko van der Sloot <K.vanderSloot at let.ru.nl>
+
+	* include/libfolia/folia_impl.h, src/folia_impl.cxx: attempt to fix
+	deeptext(). hackery alert
+
+2017-05-09  Ko van der Sloot <K.vanderSloot at let.ru.nl>
+
+	* .travis.yml: argllll
+
+2017-05-09  Ko van der Sloot <K.vanderSloot at let.ru.nl>
+
+	* .travis.yml: added Travis notices
+
+2017-05-08  Ko van der Sloot <K.vanderSloot at let.ru.nl>
+
+	* configure.ac: daring...
+
+2017-05-08  Ko van der Sloot <K.vanderSloot at let.ru.nl>
+
+	* .gitignore, README, bootstrap.sh, configure.ac: attempt to
+	simplify configuration for ICU
+
+2017-05-04  Ko van der Sloot <K.vanderSloot at let.ru.nl>
+
+	* include/libfolia/folia_document.h, src/folia_document.cxx: text
+	checking can now also be disabled using the environment variable
+	FOLIA_TEXT_CHECK (=NO)
+
+2017-05-04  Ko van der Sloot <K.vanderSloot at let.ru.nl>
+
+	* src/folia_document.cxx, src/folialint.cxx: CHECKTEXT is the
+	default mode now. But text checking is not complete still
+
+2017-04-24  Ko van der Sloot <K.vanderSloot at let.ru.nl>
+
+	* docs/folialint.1: added a man page for folialint
+
+2017-04-24  Ko van der Sloot <K.vanderSloot at let.ru.nl>
+
+	* src/folia_document.cxx: avoid nesting of XmlError exception
+
+2017-04-24  Ko van der Sloot <K.vanderSloot at let.ru.nl>
+
+	* src/folia_impl.cxx: removed debugline
+
+2017-04-23  Ko van der Sloot <K.vanderSloot at let.ru.nl>
+
+	* src/folialint.cxx: checktext is the default now. use --nochecktext
+	to disable
+
+2017-04-20  Ko van der Sloot <K.vanderSloot at let.ru.nl>
+
+	* src/folia_impl.cxx: exclude text checking for Phonemes and
+	Morphemes everywhere
+
+2017-04-20  Ko van der Sloot <K.vanderSloot at let.ru.nl>
+
+	* src/folia_document.cxx: For now NO text checking is de default
+	still
+
+2017-04-20  Ko van der Sloot <K.vanderSloot at let.ru.nl>
+
+	* src/folia_document.cxx, src/folia_impl.cxx: no text checking on
+	Morphemes and Phonemes
+
+2017-04-20  Ko van der Sloot <K.vanderSloot at let.ru.nl>
+
+	* src/folia_impl.cxx: add text checking possibility in settext()
+	functions
+
+2017-04-13  Ko van der Sloot <K.vanderSloot at let.ru.nl>
+
+	* src/folia_document.cxx: oeps. accidently we stripped datatime
+	info...
+
+2017-04-13  Ko van der Sloot <K.vanderSloot at let.ru.nl>
+
+	* include/libfolia/folia_document.h: made enum Mode local in
+	Document
+
+2017-04-13  Ko van der Sloot <K.vanderSloot at let.ru.nl>
+
+	* src/folialint.cxx: don't exit when 1 file in a series fails
+
+2017-04-13  Ko van der Sloot <K.vanderSloot at let.ru.nl>
+
+	* src/folia_impl.cxx: removed yads (yet another debug statement)
+
+2017-04-13  Ko van der Sloot <K.vanderSloot at let.ru.nl>
+
+	* include/libfolia/folia_document.h, src/folia_impl.cxx,
+	src/folialint.cxx: [document] fixed mode handling. removed dbuglines
+	[folialint] fixed mode handling.
+
+2017-04-13  Ko van der Sloot <K.vanderSloot at let.ru.nl>
+
+	* src/folia_impl.cxx: again fixed text for Correction. hart to hit
+	moving target
+
+2017-04-13  Ko van der Sloot <K.vanderSloot at let.ru.nl>
+
+	* include/libfolia/folia_document.h, src/folia_document.cxx,
+	src/folia_impl.cxx, src/folialint.cxx: added conditonal
+	textchecking. new --checktext option for folialint
+
+2017-04-12  Ko van der Sloot <K.vanderSloot at let.ru.nl>
+
+	* include/libfolia/folia_impl.h, src/folia_impl.cxx: fixt text()
+	retrieval for Correction
+
+2017-04-11  Ko van der Sloot <K.vanderSloot at let.ru.nl>
+
+	* src/folia_impl.cxx: added (unused) test checking code
+
+2017-04-11  Ko van der Sloot <K.vanderSloot at let.ru.nl>
+
+	* src/folia_impl.cxx: restrict deeptext() search to Structure, Span
+	and Correction
+
+2017-04-04  Ko van der Sloot <K.vanderSloot at let.ru.nl>
+
+	* .travis.yml: en nogmaals
+
+2017-04-04  Ko van der Sloot <K.vanderSloot at let.ru.nl>
+
+	* .travis.yml: goffer, waarom geeft travis WebLint geen duidelijke
+	melding
+
+2017-04-04  Ko van der Sloot <K.vanderSloot at let.ru.nl>
+
+	* .travis.yml: don't install gcc4.9, stich with the default
+
+2017-04-04  Ko van der Sloot <K.vanderSloot at let.ru.nl>
+
+	* configure.ac: bumped version after release
+
+2017-04-04  Ko van der Sloot <K.vanderSloot at let.ru.nl>
+
+	* NEWS: more NEWS
+
+2017-04-04  Ko van der Sloot <K.vanderSloot at let.ru.nl>
+
+	* src/Makefile.am: bumped library revision, because some functions
+	have a changed signature
+
+2017-04-04  Ko van der Sloot <K.vanderSloot at let.ru.nl>
+
+	* NEWS: NEWS for the release
+
+2017-04-04  Ko van der Sloot <K.vanderSloot at let.ru.nl>
+
+	* configure.ac: set version number for release
+
+2017-04-03  Ko van der Sloot <K.vanderSloot at let.ru.nl>
+
+	* include/libfolia/folia_impl.h, src/folia_impl.cxx: changed
+	textcontent() and phoncontent() to return a 'const' pointer.
+
+2017-04-03  Ko van der Sloot <K.vanderSloot at let.ru.nl>
+
+	* src/folia_impl.cxx: textcontent::textcontent() now returns the
+	node itself or Throws when the cls mismatches
+
+2017-03-28  Maarten van Gompel <proycon at anaproy.nl>
+
+	* src/folia_document.cxx: fix typo
+
+2017-03-28  Maarten van Gompel <proycon at anaproy.nl>
+
+	* src/folia_properties.cxx: regenerated foliaspec to solve #14
+
+2017-03-28  Maarten van Gompel <proycon at anaproy.nl>
+
+	* src/folia_properties.cxx: Regenerated from foliaspec (FoLiA
+	1.4.1), should hopefully solve #13 and #14
+
+2017-02-20  Ko van der Sloot <K.vanderSloot at let.ru.nl>
+
+	* : commit 49916aa4f9cbb032186c2a71da9297f62ea27ba1 Author: Ko van
+	der Sloot <K.vanderSloot at let.ru.nl> Date:   Mon Feb 20 17:45:17 2017
+	+0100
+
+2017-02-16  Ko van der Sloot <K.vanderSloot at let.ru.nl>
+
+	* include/libfolia/folia_impl.h, src/folia_impl.cxx: added a
+	(dangerous!) function to set the TexContent class to 'current'
+
+2017-02-16  Ko van der Sloot <K.vanderSloot at let.ru.nl>
+
+	* src/folialint.cxx: added more usage()
+
+2017-02-15  Ko van der Sloot <K.vanderSloot at let.ru.nl>
+
+	* src/folia_document.cxx, src/folia_impl.cxx: some fixes in
+	annotation ref counting
+
+2017-02-14  Ko van der Sloot <K.vanderSloot at let.ru.nl>
+
+	* src/folia_document.cxx, src/folia_impl.cxx: attempt to fix ref
+	counting of annotation-types
+
+2017-02-14  Ko van der Sloot <K.vanderSloot at let.ru.nl>
+
+	* include/libfolia/folia_document.h, src/folia_document.cxx,
+	src/folia_impl.cxx: added reference counting for annotation set
+	useage. Prvent un_declare from invalidating actions
+
+2017-02-14  Ko van der Sloot <K.vanderSloot at let.ru.nl>
+
+	* include/libfolia/folia_document.h, src/folia_document.cxx: added
+	an un_declare function to remove annotation declarations. Dangerous
+	te uses! Work in Progress
+
+2017-02-13  Ko van der Sloot <K.vanderSloot at let.ru.nl>
+
+	* src/folia_impl.cxx: small fix. str() should never throw
+
+2017-01-25  Ko van der Sloot <K.vanderSloot at let.ru.nl>
+
+	* src/folia_impl.cxx, src/folia_utils.cxx: some refactoring: avoid
+	memeory leak and fixed a small bug
+
+2017-01-24  Ko van der Sloot <K.vanderSloot at let.ru.nl>
+
+	* include/libfolia/folia_document.h, include/libfolia/folia_impl.h,
+	include/libfolia/folia_utils.h, src/Makefile.am: some more
+	refactoring to satisfy static checking
+
+2017-01-23  Ko van der Sloot <K.vanderSloot at let.ru.nl>
+
+	* .travis.yml: force Travis to use trusty
+
+2017-01-19  Ko van der Sloot <K.vanderSloot at let.ru.nl>
+
+	* src/folia_impl.cxx, src/folia_utils.cxx: some refactoring
+	triggered by CPPCHECK
+
+2017-01-06  Ko van der Sloot <K.vanderSloot at let.ru.nl>
+
+	* include/libfolia/folia_impl.h, src/folia_impl.cxx: start using the
+	new TEXTCONTAINER property
+
+2017-01-06  Ko van der Sloot <K.vanderSloot at let.ru.nl>
+
+	* src/folia_document.cxx, src/folia_impl.cxx: fixed some typos
+
+2017-01-05  Ko van der Sloot <K.vanderSloot at let.ru.nl>
+
+	* NEWS: typo and date error fixed. not worth releleasing...
+
+2017-01-05  Ko van der Sloot <K.vanderSloot at let.ru.nl>
+
+	* configure.ac: bumped version after release
+
 2017-01-05  Ko van der Sloot <K.vanderSloot at let.ru.nl>
 
 	* NEWS: updated news for upcoming release
@@ -1079,7 +1759,7 @@
 
 2016-02-17  Maarten van Gompel <proycon at anaproy.nl>
 
-	* README, README.md, bootstrap.sh: Converted README to markdown,
+	* README => README.md, bootstrap.sh: Converted README to markdown,
 	added lamabadge and travis badge
 
 2016-02-17  Maarten van Gompel <proycon at anaproy.nl>
@@ -1170,25 +1850,24 @@
 
 2016-02-02  Ko van der Sloot <K.vanderSloot at let.ru.nl>
 
-	* include/libfolia/Makefile.am, include/libfolia/document.h,
-	include/libfolia/folia_document.h, include/libfolia/folia_impl.h,
-	include/libfolia/folia_properties.h,
-	include/libfolia/folia_types.h, include/libfolia/folia_utils.h,
-	include/libfolia/foliaproperties.h, include/libfolia/foliatypes.h,
-	include/libfolia/foliautils.h, src/Makefile.am, src/document.cxx,
-	src/folia.cxx, src/folia_document.cxx, src/folia_impl.cxx,
-	src/folia_properties.cxx, src/folia_types.cxx, src/folia_utils.cxx,
-	src/foliaproperties.cxx, src/foliatypes.cxx, src/foliautils.cxx: 
-	cleanup, renaming etc will shake the tree!
+	* include/libfolia/Makefile.am, include/libfolia/{document.h =>
+	folia_document.h}, include/libfolia/folia_impl.h,
+	include/libfolia/{foliaproperties.h => folia_properties.h},
+	include/libfolia/{foliatypes.h => folia_types.h},
+	include/libfolia/{foliautils.h => folia_utils.h}, src/Makefile.am,
+	src/{document.cxx => folia_document.cxx}, src/{folia.cxx =>
+	folia_impl.cxx}, src/{foliaproperties.cxx => folia_properties.cxx},
+	src/{foliatypes.cxx => folia_types.cxx}, src/{foliautils.cxx =>
+	folia_utils.cxx}: cleanup, renaming etc will shake the tree!
 
 2016-02-02  Ko van der Sloot <K.vanderSloot at let.ru.nl>
 
 	* include/libfolia/Makefile.am, include/libfolia/document.h,
-	include/libfolia/folia.h, include/libfolia/folia_impl.h,
-	src/document.cxx, src/folia.cxx, src/folialint.cxx,
-	src/foliaproperties.cxx, src/foliatypes.cxx, src/foliautils.cxx,
-	src/simpletest.cxx: reshufle headers.  We wil provide a unified
-	"folia.h" header for external usage in the future.
+	include/libfolia/{folia.h => folia_impl.h}, src/document.cxx,
+	src/folia.cxx, src/folialint.cxx, src/foliaproperties.cxx,
+	src/foliatypes.cxx, src/foliautils.cxx, src/simpletest.cxx: reshufle
+	headers.  We wil provide a unified "folia.h" header for external
+	usage in the future.
 
 2016-02-01  Ko van der Sloot <K.vanderSloot at let.ru.nl>
 
@@ -1197,11 +1876,11 @@
 
 2016-02-01  Ko van der Sloot <K.vanderSloot at let.ru.nl>
 
-	* include/libfolia/Makefile.am, include/libfolia/foliaproperties.h,
-	include/libfolia/foliatypes.h, include/libfolia/foliautils.h,
-	include/libfolia/properties.h, src/Makefile.am, src/document.cxx,
-	src/folia.cxx, src/folia_properties.cxx, src/folialint.cxx,
-	src/foliaproperties.cxx, src/foliatypes.cxx, src/foliautils.cxx,
+	* include/libfolia/Makefile.am, include/libfolia/{properties.h =>
+	foliaproperties.h}, include/libfolia/foliatypes.h,
+	include/libfolia/foliautils.h, src/Makefile.am, src/document.cxx,
+	src/folia.cxx, src/folialint.cxx, src/{folia_properties.cxx =>
+	foliaproperties.cxx}, src/foliatypes.cxx, src/foliautils.cxx,
 	src/simpletest.cxx: some code reshuffling folia.cxx is still very
 	large
 
@@ -2099,7 +2778,7 @@
 
 2013-10-17  sloot <sloot at 12f355fe-0486-481a-ad91-c297ab22b4e3>
 
-	* bootstrap, bootstrap.sh, config.h.in, configure.ac: modernized git-svn-id: https://ilk.uvt.nl/svn/sources/libfolia/trunk@16613
+	* bootstrap => bootstrap.sh, config.h.in, configure.ac: modernized git-svn-id: https://ilk.uvt.nl/svn/sources/libfolia/trunk@16613
 	12f355fe-0486-481a-ad91-c297ab22b4e3
 
 2013-10-15  sloot <sloot at 12f355fe-0486-481a-ad91-c297ab22b4e3>
@@ -2365,14 +3044,12 @@
 
 2013-04-03  sloot <sloot at 12f355fe-0486-481a-ad91-c297ab22b4e3>
 
-	* configure.ac, include/folia/Makefile.am,
-	include/folia/document.h, include/folia/folia.h,
-	include/folia/foliautils.h, include/libfolia/Makefile.am,
-	include/libfolia/document.h, include/libfolia/folia.h,
-	include/libfolia/folia/Makefile.am,
+	* configure.ac, include/{folia => libfolia}/Makefile.am,
+	include/{folia => libfolia}/document.h, include/{folia =>
+	libfolia}/folia.h, include/libfolia/folia/Makefile.am,
 	include/libfolia/folia/document.h, include/libfolia/folia/folia.h,
-	include/libfolia/folia/foliautils.h, include/libfolia/foliautils.h: 
-	rename dir git-svn-id: https://ilk.uvt.nl/svn/sources/libfolia/trunk@15907
+	include/{ => libfolia}/folia/foliautils.h,
+	include/libfolia/foliautils.h: rename dir git-svn-id: https://ilk.uvt.nl/svn/sources/libfolia/trunk@15907
 	12f355fe-0486-481a-ad91-c297ab22b4e3
 
 2013-04-03  sloot <sloot at 12f355fe-0486-481a-ad91-c297ab22b4e3>
diff --git a/Makefile.in b/Makefile.in
index 6a69083..dbf575c 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -90,11 +90,11 @@ build_triplet = @build@
 host_triplet = @host@
 subdir = .
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
-am__aclocal_m4_deps = $(top_srcdir)/m4/ax_icu_check.m4 \
-	$(top_srcdir)/m4/ax_pthread.m4 $(top_srcdir)/m4/libtool.m4 \
-	$(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
-	$(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
-	$(top_srcdir)/m4/pkg.m4 $(top_srcdir)/configure.ac
+am__aclocal_m4_deps = $(top_srcdir)/m4/ax_pthread.m4 \
+	$(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
+	$(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
+	$(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/pkg.m4 \
+	$(top_srcdir)/configure.ac
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
 	$(ACLOCAL_M4)
 DIST_COMMON = $(srcdir)/Makefile.am $(top_srcdir)/configure \
@@ -268,13 +268,7 @@ EXEEXT = @EXEEXT@
 FGREP = @FGREP@
 GREP = @GREP@
 ICU_CFLAGS = @ICU_CFLAGS@
-ICU_CONFIG = @ICU_CONFIG@
-ICU_CPPSEARCHPATH = @ICU_CPPSEARCHPATH@
-ICU_CXXFLAGS = @ICU_CXXFLAGS@
-ICU_IOLIBS = @ICU_IOLIBS@
-ICU_LIBPATH = @ICU_LIBPATH@
 ICU_LIBS = @ICU_LIBS@
-ICU_VERSION = @ICU_VERSION@
 INSTALL = @INSTALL@
 INSTALL_DATA = @INSTALL_DATA@
 INSTALL_PROGRAM = @INSTALL_PROGRAM@
diff --git a/NEWS b/NEWS
index 6bbbada..e9e71a0 100644
--- a/NEWS
+++ b/NEWS
@@ -1,9 +1,59 @@
-1.6  2016-01-05
+1.10 2017-10-17
+Major Release, implementing FoLiA spec 1.5
+* added text checking for all 1.5 documents and up
+* added offset and ref checking for Text in all 1.5 documents and up
+* 'empty' text inside TextContent, PhonContent and Textmarkup is significamt
+* better version checking
+* text checking can be dis/enabled using FOLIA_TEXT_CHECK environment variable
+* added submetadata mechanism
+* implemented aliasses for annotation setnames
+* added an xmlstring() serializer for Document
+* bug fixes:
+  - in LineBreak serializing
+  - XmlComment is textless.
+  - miscelaneous small fixes
+
+1.9  2017-08-30
+Bug fix release
+* accept ICU 50 too (was 52) to make CentOS happy
+* XmlComment INSIDE <t> lead to crashes. fixed.
+* code changes in code that is only executed for documents in folia 1.5 format
+  (that shouldn't exist in the wild)
+
+1.8  2017-00-16
+Implements FoLiA spec 1.4.3
+* adding textclass attribute
+API changed. Bumped library version to 6.2.0
+[Ko van der Sloot]
+* added experimental textchecking code. only working for FoLiA documents
+  according to spec 1.5. NOT RELEASED YET!
+  Work in Progress
+* fix in generate_id. AUTO_GENERATE_ID property was ignored.
+* numereous bug fixes
+
+1.7  2017-04-04
+API changed so bumped library version to 6.1.0
+[Ko van der Sloot]
+* textcontent() and phoncontent() return const pointers, and also
+  work for TexContent adn PhonContent elements now
+* some reactoring, as suggested by CPPCHECK
+* typos
+* added dangerous functions to manipulate the class of a TextContent
+* added reference countion on annotations.
+  This allows to remove unneeded declarations.
+* small bug fixes:
+  - str() should never throw.
+  - avoid memory leak
+
+[maarten van Gompel]
+* fixes in folia_properties for FoliA spec 1.4.1
+
+1.6  2017-01-05
 * We now implement FoLiA spec 1.4
 * ABI breakage. .so name bumped to 6.0.0
   reason:
   - new properties added
-  - implementation of generateId() is chaneged
+  - implementation of generateId() is changed
 * enhancements to folialint. Saving a document with --strip also
   implies canonical output
 * some bug fixes
diff --git a/README b/README
index 6929b3b..cc698a6 100644
--- a/README
+++ b/README
@@ -1,94 +1 @@
-[![Build Status](https://travis-ci.org/LanguageMachines/libfolia.svg?branch=master)](https://travis-ci.org/LanguageMachines/libfolia) [![Language Machines Badge](http://applejack.science.ru.nl/lamabadge.php/ticcutils)](http://applejack.science.ru.nl/languagemachines/) 
-
-===================================
-Libfolia: FoLiA Library for C++
-===================================
-
-    Libfolia (c) CLS/ILK 2010 - 2017
-    Centre for Language Studies, Radboud University Nijmegen
-    Induction of Linguistic Knowledge Research Group, Tilburg University
-
-**Website:** https://proycon.github.io/folia/
-**Source repository:** https://LanguageMachines.github.io/libfolia
-**Contact**: lamasoftware AT science DOT ru DOT nl
-
-This is a C++ Library, developed by Ko van der Sloot, for working with the
-[Format for Linguistic Annotation (FoLiA)](https://proycon.github.io/folia/).
-The software is intended for C++ developers, and provides a high-level
-API to read, manipulate, and create FoLiA documents. This software is a
-necessary dependency for various other tools that use FoLiA.
-
-libfolia is distributed under the GNU Public Licence v3 (see the file COPYING).
-
------------------------------------------------------------------------
-Installation
------------------------------------------------------------------------
-
-This software has been tested to compile with Gcc or Clang, and runs on the
-following platforms:
-- Intel platforms running several versions of Linux, including Ubuntu, Debian,
-  Arch Linux, Fedora (both 32 and 64 bits)
-- MacOS X 10.10 or higher, FreeBSD
-
-*Contents of this distribution:*
-- Sources
-- Licensing information ( COPYING )
-- Build system based on GNU Autotools
-
-*Dependencies:*
-
-To be able to succesfully build libfolia from source, you need the following dependencies:
-- [ticcutils](https://github.com/LanguageMachines/ticcutils)
-- ``libxml2-dev`` (use your distribution's package manager)
-- ``libicu-dev``
-- A sane C++ build environment with autoconf, automake, autoconf-archive, make, gcc or clang, libtool, pkg-config
-
-To install libfolia, *first consult whether your distribution's package manager
-has an up-to-date package for it*.  If not, for easy installation of libfolia
-and all dependencies, it is included as part of our software distribution
-LaMachine: https://proycon.github.io/LaMachine .
-
-To compile and install manually from source, provided you have all the
-dependencies installed:
-
-    $ bash bootstrap.sh
-    $ ./configure
-    $ make
-    $ make install
-
-and, optionally:
-    $ make check
-
------------------------------------------------------------------------
-Documentation
------------------------------------------------------------------------
-
-An API reference or tutorial is currently lacking. Contact us if you're
-intending to use libfolia and are in need of documentation.
-
------------------------------------------------------------------------
-Related software
------------------------------------------------------------------------
-
-
-This software is developed in parallel to the FoLiA library for Python (part of
-[PyNLPl](https://github.com/proycon/pynlpl)), and draws from the same external specification.
-
-Libfolia is used by various in-house projects:
- * [ucto](https://LanguageMachines.github.io/ucto)
- * [frog](https://LanguageMachines.github.io/frog)
- * [foliautils](https://github.com/LanguageMachines/foliautils)
- * [colibri-core](https://proycon.github.io/colibri-core)
- * [wopr](https://github.com/LanguageMachines/wopr)
-
-Libfolia is tested (unit and integration tests) using the following extensive test suite:
- * [foliatest](https://github.com/LanguageMachines/foliatest)
-
-For more information on FoLiA itself, consult the [FoLiA website](https://proycon.github.io/folia/)
-
------------------------------------------------------------------------
-Acknowledgements
------------------------------------------------------------------------
-
-This software is funded in the scope of [CLARIAH](http:/www.clariah.nl)
-project.
+please see README.md
diff --git a/aclocal.m4 b/aclocal.m4
index 9c85851..fb73232 100644
--- a/aclocal.m4
+++ b/aclocal.m4
@@ -1150,7 +1150,6 @@ AC_SUBST([am__tar])
 AC_SUBST([am__untar])
 ]) # _AM_PROG_TAR
 
-m4_include([m4/ax_icu_check.m4])
 m4_include([m4/ax_pthread.m4])
 m4_include([m4/libtool.m4])
 m4_include([m4/ltoptions.m4])
diff --git a/bootstrap.sh b/bootstrap.sh
index 9d29508..4a85fb3 100644
--- a/bootstrap.sh
+++ b/bootstrap.sh
@@ -21,8 +21,6 @@
 automake=automake
 aclocal=aclocal
 
-ln -s README.md README
-
 # if you want to autogenerate a ChangeLog form svn:
 #
 #  svn2cl, a python script, as used in the GNU Enterprise project.
@@ -98,4 +96,3 @@ AUTOMAKE=automake ACLOCAL=aclocal autoreconf --install \
 # aclocal-1.9 \
 #     && automake-1.9 --add-missing --verbose --gnu \
 #     && autoconf
-
diff --git a/config.guess b/config.guess
index 1659250..2e9ad7f 100755
--- a/config.guess
+++ b/config.guess
@@ -1,8 +1,8 @@
 #! /bin/sh
 # Attempt to guess a canonical system name.
-#   Copyright 1992-2015 Free Software Foundation, Inc.
+#   Copyright 1992-2016 Free Software Foundation, Inc.
 
-timestamp='2015-08-20'
+timestamp='2016-10-02'
 
 # This file is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License as published by
@@ -27,7 +27,7 @@ timestamp='2015-08-20'
 # Originally written by Per Bothner; maintained since 2000 by Ben Elliston.
 #
 # You can get the latest version of this script from:
-# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD
+# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess
 #
 # Please send patches to <config-patches at gnu.org>.
 
@@ -50,7 +50,7 @@ version="\
 GNU config.guess ($timestamp)
 
 Originally written by Per Bothner.
-Copyright 1992-2015 Free Software Foundation, Inc.
+Copyright 1992-2016 Free Software Foundation, Inc.
 
 This is free software; see the source for copying conditions.  There is NO
 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
@@ -186,9 +186,12 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
 	    *) machine=${UNAME_MACHINE_ARCH}-unknown ;;
 	esac
 	# The Operating System including object format, if it has switched
-	# to ELF recently, or will in the future.
+	# to ELF recently (or will in the future) and ABI.
 	case "${UNAME_MACHINE_ARCH}" in
-	    arm*|earm*|i386|m68k|ns32k|sh3*|sparc|vax)
+	    earm*)
+		os=netbsdelf
+		;;
+	    arm*|i386|m68k|ns32k|sh3*|sparc|vax)
 		eval $set_cc_for_build
 		if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \
 			| grep -q __ELF__
@@ -237,6 +240,10 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
 	UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'`
 	echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE}
 	exit ;;
+    *:LibertyBSD:*:*)
+	UNAME_MACHINE_ARCH=`arch | sed 's/^.*BSD\.//'`
+	echo ${UNAME_MACHINE_ARCH}-unknown-libertybsd${UNAME_RELEASE}
+	exit ;;
     *:ekkoBSD:*:*)
 	echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE}
 	exit ;;
@@ -268,42 +275,42 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
 	ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^  The alpha \(.*\) processor.*$/\1/p' | head -n 1`
 	case "$ALPHA_CPU_TYPE" in
 	    "EV4 (21064)")
-		UNAME_MACHINE="alpha" ;;
+		UNAME_MACHINE=alpha ;;
 	    "EV4.5 (21064)")
-		UNAME_MACHINE="alpha" ;;
+		UNAME_MACHINE=alpha ;;
 	    "LCA4 (21066/21068)")
-		UNAME_MACHINE="alpha" ;;
+		UNAME_MACHINE=alpha ;;
 	    "EV5 (21164)")
-		UNAME_MACHINE="alphaev5" ;;
+		UNAME_MACHINE=alphaev5 ;;
 	    "EV5.6 (21164A)")
-		UNAME_MACHINE="alphaev56" ;;
+		UNAME_MACHINE=alphaev56 ;;
 	    "EV5.6 (21164PC)")
-		UNAME_MACHINE="alphapca56" ;;
+		UNAME_MACHINE=alphapca56 ;;
 	    "EV5.7 (21164PC)")
-		UNAME_MACHINE="alphapca57" ;;
+		UNAME_MACHINE=alphapca57 ;;
 	    "EV6 (21264)")
-		UNAME_MACHINE="alphaev6" ;;
+		UNAME_MACHINE=alphaev6 ;;
 	    "EV6.7 (21264A)")
-		UNAME_MACHINE="alphaev67" ;;
+		UNAME_MACHINE=alphaev67 ;;
 	    "EV6.8CB (21264C)")
-		UNAME_MACHINE="alphaev68" ;;
+		UNAME_MACHINE=alphaev68 ;;
 	    "EV6.8AL (21264B)")
-		UNAME_MACHINE="alphaev68" ;;
+		UNAME_MACHINE=alphaev68 ;;
 	    "EV6.8CX (21264D)")
-		UNAME_MACHINE="alphaev68" ;;
+		UNAME_MACHINE=alphaev68 ;;
 	    "EV6.9A (21264/EV69A)")
-		UNAME_MACHINE="alphaev69" ;;
+		UNAME_MACHINE=alphaev69 ;;
 	    "EV7 (21364)")
-		UNAME_MACHINE="alphaev7" ;;
+		UNAME_MACHINE=alphaev7 ;;
 	    "EV7.9 (21364A)")
-		UNAME_MACHINE="alphaev79" ;;
+		UNAME_MACHINE=alphaev79 ;;
 	esac
 	# A Pn.n version is a patched version.
 	# A Vn.n version is a released version.
 	# A Tn.n version is a released field test version.
 	# A Xn.n version is an unreleased experimental baselevel.
 	# 1.2 uses "1.2" for uname -r.
-	echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+	echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz`
 	# Reset EXIT trap before exiting to avoid spurious non-zero exit code.
 	exitcode=$?
 	trap '' 0
@@ -376,16 +383,16 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
 	exit ;;
     i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*)
 	eval $set_cc_for_build
-	SUN_ARCH="i386"
+	SUN_ARCH=i386
 	# If there is a compiler, see if it is configured for 64-bit objects.
 	# Note that the Sun cc does not turn __LP64__ into 1 like gcc does.
 	# This test works for both compilers.
-	if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then
+	if [ "$CC_FOR_BUILD" != no_compiler_found ]; then
 	    if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \
-		(CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \
+		(CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \
 		grep IS_64BIT_ARCH >/dev/null
 	    then
-		SUN_ARCH="x86_64"
+		SUN_ARCH=x86_64
 	    fi
 	fi
 	echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
@@ -410,7 +417,7 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
 	exit ;;
     sun*:*:4.2BSD:*)
 	UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null`
-	test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3
+	test "x${UNAME_RELEASE}" = x && UNAME_RELEASE=3
 	case "`/bin/arch`" in
 	    sun3)
 		echo m68k-sun-sunos${UNAME_RELEASE}
@@ -635,13 +642,13 @@ EOF
 		    sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null`
 		    sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`
 		    case "${sc_cpu_version}" in
-		      523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0
-		      528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1
+		      523) HP_ARCH=hppa1.0 ;; # CPU_PA_RISC1_0
+		      528) HP_ARCH=hppa1.1 ;; # CPU_PA_RISC1_1
 		      532)                      # CPU_PA_RISC2_0
 			case "${sc_kernel_bits}" in
-			  32) HP_ARCH="hppa2.0n" ;;
-			  64) HP_ARCH="hppa2.0w" ;;
-			  '') HP_ARCH="hppa2.0" ;;   # HP-UX 10.20
+			  32) HP_ARCH=hppa2.0n ;;
+			  64) HP_ARCH=hppa2.0w ;;
+			  '') HP_ARCH=hppa2.0 ;;   # HP-UX 10.20
 			esac ;;
 		    esac
 		fi
@@ -680,11 +687,11 @@ EOF
 		    exit (0);
 		}
 EOF
-		    (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy`
+		    (CCOPTS="" $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy`
 		    test -z "$HP_ARCH" && HP_ARCH=hppa
 		fi ;;
 	esac
-	if [ ${HP_ARCH} = "hppa2.0w" ]
+	if [ ${HP_ARCH} = hppa2.0w ]
 	then
 	    eval $set_cc_for_build
 
@@ -697,12 +704,12 @@ EOF
 	    # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess
 	    # => hppa64-hp-hpux11.23
 
-	    if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) |
+	    if echo __LP64__ | (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) |
 		grep -q __LP64__
 	    then
-		HP_ARCH="hppa2.0w"
+		HP_ARCH=hppa2.0w
 	    else
-		HP_ARCH="hppa64"
+		HP_ARCH=hppa64
 	    fi
 	fi
 	echo ${HP_ARCH}-hp-hpux${HPUX_REV}
@@ -807,14 +814,14 @@ EOF
 	echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
 	exit ;;
     F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*)
-	FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
-	FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
+	FUJITSU_PROC=`uname -m | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz`
+	FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'`
 	FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
 	echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
 	exit ;;
     5000:UNIX_System_V:4.*:*)
-	FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
-	FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'`
+	FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'`
+	FUJITSU_REL=`echo ${UNAME_RELEASE} | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/ /_/'`
 	echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
 	exit ;;
     i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*)
@@ -896,7 +903,7 @@ EOF
 	exit ;;
     *:GNU/*:*:*)
 	# other systems with GNU libc and userland
-	echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-${LIBC}
+	echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr "[:upper:]" "[:lower:]"``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-${LIBC}
 	exit ;;
     i*86:Minix:*:*)
 	echo ${UNAME_MACHINE}-pc-minix
@@ -919,7 +926,7 @@ EOF
 	  EV68*) UNAME_MACHINE=alphaev68 ;;
 	esac
 	objdump --private-headers /bin/sh | grep -q ld.so.1
-	if test "$?" = 0 ; then LIBC="gnulibc1" ; fi
+	if test "$?" = 0 ; then LIBC=gnulibc1 ; fi
 	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
 	exit ;;
     arc:Linux:*:* | arceb:Linux:*:*)
@@ -965,6 +972,9 @@ EOF
     ia64:Linux:*:*)
 	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
 	exit ;;
+    k1om:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+	exit ;;
     m32r*:Linux:*:*)
 	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
 	exit ;;
@@ -990,6 +1000,9 @@ EOF
 	eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'`
 	test x"${CPU}" != x && { echo "${CPU}-unknown-linux-${LIBC}"; exit; }
 	;;
+    mips64el:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+	exit ;;
     openrisc*:Linux:*:*)
 	echo or1k-unknown-linux-${LIBC}
 	exit ;;
@@ -1022,6 +1035,9 @@ EOF
     ppcle:Linux:*:*)
 	echo powerpcle-unknown-linux-${LIBC}
 	exit ;;
+    riscv32:Linux:*:* | riscv64:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+	exit ;;
     s390:Linux:*:* | s390x:Linux:*:*)
 	echo ${UNAME_MACHINE}-ibm-linux-${LIBC}
 	exit ;;
@@ -1120,7 +1136,7 @@ EOF
 	# uname -m prints for DJGPP always 'pc', but it prints nothing about
 	# the processor, so we play safe by assuming i586.
 	# Note: whatever this is, it MUST be the same as what config.sub
-	# prints for the "djgpp" host, or else GDB configury will decide that
+	# prints for the "djgpp" host, or else GDB configure will decide that
 	# this is a cross-build.
 	echo i586-pc-msdosdjgpp
 	exit ;;
@@ -1269,6 +1285,9 @@ EOF
     SX-8R:SUPER-UX:*:*)
 	echo sx8r-nec-superux${UNAME_RELEASE}
 	exit ;;
+    SX-ACE:SUPER-UX:*:*)
+	echo sxace-nec-superux${UNAME_RELEASE}
+	exit ;;
     Power*:Rhapsody:*:*)
 	echo powerpc-apple-rhapsody${UNAME_RELEASE}
 	exit ;;
@@ -1282,9 +1301,9 @@ EOF
 	    UNAME_PROCESSOR=powerpc
 	fi
 	if test `echo "$UNAME_RELEASE" | sed -e 's/\..*//'` -le 10 ; then
-	    if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then
+	    if [ "$CC_FOR_BUILD" != no_compiler_found ]; then
 		if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \
-		    (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \
+		    (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \
 		    grep IS_64BIT_ARCH >/dev/null
 		then
 		    case $UNAME_PROCESSOR in
@@ -1306,7 +1325,7 @@ EOF
 	exit ;;
     *:procnto*:*:* | *:QNX:[0123456789]*:*)
 	UNAME_PROCESSOR=`uname -p`
-	if test "$UNAME_PROCESSOR" = "x86"; then
+	if test "$UNAME_PROCESSOR" = x86; then
 		UNAME_PROCESSOR=i386
 		UNAME_MACHINE=pc
 	fi
@@ -1337,7 +1356,7 @@ EOF
 	# "uname -m" is not consistent, so use $cputype instead. 386
 	# is converted to i386 for consistency with other x86
 	# operating systems.
-	if test "$cputype" = "386"; then
+	if test "$cputype" = 386; then
 	    UNAME_MACHINE=i386
 	else
 	    UNAME_MACHINE="$cputype"
@@ -1379,7 +1398,7 @@ EOF
 	echo i386-pc-xenix
 	exit ;;
     i*86:skyos:*:*)
-	echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//'
+	echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE} | sed -e 's/ .*$//'`
 	exit ;;
     i*86:rdos:*:*)
 	echo ${UNAME_MACHINE}-pc-rdos
@@ -1390,23 +1409,25 @@ EOF
     x86_64:VMkernel:*:*)
 	echo ${UNAME_MACHINE}-unknown-esx
 	exit ;;
+    amd64:Isilon\ OneFS:*:*)
+	echo x86_64-unknown-onefs
+	exit ;;
 esac
 
 cat >&2 <<EOF
 $0: unable to guess system type
 
-This script, last modified $timestamp, has failed to recognize
-the operating system you are using. It is advised that you
-download the most up to date version of the config scripts from
+This script (version $timestamp), has failed to recognize the
+operating system you are using. If your script is old, overwrite
+config.guess and config.sub with the latest versions from:
 
-  http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD
+  http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess
 and
-  http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD
+  http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub
 
-If the version you run ($0) is already up to date, please
-send the following data and any information you think might be
-pertinent to <config-patches at gnu.org> in order to provide the needed
-information to handle your system.
+If $0 has already been updated, send the following data and any
+information you think might be pertinent to config-patches at gnu.org to
+provide the necessary information to handle your system.
 
 config.guess timestamp = $timestamp
 
diff --git a/config.h.in b/config.h.in
index 209b3c7..214ce6d 100644
--- a/config.h.in
+++ b/config.h.in
@@ -3,9 +3,6 @@
 /* Define to 1 if you have the <dlfcn.h> header file. */
 #undef HAVE_DLFCN_H
 
-/* we want to use ICU */
-#undef HAVE_ICU
-
 /* Define to 1 if you have the <inttypes.h> header file. */
 #undef HAVE_INTTYPES_H
 
diff --git a/config.sub b/config.sub
index 1acc966..dd2ca93 100755
--- a/config.sub
+++ b/config.sub
@@ -1,8 +1,8 @@
 #! /bin/sh
 # Configuration validation subroutine script.
-#   Copyright 1992-2015 Free Software Foundation, Inc.
+#   Copyright 1992-2016 Free Software Foundation, Inc.
 
-timestamp='2015-08-20'
+timestamp='2016-11-04'
 
 # This file is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License as published by
@@ -33,7 +33,7 @@ timestamp='2015-08-20'
 # Otherwise, we print the canonical config type on stdout and succeed.
 
 # You can get the latest version of this script from:
-# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD
+# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub
 
 # This file is supposed to be the same for all GNU packages
 # and recognize all the CPU types, system types and aliases
@@ -53,8 +53,7 @@ timestamp='2015-08-20'
 me=`echo "$0" | sed -e 's,.*/,,'`
 
 usage="\
-Usage: $0 [OPTION] CPU-MFR-OPSYS
-       $0 [OPTION] ALIAS
+Usage: $0 [OPTION] CPU-MFR-OPSYS or ALIAS
 
 Canonicalize a configuration name.
 
@@ -68,7 +67,7 @@ Report bugs and patches to <config-patches at gnu.org>."
 version="\
 GNU config.sub ($timestamp)
 
-Copyright 1992-2015 Free Software Foundation, Inc.
+Copyright 1992-2016 Free Software Foundation, Inc.
 
 This is free software; see the source for copying conditions.  There is NO
 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
@@ -118,7 +117,7 @@ case $maybe_os in
   nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \
   linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \
   knetbsd*-gnu* | netbsd*-gnu* | netbsd*-eabi* | \
-  kopensolaris*-gnu* | \
+  kopensolaris*-gnu* | cloudabi*-eabi* | \
   storm-chaos* | os2-emx* | rtmk-nova*)
     os=-$maybe_os
     basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
@@ -302,6 +301,7 @@ case $basic_machine in
 	| open8 | or1k | or1knd | or32 \
 	| pdp10 | pdp11 | pj | pjl \
 	| powerpc | powerpc64 | powerpc64le | powerpcle \
+	| pru \
 	| pyramid \
 	| riscv32 | riscv64 \
 	| rl78 | rx \
@@ -429,6 +429,7 @@ case $basic_machine in
 	| orion-* \
 	| pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
 	| powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \
+	| pru-* \
 	| pyramid-* \
 	| riscv32-* | riscv64-* \
 	| rl78-* | romp-* | rs6000-* | rx-* \
@@ -521,7 +522,7 @@ case $basic_machine in
 		basic_machine=i386-pc
 		os=-aros
 		;;
-        asmjs)
+	asmjs)
 		basic_machine=asmjs-unknown
 		;;
 	aux)
@@ -644,6 +645,14 @@ case $basic_machine in
 		basic_machine=m68k-bull
 		os=-sysv3
 		;;
+	e500v[12])
+		basic_machine=powerpc-unknown
+		os=$os"spe"
+		;;
+	e500v[12]-*)
+		basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
+		os=$os"spe"
+		;;
 	ebmon29k)
 		basic_machine=a29k-amd
 		os=-ebmon
@@ -1023,7 +1032,7 @@ case $basic_machine in
 	ppc-* | ppcbe-*)
 		basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
 		;;
-	ppcle | powerpclittle | ppc-le | powerpc-little)
+	ppcle | powerpclittle)
 		basic_machine=powerpcle-unknown
 		;;
 	ppcle-* | powerpclittle-*)
@@ -1033,7 +1042,7 @@ case $basic_machine in
 		;;
 	ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'`
 		;;
-	ppc64le | powerpc64little | ppc64-le | powerpc64-little)
+	ppc64le | powerpc64little)
 		basic_machine=powerpc64le-unknown
 		;;
 	ppc64le-* | powerpc64little-*)
@@ -1383,14 +1392,14 @@ case $os in
 	      | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
 	      | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
 	      | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \
-	      | -bitrig* | -openbsd* | -solidbsd* \
+	      | -bitrig* | -openbsd* | -solidbsd* | -libertybsd* \
 	      | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \
 	      | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
 	      | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
 	      | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
 	      | -chorusos* | -chorusrdb* | -cegcc* \
 	      | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
-	      | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \
+	      | -midipix* | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \
 	      | -linux-newlib* | -linux-musl* | -linux-uclibc* \
 	      | -uxpv* | -beos* | -mpeix* | -udk* | -moxiebox* \
 	      | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
@@ -1399,7 +1408,8 @@ case $os in
 	      | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
 	      | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \
 	      | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \
-	      | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es* | -tirtos*)
+	      | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es* \
+	      | -onefs* | -tirtos* | -phoenix* | -fuchsia*)
 	# Remember, each alternative MUST END IN *, to match a version number.
 		;;
 	-qnx*)
@@ -1531,6 +1541,8 @@ case $os in
 		;;
 	-nacl*)
 		;;
+	-ios)
+		;;
 	-none)
 		;;
 	*)
diff --git a/configure b/configure
index 109f504..95139ce 100755
--- a/configure
+++ b/configure
@@ -1,6 +1,6 @@
 #! /bin/sh
 # Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.69 for libfolia 1.6.
+# Generated by GNU Autoconf 2.69 for libfolia 1.10.
 #
 # Report bugs to <lamasoftware at science.ru.nl>.
 #
@@ -590,8 +590,8 @@ MAKEFLAGS=
 # Identity of this package.
 PACKAGE_NAME='libfolia'
 PACKAGE_TARNAME='libfolia'
-PACKAGE_VERSION='1.6'
-PACKAGE_STRING='libfolia 1.6'
+PACKAGE_VERSION='1.10'
+PACKAGE_STRING='libfolia 1.10'
 PACKAGE_BUGREPORT='lamasoftware at science.ru.nl'
 PACKAGE_URL=''
 
@@ -636,16 +636,10 @@ ac_subst_vars='am__EXEEXT_FALSE
 am__EXEEXT_TRUE
 LTLIBOBJS
 LIBOBJS
-ticcutils_LIBS
-ticcutils_CFLAGS
-ICU_IOLIBS
 ICU_LIBS
-ICU_LIBPATH
-ICU_VERSION
-ICU_CPPSEARCHPATH
-ICU_CXXFLAGS
 ICU_CFLAGS
-ICU_CONFIG
+ticcutils_LIBS
+ticcutils_CFLAGS
 XML2_LIBS
 XML2_CFLAGS
 PKG_CONFIG_LIBDIR
@@ -790,7 +784,6 @@ with_gnu_ld
 with_sysroot
 enable_libtool_lock
 with_icu
-with_ticcutils
 '
       ac_precious_vars='build_alias
 host_alias
@@ -812,7 +805,9 @@ PKG_CONFIG_LIBDIR
 XML2_CFLAGS
 XML2_LIBS
 ticcutils_CFLAGS
-ticcutils_LIBS'
+ticcutils_LIBS
+ICU_CFLAGS
+ICU_LIBS'
 
 
 # Initialize some variables set by options.
@@ -1363,7 +1358,7 @@ if test "$ac_init_help" = "long"; then
   # Omit some internal or obsolete options to make the list less imposing.
   # This message is too long to be a string in the A/UX 3.1 sh.
   cat <<_ACEOF
-\`configure' configures libfolia 1.6 to adapt to many kinds of systems.
+\`configure' configures libfolia 1.10 to adapt to many kinds of systems.
 
 Usage: $0 [OPTION]... [VAR=VALUE]...
 
@@ -1434,7 +1429,7 @@ fi
 
 if test -n "$ac_init_help"; then
   case $ac_init_help in
-     short | recursive ) echo "Configuration of libfolia 1.6:";;
+     short | recursive ) echo "Configuration of libfolia 1.10:";;
    esac
   cat <<\_ACEOF
 
@@ -1465,10 +1460,7 @@ Optional Packages:
   --with-gnu-ld           assume the C compiler uses GNU ld [default=no]
   --with-sysroot[=DIR]    Search for dependent libraries within DIR (or the
                           compiler's sysroot if not specified).
-  --with-icu=DIR       use ICU installed in <DIR>
-  --with-ticcutils=DIR       use ticcutils installed in <DIR>;
-               note that you can install ticcutils in a non-default directory with
-               ./configure --prefix=<DIR> in the ticcutils installation directory
+  --with-icu=DIR       use icu installed in <DIR>
 
 Some influential environment variables:
   CXX         C++ compiler command
@@ -1495,6 +1487,8 @@ Some influential environment variables:
               C compiler flags for ticcutils, overriding pkg-config
   ticcutils_LIBS
               linker flags for ticcutils, overriding pkg-config
+  ICU_CFLAGS  C compiler flags for ICU, overriding pkg-config
+  ICU_LIBS    linker flags for ICU, overriding pkg-config
 
 Use these variables to override the choices made by `configure' or to help
 it to find libraries and programs with nonstandard names/locations.
@@ -1562,7 +1556,7 @@ fi
 test -n "$ac_init_help" && exit $ac_status
 if $ac_init_version; then
   cat <<\_ACEOF
-libfolia configure 1.6
+libfolia configure 1.10
 generated by GNU Autoconf 2.69
 
 Copyright (C) 2012 Free Software Foundation, Inc.
@@ -2082,7 +2076,7 @@ cat >config.log <<_ACEOF
 This file contains any messages produced by compilers while
 running configure, to aid debugging if configure makes a mistake.
 
-It was created by libfolia $as_me 1.6, which was
+It was created by libfolia $as_me 1.10, which was
 generated by GNU Autoconf 2.69.  Invocation command line was
 
   $ $0 $@
@@ -2945,7 +2939,7 @@ fi
 
 # Define the identity of the package.
  PACKAGE='libfolia'
- VERSION='1.6'
+ VERSION='1.10'
 
 
 cat >>confdefs.h <<_ACEOF
@@ -16059,6 +16053,20 @@ fi
 
 
 # Checks for library functions.
+for ac_func in localtime_r
+do :
+  ac_fn_cxx_check_func "$LINENO" "localtime_r" "ac_cv_func_localtime_r"
+if test "x$ac_cv_func_localtime_r" = xyes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_LOCALTIME_R 1
+_ACEOF
+
+fi
+done
+
+
+
+
 
 
 ac_ext=c
@@ -16069,21 +16077,32 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu
 
 ax_pthread_ok=no
 
+# hack for Clang analyzer
+SUBST="cc-analyzer"
+if test "${CC#*$SUBST}" != $CC; then
+   OLDCC=${CC}
+   CC=clang
+fi
+
 # We used to check for pthread.h first, but this fails if pthread.h
-# requires special compiler flags (e.g. on True64 or Sequent).
+# requires special compiler flags (e.g. on Tru64 or Sequent).
 # It gets checked for in the link test anyway.
 
 # First of all, check if the user has set any of the PTHREAD_LIBS,
 # etcetera environment variables, and if threads linking works using
 # them:
-if test x"$PTHREAD_LIBS$PTHREAD_CFLAGS" != x; then
-        save_CFLAGS="$CFLAGS"
-        CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
-        save_LIBS="$LIBS"
-        LIBS="$PTHREAD_LIBS $LIBS"
-        { $as_echo "$as_me:${as_lineno-$LINENO}: checking for pthread_join in LIBS=$PTHREAD_LIBS with CFLAGS=$PTHREAD_CFLAGS" >&5
-$as_echo_n "checking for pthread_join in LIBS=$PTHREAD_LIBS with CFLAGS=$PTHREAD_CFLAGS... " >&6; }
-        cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+if test "x$PTHREAD_CFLAGS$PTHREAD_LIBS" != "x"; then
+	ax_pthread_save_CC="$CC"
+	ax_pthread_save_CFLAGS="$CFLAGS"
+	ax_pthread_save_LIBS="$LIBS"
+	if test "x$PTHREAD_CC" != "x"; then :
+  CC="$PTHREAD_CC"
+fi
+	CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
+	LIBS="$PTHREAD_LIBS $LIBS"
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for pthread_join using $CC $PTHREAD_CFLAGS $PTHREAD_LIBS" >&5
+$as_echo_n "checking for pthread_join using $CC $PTHREAD_CFLAGS $PTHREAD_LIBS... " >&6; }
+	cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 
 /* Override any GCC internal prototype to avoid an error.
@@ -16106,14 +16125,15 @@ if ac_fn_c_try_link "$LINENO"; then :
 fi
 rm -f core conftest.err conftest.$ac_objext \
     conftest$ac_exeext conftest.$ac_ext
-        { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_pthread_ok" >&5
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_pthread_ok" >&5
 $as_echo "$ax_pthread_ok" >&6; }
-        if test x"$ax_pthread_ok" = xno; then
-                PTHREAD_LIBS=""
-                PTHREAD_CFLAGS=""
-        fi
-        LIBS="$save_LIBS"
-        CFLAGS="$save_CFLAGS"
+	if test "x$ax_pthread_ok" = "xno"; then
+		PTHREAD_LIBS=""
+		PTHREAD_CFLAGS=""
+	fi
+	CC="$ax_pthread_save_CC"
+	CFLAGS="$ax_pthread_save_CFLAGS"
+	LIBS="$ax_pthread_save_LIBS"
 fi
 
 # We must check for the threads library under a number of different
@@ -16126,7 +16146,7 @@ fi
 # which indicates that we try without any flags at all, and "pthread-config"
 # which is a program returning the flags for the Pth emulation library.
 
-ax_pthread_flags="pthreads none -Kthread -kthread lthread -pthread -pthreads -mthreads pthread --thread-safe -mt pthread-config"
+ax_pthread_flags="pthreads none -Kthread -pthread -pthreads -mthreads pthread --thread-safe -mt pthread-config"
 
 # The ordering *is* (sometimes) important.  Some notes on the
 # individual items follow:
@@ -16135,86 +16155,259 @@ ax_pthread_flags="pthreads none -Kthread -kthread lthread -pthread -pthreads -mt
 # none: in case threads are in libc; should be tried before -Kthread and
 #       other compiler flags to prevent continual compiler warnings
 # -Kthread: Sequent (threads in libc, but -Kthread needed for pthread.h)
-# -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able)
-# lthread: LinuxThreads port on FreeBSD (also preferred to -pthread)
-# -pthread: Linux/gcc (kernel threads), BSD/gcc (userland threads)
-# -pthreads: Solaris/gcc
-# -mthreads: Mingw32/gcc, Lynx/gcc
+# -pthread: Linux/gcc (kernel threads), BSD/gcc (userland threads), Tru64
+#           (Note: HP C rejects this with "bad form for `-t' option")
+# -pthreads: Solaris/gcc (Note: HP C also rejects)
 # -mt: Sun Workshop C (may only link SunOS threads [-lthread], but it
-#      doesn't hurt to check since this sometimes defines pthreads too;
-#      also defines -D_REENTRANT)
-#      ... -mt is also the pthreads flag for HP/aCC
+#      doesn't hurt to check since this sometimes defines pthreads and
+#      -D_REENTRANT too), HP C (must be checked before -lpthread, which
+#      is present but should not be used directly; and before -mthreads,
+#      because the compiler interprets this as "-mt" + "-hreads")
+# -mthreads: Mingw32/gcc, Lynx/gcc
 # pthread: Linux, etcetera
 # --thread-safe: KAI C++
 # pthread-config: use pthread-config program (for GNU Pth library)
 
-case ${host_os} in
-        solaris*)
+case $host_os in
 
-        # On Solaris (at least, for some versions), libc contains stubbed
-        # (non-functional) versions of the pthreads routines, so link-based
-        # tests will erroneously succeed.  (We need to link with -pthreads/-mt/
-        # -lpthread.)  (The stubs are missing pthread_cleanup_push, or rather
-        # a function called by this macro, so we could check for that, but
-        # who knows whether they'll stub that too in a future libc.)  So,
-        # we'll just look for -pthreads and -lpthread first:
+	freebsd*)
 
-        ax_pthread_flags="-pthreads pthread -mt -pthread $ax_pthread_flags"
-        ;;
+	# -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able)
+	# lthread: LinuxThreads port on FreeBSD (also preferred to -pthread)
 
-        darwin*)
-        ax_pthread_flags="-pthread $ax_pthread_flags"
-        ;;
+	ax_pthread_flags="-kthread lthread $ax_pthread_flags"
+	;;
+
+	hpux*)
+
+	# From the cc(1) man page: "[-mt] Sets various -D flags to enable
+	# multi-threading and also sets -lpthread."
+
+	ax_pthread_flags="-mt -pthread pthread $ax_pthread_flags"
+	;;
+
+	openedition*)
+
+	# IBM z/OS requires a feature-test macro to be defined in order to
+	# enable POSIX threads at all, so give the user a hint if this is
+	# not set. (We don't define these ourselves, as they can affect
+	# other portions of the system API in unpredictable ways.)
+
+	cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+#	     if !defined(_OPEN_THREADS) && !defined(_UNIX03_THREADS)
+	     AX_PTHREAD_ZOS_MISSING
+#	     endif
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "AX_PTHREAD_ZOS_MISSING" >/dev/null 2>&1; then :
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: IBM z/OS requires -D_OPEN_THREADS or -D_UNIX03_THREADS to enable pthreads support." >&5
+$as_echo "$as_me: WARNING: IBM z/OS requires -D_OPEN_THREADS or -D_UNIX03_THREADS to enable pthreads support." >&2;}
+fi
+rm -f conftest*
+
+	;;
+
+	solaris*)
+
+	# On Solaris (at least, for some versions), libc contains stubbed
+	# (non-functional) versions of the pthreads routines, so link-based
+	# tests will erroneously succeed. (N.B.: The stubs are missing
+	# pthread_cleanup_push, or rather a function called by this macro,
+	# so we could check for that, but who knows whether they'll stub
+	# that too in a future libc.)  So we'll check first for the
+	# standard Solaris way of linking pthreads (-mt -lpthread).
+
+	ax_pthread_flags="-mt,pthread pthread $ax_pthread_flags"
+	;;
 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.
+# GCC generally uses -pthread, or -pthreads on some platforms (e.g. SPARC)
 
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if compiler needs -Werror to reject unknown flags" >&5
-$as_echo_n "checking if compiler needs -Werror to reject unknown flags... " >&6; }
-save_CFLAGS="$CFLAGS"
-ax_pthread_extra_flags="-Werror"
-CFLAGS="$CFLAGS $ax_pthread_extra_flags -Wunknown-warning-option -Wsizeof-array-argument"
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+if test "x$GCC" = "xyes"; then :
+  ax_pthread_flags="-pthread -pthreads $ax_pthread_flags"
+fi
+
+# The presence of a feature test macro requesting re-entrant function
+# definitions is, on some systems, a strong hint that pthreads support is
+# correctly enabled
+
+case $host_os in
+	darwin* | hpux* | linux* | osf* | solaris*)
+	ax_pthread_check_macro="_REENTRANT"
+	;;
+
+	aix* | freebsd*)
+	ax_pthread_check_macro="_THREAD_SAFE"
+	;;
+
+	*)
+	ax_pthread_check_macro="--"
+	;;
+esac
+if test "x$ax_pthread_check_macro" = "x--"; then :
+  ax_pthread_check_cond=0
+else
+  ax_pthread_check_cond="!defined($ax_pthread_check_macro)"
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC is Clang" >&5
+$as_echo_n "checking whether $CC is Clang... " >&6; }
+if ${ax_cv_PTHREAD_CLANG+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ax_cv_PTHREAD_CLANG=no
+     # Note that Autoconf sets GCC=yes for Clang as well as GCC
+     if test "x$GCC" = "xyes"; then
+	cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
-int foo(void);
-int
-main ()
-{
-foo()
-  ;
-  return 0;
-}
+/* Note: Clang 2.7 lacks __clang_[a-z]+__ */
+#	     if defined(__clang__) && defined(__llvm__)
+	     AX_PTHREAD_CC_IS_CLANG
+#	     endif
+
 _ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
-$as_echo "yes" >&6; }
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "AX_PTHREAD_CC_IS_CLANG" >/dev/null 2>&1; then :
+  ax_cv_PTHREAD_CLANG=yes
+fi
+rm -f conftest*
+
+     fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_PTHREAD_CLANG" >&5
+$as_echo "$ax_cv_PTHREAD_CLANG" >&6; }
+ax_pthread_clang="$ax_cv_PTHREAD_CLANG"
+
+ax_pthread_clang_warning=no
+
+# Clang needs special handling, because older versions handle the -pthread
+# option in a rather... idiosyncratic way
+
+if test "x$ax_pthread_clang" = "xyes"; then
+
+	# Clang takes -pthread; it has never supported any other flag
+
+	# (Note 1: This will need to be revisited if a system that Clang
+	# supports has POSIX threads in a separate library.  This tends not
+	# to be the way of modern systems, but it's conceivable.)
+
+	# (Note 2: On some systems, notably Darwin, -pthread is not needed
+	# to get POSIX threads support; the API is always present and
+	# active.  We could reasonably leave PTHREAD_CFLAGS empty.  But
+	# -pthread does define _REENTRANT, and while the Darwin headers
+	# ignore this macro, third-party headers might not.)
+
+	PTHREAD_CFLAGS="-pthread"
+	PTHREAD_LIBS=
+
+	ax_pthread_ok=yes
+
+	# However, older versions of Clang make a point of warning the user
+	# that, in an invocation where only linking and no compilation is
+	# taking place, the -pthread option has no effect ("argument unused
+	# during compilation").  They expect -pthread to be passed in only
+	# when source code is being compiled.
+	#
+	# Problem is, this is at odds with the way Automake and most other
+	# C build frameworks function, which is that the same flags used in
+	# compilation (CFLAGS) are also used in linking.  Many systems
+	# supported by AX_PTHREAD require exactly this for POSIX threads
+	# support, and in fact it is often not straightforward to specify a
+	# flag that is used only in the compilation phase and not in
+	# linking.  Such a scenario is extremely rare in practice.
+	#
+	# Even though use of the -pthread flag in linking would only print
+	# a warning, this can be a nuisance for well-run software projects
+	# that build with -Werror.  So if the active version of Clang has
+	# this misfeature, we search for an option to squash it.
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether Clang needs flag to prevent \"argument unused\" warning when linking with -pthread" >&5
+$as_echo_n "checking whether Clang needs flag to prevent \"argument unused\" warning when linking with -pthread... " >&6; }
+if ${ax_cv_PTHREAD_CLANG_NO_WARN_FLAG+:} false; then :
+  $as_echo_n "(cached) " >&6
 else
-  ax_pthread_extra_flags=
-                   { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
+  ax_cv_PTHREAD_CLANG_NO_WARN_FLAG=unknown
+	     # Create an alternate version of $ac_link that compiles and
+	     # links in two steps (.c -> .o, .o -> exe) instead of one
+	     # (.c -> exe), because the warning occurs only in the second
+	     # step
+	     ax_pthread_save_ac_link="$ac_link"
+	     ax_pthread_sed='s/conftest\.\$ac_ext/conftest.$ac_objext/g'
+	     ax_pthread_link_step=`$as_echo "$ac_link" | sed "$ax_pthread_sed"`
+	     ax_pthread_2step_ac_link="($ac_compile) && (echo ==== >&5) && ($ax_pthread_link_step)"
+	     ax_pthread_save_CFLAGS="$CFLAGS"
+	     for ax_pthread_try in '' -Qunused-arguments -Wno-unused-command-line-argument unknown; do
+		if test "x$ax_pthread_try" = "xunknown"; then :
+  break
 fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-CFLAGS="$save_CFLAGS"
+		CFLAGS="-Werror -Wunknown-warning-option $ax_pthread_try -pthread $ax_pthread_save_CFLAGS"
+		ac_link="$ax_pthread_save_ac_link"
+		cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+int main(void){return 0;}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_link="$ax_pthread_2step_ac_link"
+		     cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+int main(void){return 0;}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  break
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+	     done
+	     ac_link="$ax_pthread_save_ac_link"
+	     CFLAGS="$ax_pthread_save_CFLAGS"
+	     if test "x$ax_pthread_try" = "x"; then :
+  ax_pthread_try=no
+fi
+	     ax_cv_PTHREAD_CLANG_NO_WARN_FLAG="$ax_pthread_try"
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_PTHREAD_CLANG_NO_WARN_FLAG" >&5
+$as_echo "$ax_cv_PTHREAD_CLANG_NO_WARN_FLAG" >&6; }
+
+	case "$ax_cv_PTHREAD_CLANG_NO_WARN_FLAG" in
+		no | unknown) ;;
+		*) PTHREAD_CFLAGS="$ax_cv_PTHREAD_CLANG_NO_WARN_FLAG $PTHREAD_CFLAGS" ;;
+	esac
+
+fi # $ax_pthread_clang = yes
 
-if test x"$ax_pthread_ok" = xno; then
-for flag in $ax_pthread_flags; do
+if test "x$ax_pthread_ok" = "xno"; then
+for ax_pthread_try_flag in $ax_pthread_flags; do
 
-        case $flag in
-                none)
-                { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether pthreads work without any flags" >&5
+	case $ax_pthread_try_flag in
+		none)
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether pthreads work without any flags" >&5
 $as_echo_n "checking whether pthreads work without any flags... " >&6; }
-                ;;
+		;;
 
-                -*)
-                { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether pthreads work with $flag" >&5
-$as_echo_n "checking whether pthreads work with $flag... " >&6; }
-                PTHREAD_CFLAGS="$flag"
-                ;;
+		-mt,pthread)
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether pthreads work with -mt -lpthread" >&5
+$as_echo_n "checking whether pthreads work with -mt -lpthread... " >&6; }
+		PTHREAD_CFLAGS="-mt"
+		PTHREAD_LIBS="-lpthread"
+		;;
 
-                pthread-config)
-                # Extract the first word of "pthread-config", so it can be a program name with args.
+		-*)
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether pthreads work with $ax_pthread_try_flag" >&5
+$as_echo_n "checking whether pthreads work with $ax_pthread_try_flag... " >&6; }
+		PTHREAD_CFLAGS="$ax_pthread_try_flag"
+		;;
+
+		pthread-config)
+		# Extract the first word of "pthread-config", so it can be a program name with args.
 set dummy pthread-config; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
@@ -16252,46 +16445,52 @@ $as_echo "no" >&6; }
 fi
 
 
-                if test x"$ax_pthread_config" = xno; then continue; fi
-                PTHREAD_CFLAGS="`pthread-config --cflags`"
-                PTHREAD_LIBS="`pthread-config --ldflags` `pthread-config --libs`"
-                ;;
+		if test "x$ax_pthread_config" = "xno"; then :
+  continue
+fi
+		PTHREAD_CFLAGS="`pthread-config --cflags`"
+		PTHREAD_LIBS="`pthread-config --ldflags` `pthread-config --libs`"
+		;;
 
-                *)
-                { $as_echo "$as_me:${as_lineno-$LINENO}: checking for the pthreads library -l$flag" >&5
-$as_echo_n "checking for the pthreads library -l$flag... " >&6; }
-                PTHREAD_LIBS="-l$flag"
-                ;;
-        esac
+		*)
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for the pthreads library -l$ax_pthread_try_flag" >&5
+$as_echo_n "checking for the pthreads library -l$ax_pthread_try_flag... " >&6; }
+		PTHREAD_LIBS="-l$ax_pthread_try_flag"
+		;;
+	esac
 
-        save_LIBS="$LIBS"
-        save_CFLAGS="$CFLAGS"
-        LIBS="$PTHREAD_LIBS $LIBS"
-        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
-        # need a special flag -Kthread to make this header compile.)
-        # We check for pthread_join because it is in -lpthread on IRIX
-        # while pthread_create is in libc.  We check for pthread_attr_init
-        # due to DEC craziness with -lpthreads.  We check for
-        # pthread_cleanup_push because it is one of the few pthread
-        # functions on Solaris that doesn't have a non-functional libc stub.
-        # We try pthread_create on general principles.
-        cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+	ax_pthread_save_CFLAGS="$CFLAGS"
+	ax_pthread_save_LIBS="$LIBS"
+	CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
+	LIBS="$PTHREAD_LIBS $LIBS"
+
+	# Check for various functions.  We must include pthread.h,
+	# since some functions may be macros.  (On the Sequent, we
+	# need a special flag -Kthread to make this header compile.)
+	# We check for pthread_join because it is in -lpthread on IRIX
+	# while pthread_create is in libc.  We check for pthread_attr_init
+	# due to DEC craziness with -lpthreads.  We check for
+	# pthread_cleanup_push because it is one of the few pthread
+	# functions on Solaris that doesn't have a non-functional libc stub.
+	# We try pthread_create on general principles.
+
+	cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 #include <pthread.h>
-                        static void routine(void *a) { a = 0; }
-                        static void *start_routine(void *a) { return a; }
+#			if $ax_pthread_check_cond
+#			 error "$ax_pthread_check_macro must be defined"
+#			endif
+			static void routine(void *a) { a = 0; }
+			static void *start_routine(void *a) { return a; }
 int
 main ()
 {
 pthread_t th; pthread_attr_t attr;
-                        pthread_create(&th, 0, start_routine, 0);
-                        pthread_join(th, 0);
-                        pthread_attr_init(&attr);
-                        pthread_cleanup_push(routine, 0);
-                        pthread_cleanup_pop(0) /* ; */
+			pthread_create(&th, 0, start_routine, 0);
+			pthread_join(th, 0);
+			pthread_attr_init(&attr);
+			pthread_cleanup_push(routine, 0);
+			pthread_cleanup_pop(0) /* ; */
   ;
   return 0;
 }
@@ -16302,87 +16501,95 @@ fi
 rm -f core conftest.err conftest.$ac_objext \
     conftest$ac_exeext conftest.$ac_ext
 
-        LIBS="$save_LIBS"
-        CFLAGS="$save_CFLAGS"
+	CFLAGS="$ax_pthread_save_CFLAGS"
+	LIBS="$ax_pthread_save_LIBS"
 
-        { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_pthread_ok" >&5
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_pthread_ok" >&5
 $as_echo "$ax_pthread_ok" >&6; }
-        if test "x$ax_pthread_ok" = xyes; then
-                break;
-        fi
+	if test "x$ax_pthread_ok" = "xyes"; then :
+  break
+fi
 
-        PTHREAD_LIBS=""
-        PTHREAD_CFLAGS=""
+	PTHREAD_LIBS=""
+	PTHREAD_CFLAGS=""
 done
 fi
 
 # Various other checks:
-if test "x$ax_pthread_ok" = xyes; then
-        save_LIBS="$LIBS"
-        LIBS="$PTHREAD_LIBS $LIBS"
-        save_CFLAGS="$CFLAGS"
-        CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
-
-        # Detect AIX lossage: JOINABLE attribute is called UNDETACHED.
-        { $as_echo "$as_me:${as_lineno-$LINENO}: checking for joinable pthread attribute" >&5
+if test "x$ax_pthread_ok" = "xyes"; then
+	ax_pthread_save_CFLAGS="$CFLAGS"
+	ax_pthread_save_LIBS="$LIBS"
+	CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
+	LIBS="$PTHREAD_LIBS $LIBS"
+
+	# Detect AIX lossage: JOINABLE attribute is called UNDETACHED.
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for joinable pthread attribute" >&5
 $as_echo_n "checking for joinable pthread attribute... " >&6; }
-        attr_name=unknown
-        for attr in PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_UNDETACHED; do
-            cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+if ${ax_cv_PTHREAD_JOINABLE_ATTR+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ax_cv_PTHREAD_JOINABLE_ATTR=unknown
+	     for ax_pthread_attr in PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_UNDETACHED; do
+		 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 #include <pthread.h>
 int
 main ()
 {
-int attr = $attr; return attr /* ; */
+int attr = $ax_pthread_attr; return attr /* ; */
   ;
   return 0;
 }
 _ACEOF
 if ac_fn_c_try_link "$LINENO"; then :
-  attr_name=$attr; break
+  ax_cv_PTHREAD_JOINABLE_ATTR=$ax_pthread_attr; break
 fi
 rm -f core conftest.err conftest.$ac_objext \
     conftest$ac_exeext conftest.$ac_ext
-        done
-        { $as_echo "$as_me:${as_lineno-$LINENO}: result: $attr_name" >&5
-$as_echo "$attr_name" >&6; }
-        if test "$attr_name" != PTHREAD_CREATE_JOINABLE; then
+	     done
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_PTHREAD_JOINABLE_ATTR" >&5
+$as_echo "$ax_cv_PTHREAD_JOINABLE_ATTR" >&6; }
+	if test "x$ax_cv_PTHREAD_JOINABLE_ATTR" != "xunknown" && \
+	       test "x$ax_cv_PTHREAD_JOINABLE_ATTR" != "xPTHREAD_CREATE_JOINABLE" && \
+	       test "x$ax_pthread_joinable_attr_defined" != "xyes"; then :
 
 cat >>confdefs.h <<_ACEOF
-#define PTHREAD_CREATE_JOINABLE $attr_name
+#define PTHREAD_CREATE_JOINABLE $ax_cv_PTHREAD_JOINABLE_ATTR
 _ACEOF
 
-        fi
+	       ax_pthread_joinable_attr_defined=yes
 
-        { $as_echo "$as_me:${as_lineno-$LINENO}: checking if more special flags are required for pthreads" >&5
-$as_echo_n "checking if more special flags are required for pthreads... " >&6; }
-        flag=no
-        case ${host_os} in
-            aix* | freebsd* | darwin*) flag="-D_THREAD_SAFE";;
-            osf* | hpux*) flag="-D_REENTRANT";;
-            solaris*)
-            if test "$GCC" = "yes"; then
-                flag="-D_REENTRANT"
-            else
-                # TODO: What about Clang on Solaris?
-                flag="-mt -D_REENTRANT"
-            fi
-            ;;
-        esac
-        { $as_echo "$as_me:${as_lineno-$LINENO}: result: $flag" >&5
-$as_echo "$flag" >&6; }
-        if test "x$flag" != xno; then
-            PTHREAD_CFLAGS="$flag $PTHREAD_CFLAGS"
-        fi
+fi
 
-        { $as_echo "$as_me:${as_lineno-$LINENO}: checking for PTHREAD_PRIO_INHERIT" >&5
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether more special flags are required for pthreads" >&5
+$as_echo_n "checking whether more special flags are required for pthreads... " >&6; }
+if ${ax_cv_PTHREAD_SPECIAL_FLAGS+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ax_cv_PTHREAD_SPECIAL_FLAGS=no
+	     case $host_os in
+	     solaris*)
+	     ax_cv_PTHREAD_SPECIAL_FLAGS="-D_POSIX_PTHREAD_SEMANTICS"
+	     ;;
+	     esac
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_PTHREAD_SPECIAL_FLAGS" >&5
+$as_echo "$ax_cv_PTHREAD_SPECIAL_FLAGS" >&6; }
+	if test "x$ax_cv_PTHREAD_SPECIAL_FLAGS" != "xno" && \
+	       test "x$ax_pthread_special_flags_added" != "xyes"; then :
+  PTHREAD_CFLAGS="$ax_cv_PTHREAD_SPECIAL_FLAGS $PTHREAD_CFLAGS"
+	       ax_pthread_special_flags_added=yes
+fi
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for PTHREAD_PRIO_INHERIT" >&5
 $as_echo_n "checking for PTHREAD_PRIO_INHERIT... " >&6; }
 if ${ax_cv_PTHREAD_PRIO_INHERIT+:} false; then :
   $as_echo_n "(cached) " >&6
 else
-
-                cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 #include <pthread.h>
 int
@@ -16404,23 +16611,26 @@ rm -f core conftest.err conftest.$ac_objext \
 fi
 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_PTHREAD_PRIO_INHERIT" >&5
 $as_echo "$ax_cv_PTHREAD_PRIO_INHERIT" >&6; }
-        if test "x$ax_cv_PTHREAD_PRIO_INHERIT" = "xyes"; then :
+	if test "x$ax_cv_PTHREAD_PRIO_INHERIT" = "xyes" && \
+	       test "x$ax_pthread_prio_inherit_defined" != "xyes"; then :
 
 $as_echo "#define HAVE_PTHREAD_PRIO_INHERIT 1" >>confdefs.h
 
+	       ax_pthread_prio_inherit_defined=yes
+
 fi
 
-        LIBS="$save_LIBS"
-        CFLAGS="$save_CFLAGS"
+	CFLAGS="$ax_pthread_save_CFLAGS"
+	LIBS="$ax_pthread_save_LIBS"
 
-        # More AIX lossage: compile with *_r variant
-        if test "x$GCC" != xyes; then
-            case $host_os in
-                aix*)
-                case "x/$CC" in #(
+	# More AIX lossage: compile with *_r variant
+	if test "x$GCC" != "xyes"; then
+	    case $host_os in
+		aix*)
+		case "x/$CC" in #(
   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
-                   case "x$CC" in #(
+		     case "x$CC" in #(
   x/*) :
     if as_fn_executable_p ${CC}_r; then :
   PTHREAD_CC="${CC}_r"
@@ -16473,9 +16683,9 @@ esac ;; #(
   *) :
      ;;
 esac
-                ;;
-            esac
-        fi
+		;;
+	    esac
+	fi
 fi
 
 test -n "$PTHREAD_CC" || PTHREAD_CC="$CC"
@@ -16485,15 +16695,21 @@ test -n "$PTHREAD_CC" || PTHREAD_CC="$CC"
 
 
 # Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND:
-if test x"$ax_pthread_ok" = xyes; then
+if test "x$ax_pthread_ok" = "xyes"; then
 
 $as_echo "#define HAVE_PTHREAD 1" >>confdefs.h
 
-        :
+	:
 else
-        ax_pthread_ok=no
-        as_fn_error $? "We need pthread support!" "$LINENO" 5
+	ax_pthread_ok=no
+	as_fn_error $? "We need pthread support!" "$LINENO" 5
 fi
+
+# undo hack for Clang analyzer
+if test "${OLDCC#*$SUBST}" != ${OLDCC}; then
+   CC=${OLDCC}
+fi
+
 ac_ext=cpp
 ac_cpp='$CXXCPP $CPPFLAGS'
 ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
@@ -16501,197 +16717,85 @@ ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ex
 ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
 
 
+LIBS="$PTHREAD_LIBS $LIBS"
+CXXFLAGS="$CXXFLAGS $PTHREAD_CFLAGS"
 
-if test x"$ax_pthread_ok" = xyes; then
-   LIBS="$PTHREAD_LIBS $LIBS" \
-   CXXFLAGS="$CXXFLAGS $PTHREAD_CFLAGS"
+if test $prefix = "NONE"; then
+   prefix="$ac_default_prefix"
 fi
 
-for ac_func in localtime_r
-do :
-  ac_fn_cxx_check_func "$LINENO" "localtime_r" "ac_cv_func_localtime_r"
-if test "x$ac_cv_func_localtime_r" = xyes; then :
-  cat >>confdefs.h <<_ACEOF
-#define HAVE_LOCALTIME_R 1
-_ACEOF
-
-fi
-done
 
 
 
 
-ac_ext=c
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
 
-ax_pthread_ok=no
 
-# We used to check for pthread.h first, but this fails if pthread.h
-# requires special compiler flags (e.g. on True64 or Sequent).
-# It gets checked for in the link test anyway.
 
-# First of all, check if the user has set any of the PTHREAD_LIBS,
-# etcetera environment variables, and if threads linking works using
-# them:
-if test x"$PTHREAD_LIBS$PTHREAD_CFLAGS" != x; then
-        save_CFLAGS="$CFLAGS"
-        CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
-        save_LIBS="$LIBS"
-        LIBS="$PTHREAD_LIBS $LIBS"
-        { $as_echo "$as_me:${as_lineno-$LINENO}: checking for pthread_join in LIBS=$PTHREAD_LIBS with CFLAGS=$PTHREAD_CFLAGS" >&5
-$as_echo_n "checking for pthread_join in LIBS=$PTHREAD_LIBS with CFLAGS=$PTHREAD_CFLAGS... " >&6; }
-        cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
+if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then
+	if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}pkg-config", so it can be a program name with args.
+set dummy ${ac_tool_prefix}pkg-config; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_PKG_CONFIG+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  case $PKG_CONFIG in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_PKG_CONFIG="$PKG_CONFIG" # Let the user override the test with a path.
+  ;;
+  *)
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_path_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
 
-/* Override any GCC internal prototype to avoid an error.
-   Use char because int might match the return type of a GCC
-   builtin and then its argument prototype would still apply.  */
-#ifdef __cplusplus
-extern "C"
-#endif
-char pthread_join ();
-int
-main ()
-{
-return pthread_join ();
-  ;
-  return 0;
-}
-_ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
-  ax_pthread_ok=yes
+  ;;
+esac
 fi
-rm -f core conftest.err conftest.$ac_objext \
-    conftest$ac_exeext conftest.$ac_ext
-        { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_pthread_ok" >&5
-$as_echo "$ax_pthread_ok" >&6; }
-        if test x"$ax_pthread_ok" = xno; then
-                PTHREAD_LIBS=""
-                PTHREAD_CFLAGS=""
-        fi
-        LIBS="$save_LIBS"
-        CFLAGS="$save_CFLAGS"
+PKG_CONFIG=$ac_cv_path_PKG_CONFIG
+if test -n "$PKG_CONFIG"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PKG_CONFIG" >&5
+$as_echo "$PKG_CONFIG" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
 fi
 
-# We must check for the threads library under a number of different
-# names; the ordering is very important because some systems
-# (e.g. DEC) have both -lpthread and -lpthreads, where one of the
-# libraries is broken (non-POSIX).
-
-# Create a list of thread flags to try.  Items starting with a "-" are
-# C compiler flags, and other items are library names, except for "none"
-# which indicates that we try without any flags at all, and "pthread-config"
-# which is a program returning the flags for the Pth emulation library.
-
-ax_pthread_flags="pthreads none -Kthread -kthread lthread -pthread -pthreads -mthreads pthread --thread-safe -mt pthread-config"
-
-# The ordering *is* (sometimes) important.  Some notes on the
-# individual items follow:
 
-# pthreads: AIX (must check this before -lpthread)
-# none: in case threads are in libc; should be tried before -Kthread and
-#       other compiler flags to prevent continual compiler warnings
-# -Kthread: Sequent (threads in libc, but -Kthread needed for pthread.h)
-# -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able)
-# lthread: LinuxThreads port on FreeBSD (also preferred to -pthread)
-# -pthread: Linux/gcc (kernel threads), BSD/gcc (userland threads)
-# -pthreads: Solaris/gcc
-# -mthreads: Mingw32/gcc, Lynx/gcc
-# -mt: Sun Workshop C (may only link SunOS threads [-lthread], but it
-#      doesn't hurt to check since this sometimes defines pthreads too;
-#      also defines -D_REENTRANT)
-#      ... -mt is also the pthreads flag for HP/aCC
-# pthread: Linux, etcetera
-# --thread-safe: KAI C++
-# pthread-config: use pthread-config program (for GNU Pth library)
-
-case ${host_os} in
-        solaris*)
-
-        # On Solaris (at least, for some versions), libc contains stubbed
-        # (non-functional) versions of the pthreads routines, so link-based
-        # tests will erroneously succeed.  (We need to link with -pthreads/-mt/
-        # -lpthread.)  (The stubs are missing pthread_cleanup_push, or rather
-        # a function called by this macro, so we could check for that, but
-        # who knows whether they'll stub that too in a future libc.)  So,
-        # we'll just look for -pthreads and -lpthread first:
-
-        ax_pthread_flags="-pthreads pthread -mt -pthread $ax_pthread_flags"
-        ;;
-
-        darwin*)
-        ax_pthread_flags="-pthread $ax_pthread_flags"
-        ;;
-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.
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if compiler needs -Werror to reject unknown flags" >&5
-$as_echo_n "checking if compiler needs -Werror to reject unknown flags... " >&6; }
-save_CFLAGS="$CFLAGS"
-ax_pthread_extra_flags="-Werror"
-CFLAGS="$CFLAGS $ax_pthread_extra_flags -Wunknown-warning-option -Wsizeof-array-argument"
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-int foo(void);
-int
-main ()
-{
-foo()
-  ;
-  return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
-$as_echo "yes" >&6; }
-else
-  ax_pthread_extra_flags=
-                   { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
 fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-CFLAGS="$save_CFLAGS"
-
-if test x"$ax_pthread_ok" = xno; then
-for flag in $ax_pthread_flags; do
-
-        case $flag in
-                none)
-                { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether pthreads work without any flags" >&5
-$as_echo_n "checking whether pthreads work without any flags... " >&6; }
-                ;;
-
-                -*)
-                { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether pthreads work with $flag" >&5
-$as_echo_n "checking whether pthreads work with $flag... " >&6; }
-                PTHREAD_CFLAGS="$flag"
-                ;;
-
-                pthread-config)
-                # Extract the first word of "pthread-config", so it can be a program name with args.
-set dummy pthread-config; ac_word=$2
+if test -z "$ac_cv_path_PKG_CONFIG"; then
+  ac_pt_PKG_CONFIG=$PKG_CONFIG
+  # Extract the first word of "pkg-config", so it can be a program name with args.
+set dummy pkg-config; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_prog_ax_pthread_config+:} false; then :
+if ${ac_cv_path_ac_pt_PKG_CONFIG+:} false; then :
   $as_echo_n "(cached) " >&6
 else
-  if test -n "$ax_pthread_config"; then
-  ac_cv_prog_ax_pthread_config="$ax_pthread_config" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+  case $ac_pt_PKG_CONFIG in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_ac_pt_PKG_CONFIG="$ac_pt_PKG_CONFIG" # Let the user override the test with a path.
+  ;;
+  *)
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
 for as_dir in $PATH
 do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
     for ac_exec_ext in '' $ac_executable_extensions; do
   if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
-    ac_cv_prog_ax_pthread_config="yes"
+    ac_cv_path_ac_pt_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext"
     $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
   fi
@@ -16699,273 +16803,63 @@ done
   done
 IFS=$as_save_IFS
 
-  test -z "$ac_cv_prog_ax_pthread_config" && ac_cv_prog_ax_pthread_config="no"
-fi
+  ;;
+esac
 fi
-ax_pthread_config=$ac_cv_prog_ax_pthread_config
-if test -n "$ax_pthread_config"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_pthread_config" >&5
-$as_echo "$ax_pthread_config" >&6; }
+ac_pt_PKG_CONFIG=$ac_cv_path_ac_pt_PKG_CONFIG
+if test -n "$ac_pt_PKG_CONFIG"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_pt_PKG_CONFIG" >&5
+$as_echo "$ac_pt_PKG_CONFIG" >&6; }
 else
   { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
 $as_echo "no" >&6; }
 fi
 
-
-                if test x"$ax_pthread_config" = xno; then continue; fi
-                PTHREAD_CFLAGS="`pthread-config --cflags`"
-                PTHREAD_LIBS="`pthread-config --ldflags` `pthread-config --libs`"
-                ;;
-
-                *)
-                { $as_echo "$as_me:${as_lineno-$LINENO}: checking for the pthreads library -l$flag" >&5
-$as_echo_n "checking for the pthreads library -l$flag... " >&6; }
-                PTHREAD_LIBS="-l$flag"
-                ;;
-        esac
-
-        save_LIBS="$LIBS"
-        save_CFLAGS="$CFLAGS"
-        LIBS="$PTHREAD_LIBS $LIBS"
-        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
-        # need a special flag -Kthread to make this header compile.)
-        # We check for pthread_join because it is in -lpthread on IRIX
-        # while pthread_create is in libc.  We check for pthread_attr_init
-        # due to DEC craziness with -lpthreads.  We check for
-        # pthread_cleanup_push because it is one of the few pthread
-        # functions on Solaris that doesn't have a non-functional libc stub.
-        # We try pthread_create on general principles.
-        cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-#include <pthread.h>
-                        static void routine(void *a) { a = 0; }
-                        static void *start_routine(void *a) { return a; }
-int
-main ()
-{
-pthread_t th; pthread_attr_t attr;
-                        pthread_create(&th, 0, start_routine, 0);
-                        pthread_join(th, 0);
-                        pthread_attr_init(&attr);
-                        pthread_cleanup_push(routine, 0);
-                        pthread_cleanup_pop(0) /* ; */
-  ;
-  return 0;
-}
-_ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
-  ax_pthread_ok=yes
-fi
-rm -f core conftest.err conftest.$ac_objext \
-    conftest$ac_exeext conftest.$ac_ext
-
-        LIBS="$save_LIBS"
-        CFLAGS="$save_CFLAGS"
-
-        { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_pthread_ok" >&5
-$as_echo "$ax_pthread_ok" >&6; }
-        if test "x$ax_pthread_ok" = xyes; then
-                break;
-        fi
-
-        PTHREAD_LIBS=""
-        PTHREAD_CFLAGS=""
-done
-fi
-
-# Various other checks:
-if test "x$ax_pthread_ok" = xyes; then
-        save_LIBS="$LIBS"
-        LIBS="$PTHREAD_LIBS $LIBS"
-        save_CFLAGS="$CFLAGS"
-        CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
-
-        # Detect AIX lossage: JOINABLE attribute is called UNDETACHED.
-        { $as_echo "$as_me:${as_lineno-$LINENO}: checking for joinable pthread attribute" >&5
-$as_echo_n "checking for joinable pthread attribute... " >&6; }
-        attr_name=unknown
-        for attr in PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_UNDETACHED; do
-            cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-#include <pthread.h>
-int
-main ()
-{
-int attr = $attr; return attr /* ; */
-  ;
-  return 0;
-}
-_ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
-  attr_name=$attr; break
-fi
-rm -f core conftest.err conftest.$ac_objext \
-    conftest$ac_exeext conftest.$ac_ext
-        done
-        { $as_echo "$as_me:${as_lineno-$LINENO}: result: $attr_name" >&5
-$as_echo "$attr_name" >&6; }
-        if test "$attr_name" != PTHREAD_CREATE_JOINABLE; then
-
-cat >>confdefs.h <<_ACEOF
-#define PTHREAD_CREATE_JOINABLE $attr_name
-_ACEOF
-
-        fi
-
-        { $as_echo "$as_me:${as_lineno-$LINENO}: checking if more special flags are required for pthreads" >&5
-$as_echo_n "checking if more special flags are required for pthreads... " >&6; }
-        flag=no
-        case ${host_os} in
-            aix* | freebsd* | darwin*) flag="-D_THREAD_SAFE";;
-            osf* | hpux*) flag="-D_REENTRANT";;
-            solaris*)
-            if test "$GCC" = "yes"; then
-                flag="-D_REENTRANT"
-            else
-                # TODO: What about Clang on Solaris?
-                flag="-mt -D_REENTRANT"
-            fi
-            ;;
-        esac
-        { $as_echo "$as_me:${as_lineno-$LINENO}: result: $flag" >&5
-$as_echo "$flag" >&6; }
-        if test "x$flag" != xno; then
-            PTHREAD_CFLAGS="$flag $PTHREAD_CFLAGS"
-        fi
-
-        { $as_echo "$as_me:${as_lineno-$LINENO}: checking for PTHREAD_PRIO_INHERIT" >&5
-$as_echo_n "checking for PTHREAD_PRIO_INHERIT... " >&6; }
-if ${ax_cv_PTHREAD_PRIO_INHERIT+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-
-                cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-#include <pthread.h>
-int
-main ()
-{
-int i = PTHREAD_PRIO_INHERIT;
-  ;
-  return 0;
-}
-_ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
-  ax_cv_PTHREAD_PRIO_INHERIT=yes
+  if test "x$ac_pt_PKG_CONFIG" = x; then
+    PKG_CONFIG=""
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    PKG_CONFIG=$ac_pt_PKG_CONFIG
+  fi
 else
-  ax_cv_PTHREAD_PRIO_INHERIT=no
-fi
-rm -f core conftest.err conftest.$ac_objext \
-    conftest$ac_exeext conftest.$ac_ext
-
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_PTHREAD_PRIO_INHERIT" >&5
-$as_echo "$ax_cv_PTHREAD_PRIO_INHERIT" >&6; }
-        if test "x$ax_cv_PTHREAD_PRIO_INHERIT" = "xyes"; then :
-
-$as_echo "#define HAVE_PTHREAD_PRIO_INHERIT 1" >>confdefs.h
-
+  PKG_CONFIG="$ac_cv_path_PKG_CONFIG"
 fi
 
-        LIBS="$save_LIBS"
-        CFLAGS="$save_CFLAGS"
-
-        # More AIX lossage: compile with *_r variant
-        if test "x$GCC" != xyes; then
-            case $host_os in
-                aix*)
-                case "x/$CC" in #(
-  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
-                   case "x$CC" in #(
-  x/*) :
-    if as_fn_executable_p ${CC}_r; then :
-  PTHREAD_CC="${CC}_r"
-fi ;; #(
-  *) :
-    for ac_prog in ${CC}_r
-do
-  # Extract the first word of "$ac_prog", so it can be a program name with args.
-set dummy $ac_prog; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_prog_PTHREAD_CC+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  if test -n "$PTHREAD_CC"; then
-  ac_cv_prog_PTHREAD_CC="$PTHREAD_CC" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-    for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
-    ac_cv_prog_PTHREAD_CC="$ac_prog"
-    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
-    break 2
-  fi
-done
-  done
-IFS=$as_save_IFS
-
-fi
 fi
-PTHREAD_CC=$ac_cv_prog_PTHREAD_CC
-if test -n "$PTHREAD_CC"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PTHREAD_CC" >&5
-$as_echo "$PTHREAD_CC" >&6; }
-else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+if test -n "$PKG_CONFIG"; then
+	_pkg_min_version=0.9.0
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking pkg-config is at least version $_pkg_min_version" >&5
+$as_echo_n "checking pkg-config is at least version $_pkg_min_version... " >&6; }
+	if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+	else
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
 $as_echo "no" >&6; }
+		PKG_CONFIG=""
+	fi
 fi
 
-
-  test -n "$PTHREAD_CC" && break
-done
-test -n "$PTHREAD_CC" || PTHREAD_CC="$CC"
- ;;
-esac ;; #(
-  *) :
-     ;;
-esac
-                ;;
-            esac
-        fi
+if test "x$PKG_CONFIG_PATH" = x; then
+   export PKG_CONFIG_PATH="$prefix/lib/pkgconfig"
+else
+   export PKG_CONFIG_PATH="$PKG_CONFIG_PATH:$prefix/lib/pkgconfig"
 fi
 
-test -n "$PTHREAD_CC" || PTHREAD_CC="$CC"
-
-
-
-
 
-# Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND:
-if test x"$ax_pthread_ok" = xyes; then
-
-$as_echo "#define HAVE_PTHREAD 1" >>confdefs.h
-
-        :
-else
-        ax_pthread_ok=no
-        as_fn_error $? "We need pthread support!" "$LINENO" 5
+# Check whether --with-icu was given.
+if test "${with_icu+set}" = set; then :
+  withval=$with_icu; PKG_CONFIG_PATH="$PKG_CONFIG_PATH:$withval/lib/pkgconfig"
 fi
-ac_ext=cpp
-ac_cpp='$CXXCPP $CPPFLAGS'
-ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
 
 
-
-if test x"$ax_pthread_ok" = xyes; then
-   LIBS="$PTHREAD_LIBS $LIBS" \
-   CXXFLAGS="$CXXFLAGS $PTHREAD_CFLAGS"
-fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: pkg-config search path: $PKG_CONFIG_PATH " >&5
+$as_echo "$as_me: pkg-config search path: $PKG_CONFIG_PATH " >&6;}
 
 
 
@@ -17181,172 +17075,6 @@ fi
 CXXFLAGS="$CXXFLAGS $XML2_CFLAGS"
 LIBS="$XML2_LIBS $LIBS"
 
-if test $prefix = "NONE"; then
-   prefix="$ac_default_prefix"
-fi
-useICU=1;
-# inspired by feh-1.3.4/configure.ac.  Tnx Tom Gilbert and feh hackers.
-
-# Check whether --with-icu was given.
-if test "${with_icu+set}" = set; then :
-  withval=$with_icu; if test "$with_icu" = "no"; then
-           useICU=0
-	else
-	   CXXFLAGS="$CXXFLAGS -I$withval/include"
-           LIBS="-L$withval/lib $LIBS"
-	fi
-fi
-
-
-if test "$useICU" = "1"; then
-
-  succeeded=no
-
-  if test -z "$ICU_CONFIG"; then
-     # Extract the first word of "icu-config", so it can be a program name with args.
-set dummy icu-config; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_path_ICU_CONFIG+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  case $ICU_CONFIG in
-  [\\/]* | ?:[\\/]*)
-  ac_cv_path_ICU_CONFIG="$ICU_CONFIG" # Let the user override the test with a path.
-  ;;
-  *)
-  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-    for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
-    ac_cv_path_ICU_CONFIG="$as_dir/$ac_word$ac_exec_ext"
-    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
-    break 2
-  fi
-done
-  done
-IFS=$as_save_IFS
-
-  test -z "$ac_cv_path_ICU_CONFIG" && ac_cv_path_ICU_CONFIG="no"
-  ;;
-esac
-fi
-ICU_CONFIG=$ac_cv_path_ICU_CONFIG
-if test -n "$ICU_CONFIG"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ICU_CONFIG" >&5
-$as_echo "$ICU_CONFIG" >&6; }
-else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
-
-  fi
-
-  if test "$ICU_CONFIG" = "no" ; then
-     echo "*** The icu-config script could not be found. Make sure it is"
-     echo "*** in your path, and that taglib is properly installed."
-     echo "*** Or see http://www.icu-project.org/"
-  else
-	ICU_VERSION=`$ICU_CONFIG --version`
-	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ICU >= 4.2" >&5
-$as_echo_n "checking for ICU >= 4.2... " >&6; }
-	VERSION_CHECK=`expr $ICU_VERSION \>\= 4.2`
-	if test "$VERSION_CHECK" = "1" ; then
-	   { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
-$as_echo "yes" >&6; }
-	   succeeded=yes
-
-	   { $as_echo "$as_me:${as_lineno-$LINENO}: checking ICU_CFLAGS" >&5
-$as_echo_n "checking ICU_CFLAGS... " >&6; }
-	   ICU_CFLAGS=`$ICU_CONFIG --cflags`
-	   { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ICU_CFLAGS" >&5
-$as_echo "$ICU_CFLAGS" >&6; }
-
-	   { $as_echo "$as_me:${as_lineno-$LINENO}: checking ICU_CPPSEARCHPATH" >&5
-$as_echo_n "checking ICU_CPPSEARCHPATH... " >&6; }
-	   ICU_CPPSEARCHPATH=`$ICU_CONFIG --cppflags-searchpath`
-	   { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ICU_CPPSEARCHPATH" >&5
-$as_echo "$ICU_CPPSEARCHPATH" >&6; }
-
-	   { $as_echo "$as_me:${as_lineno-$LINENO}: checking ICU_CXXFLAGS" >&5
-$as_echo_n "checking ICU_CXXFLAGS... " >&6; }
-	   ICU_CXXFLAGS=`$ICU_CONFIG --cxxflags`
-	   { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ICU_CXXFLAGS" >&5
-$as_echo "$ICU_CXXFLAGS" >&6; }
-
-	   { $as_echo "$as_me:${as_lineno-$LINENO}: checking ICU_LIBS" >&5
-$as_echo_n "checking ICU_LIBS... " >&6; }
-	   ICU_LIBS=`$ICU_CONFIG --ldflags-libsonly`
-	   { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ICU_LIBS" >&5
-$as_echo "$ICU_LIBS" >&6; }
-
-	   { $as_echo "$as_me:${as_lineno-$LINENO}: checking ICU_LIBPATH" >&5
-$as_echo_n "checking ICU_LIBPATH... " >&6; }
-	   ICU_LIBPATH=`$ICU_CONFIG --ldflags-searchpath`
-	   { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ICU_LIBPATH" >&5
-$as_echo "$ICU_LIBPATH" >&6; }
-
-	   { $as_echo "$as_me:${as_lineno-$LINENO}: checking ICU_IOLIBS" >&5
-$as_echo_n "checking ICU_IOLIBS... " >&6; }
-	   ICU_IOLIBS=`$ICU_CONFIG --ldflags-icuio`
-	   { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ICU_IOLIBS" >&5
-$as_echo "$ICU_IOLIBS" >&6; }
-	else
-	   ICU_CFLAGS=""
-	   ICU_CXXFLAGS=""
-	   ICU_CPPSEARCHPATH=""
-	   ICU_LIBPATH=""
-	   ICU_LIBS=""
-	   ICU_IOLIBS=""
-	   ## If we have a custom action on failure, don't print errors, but
-	   ## do set a variable so people can do so.
-
-        fi
-
-
-
-
-
-
-
-
-  fi
-
-  if test $succeeded = yes; then
-     CXXFLAGS="$CXXFLAGS $ICU_CPPSEARCHPATH"
-		LIBS="$ICU_LIBPATH $ICU_LIBS $ICU_IOLIBS $LIBS"
-  else
-     { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
-$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-as_fn_error $? "\"No ICU development environment found. Please check if libicu-dev or the like is installed\"
-See \`config.log' for more details" "$LINENO" 5; }
-  fi
-
-
-$as_echo "#define HAVE_ICU 1" >>confdefs.h
-
-else
-  as_fn_error $? "\"ICU support is required\"" "$LINENO" 5
-fi
-
-# ugly hack when PKG_CONFIG_PATH isn't defined.
-# couldn't get it to work otherwise
-if test "x$PKG_CONFIG_PATH" = x; then
-     export PKG_CONFIG_PATH=""
-fi
-
-# Check whether --with-ticcutils was given.
-if test "${with_ticcutils+set}" = set; then :
-  withval=$with_ticcutils; PKG_CONFIG_PATH="$PKG_CONFIG_PATH:$withval/lib/pkgconfig"
-else
-  PKG_CONFIG_PATH="$PKG_CONFIG_PATH:$prefix/lib/pkgconfig"
-fi
-
-#  AC_MSG_NOTICE( [pkg-config search path: $PKG_CONFIG_PATH] )
 
 pkg_failed=no
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ticcutils" >&5
@@ -17442,6 +17170,99 @@ CXXFLAGS="$CXXFLAGS $ticcutils_CFLAGS"
 LIBS="$ticcutils_LIBS $LIBS"
 
 
+pkg_failed=no
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ICU" >&5
+$as_echo_n "checking for ICU... " >&6; }
+
+if test -n "$ICU_CFLAGS"; then
+    pkg_cv_ICU_CFLAGS="$ICU_CFLAGS"
+ elif test -n "$PKG_CONFIG"; then
+    if test -n "$PKG_CONFIG" && \
+    { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"icu-uc >= 50 icu-io \""; } >&5
+  ($PKG_CONFIG --exists --print-errors "icu-uc >= 50 icu-io ") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then
+  pkg_cv_ICU_CFLAGS=`$PKG_CONFIG --cflags "icu-uc >= 50 icu-io " 2>/dev/null`
+		      test "x$?" != "x0" && pkg_failed=yes
+else
+  pkg_failed=yes
+fi
+ else
+    pkg_failed=untried
+fi
+if test -n "$ICU_LIBS"; then
+    pkg_cv_ICU_LIBS="$ICU_LIBS"
+ elif test -n "$PKG_CONFIG"; then
+    if test -n "$PKG_CONFIG" && \
+    { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"icu-uc >= 50 icu-io \""; } >&5
+  ($PKG_CONFIG --exists --print-errors "icu-uc >= 50 icu-io ") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then
+  pkg_cv_ICU_LIBS=`$PKG_CONFIG --libs "icu-uc >= 50 icu-io " 2>/dev/null`
+		      test "x$?" != "x0" && pkg_failed=yes
+else
+  pkg_failed=yes
+fi
+ else
+    pkg_failed=untried
+fi
+
+
+
+if test $pkg_failed = yes; then
+   	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
+        _pkg_short_errors_supported=yes
+else
+        _pkg_short_errors_supported=no
+fi
+        if test $_pkg_short_errors_supported = yes; then
+	        ICU_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "icu-uc >= 50 icu-io " 2>&1`
+        else
+	        ICU_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "icu-uc >= 50 icu-io " 2>&1`
+        fi
+	# Put the nasty error message in config.log where it belongs
+	echo "$ICU_PKG_ERRORS" >&5
+
+	as_fn_error $? "Package requirements (icu-uc >= 50 icu-io ) were not met:
+
+$ICU_PKG_ERRORS
+
+Consider adjusting the PKG_CONFIG_PATH environment variable if you
+installed software in a non-standard prefix.
+
+Alternatively, you may set the environment variables ICU_CFLAGS
+and ICU_LIBS to avoid the need to call pkg-config.
+See the pkg-config man page for more details." "$LINENO" 5
+elif test $pkg_failed = untried; then
+     	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+	{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "The pkg-config script could not be found or is too old.  Make sure it
+is in your PATH or set the PKG_CONFIG environment variable to the full
+path to pkg-config.
+
+Alternatively, you may set the environment variables ICU_CFLAGS
+and ICU_LIBS to avoid the need to call pkg-config.
+See the pkg-config man page for more details.
+
+To get pkg-config, see <http://pkg-config.freedesktop.org/>.
+See \`config.log' for more details" "$LINENO" 5; }
+else
+	ICU_CFLAGS=$pkg_cv_ICU_CFLAGS
+	ICU_LIBS=$pkg_cv_ICU_LIBS
+        { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+fi
+CXXFLAGS="$CXXFLAGS $ICU_CFLAGS"
+LIBS="$ICU_LIBS $LIBS"
+
 ac_config_files="$ac_config_files Makefile folia.pc m4/Makefile src/Makefile include/Makefile include/libfolia/Makefile"
 
 cat >confcache <<\_ACEOF
@@ -17978,7 +17799,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
 # report actual input values of CONFIG_FILES etc. instead of their
 # values after options handling.
 ac_log="
-This file was extended by libfolia $as_me 1.6, which was
+This file was extended by libfolia $as_me 1.10, which was
 generated by GNU Autoconf 2.69.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
@@ -18044,7 +17865,7 @@ _ACEOF
 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
 ac_cs_version="\\
-libfolia config.status 1.6
+libfolia config.status 1.10
 configured by $0, generated by GNU Autoconf 2.69,
   with options \\"\$ac_cs_config\\"
 
diff --git a/configure.ac b/configure.ac
index 3560e9f..82b3eb5 100644
--- a/configure.ac
+++ b/configure.ac
@@ -2,7 +2,7 @@
 # Process this file with autoconf to produce a configure script.
 
 AC_PREREQ(2.59)
-AC_INIT([libfolia], [1.6], [lamasoftware at science.ru.nl])
+AC_INIT([libfolia], [1.10], [lamasoftware at science.ru.nl])
 AM_INIT_AUTOMAKE([foreign])
 AC_CONFIG_SRCDIR([configure.ac])
 AC_CONFIG_MACRO_DIR([m4])
@@ -39,67 +39,43 @@ AC_C_INLINE
 AC_TYPE_SIZE_T
 
 # Checks for library functions.
-AX_PTHREAD([],[AC_MSG_ERROR([We need pthread support!])])
-
-if test x"$ax_pthread_ok" = xyes; then
-   LIBS="$PTHREAD_LIBS $LIBS" \
-   CXXFLAGS="$CXXFLAGS $PTHREAD_CFLAGS"
-fi
-
 AC_CHECK_FUNCS([localtime_r])
 
 AX_PTHREAD([],[AC_MSG_ERROR([We need pthread support!])])
+LIBS="$PTHREAD_LIBS $LIBS"
+CXXFLAGS="$CXXFLAGS $PTHREAD_CFLAGS"
 
-if test x"$ax_pthread_ok" = xyes; then
-   LIBS="$PTHREAD_LIBS $LIBS" \
-   CXXFLAGS="$CXXFLAGS $PTHREAD_CFLAGS"
+if test $prefix = "NONE"; then
+   prefix="$ac_default_prefix"
 fi
 
 PKG_PROG_PKG_CONFIG
-PKG_CHECK_MODULES([XML2], [libxml-2.0 >= 2.6.16] )
-CXXFLAGS="$CXXFLAGS $XML2_CFLAGS"
-LIBS="$XML2_LIBS $LIBS"
 
-if test $prefix = "NONE"; then
-   prefix="$ac_default_prefix"
-fi
-useICU=1;
-# inspired by feh-1.3.4/configure.ac.  Tnx Tom Gilbert and feh hackers.
-AC_ARG_WITH(icu,
-       [  --with-icu=DIR       use ICU installed in <DIR>],
-       [if test "$with_icu" = "no"; then
-           useICU=0
-	else
-	   CXXFLAGS="$CXXFLAGS -I$withval/include"
-           LIBS="-L$withval/lib $LIBS"
-	fi] )
-
-if test "$useICU" = "1"; then
-  AX_ICU_CHECK( [4.2],
-		[CXXFLAGS="$CXXFLAGS $ICU_CPPSEARCHPATH"
-		LIBS="$ICU_LIBPATH $ICU_LIBS $ICU_IOLIBS $LIBS"],
-		[AC_MSG_FAILURE( "No ICU development environment found. Please check if libicu-dev or the like is installed" )] )
-  AC_DEFINE(HAVE_ICU, 1, we want to use ICU )
+if test "x$PKG_CONFIG_PATH" = x; then
+   export PKG_CONFIG_PATH="$prefix/lib/pkgconfig"
 else
-  AC_MSG_ERROR("ICU support is required")
+   export PKG_CONFIG_PATH="$PKG_CONFIG_PATH:$prefix/lib/pkgconfig"
 fi
 
-# ugly hack when PKG_CONFIG_PATH isn't defined.
-# couldn't get it to work otherwise
-if test "x$PKG_CONFIG_PATH" = x; then
-     export PKG_CONFIG_PATH=""
-fi
-AC_ARG_WITH(ticcutils,
-       [  --with-ticcutils=DIR       use ticcutils installed in <DIR>;
-               note that you can install ticcutils in a non-default directory with
-               ./configure --prefix=<DIR> in the ticcutils installation directory],
+AC_ARG_WITH(icu,
+       [  --with-icu=DIR       use icu installed in <DIR>],
        [PKG_CONFIG_PATH="$PKG_CONFIG_PATH:$withval/lib/pkgconfig"],
-       [PKG_CONFIG_PATH="$PKG_CONFIG_PATH:$prefix/lib/pkgconfig"])
-#  AC_MSG_NOTICE( [pkg-config search path: $PKG_CONFIG_PATH] )
+       [])
+
+AC_MSG_NOTICE( [pkg-config search path: $PKG_CONFIG_PATH] )
+
+PKG_PROG_PKG_CONFIG
+PKG_CHECK_MODULES([XML2], [libxml-2.0 >= 2.6.16] )
+CXXFLAGS="$CXXFLAGS $XML2_CFLAGS"
+LIBS="$XML2_LIBS $LIBS"
+
 PKG_CHECK_MODULES([ticcutils], [ticcutils >= 0.14] )
 CXXFLAGS="$CXXFLAGS $ticcutils_CFLAGS"
 LIBS="$ticcutils_LIBS $LIBS"
 
+PKG_CHECK_MODULES([ICU], [icu-uc >= 50 icu-io] )
+CXXFLAGS="$CXXFLAGS $ICU_CFLAGS"
+LIBS="$ICU_LIBS $LIBS"
 
 AC_OUTPUT([
   Makefile
diff --git a/include/Makefile.in b/include/Makefile.in
index e5b3bb0..dff4b67 100644
--- a/include/Makefile.in
+++ b/include/Makefile.in
@@ -91,11 +91,11 @@ build_triplet = @build@
 host_triplet = @host@
 subdir = include
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
-am__aclocal_m4_deps = $(top_srcdir)/m4/ax_icu_check.m4 \
-	$(top_srcdir)/m4/ax_pthread.m4 $(top_srcdir)/m4/libtool.m4 \
-	$(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
-	$(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
-	$(top_srcdir)/m4/pkg.m4 $(top_srcdir)/configure.ac
+am__aclocal_m4_deps = $(top_srcdir)/m4/ax_pthread.m4 \
+	$(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
+	$(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
+	$(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/pkg.m4 \
+	$(top_srcdir)/configure.ac
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
 	$(ACLOCAL_M4)
 DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
@@ -216,13 +216,7 @@ EXEEXT = @EXEEXT@
 FGREP = @FGREP@
 GREP = @GREP@
 ICU_CFLAGS = @ICU_CFLAGS@
-ICU_CONFIG = @ICU_CONFIG@
-ICU_CPPSEARCHPATH = @ICU_CPPSEARCHPATH@
-ICU_CXXFLAGS = @ICU_CXXFLAGS@
-ICU_IOLIBS = @ICU_IOLIBS@
-ICU_LIBPATH = @ICU_LIBPATH@
 ICU_LIBS = @ICU_LIBS@
-ICU_VERSION = @ICU_VERSION@
 INSTALL = @INSTALL@
 INSTALL_DATA = @INSTALL_DATA@
 INSTALL_PROGRAM = @INSTALL_PROGRAM@
diff --git a/include/libfolia/Makefile.in b/include/libfolia/Makefile.in
index 09cba8b..efb0dae 100644
--- a/include/libfolia/Makefile.in
+++ b/include/libfolia/Makefile.in
@@ -90,11 +90,11 @@ build_triplet = @build@
 host_triplet = @host@
 subdir = include/libfolia
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
-am__aclocal_m4_deps = $(top_srcdir)/m4/ax_icu_check.m4 \
-	$(top_srcdir)/m4/ax_pthread.m4 $(top_srcdir)/m4/libtool.m4 \
-	$(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
-	$(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
-	$(top_srcdir)/m4/pkg.m4 $(top_srcdir)/configure.ac
+am__aclocal_m4_deps = $(top_srcdir)/m4/ax_pthread.m4 \
+	$(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
+	$(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
+	$(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/pkg.m4 \
+	$(top_srcdir)/configure.ac
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
 	$(ACLOCAL_M4)
 DIST_COMMON = $(srcdir)/Makefile.am $(pkginclude_HEADERS) \
@@ -203,13 +203,7 @@ EXEEXT = @EXEEXT@
 FGREP = @FGREP@
 GREP = @GREP@
 ICU_CFLAGS = @ICU_CFLAGS@
-ICU_CONFIG = @ICU_CONFIG@
-ICU_CPPSEARCHPATH = @ICU_CPPSEARCHPATH@
-ICU_CXXFLAGS = @ICU_CXXFLAGS@
-ICU_IOLIBS = @ICU_IOLIBS@
-ICU_LIBPATH = @ICU_LIBPATH@
 ICU_LIBS = @ICU_LIBS@
-ICU_VERSION = @ICU_VERSION@
 INSTALL = @INSTALL@
 INSTALL_DATA = @INSTALL_DATA@
 INSTALL_PROGRAM = @INSTALL_PROGRAM@
diff --git a/include/libfolia/folia_document.h b/include/libfolia/folia_document.h
index b64a272..40b538c 100644
--- a/include/libfolia/folia_document.h
+++ b/include/libfolia/folia_document.h
@@ -79,21 +79,24 @@ namespace folia {
   class Document {
     friend bool operator==( const Document&, const Document& );
     friend std::ostream& operator<<( std::ostream&, const Document * );
+    enum Mode { NOMODE=0, PERMISSIVE=1, CHECKTEXT=2, FIXTEXT=4, STRIP=8 };
+
   public:
     Document();
-    Document( const std::string& );
+    explicit Document( const std::string& );
     ~Document();
     void init();
     bool readFromFile( const std::string& );
     bool readFromString( const std::string& );
-    bool save( std::ostream&, const std::string&, bool = false );
-    bool save( std::ostream& os, bool kanon = false ){
+    bool save( std::ostream&, const std::string&, bool = false ) const;
+    bool save( std::ostream& os, bool kanon = false ) const {
       return save( os, "", kanon );
     }
-    bool save( const std::string&, const std::string&, bool = false );
-    bool save( const std::string& s, bool kanon = false ){
+    bool save( const std::string&, const std::string&, bool = false ) const ;
+    bool save( const std::string& s, bool kanon = false ) const {
       return save( s, "", kanon );
     }
+    std::string xmlstring( bool k = false ) const;
     int size() const;
     FoliaElement* doc() const { return foliadoc; }
     Text* addText( const KWargs& );
@@ -127,8 +130,8 @@ namespace folia {
     bool toXml( const std::string&,
 		const std::string& ="",
 		bool = false ) const;
-    std::string metadatatype() const { return _metadatatype; };
-    std::string metadatafile() const { return _metadatafile; };
+    std::string metadatatype() const;
+    std::string metadatafile() const;
     void set_metadata( const std::string& type, const std::string& value );
     const std::string get_metadata( const std::string& type ) const;
 
@@ -144,6 +147,10 @@ namespace folia {
 		     const std::string&,
 		     const std::string& );
     bool isDeclared( AnnotationType::AnnotationType, const std::string& = "" );
+    std::string unalias( AnnotationType::AnnotationType,
+			 const std::string& ) const;
+    std::string alias( AnnotationType::AnnotationType,
+		       const std::string& ) const;
     std::string defaultset( AnnotationType::AnnotationType ) const;
 
     std::string defaultannotator( AnnotationType::AnnotationType,
@@ -157,20 +164,30 @@ namespace folia {
     FoliaElement* parseXml( );
 
     std::string id() const { return _id; };
-    std::string language() const { return _language; };
+    std::string language() const;
     void declare( AnnotationType::AnnotationType,
 		  const std::string&,
 		  const std::string& = "" );
     void declare( AnnotationType::AnnotationType,
 		  const std::string&, const std::string&,
-		  const std::string&, const std::string& );
+		  const std::string&, const std::string&,
+		  const std::string& = "" );
+    void un_declare( AnnotationType::AnnotationType,
+		     const std::string& );
     xmlDoc *XmlDoc() const { return _xmldoc; };
     xmlNs *foliaNs() const { return _foliaNsOut; };
     void keepForDeletion( FoliaElement *p ) { delSet.insert( p ); };
     void addExternal( External *p ) { externals.push_back( p ); };
     FoliaElement *resolveExternals( FoliaElement* );
     int debug;
-    bool permissive() const { return mode == "permissive"; };
+    bool permissive() const { return mode & PERMISSIVE; };
+    bool checktext() const {
+      return mode & CHECKTEXT;
+    };
+    bool fixtext() const {
+      return mode & FIXTEXT;
+    };
+    bool strip() const { return mode & STRIP; };
     class at_t {
       friend std::ostream& operator<<( std::ostream&, const at_t& );
     public:
@@ -179,17 +196,49 @@ namespace folia {
       std::string t;
       std::string d;
     };
+    void incrRef( AnnotationType::AnnotationType, const std::string& );
+    void decrRef( AnnotationType::AnnotationType, const std::string& );
+    void setmode( const std::string& );
+    std::string getmode() const;
+    std::multimap<AnnotationType::AnnotationType,std::string> unused_declarations( ) const;
+      const MetaData *get_submetadata( const std::string& m ){
+      const auto& it = submetadata.find( m );
+      if ( it == submetadata.end() ){
+	return 0;
+      } else {
+	return it->second;
+      }
+    }
+    void cache_textcontent( TextContent *tc ){
+      t_offset_validation_buffer.push_back( tc );
+    }
+    void cache_phoncontent( PhonContent *tc ){
+      p_offset_validation_buffer.push_back( tc );
+    }
+    bool validate_offsets() const;
+    static int compare_to_lib_version( const std::string& );
+    static std::string library_version();
+    std::string version() const { return _version; };
+    std::string update_version();
   private:
     std::map<AnnotationType::AnnotationType,std::multimap<std::string,at_t> > annotationdefaults;
     std::vector<std::pair<AnnotationType::AnnotationType,std::string>> anno_sort;
+    std::map<AnnotationType::AnnotationType,std::map<std::string,int> > annotationrefs;
+    std::map<AnnotationType::AnnotationType,std::map<std::string,std::string>> alias_set;
+    std::map<AnnotationType::AnnotationType,std::map<std::string,std::string>> set_alias;
+    std::vector<TextContent*> t_offset_validation_buffer;
+    std::vector<PhonContent*> p_offset_validation_buffer;
+
     FoliaElement* parseFoliaDoc( xmlNode * );
     void parsemeta( xmlNode * );
     void setimdi( xmlNode * );
-    void setDocumentProps( KWargs&  );
+    void setDocumentProps( KWargs& );
     void parseannotations( xmlNode * );
+    void parsesubmeta( xmlNode * );
     void getstyles();
     void setannotations( xmlNode *) const;
     void setmetadata( xmlNode * ) const;
+    void addsubmetadata( xmlNode *) const;
     void setstyles( xmlDoc* ) const;
     xmlDoc *to_xmlDoc( const std::string& ="", bool=false ) const;
     std::map<std::string, FoliaElement* > sindex;
@@ -203,20 +252,12 @@ namespace folia {
     const xmlChar* _foliaNsIn_href;
     const xmlChar* _foliaNsIn_prefix;
     mutable xmlNs *_foliaNsOut;
-    std::string _metadatatype;
-    xmlNode *_metadata;
-    std::vector<ForeignData *> _foreigndata;
-    std::string _metadatafile;
-    std::string _title;
-    std::string _date;
-    std::string _language;
-    std::string _publisher;
-    std::string _license;
-    std::map<std::string,std::string> meta_atts;
+    MetaData *_metadata;
+    std::map<std::string,MetaData *> submetadata;
     std::multimap<std::string,std::string> styles;
-    std::string mode;
+    Mode mode;
     std::string filename;
-    std::string version;
+    std::string _version;
     bool external;
     Document( const Document& ); // inhibit copies
     Document& operator=( const Document& ); // inhibit copies
diff --git a/include/libfolia/folia_impl.h b/include/libfolia/folia_impl.h
index b7de9e5..b400d1b 100644
--- a/include/libfolia/folia_impl.h
+++ b/include/libfolia/folia_impl.h
@@ -56,6 +56,7 @@ namespace folia {
   class DependencyDependent;
   class Paragraph;
   class Morpheme;
+  class MetaData;
 
   class properties;
   extern const std::set<ElementType> default_ignore_annotations;
@@ -201,6 +202,9 @@ namespace folia {
     virtual MorphologyLayer *getMorphologyLayers( const std::string&,
 						  std::vector<MorphologyLayer*>& ) const NOT_IMPLEMENTED;
 
+    virtual const MetaData *getmetadata() const = 0;
+    virtual const std::string getmetadata( const std::string& ) const = 0;
+
     template <typename F>
       std::vector<F*> annotations( const std::string& s = "" ) const {
       if ( allowannotations() ){
@@ -270,6 +274,9 @@ namespace folia {
 
     // text/string content
     bool hastext( const std::string& = "current" ) const;
+    bool hasphon( const std::string& = "current" ) const;
+    virtual void check_text_consistency() const = 0;
+    virtual void check_append_text_consistency( const FoliaElement * ) const = 0;
 
     virtual const std::string str( const std::string& = "current" ) const = 0;
     const UnicodeString unicode( const std::string& cls = "current" ) const { return text( cls ); };
@@ -281,6 +288,8 @@ namespace folia {
 				bool = false ) const = 0;
     virtual bool printable() const = 0;
     virtual bool speakable() const = 0;
+    virtual bool is_textcontainer() const = 0;
+    virtual bool is_phoncontainer() const = 0;
 
     // Word
     virtual Word *previous() const NOT_IMPLEMENTED;
@@ -293,7 +302,7 @@ namespace folia {
     virtual std::vector<Word*> rightcontext( size_t,
 					     const std::string& ="" ) const NOT_IMPLEMENTED;
     virtual Word *addWord( const KWargs& ) = 0;
-    Word *addWord( const std::string& s ){
+    Word *addWord( const std::string& s="" ){
       return addWord( getArgs(s) );
     }
 
@@ -334,15 +343,22 @@ namespace folia {
     virtual Correction *correct( const std::string& = "" ) NOT_IMPLEMENTED;
 
     // TextContent
-    virtual TextContent *textcontent( const std::string& = "current" ) const = 0;
-    TextContent *settext( const std::string&, const std::string& = "current" );
-    TextContent *settext( const std::string&, int , const std::string& = "current" );
-    TextContent *setutext( const UnicodeString&, const std::string& = "current" );
-    TextContent *setutext( const UnicodeString&, int , const std::string& = "current" );
+    virtual const TextContent *textcontent( const std::string& = "current" ) const = 0;
+    TextContent *settext( const std::string&,
+			  const std::string& = "current" );
+    TextContent *settext( const std::string&,
+			  int,
+			  const std::string& = "current" );
+    TextContent *setutext( const UnicodeString&,
+			   const std::string& = "current" );
+    TextContent *setutext( const UnicodeString&,
+			   int ,
+			   const std::string& = "current" );
     virtual int offset() const NOT_IMPLEMENTED;
 
+    void cleartextcontent( const std::string& = "current" );
     // PhonContent
-    virtual PhonContent *phoncontent( const std::string& = "current" ) const = 0;
+    virtual const PhonContent *phoncontent( const std::string& = "current" ) const = 0;
 
     // properties
     virtual const std::string& getTextDelimiter( bool retaintok=false ) const = 0;
@@ -359,6 +375,7 @@ namespace folia {
     virtual const std::string speech_src() const = 0;
     virtual const std::string speech_speaker() const = 0;
     virtual const std::string language( const std::string& = "" ) const = 0;
+    virtual const std::string set_to_current() NOT_IMPLEMENTED;
     virtual double confidence() const = 0;
     virtual void confidence( double ) = 0;
     virtual ElementType element_id() const = 0;
@@ -434,6 +451,7 @@ namespace folia {
     virtual void setAttributes( const KWargs& ) = 0;
     virtual KWargs collectAttributes() const = 0;
     virtual void setAuth( bool b ) = 0;
+    virtual bool auth( ) const = 0;
     virtual const std::string generateId( const std::string& ) NOT_IMPLEMENTED;
   };
 
@@ -457,7 +475,7 @@ namespace folia {
 
     void classInit( const KWargs& a ){
       // this funcion is needed because calling the virtual function
-      // setAttributes from the constuctor will NOT call the right version
+      // setAttributes from the constructor will NOT call the right version
       // THIS IS BY DESIGN.
       init(); // virtual init
       setAttributes( a ); // also virtual!
@@ -483,7 +501,7 @@ namespace folia {
     bool acceptable( ElementType ) const;
     bool addable( const FoliaElement * ) const;
     FoliaElement *append( FoliaElement* );
-    FoliaElement *postappend( ) { return this; };
+    FoliaElement *postappend( );
     void remove( size_t, bool = true );
     void remove( FoliaElement *, bool = true );
     std::vector<FoliaElement*> findreplacables( FoliaElement * ) const;
@@ -493,6 +511,10 @@ namespace folia {
     // Sentences
     Sentence *addSentence( const KWargs& );
 
+    const MetaData *getmetadata() const;
+    const std::string getmetadata( const std::string&  ) const;
+
+
     // Selections
     template <typename F>
       std::vector<F*> select( bool recurse = true ) const {
@@ -577,9 +599,9 @@ namespace folia {
     Word *addWord( const KWargs& );
 
     // TextContent
-    TextContent *textcontent( const std::string& = "current" ) const;
+    const TextContent *textcontent( const std::string& = "current" ) const;
     // PhonContent
-    PhonContent *phoncontent( const std::string& = "current" ) const;
+    const PhonContent *phoncontent( const std::string& = "current" ) const;
 
     // properties
     const std::string& getTextDelimiter( bool retaintok=false ) const;
@@ -593,6 +615,7 @@ namespace folia {
     const std::string id() const { return _id; };
     const std::string begintime() const { return _begintime; };
     const std::string endtime() const { return _endtime; };
+    const std::string textclass() const { return _textclass; };
     const std::string speech_src() const;
     const std::string speech_speaker() const;
     const std::string language( const std::string& = "" ) const;
@@ -614,6 +637,8 @@ namespace folia {
     const std::set<ElementType>& required_data() const;
     bool printable() const;
     bool speakable() const;
+    bool is_textcontainer() const;
+    bool is_phoncontainer() const;
     bool xlink() const;
     bool auth() const;
     bool setonly() const;
@@ -622,6 +647,8 @@ namespace folia {
     Document *doc() const { return mydoc; };
 
     bool checkAtts();
+    void check_text_consistency() const;
+    void check_append_text_consistency( const FoliaElement * ) const;
 
     std::vector<FoliaElement*> select( ElementType elementtype,
 				       bool = true ) const;
@@ -661,6 +688,8 @@ namespace folia {
     std::string _begintime;
     std::string _endtime;
     std::string _speaker;
+    std::string _textclass;
+    std::string _metadata;
     AnnotatorType _annotator_type;
     double _confidence;
     int _refcount;
@@ -757,7 +786,7 @@ namespace folia {
       // DO NOT USE AbstractStructureElement as a real node!!
     AbstractStructureElement( const properties& props, Document *d=0 ):
       FoliaImpl( props, d ){ classInit(); };
-    AbstractStructureElement( Document *d=0 ):
+      explicit AbstractStructureElement( Document *d=0 ):
       FoliaImpl( PROPS, d ) { classInit(); };
     public:
       std::vector<Alternative *> alternatives( ElementType = BASE,
@@ -787,7 +816,7 @@ namespace folia {
     // DO NOT USE AbstractTokenAnnotation as a real node!!
     AbstractTokenAnnotation( const properties& props, Document *d=0 ):
       FoliaImpl( props, d ){ classInit(); };
-    AbstractTokenAnnotation( Document *d=0 ):
+      explicit AbstractTokenAnnotation( Document *d=0 ):
       FoliaImpl( PROPS, d ){ classInit(); };
 
     private:
@@ -806,7 +835,7 @@ namespace folia {
       // DO NOT USE AbstractSpanAnnotation as a real node!!
     AbstractSpanAnnotation( const properties& props, Document *d=0 ):
       FoliaImpl( props, d ){ classInit(); };
-    AbstractSpanAnnotation( Document *d=0 ):
+      explicit AbstractSpanAnnotation( Document *d=0 ):
       FoliaImpl( PROPS, d ){ classInit(); };
     public:
       xmlNode *xml( bool, bool=false ) const;
@@ -823,10 +852,10 @@ namespace folia {
     {
       friend void static_init();
     protected:
-    // DO NOT USE AbstractExtendedTokenAnnotation as a real node!!
+      // DO NOT USE AbstractExtendedTokenAnnotation as a real node!!
     AbstractExtendedTokenAnnotation( const properties& props, Document *d=0 ):
       AbstractTokenAnnotation( props, d ){ classInit(); };
-    AbstractExtendedTokenAnnotation( Document *d=0 ):
+      explicit AbstractExtendedTokenAnnotation( Document *d=0 ):
       AbstractTokenAnnotation( PROPS, d ){ classInit(); };
 
     private:
@@ -836,7 +865,7 @@ namespace folia {
   class ComplexAlignment: public FoliaImpl {
     friend void static_init();
   public:
-  ComplexAlignment( Document *d=0 ):
+    explicit ComplexAlignment( Document *d=0 ):
     FoliaImpl( PROPS, d ){ classInit(); }
   ComplexAlignment( const KWargs& a, Document *d=0 ):
     FoliaImpl( PROPS, d ){ classInit( a ); }
@@ -848,10 +877,10 @@ namespace folia {
   class ForeignData: public FoliaImpl {
     friend void static_init();
   public:
+    explicit ForeignData( Document *d=0 ):
+    FoliaImpl( PROPS, d ){ classInit(); };
   ForeignData( const properties& props, Document *d=0 ):
     FoliaImpl( props, d ){ classInit(); };
-  ForeignData( Document *d=0 ):
-    FoliaImpl( PROPS, d ){ classInit(); };
     ~ForeignData();
 
     FoliaElement* parseXml( const xmlNode * );
@@ -864,6 +893,69 @@ namespace folia {
     xmlNode *_foreign_data;
   };
 
+#define META_NOT_IMPLEMENTED {						\
+    throw NotImplementedError( "MetaTags::" + std::string(__func__) ); \
+  }
+
+  class MetaData {
+  public:
+  MetaData( const std::string& type ): _type(type){};
+    virtual ~MetaData(){};
+    virtual void add_av( const std::string&, const std::string& ) META_NOT_IMPLEMENTED;
+    virtual const KWargs& get_avs() const META_NOT_IMPLEMENTED;
+    virtual const std::string get_val( const std::string& ) const {
+      return "";
+    }
+    virtual void add_foreign( const xmlNode * ) META_NOT_IMPLEMENTED;
+    virtual std::string datatype() const { return "BaseMetaData"; };
+    std::string type() const { return _type; };
+    virtual std::string src() const META_NOT_IMPLEMENTED;
+    virtual const std::vector<FoliaElement*> get_foreigners() const META_NOT_IMPLEMENTED;
+  private:
+    std::string _type;
+  };
+
+  class NativeMetaData: public MetaData {
+  public:
+    explicit NativeMetaData( const std::string& t ): MetaData(t) {};
+    void add_av( const std::string& a, const std::string& v )
+    { _attribs[a] = v; };
+    const KWargs& get_avs() const {
+      return _attribs;
+    }
+    const std::string get_val( const std::string& at ) const {
+      auto const& it = _attribs.find( at );
+      if ( it != _attribs.end() ){
+	return it->second;
+      }
+      return "";
+    }
+    std::string datatype() const { return "NativeMetaData"; };
+  private:
+    KWargs _attribs;
+  };
+
+  class ForeignMetaData: public MetaData {
+  public:
+  ForeignMetaData( const std::string& t ): MetaData(t) {};
+    ~ForeignMetaData();
+    void add_foreign( const xmlNode * );
+    std::string datatype() const { return "ForeignMetaData"; };
+    const std::vector<FoliaElement*> get_foreigners() const { return foreigners;};
+  private:
+    std::vector<FoliaElement*> foreigners;
+  };
+
+  class ExternalMetaData: public MetaData {
+  public:
+  ExternalMetaData( const std::string& t,
+		    const std::string& src ): MetaData(t) { _src = src; };
+    std::string datatype() const { return "ExternalMetaData"; };
+    std::string src() const { return _src; };
+  private:
+    std::string _src;
+  };
+
   const std::string EMPTY_STRING = "";
 
   class AbstractTextMarkup: public FoliaImpl {
@@ -872,7 +964,7 @@ namespace folia {
     // DO NOT USE AbstractTextMarkup as a real node!!
   AbstractTextMarkup( const properties& props, Document *d=0 ):
     FoliaImpl( props, d ){ classInit(); };
-  AbstractTextMarkup( Document *d=0 ):
+    explicit AbstractTextMarkup( Document *d=0 ):
     FoliaImpl( PROPS, d ){ classInit(); };
   public:
     void setAttributes( const KWargs& );
@@ -888,7 +980,7 @@ namespace folia {
   class TextMarkupGap: public AbstractTextMarkup {
     friend void static_init();
   public:
-  TextMarkupGap( Document *d=0 ):
+    explicit TextMarkupGap( Document *d=0 ):
     AbstractTextMarkup( PROPS, d ) { classInit(); };
   TextMarkupGap(  const KWargs& a, Document *d=0 ):
     AbstractTextMarkup( PROPS, d ) { classInit(a); };
@@ -899,7 +991,7 @@ namespace folia {
   class TextMarkupString: public AbstractTextMarkup {
     friend void static_init();
   public:
-  TextMarkupString( Document *d=0 ):
+  explicit TextMarkupString( Document *d=0 ):
     AbstractTextMarkup( PROPS, d ) { classInit(); };
   TextMarkupString( const KWargs& a, Document *d=0 ):
     AbstractTextMarkup( PROPS, d ) { classInit(a); };
@@ -910,7 +1002,7 @@ namespace folia {
   class TextMarkupCorrection: public AbstractTextMarkup {
     friend void static_init();
   public:
-  TextMarkupCorrection( Document *d=0 ):
+    explicit TextMarkupCorrection( Document *d=0 ):
     AbstractTextMarkup( PROPS, d ){ classInit(); };
   TextMarkupCorrection( const KWargs& a, Document *d=0 ):
     AbstractTextMarkup( PROPS, d ) { classInit(a); };
@@ -927,7 +1019,7 @@ namespace folia {
   class TextMarkupError: public AbstractTextMarkup {
     friend void static_init();
   public:
-  TextMarkupError( Document *d=0 ):
+    explicit TextMarkupError( Document *d=0 ):
     AbstractTextMarkup( PROPS, d ){ classInit(); };
   TextMarkupError( const KWargs& a, Document *d=0 ):
     AbstractTextMarkup( PROPS, d ) { classInit(a); };
@@ -939,7 +1031,7 @@ namespace folia {
   class TextMarkupStyle: public AbstractTextMarkup {
     friend void static_init();
   public:
-  TextMarkupStyle( Document *d=0 ):
+    explicit TextMarkupStyle( Document *d=0 ):
     AbstractTextMarkup( PROPS, d ){ classInit(); };
   TextMarkupStyle( const KWargs& a, Document *d=0 ):
     AbstractTextMarkup( PROPS, d ) { classInit(a); };
@@ -951,25 +1043,34 @@ namespace folia {
   class TextContent: public FoliaImpl {
     friend void static_init();
   public:
-  TextContent( Document *d = 0 ):
+    explicit TextContent( Document *d = 0 ):
     FoliaImpl( PROPS, d ){ classInit(); }
   TextContent( const KWargs& a, Document *d=0 ):
     FoliaImpl( PROPS, d ){ classInit(a); }
     void setAttributes( const KWargs& );
     KWargs collectAttributes() const;
     int offset() const { return _offset; };
-    TextContent *postappend();
     std::vector<FoliaElement*> findreplacables( FoliaElement * ) const;
+    const std::string set_to_current() { // Don't use without thinking twice!
+      std::string res = _class;
+      _class="current";
+      return res;
+    }
+    FoliaElement *postappend();
+    FoliaElement *getreference() const;
+    std::string ref() const { return _ref; };
   private:
     void init();
+    FoliaElement *finddefaultreference() const;
     static properties PROPS;
     int _offset;
+    std::string _ref;
   };
 
   class PhonContent: public FoliaImpl {
     friend void static_init();
   public:
-  PhonContent( Document *d = 0 ):
+  explicit PhonContent( Document *d = 0 ):
     FoliaImpl(PROPS,d){ classInit(); }
   PhonContent( const KWargs& a, Document *d = 0 ):
     FoliaImpl(PROPS,d){ classInit( a ); }
@@ -978,16 +1079,21 @@ namespace folia {
     const UnicodeString phon( const std::string& = "current",
 			      bool = false ) const;
     int offset() const { return _offset; };
+    FoliaElement *postappend();
+    FoliaElement *getreference() const;
+    std::string ref() const { return _ref; };
   private:
     void init();
+    FoliaElement *finddefaultreference() const;
     static properties PROPS;
     int _offset;
+    std::string _ref;
   };
 
   class FoLiA: public FoliaImpl {
     friend void static_init();
   public:
-  FoLiA( Document *d = 0 ):
+    explicit FoLiA( Document *d = 0 ):
     FoliaImpl( PROPS,d) { classInit(); }
   FoLiA( const KWargs& a, Document *d = 0 ):
     FoliaImpl( PROPS, d ) { classInit( a ); }
@@ -1000,7 +1106,7 @@ namespace folia {
   class DCOI: public FoliaImpl {
     friend void static_init();
   public:
-  DCOI( Document *d = 0 ):
+    explicit DCOI( Document *d = 0 ):
     FoliaImpl( PROPS, d ) { classInit( ); }
   DCOI( const KWargs& a, Document *d = 0 ):
     FoliaImpl( PROPS, d ) { classInit( a ); }
@@ -1012,7 +1118,7 @@ namespace folia {
   class Head: public AbstractStructureElement {
     friend void static_init();
   public:
-  Head( Document *d = 0 ):
+  explicit Head( Document *d = 0 ):
     AbstractStructureElement( PROPS, d ) {  classInit(); }
   Head( const KWargs& a, Document *d = 0 ):
     AbstractStructureElement( PROPS, d ) {  classInit( a ); }
@@ -1024,7 +1130,7 @@ namespace folia {
   class TableHead: public AbstractStructureElement {
     friend void static_init();
   public:
-  TableHead( Document *d = 0 ):
+  explicit TableHead( Document *d = 0 ):
     AbstractStructureElement( PROPS, d ) {  classInit( ); }
   TableHead( const KWargs& a, Document *d = 0 ):
     AbstractStructureElement( PROPS, d ) {  classInit( a ); }
@@ -1036,7 +1142,7 @@ namespace folia {
   class Table: public AbstractStructureElement {
     friend void static_init();
   public:
-  Table( Document *d = 0 ):
+  explicit Table( Document *d = 0 ):
     AbstractStructureElement( PROPS, d ) {  classInit(); };
   Table( const KWargs& a, Document *d = 0  ):
     AbstractStructureElement( PROPS, d ) {  classInit( a ); };
@@ -1047,7 +1153,7 @@ namespace folia {
   class Row: public AbstractStructureElement {
     friend void static_init();
   public:
-  Row( Document *d = 0 ):
+  explicit Row( Document *d = 0 ):
     AbstractStructureElement( PROPS, d ) {  classInit(); };
   Row( const KWargs& a, Document *d = 0 ):
     AbstractStructureElement( PROPS, d ) {  classInit( a ); };
@@ -1058,7 +1164,7 @@ namespace folia {
   class Cell: public AbstractStructureElement {
     friend void static_init();
   public:
-  Cell( Document *d = 0 ):
+    explicit Cell( Document *d = 0 ):
     AbstractStructureElement( PROPS, d ) {  classInit(); };
   Cell( const KWargs& a, Document *d ):
     AbstractStructureElement( PROPS, d ) {  classInit( a ); };
@@ -1069,7 +1175,7 @@ namespace folia {
   class Gap: public FoliaImpl {
     friend void static_init();
   public:
-  Gap( Document *d = 0 ):
+    explicit Gap( Document *d = 0 ):
     FoliaImpl( PROPS, d ) { classInit(); }
   Gap( const KWargs& a, Document *d = 0 ):
     FoliaImpl( PROPS, d ) { classInit( a ); }
@@ -1082,7 +1188,7 @@ namespace folia {
   class Content: public FoliaImpl {
     friend void static_init();
   public:
-  Content( Document *d = 0 ):
+    explicit Content( Document *d = 0 ):
     FoliaImpl( PROPS, d ) { classInit(); }
   Content( const KWargs& a, Document *d = 0 ):
     FoliaImpl( PROPS, d ) { classInit( a ); }
@@ -1099,7 +1205,7 @@ namespace folia {
   class Metric: public FoliaImpl {
     friend void static_init();
   public:
-  Metric( Document *d = 0 ):
+  explicit Metric( Document *d = 0 ):
     FoliaImpl( PROPS, d ) { classInit(); }
   Metric( const KWargs& a, Document *d = 0 ):
     FoliaImpl( PROPS, d ) { classInit( a ); }
@@ -1111,7 +1217,7 @@ namespace folia {
   class Division: public AbstractStructureElement {
     friend void static_init();
   public:
-  Division( Document *d=0 ):
+    explicit Division( Document *d=0 ):
     AbstractStructureElement( PROPS, d ) { classInit(); };
   Division( const KWargs& a, Document *d = 0 ):
     AbstractStructureElement( PROPS, d ) { classInit( a ); };
@@ -1123,7 +1229,7 @@ namespace folia {
   class Linebreak: public AbstractStructureElement {
     friend void static_init();
   public:
-  Linebreak( Document *d=0 ):
+    explicit Linebreak( Document *d=0 ):
     AbstractStructureElement( PROPS, d ){ classInit(); };
   Linebreak( const KWargs& a, Document *d = 0 ):
     AbstractStructureElement( PROPS, d ){ classInit( a ); };
@@ -1144,7 +1250,7 @@ namespace folia {
   class Whitespace: public AbstractStructureElement {
     friend void static_init();
   public:
-  Whitespace( Document *d=0 ):
+    explicit Whitespace( Document *d=0 ):
     AbstractStructureElement( PROPS, d ){ classInit(); }
   Whitespace( const KWargs& a, Document *d = 0 ):
     AbstractStructureElement( PROPS, d ){ classInit( a ); }
@@ -1160,7 +1266,7 @@ namespace folia {
   class Word: public AbstractStructureElement {
     friend void static_init();
   public:
-  Word( Document *d = 0 ):
+    explicit Word( Document *d = 0 ):
     AbstractStructureElement(PROPS, d ) { classInit(); }
   Word( const properties& p, Document *d=0 ):
     AbstractStructureElement( p, d ) { classInit(); }
@@ -1193,6 +1299,7 @@ namespace folia {
     MorphologyLayer *addMorphologyLayer( const KWargs& );
     MorphologyLayer *getMorphologyLayers( const std::string&,
 					  std::vector<MorphologyLayer*>& ) const;
+    bool space() const { return _space; };
   private:
     void init();
     static properties PROPS;
@@ -1202,7 +1309,7 @@ namespace folia {
   class Part: public AbstractStructureElement {
     friend void static_init();
   public:
-  Part( Document *d=0 ):
+    explicit Part( Document *d=0 ):
     AbstractStructureElement( PROPS, d ){ classInit(); }
   Part( const KWargs& a, Document *d = 0 ):
     AbstractStructureElement( PROPS, d ){ classInit( a ); }
@@ -1217,7 +1324,7 @@ namespace folia {
     public AllowCorrection {
     friend void static_init();
   public:
-  String( Document *d=0 ):
+    explicit String( Document *d=0 ):
     AbstractTokenAnnotation( PROPS, d ){ classInit(); }
   String( const KWargs& a, Document *d =0 ):
     AbstractTokenAnnotation( PROPS, d ){ classInit( a ); }
@@ -1228,7 +1335,7 @@ namespace folia {
   class PlaceHolder: public Word {
     friend void static_init();
   public:
-  PlaceHolder( Document *d=0 ):
+    explicit PlaceHolder( Document *d=0 ):
     Word( PROPS, d ){ classInit(); }
   PlaceHolder( const KWargs& a, Document *d = 0 ):
     Word( PROPS, d ){ classInit( a ); }
@@ -1241,7 +1348,7 @@ namespace folia {
   class Sentence: public AbstractStructureElement {
     friend void static_init();
   public:
-  Sentence( Document *d=0 ):
+    explicit Sentence( Document *d=0 ):
     AbstractStructureElement( PROPS, d ){ classInit(); }
   Sentence( const KWargs& a, Document *d =0 ):
     AbstractStructureElement( PROPS, d ){ classInit( a ); }
@@ -1265,7 +1372,7 @@ namespace folia {
   class Speech: public AbstractStructureElement {
     friend void static_init();
   public:
-  Speech( Document *d=0 ):
+    explicit Speech( Document *d=0 ):
     AbstractStructureElement( PROPS, d ){ classInit(); }
   Speech( const KWargs& a, Document *d = 0 ):
     AbstractStructureElement( PROPS, d ){ classInit( a ); }
@@ -1277,7 +1384,7 @@ namespace folia {
   class Text: public AbstractStructureElement {
     friend void static_init();
   public:
-  Text( Document *d=0 ):
+    explicit Text( Document *d=0 ):
     AbstractStructureElement( PROPS, d ){ classInit(); }
   Text( const KWargs& a, Document *d = 0 ):
     AbstractStructureElement( PROPS, d ){ classInit( a ); }
@@ -1289,7 +1396,7 @@ namespace folia {
   class Utterance: public AbstractStructureElement {
     friend void static_init();
   public:
-  Utterance( Document *d=0 ):
+    explicit Utterance( Document *d=0 ):
     AbstractStructureElement( PROPS, d ){ classInit(); }
   Utterance( const KWargs& a, Document *d = 0 ):
     AbstractStructureElement( PROPS, d ){ classInit( a ); }
@@ -1301,7 +1408,7 @@ namespace folia {
   class Event: public AbstractStructureElement {
     friend void static_init();
   public:
-  Event( Document *d=0 ):
+    explicit Event( Document *d=0 ):
     AbstractStructureElement( PROPS, d ){ classInit(); }
   Event( const KWargs& a, Document *d = 0 ):
     AbstractStructureElement( PROPS, d ){ classInit( a ); }
@@ -1313,7 +1420,7 @@ namespace folia {
   class Caption: public AbstractStructureElement {
     friend void static_init();
   public:
-  Caption( Document *d=0 ):
+    explicit Caption( Document *d=0 ):
     AbstractStructureElement( PROPS, d ){ classInit(); }
   Caption( const KWargs& a, Document *d = 0 ):
     AbstractStructureElement( PROPS, d ){ classInit( a ); }
@@ -1325,7 +1432,7 @@ namespace folia {
   class Label: public AbstractStructureElement {
     friend void static_init();
   public:
-  Label( Document *d=0 ):
+   explicit Label( Document *d=0 ):
     AbstractStructureElement( PROPS, d ){ classInit(); }
   Label( const KWargs& a, Document *d = 0 ):
     AbstractStructureElement( PROPS, d ){ classInit( a ); }
@@ -1336,7 +1443,7 @@ namespace folia {
   class ListItem: public AbstractStructureElement {
     friend void static_init();
   public:
-  ListItem( Document *d=0 ):
+    explicit ListItem( Document *d=0 ):
     AbstractStructureElement( PROPS, d ){ classInit(); }
   ListItem( const KWargs& a, Document *d = 0 ):
     AbstractStructureElement( PROPS, d ){ classInit( a ); }
@@ -1348,7 +1455,7 @@ namespace folia {
   class List: public AbstractStructureElement {
     friend void static_init();
   public:
-  List( Document *d=0 ):
+    explicit List( Document *d=0 ):
     AbstractStructureElement( PROPS, d ){ classInit(); }
   List( const KWargs& a, Document *d = 0 ):
     AbstractStructureElement( PROPS, d ){ classInit( a ); }
@@ -1360,7 +1467,7 @@ namespace folia {
   class Figure: public AbstractStructureElement {
     friend void static_init();
   public:
-  Figure( Document *d=0 ):
+    explicit Figure( Document *d=0 ):
     AbstractStructureElement( PROPS, d ){ classInit(); }
   Figure( const KWargs& a, Document *d = 0 ):
     AbstractStructureElement( PROPS, d ){ classInit( a ); }
@@ -1374,7 +1481,7 @@ namespace folia {
   class Paragraph: public AbstractStructureElement {
     friend void static_init();
   public:
-  Paragraph( Document *d=0 ):
+    explicit Paragraph( Document *d=0 ):
     AbstractStructureElement( PROPS, d ){ classInit(); }
   Paragraph( const KWargs& a, Document *d = 0 ):
     AbstractStructureElement( PROPS, d ){ classInit( a ); }
@@ -1386,7 +1493,7 @@ namespace folia {
   class Alternative: public AbstractStructureElement {
     friend void static_init();
   public:
-  Alternative( Document *d=0 ):
+    explicit Alternative( Document *d=0 ):
     AbstractStructureElement( PROPS, d ){ classInit(); }
   Alternative( const KWargs& a, Document *d = 0 ):
     AbstractStructureElement( PROPS, d ){ classInit( a ); }
@@ -1399,7 +1506,7 @@ namespace folia {
   class AlternativeLayers: public FoliaImpl {
     friend void static_init();
   public:
-  AlternativeLayers( Document *d = 0 ):
+    explicit AlternativeLayers( Document *d = 0 ):
     FoliaImpl( PROPS, d ){ classInit(); }
   AlternativeLayers( const KWargs& a, Document *d = 0 ):
     FoliaImpl( PROPS, d ){ classInit( a ); }
@@ -1436,7 +1543,7 @@ namespace folia {
   class PosAnnotation: public AbstractTokenAnnotation {
     friend void static_init();
   public:
-  PosAnnotation( Document *d=0 ):
+    explicit PosAnnotation( Document *d=0 ):
     AbstractTokenAnnotation( PROPS, d ){ classInit(); }
   PosAnnotation( const KWargs& a, Document *d = 0 ):
     AbstractTokenAnnotation( PROPS, d ){ classInit( a ); }
@@ -1448,7 +1555,7 @@ namespace folia {
   class LemmaAnnotation: public AbstractTokenAnnotation {
     friend void static_init();
   public:
-  LemmaAnnotation( Document *d=0 ):
+    explicit LemmaAnnotation( Document *d=0 ):
     AbstractTokenAnnotation( PROPS, d ){ classInit(); }
   LemmaAnnotation( const KWargs& a, Document *d = 0 ):
     AbstractTokenAnnotation( PROPS, d ){ classInit( a ); }
@@ -1460,7 +1567,7 @@ namespace folia {
   class LangAnnotation: public AbstractExtendedTokenAnnotation {
     friend void static_init();
   public:
-  LangAnnotation( Document *d=0 ):
+    explicit LangAnnotation( Document *d=0 ):
     AbstractExtendedTokenAnnotation( PROPS, d ){ classInit(); }
   LangAnnotation( const KWargs& a, Document *d = 0 ):
     AbstractExtendedTokenAnnotation( PROPS, d ){ classInit( a ); }
@@ -1472,7 +1579,7 @@ namespace folia {
   class Phoneme: public AbstractTokenAnnotation {
     friend void static_init();
   public:
-  Phoneme( Document *d=0 ):
+    explicit Phoneme( Document *d=0 ):
     AbstractTokenAnnotation( PROPS, d ){ classInit(); }
   Phoneme( const KWargs& a, Document *d = 0 ):
     AbstractTokenAnnotation( PROPS, d ){ classInit( a ); }
@@ -1484,7 +1591,7 @@ namespace folia {
   class DomainAnnotation: public AbstractExtendedTokenAnnotation {
     friend void static_init();
   public:
-  DomainAnnotation( Document *d=0 ):
+    explicit DomainAnnotation( Document *d=0 ):
     AbstractExtendedTokenAnnotation( PROPS, d ){ classInit(); }
   DomainAnnotation( const KWargs& a, Document *d = 0 ):
     AbstractExtendedTokenAnnotation( PROPS, d ){ classInit( a ); }
@@ -1496,7 +1603,7 @@ namespace folia {
   class SenseAnnotation: public AbstractTokenAnnotation {
     friend void static_init();
   public:
-  SenseAnnotation( Document *d=0 ):
+    explicit SenseAnnotation( Document *d=0 ):
     AbstractTokenAnnotation( PROPS, d ){ classInit(); }
   SenseAnnotation( const KWargs& a, Document *d = 0 ):
     AbstractTokenAnnotation( PROPS, d ){ classInit( a ); }
@@ -1508,7 +1615,7 @@ namespace folia {
   class SubjectivityAnnotation: public AbstractTokenAnnotation {
     friend void static_init();
   public:
-  SubjectivityAnnotation( Document *d=0 ):
+    explicit SubjectivityAnnotation( Document *d=0 ):
     AbstractTokenAnnotation( PROPS, d ){ classInit(); }
   SubjectivityAnnotation( const KWargs& a, Document *d = 0 ):
     AbstractTokenAnnotation( PROPS, d ){ classInit( a ); }
@@ -1520,7 +1627,7 @@ namespace folia {
   class Quote: public AbstractStructureElement {
     friend void static_init();
   public:
-  Quote( Document *d=0 ):
+    explicit Quote( Document *d=0 ):
     AbstractStructureElement( PROPS, d ){ classInit(); };
   Quote( const KWargs& a, Document *d = 0 ):
     AbstractStructureElement( PROPS, d ){ classInit( a ); };
@@ -1534,10 +1641,10 @@ namespace folia {
   class Feature: public FoliaImpl {
     friend void static_init();
   public:
+    explicit Feature( Document *d = 0 ):
+    FoliaImpl( PROPS, d ){ classInit(); }
   Feature( const properties&p, Document *d = 0 ):
     FoliaImpl( p, d ){ classInit(); }
-  Feature( Document *d = 0 ):
-    FoliaImpl( PROPS, d ){ classInit(); }
   Feature( const KWargs& a, Document *d = 0 ):
     FoliaImpl( PROPS, d ){ classInit( a ); }
 
@@ -1555,7 +1662,7 @@ namespace folia {
   class BegindatetimeFeature: public Feature {
     friend void static_init();
   public:
-  BegindatetimeFeature( Document *d=0 ):
+    explicit BegindatetimeFeature( Document *d=0 ):
     Feature( PROPS, d ){ classInit(); }
   BegindatetimeFeature( const KWargs& a, Document *d = 0 ):
     Feature( PROPS, d ){ classInit( a ); }
@@ -1567,7 +1674,7 @@ namespace folia {
   class EnddatetimeFeature: public Feature {
     friend void static_init();
   public:
-  EnddatetimeFeature( Document *d=0 ):
+  explicit EnddatetimeFeature( Document *d=0 ):
     Feature( PROPS, d ){ classInit(); }
   EnddatetimeFeature( const KWargs& a, Document *d = 0 ):
     Feature( PROPS, d ){ classInit( a ); }
@@ -1579,7 +1686,7 @@ namespace folia {
   class SynsetFeature: public Feature {
     friend void static_init();
   public:
-  SynsetFeature( Document *d=0 ):
+  explicit SynsetFeature( Document *d=0 ):
     Feature( PROPS, d ){ classInit(); }
   SynsetFeature( const KWargs& a, Document *d = 0 ):
     Feature( PROPS, d ){ classInit( a ); }
@@ -1591,7 +1698,7 @@ namespace folia {
   class ActorFeature: public Feature {
     friend void static_init();
   public:
-  ActorFeature( Document *d=0 ):
+    explicit ActorFeature( Document *d=0 ):
     Feature( PROPS, d ){ classInit(); }
   ActorFeature( const KWargs& a, Document *d = 0 ):
     Feature( PROPS, d ){ classInit( a ); }
@@ -1603,7 +1710,7 @@ namespace folia {
   class PolarityFeature: public Feature {
     friend void static_init();
   public:
-  PolarityFeature( Document *d=0 ):
+    explicit PolarityFeature( Document *d=0 ):
     Feature( PROPS, d ){ classInit(); }
   PolarityFeature( const KWargs& a, Document *d = 0 ):
     Feature( PROPS, d ){ classInit( a ); }
@@ -1615,7 +1722,7 @@ namespace folia {
   class StrengthFeature: public Feature {
     friend void static_init();
   public:
-  StrengthFeature( Document *d=0 ):
+    explicit StrengthFeature( Document *d=0 ):
     Feature( PROPS, d ){ classInit(); }
   StrengthFeature( const KWargs& a, Document *d = 0 ):
     Feature( PROPS, d ){ classInit( a ); }
@@ -1628,7 +1735,7 @@ namespace folia {
   class HeadFeature: public Feature {
     friend void static_init();
   public:
-  HeadFeature( Document *d=0 ):
+    explicit HeadFeature( Document *d=0 ):
     Feature( PROPS, d ){ classInit(); }
   HeadFeature( const KWargs& a, Document *d = 0 ):
     Feature( PROPS, d ){ classInit( a ); }
@@ -1640,7 +1747,7 @@ namespace folia {
   class ValueFeature: public Feature {
     friend void static_init();
   public:
-  ValueFeature( Document *d=0 ):
+    explicit ValueFeature( Document *d=0 ):
     Feature( PROPS, d ){ classInit(); }
   ValueFeature( const KWargs& a, Document *d = 0 ):
     Feature( PROPS, d ){ classInit( a ); }
@@ -1652,7 +1759,7 @@ namespace folia {
   class FunctionFeature: public Feature {
     friend void static_init();
   public:
-  FunctionFeature( Document *d=0 ):
+    explicit FunctionFeature( Document *d=0 ):
     Feature( PROPS, d ){ classInit(); }
   FunctionFeature( const KWargs& a, Document *d = 0 ):
     Feature( PROPS, d ){ classInit( a ); }
@@ -1664,7 +1771,7 @@ namespace folia {
   class TimeFeature: public Feature {
     friend void static_init();
   public:
-  TimeFeature( Document *d=0 ):
+    explicit TimeFeature( Document *d=0 ):
     Feature( PROPS, d ){ classInit(); }
   TimeFeature( const KWargs& a, Document *d = 0 ):
     Feature( PROPS, d ){ classInit( a ); }
@@ -1676,7 +1783,7 @@ namespace folia {
   class LevelFeature: public Feature {
     friend void static_init();
   public:
-  LevelFeature( Document *d=0 ):
+    explicit LevelFeature( Document *d=0 ):
     Feature( PROPS, d ){ classInit(); }
   LevelFeature( const KWargs& a, Document *d = 0 ):
     Feature( PROPS, d ){ classInit( a ); }
@@ -1688,7 +1795,7 @@ namespace folia {
   class ModalityFeature: public Feature {
     friend void static_init();
   public:
-  ModalityFeature( Document *d=0 ):
+    explicit ModalityFeature( Document *d=0 ):
     Feature( PROPS, d ){ classInit(); }
   ModalityFeature( const KWargs& a, Document *d = 0 ):
     Feature( PROPS, d ){ classInit( a ); }
@@ -1700,7 +1807,7 @@ namespace folia {
   class StyleFeature: public Feature {
     friend void static_init();
   public:
-  StyleFeature( Document *d=0 ):
+    explicit StyleFeature( Document *d=0 ):
     Feature( PROPS, d ){ classInit(); }
   StyleFeature( const KWargs& a, Document *d = 0 ):
     Feature( PROPS, d ){ classInit( a ); }
@@ -1712,7 +1819,7 @@ namespace folia {
   class WordReference: public FoliaImpl {
     friend void static_init();
   public:
-  WordReference( Document *d = 0 ):
+    explicit WordReference( Document *d = 0 ):
     FoliaImpl( PROPS, d ){ classInit(); }
   WordReference( const KWargs& a, Document *d = 0 ):
     FoliaImpl( PROPS, d ){ classInit( a ); }
@@ -1725,7 +1832,7 @@ namespace folia {
   class Alignment: public FoliaImpl {
     friend void static_init();
   public:
-  Alignment( Document *d = 0 ):
+    explicit Alignment( Document *d = 0 ):
     FoliaImpl( PROPS, d ){ classInit(); }
   Alignment( const KWargs& a, Document *d = 0 ):
     FoliaImpl( PROPS, d ){ classInit( a ); }
@@ -1743,7 +1850,7 @@ namespace folia {
     friend void static_init();
     friend class Alignment;
   public:
-  AlignReference( Document *d = 0 ):
+    explicit AlignReference( Document *d = 0 ):
     FoliaImpl( PROPS, d ){ classInit(); }
   AlignReference( const KWargs& a, Document *d = 0 ):
     FoliaImpl( PROPS, d ){ classInit( a ); }
@@ -1766,7 +1873,7 @@ namespace folia {
   class SyntacticUnit: public AbstractSpanAnnotation {
     friend void static_init();
   public:
-  SyntacticUnit( Document *d = 0 ):
+    explicit SyntacticUnit( Document *d = 0 ):
     AbstractSpanAnnotation( PROPS, d ){ classInit(); }
   SyntacticUnit( const KWargs& a, Document *d = 0 ):
     AbstractSpanAnnotation( PROPS, d ){ classInit( a ); }
@@ -1778,7 +1885,7 @@ namespace folia {
   class Chunk: public AbstractSpanAnnotation {
     friend void static_init();
   public:
-  Chunk( Document *d=0 ):
+    explicit Chunk( Document *d=0 ):
     AbstractSpanAnnotation( PROPS, d ){ classInit(); }
   Chunk( const KWargs& a, Document *d = 0 ):
     AbstractSpanAnnotation( PROPS, d ){ classInit( a ); }
@@ -1790,7 +1897,7 @@ namespace folia {
   class Entity: public AbstractSpanAnnotation {
     friend void static_init();
   public:
-  Entity( Document *d=0 ):
+    explicit Entity( Document *d=0 ):
     AbstractSpanAnnotation( PROPS, d ){ classInit(); }
   Entity( const KWargs& a, Document *d = 0 ):
     AbstractSpanAnnotation( PROPS, d ){ classInit( a ); }
@@ -1799,13 +1906,13 @@ namespace folia {
     static properties PROPS;
   };
 
-    class AbstractSpanRole: public AbstractSpanAnnotation {
+  class AbstractSpanRole: public AbstractSpanAnnotation {
     friend void static_init();
   public:
+    explicit AbstractSpanRole( Document *d=0 ):
+    AbstractSpanAnnotation( PROPS, d ){ classInit(); }
   AbstractSpanRole( const properties& props, Document *d=0 ):
     AbstractSpanAnnotation( props, d ){ classInit(); }
-  AbstractSpanRole( Document *d=0 ):
-    AbstractSpanAnnotation( PROPS, d ){ classInit(); }
 
   private:
     static properties PROPS;
@@ -1814,7 +1921,7 @@ namespace folia {
   class Headspan: public AbstractSpanRole {
     friend void static_init();
   public:
-  Headspan( Document *d=0 ):
+    explicit Headspan( Document *d=0 ):
     AbstractSpanRole( PROPS, d ){ classInit(); }
   Headspan( const KWargs& a, Document *d = 0 ):
     AbstractSpanRole( PROPS, d ){ classInit( a ); }
@@ -1826,7 +1933,7 @@ namespace folia {
   class DependencyDependent: public AbstractSpanRole {
     friend void static_init();
   public:
-  DependencyDependent( Document *d=0 ):
+    explicit DependencyDependent( Document *d=0 ):
     AbstractSpanRole( PROPS, d ){ classInit(); }
   DependencyDependent( const KWargs& a, Document *d = 0 ):
     AbstractSpanRole( PROPS, d ){ classInit( a ); }
@@ -1838,7 +1945,7 @@ namespace folia {
   class Source: public AbstractSpanRole {
     friend void static_init();
   public:
-  Source( Document *d=0 ):
+    explicit Source( Document *d=0 ):
     AbstractSpanRole( PROPS, d ){ classInit(); }
   Source( const KWargs& a, Document *d = 0 ):
     AbstractSpanRole( PROPS, d ){ classInit( a ); }
@@ -1850,7 +1957,7 @@ namespace folia {
   class Target: public AbstractSpanRole {
     friend void static_init();
   public:
-  Target( Document *d=0 ):
+    explicit Target( Document *d=0 ):
     AbstractSpanRole( PROPS, d ){ classInit(); }
   Target( const KWargs& a, Document *d = 0 ):
     AbstractSpanRole( PROPS, d ){ classInit( a ); }
@@ -1862,7 +1969,7 @@ namespace folia {
   class Relation: public AbstractSpanRole {
     friend void static_init();
   public:
-  Relation( Document *d=0 ):
+    explicit Relation( Document *d=0 ):
     AbstractSpanRole( PROPS, d ){ classInit(); }
   Relation( const KWargs& a, Document *d = 0 ):
     AbstractSpanRole( PROPS, d ){ classInit( a ); }
@@ -1874,7 +1981,7 @@ namespace folia {
   class Dependency: public AbstractSpanAnnotation {
     friend void static_init();
   public:
-  Dependency( Document *d=0 ):
+    explicit Dependency( Document *d=0 ):
     AbstractSpanAnnotation( PROPS, d ){ classInit(); }
   Dependency( const KWargs& a, Document *d = 0 ):
     AbstractSpanAnnotation( PROPS, d ){ classInit( a ); }
@@ -1888,7 +1995,7 @@ namespace folia {
   class CoreferenceLink: public AbstractSpanRole {
     friend void static_init();
   public:
-  CoreferenceLink( Document *d=0 ):
+    explicit CoreferenceLink( Document *d=0 ):
     AbstractSpanRole( PROPS, d ){ classInit(); }
   CoreferenceLink( const KWargs& a, Document *d = 0 ):
     AbstractSpanRole( PROPS, d ){ classInit( a ); }
@@ -1900,7 +2007,7 @@ namespace folia {
   class CoreferenceChain: public AbstractSpanAnnotation {
     friend void static_init();
   public:
-  CoreferenceChain( Document *d=0 ):
+    explicit CoreferenceChain( Document *d=0 ):
     AbstractSpanAnnotation( PROPS, d ){ classInit(); }
   CoreferenceChain( const KWargs& a, Document *d = 0 ):
     AbstractSpanAnnotation( PROPS, d ){ classInit( a ); }
@@ -1912,7 +2019,7 @@ namespace folia {
   class SemanticRole: public AbstractSpanAnnotation {
     friend void static_init();
   public:
-  SemanticRole( Document *d=0 ):
+    explicit SemanticRole( Document *d=0 ):
     AbstractSpanAnnotation( PROPS, d ){ classInit(); }
   SemanticRole( const KWargs& a, Document *d = 0 ):
     AbstractSpanAnnotation( PROPS, d ){ classInit( a ); }
@@ -1924,7 +2031,7 @@ namespace folia {
   class Predicate: public AbstractSpanAnnotation {
     friend void static_init();
   public:
-  Predicate( Document *d=0 ):
+    explicit Predicate( Document *d=0 ):
     AbstractSpanAnnotation( PROPS, d ){ classInit(); }
   Predicate( const KWargs& a, Document *d = 0 ):
     AbstractSpanAnnotation( PROPS, d ){ classInit( a ); }
@@ -1936,7 +2043,7 @@ namespace folia {
   class Sentiment: public AbstractSpanAnnotation {
     friend void static_init();
   public:
-  Sentiment( Document *d=0 ):
+    explicit Sentiment( Document *d=0 ):
     AbstractSpanAnnotation( PROPS, d ){ classInit(); }
   Sentiment( const KWargs& a, Document *d = 0 ):
     AbstractSpanAnnotation( PROPS, d ){ classInit( a ); }
@@ -1948,7 +2055,7 @@ namespace folia {
   class Statement: public AbstractSpanAnnotation {
     friend void static_init();
   public:
-  Statement( Document *d=0 ):
+    explicit Statement( Document *d=0 ):
     AbstractSpanAnnotation( PROPS, d ){ classInit(); }
   Statement( const KWargs& a, Document *d = 0 ):
     AbstractSpanAnnotation( PROPS, d ){ classInit( a ); }
@@ -1960,7 +2067,7 @@ namespace folia {
   class Observation: public AbstractSpanAnnotation {
     friend void static_init();
   public:
-  Observation( Document *d=0 ):
+    explicit Observation( Document *d=0 ):
     AbstractSpanAnnotation( PROPS, d ){ classInit(); }
   Observation( const KWargs& a, Document *d = 0 ):
     AbstractSpanAnnotation( PROPS, d ){ classInit( a ); }
@@ -1979,7 +2086,7 @@ namespace folia {
       friend void static_init();
     protected:
       // DO NOT USE AbstractAnnotationLayer as a real node!!
-    AbstractAnnotationLayer( Document *d = 0 ):
+      explicit AbstractAnnotationLayer( Document *d = 0 ):
       FoliaImpl( PROPS, d ) { classInit(); };
     AbstractAnnotationLayer( const properties& props, Document *d = 0 ):
       FoliaImpl( props, d ) { classInit(); };
@@ -2000,7 +2107,7 @@ namespace folia {
     // DO NOT USE AbstractCorrectionChild as a real node!!
   AbstractCorrectionChild( const properties& props, Document *d=0 ):
     FoliaImpl( props, d ){ classInit(); };
-  AbstractCorrectionChild( Document *d=0 ):
+    explicit AbstractCorrectionChild( Document *d=0 ):
     FoliaImpl( PROPS, d ){ classInit(); };
   private:
     static properties PROPS;
@@ -2009,7 +2116,7 @@ namespace folia {
   class New: public AbstractCorrectionChild {
     friend void static_init();
   public:
-  New( Document *d=0 ):
+  explicit New( Document *d=0 ):
     AbstractCorrectionChild( PROPS, d ) { classInit(); }
   New( const KWargs& a, Document *d = 0 ):
     AbstractCorrectionChild( PROPS, d ) { classInit( a ); }
@@ -2021,7 +2128,7 @@ namespace folia {
   class Current: public AbstractCorrectionChild {
     friend void static_init();
   public:
-  Current( Document *d=0 ):
+  explicit Current( Document *d=0 ):
     AbstractCorrectionChild( PROPS, d ) { classInit(); }
   Current( const KWargs& a, Document *d = 0 ):
     AbstractCorrectionChild( PROPS, d ) { classInit( a ); }
@@ -2033,7 +2140,7 @@ namespace folia {
   class Original: public AbstractCorrectionChild {
     friend void static_init();
   public:
-  Original( Document *d=0 ):
+  explicit Original( Document *d=0 ):
     AbstractCorrectionChild( PROPS, d ) { classInit(); }
   Original( const KWargs& a, Document *d = 0 ):
     AbstractCorrectionChild( PROPS, d ) { classInit( a ); }
@@ -2045,7 +2152,7 @@ namespace folia {
   class Suggestion: public AbstractCorrectionChild {
     friend void static_init();
   public:
-  Suggestion( Document *d=0 ):
+  explicit Suggestion( Document *d=0 ):
     AbstractCorrectionChild( PROPS, d ) { classInit(); }
   Suggestion( const KWargs& a, Document *d = 0 ):
     AbstractCorrectionChild( PROPS, d ) { classInit( a ); }
@@ -2060,7 +2167,7 @@ namespace folia {
   class Description: public FoliaImpl {
     friend void static_init();
   public:
-  Description( Document *d=0 ):
+  explicit Description( Document *d=0 ):
     FoliaImpl( PROPS, d ) { classInit(); }
   Description( const KWargs& a, Document *d =0 ):
     FoliaImpl( PROPS, d ) { classInit( a ); }
@@ -2078,7 +2185,7 @@ namespace folia {
   class Comment: public FoliaImpl {
     friend void static_init();
   public:
-  Comment( Document *d=0 ):
+  explicit Comment( Document *d=0 ):
     FoliaImpl( PROPS, d ) { classInit(); }
   Comment( const KWargs& a, Document *d =0 ):
     FoliaImpl( PROPS, d ) { classInit( a ); }
@@ -2096,13 +2203,15 @@ namespace folia {
   class XmlComment: public FoliaImpl {
     friend void static_init();
   public:
-  XmlComment( Document *d=0 ):
+  explicit XmlComment( Document *d=0 ):
     FoliaImpl( PROPS, d ) { classInit(); }
   XmlComment( const KWargs& a, Document *d = 0 ):
     FoliaImpl( PROPS, d ) { classInit( a ); }
 
     FoliaElement* parseXml( const xmlNode * );
     xmlNode *xml( bool, bool=false ) const;
+    const UnicodeString text( const std::string& = "current",
+			      bool = false, bool = false ) const { return ""; };
   private:
     static properties PROPS;
     std::string _value;
@@ -2111,14 +2220,14 @@ namespace folia {
   class XmlText: public FoliaImpl {
     friend void static_init();
   public:
-  XmlText( Document *d = 0 ):
+  explicit XmlText( Document *d = 0 ):
     FoliaImpl( PROPS, d ) { classInit(); }
   XmlText( const KWargs& a, Document *d = 0 ):
     FoliaImpl(PROPS, d ) { classInit( a ); }
 
     FoliaElement* parseXml( const xmlNode * );
     xmlNode *xml( bool, bool=false ) const;
-    bool setvalue( const std::string& s ) { _value = s; return true; };
+    bool setvalue( const std::string& );
     const std::string& getTextDelimiter( bool ) const { return EMPTY_STRING; };
     const UnicodeString text( const std::string& = "current",
 			      bool = false, bool = false ) const;
@@ -2130,7 +2239,7 @@ namespace folia {
   class External: public FoliaImpl {
     friend void static_init();
   public:
-  External( Document *d = 0 ):
+  explicit External( Document *d = 0 ):
     FoliaImpl( PROPS, d ), _include(false) { classInit(); }
   External( const KWargs& a, Document *d = 0 ):
     FoliaImpl( PROPS, d ), _include(false) { classInit( a ); }
@@ -2147,7 +2256,7 @@ namespace folia {
   class Note: public AbstractStructureElement {
     friend void static_init();
   public:
-  Note( Document *d=0 ):
+  explicit Note( Document *d=0 ):
     AbstractStructureElement( PROPS, d ){ classInit(); }
   Note( const KWargs& a, Document *d = 0 ):
     AbstractStructureElement( PROPS, d ){ classInit( a ); }
@@ -2161,7 +2270,7 @@ namespace folia {
   class Definition: public AbstractStructureElement {
     friend void static_init();
   public:
-  Definition( Document *d=0 ):
+  explicit Definition( Document *d=0 ):
     AbstractStructureElement( PROPS, d ){ classInit(); }
   Definition( const KWargs& a, Document *d = 0 ):
     AbstractStructureElement( PROPS, d ){ classInit( a ); }
@@ -2173,7 +2282,7 @@ namespace folia {
   class Term: public AbstractStructureElement {
     friend void static_init();
   public:
-  Term( Document *d=0 ):
+  explicit Term( Document *d=0 ):
     AbstractStructureElement( PROPS, d ){ classInit(); }
   Term( const KWargs& a, Document *d = 0 ):
     AbstractStructureElement( PROPS, d ){ classInit( a ); }
@@ -2185,7 +2294,7 @@ namespace folia {
   class Example: public AbstractStructureElement {
     friend void static_init();
   public:
-  Example( Document *d=0 ):
+  explicit Example( Document *d=0 ):
     AbstractStructureElement( PROPS, d ){ classInit(); }
   Example( const KWargs& a, Document *d = 0 ):
     AbstractStructureElement( PROPS, d ){ classInit( a ); }
@@ -2197,7 +2306,7 @@ namespace folia {
   class Entry: public AbstractStructureElement {
     friend void static_init();
   public:
-  Entry( Document *d=0 ):
+  explicit Entry( Document *d=0 ):
     AbstractStructureElement( PROPS, d ){ classInit(); }
   Entry( const KWargs& a, Document *d = 0 ):
     AbstractStructureElement( PROPS, d ){ classInit( a ); }
@@ -2210,7 +2319,7 @@ namespace folia {
     friend void static_init();
     friend class Note;
   public:
-  Reference( Document *d=0 ):
+  explicit Reference( Document *d=0 ):
     AbstractStructureElement( PROPS, d ){ classInit(); }
   Reference( const KWargs& a, Document *d = 0 ):
     AbstractStructureElement( PROPS, d ){ classInit( a ); }
@@ -2229,7 +2338,7 @@ namespace folia {
   class Correction: public AbstractTokenAnnotation {
     friend void static_init();
   public:
-  Correction( Document *d=0 ):
+  explicit Correction( Document *d=0 ):
     AbstractTokenAnnotation( PROPS, d ){ classInit(); }
   Correction( const KWargs& a, Document *d = 0 ):
     AbstractTokenAnnotation( PROPS, d ){ classInit( a ); }
@@ -2248,8 +2357,8 @@ namespace folia {
     Suggestion *suggestions( size_t ) const;
     const UnicodeString text( const std::string& = "current",
 			      bool = false, bool = false ) const;
-    TextContent *textcontent( const std::string& = "current" ) const;
-    PhonContent *phoncontent( const std::string& = "current" ) const;
+    const TextContent *textcontent( const std::string& = "current" ) const;
+    const PhonContent *phoncontent( const std::string& = "current" ) const;
     const std::string& getTextDelimiter( bool=false) const;
   private:
     static properties PROPS;
@@ -2258,7 +2367,7 @@ namespace folia {
   class ErrorDetection: public AbstractExtendedTokenAnnotation  {
     friend void static_init();
   public:
-  ErrorDetection( Document *d=0 ):
+  explicit ErrorDetection( Document *d=0 ):
     AbstractExtendedTokenAnnotation( PROPS, d ){ classInit(); }
   ErrorDetection( const KWargs& a, Document *d = 0 ):
     AbstractExtendedTokenAnnotation( PROPS, d ){ classInit( a ); }
@@ -2270,7 +2379,7 @@ namespace folia {
   class TimeSegment: public AbstractSpanAnnotation {
     friend void static_init();
   public:
-  TimeSegment( Document *d=0 ):
+  explicit TimeSegment( Document *d=0 ):
     AbstractSpanAnnotation( PROPS, d ){ classInit(); }
   TimeSegment( const KWargs& a, Document *d = 0 ):
     AbstractSpanAnnotation( PROPS, d ){ classInit( a ); }
@@ -2282,7 +2391,7 @@ namespace folia {
   class Morpheme: public AbstractStructureElement {
     friend void static_init();
   public:
-  Morpheme( Document *d=0 ):
+    explicit Morpheme( Document *d=0 ):
     AbstractStructureElement( PROPS, d ){ classInit(); }
   Morpheme( const KWargs& a, Document *d = 0 ):
     AbstractStructureElement( PROPS, d ){ classInit( a ); }
@@ -2294,7 +2403,7 @@ namespace folia {
   class SyntaxLayer: public AbstractAnnotationLayer {
     friend void static_init();
   public:
-  SyntaxLayer( Document *d=0 ):
+    explicit SyntaxLayer( Document *d=0 ):
     AbstractAnnotationLayer( PROPS, d ){ classInit(); }
   SyntaxLayer( const KWargs& a, Document *d = 0 ):
     AbstractAnnotationLayer( PROPS, d ){ classInit( a ); }
@@ -2306,7 +2415,7 @@ namespace folia {
   class ChunkingLayer: public AbstractAnnotationLayer {
     friend void static_init();
   public:
-  ChunkingLayer( Document *d=0 ):
+    explicit ChunkingLayer( Document *d=0 ):
     AbstractAnnotationLayer( PROPS, d ){ classInit(); }
   ChunkingLayer( const KWargs& a, Document *d = 0 ):
     AbstractAnnotationLayer( PROPS, d ){ classInit( a ); }
@@ -2318,7 +2427,7 @@ namespace folia {
   class EntitiesLayer: public AbstractAnnotationLayer {
     friend void static_init();
   public:
-  EntitiesLayer( Document *d=0 ):
+    explicit EntitiesLayer( Document *d=0 ):
     AbstractAnnotationLayer( PROPS, d ){ classInit(); }
   EntitiesLayer( const KWargs& a, Document *d = 0 ):
     AbstractAnnotationLayer( PROPS, d ){ classInit( a ); }
@@ -2330,7 +2439,7 @@ namespace folia {
   class TimingLayer: public AbstractAnnotationLayer {
     friend void static_init();
   public:
-  TimingLayer( Document *d=0 ):
+    explicit TimingLayer( Document *d=0 ):
     AbstractAnnotationLayer( PROPS, d ){ classInit(); }
   TimingLayer( const KWargs& a, Document *d = 0 ):
     AbstractAnnotationLayer( PROPS, d ){ classInit( a ); }
@@ -2342,7 +2451,7 @@ namespace folia {
   class MorphologyLayer: public AbstractAnnotationLayer {
     friend void static_init();
   public:
-  MorphologyLayer( Document *d=0 ):
+    explicit MorphologyLayer( Document *d=0 ):
     AbstractAnnotationLayer( PROPS, d ){ classInit(); }
   MorphologyLayer( const KWargs& a, Document *d = 0 ):
     AbstractAnnotationLayer( PROPS, d ){ classInit( a ); }
@@ -2354,7 +2463,7 @@ namespace folia {
   class PhonologyLayer: public AbstractAnnotationLayer {
     friend void static_init();
   public:
-  PhonologyLayer( Document *d=0 ):
+    explicit PhonologyLayer( Document *d=0 ):
     AbstractAnnotationLayer( PROPS, d ){ classInit(); }
   PhonologyLayer( const KWargs& a, Document *d = 0 ):
     AbstractAnnotationLayer( PROPS, d ){ classInit( a ); }
@@ -2366,7 +2475,7 @@ namespace folia {
   class DependenciesLayer: public AbstractAnnotationLayer {
     friend void static_init();
   public:
-  DependenciesLayer( Document *d=0 ):
+    explicit DependenciesLayer( Document *d=0 ):
     AbstractAnnotationLayer( PROPS, d ){ classInit(); }
   DependenciesLayer( const KWargs& a, Document *d = 0 ):
     AbstractAnnotationLayer( PROPS, d ){ classInit( a ); }
@@ -2378,7 +2487,7 @@ namespace folia {
   class CoreferenceLayer: public AbstractAnnotationLayer {
     friend void static_init();
   public:
-  CoreferenceLayer( Document *d=0 ):
+    explicit CoreferenceLayer( Document *d=0 ):
     AbstractAnnotationLayer( PROPS, d ){ classInit(); }
   CoreferenceLayer( const KWargs& a, Document *d = 0 ):
     AbstractAnnotationLayer( PROPS, d ){ classInit( a ); }
@@ -2390,7 +2499,7 @@ namespace folia {
   class SemanticRolesLayer: public AbstractAnnotationLayer {
     friend void static_init();
   public:
-  SemanticRolesLayer( Document *d=0 ):
+    explicit SemanticRolesLayer( Document *d=0 ):
     AbstractAnnotationLayer( PROPS, d ){ classInit(); }
   SemanticRolesLayer( const KWargs& a, Document *d = 0 ):
     AbstractAnnotationLayer( PROPS, d ){ classInit( a ); }
@@ -2401,7 +2510,7 @@ namespace folia {
   class StatementLayer: public AbstractAnnotationLayer {
     friend void static_init();
   public:
-  StatementLayer( Document *d=0 ):
+    explicit StatementLayer( Document *d=0 ):
     AbstractAnnotationLayer( PROPS, d ){ classInit(); }
   StatementLayer( const KWargs& a, Document *d = 0 ):
     AbstractAnnotationLayer( PROPS, d ){ classInit( a ); }
@@ -2412,7 +2521,7 @@ namespace folia {
   class SentimentLayer: public AbstractAnnotationLayer {
     friend void static_init();
   public:
-  SentimentLayer( Document *d=0 ):
+    explicit SentimentLayer( Document *d=0 ):
     AbstractAnnotationLayer( PROPS, d ){ classInit(); }
   SentimentLayer( const KWargs& a, Document *d = 0 ):
     AbstractAnnotationLayer( PROPS, d ){ classInit( a ); }
@@ -2423,7 +2532,7 @@ namespace folia {
   class ObservationLayer: public AbstractAnnotationLayer {
     friend void static_init();
   public:
-  ObservationLayer( Document *d=0  ):
+    explicit ObservationLayer( Document *d=0  ):
     AbstractAnnotationLayer( PROPS, d ){ classInit(); }
   ObservationLayer( const KWargs& a, Document *d = 0 ):
     AbstractAnnotationLayer( PROPS, d ){ classInit( a ); }
@@ -2434,7 +2543,7 @@ namespace folia {
   class ComplexAlignmentLayer: public AbstractAnnotationLayer {
     friend void static_init();
   public:
-  ComplexAlignmentLayer( Document *d=0  ):
+    explicit ComplexAlignmentLayer( Document *d=0  ):
     AbstractAnnotationLayer( PROPS, d ){ classInit(); }
   ComplexAlignmentLayer( const KWargs& a, Document *d = 0 ):
     AbstractAnnotationLayer( PROPS, d ){ classInit( a ); }
diff --git a/include/libfolia/folia_types.h b/include/libfolia/folia_types.h
index 18803cd..a9e9a99 100644
--- a/include/libfolia/folia_types.h
+++ b/include/libfolia/folia_types.h
@@ -43,7 +43,7 @@ namespace folia {
 
   //foliaspec:attributes
   //Defines all common FoLiA attributes (as part of the Attrib enumeration)
-  enum Attrib : int { NO_ATT=0, ID=1, CLASS=2, ANNOTATOR=4, CONFIDENCE=8, N=16, DATETIME=32, BEGINTIME=64, ENDTIME=128, SRC=256, SPEAKER=512, ALL=1024 };
+  enum Attrib : int { NO_ATT=0, ID=1, CLASS=2, ANNOTATOR=4, CONFIDENCE=8, N=16, DATETIME=32, BEGINTIME=64, ENDTIME=128, SRC=256, SPEAKER=512, TEXTCLASS=1024, METADATA=2048, ALL=4096 };
 
   inline Attrib& operator++( Attrib & a ){
     return a = ( SPEAKER == a )
diff --git a/include/libfolia/folia_utils.h b/include/libfolia/folia_utils.h
index 4e21b77..bd3875f 100644
--- a/include/libfolia/folia_utils.h
+++ b/include/libfolia/folia_utils.h
@@ -50,58 +50,74 @@ namespace folia {
 
   class ArgsError: public std::runtime_error {
   public:
-  ArgsError( const std::string& s ): std::runtime_error( "error in argument list: " + s  ){};
+    explicit ArgsError( const std::string& s ): std::runtime_error( "error in argument list: " + s  ){};
   };
 
   class KeyError: public std::out_of_range {
   public:
-  KeyError(): std::out_of_range( "key out of range" ){};
+    explicit KeyError(): std::out_of_range( "key out of range" ){};
+    KeyError( const std::string& s ): std::out_of_range( "key out of range: " + s ){};
   };
 
   class NotImplementedError: public std::runtime_error {
   public:
-  NotImplementedError( const std::string& s ):
+    explicit NotImplementedError( const std::string& s ):
     std::runtime_error( "NOT IMPLEMENTED: " + s ){};
   };
 
   class ValueError: public std::runtime_error {
   public:
-  ValueError( const std::string& s ): std::runtime_error( s ){};
+    explicit ValueError( const std::string& s ): std::runtime_error( s ){};
   };
 
   class XmlError: public std::runtime_error {
   public:
-  XmlError( const std::string& s ): std::runtime_error( "XML error: " + s ){};
+    explicit XmlError( const std::string& s ): std::runtime_error( "XML error: " + s ){};
+  };
+
+  class MetaDataError: public std::runtime_error {
+  public:
+    explicit MetaDataError( const std::string& s ): std::runtime_error( "MetaData problem: " + s ){};
   };
 
   class NoSuchAnnotation: public std::runtime_error {
   public:
-  NoSuchAnnotation( const std::string& s ): std::runtime_error( "no such annotation: " + s ){};
+    explicit NoSuchAnnotation( const std::string& s ): std::runtime_error( "no such annotation: " + s ){};
   };
 
   class NoSuchText: public std::runtime_error {
   public:
-  NoSuchText( const std::string& s ): std::runtime_error( "no such text: " + s ){};
+    explicit NoSuchText( const std::string& s ): std::runtime_error( "no such text: " + s ){};
   };
 
   class NoSuchPhon: public std::runtime_error {
   public:
-  NoSuchPhon( const std::string& s ): std::runtime_error( "no such phoneme: " + s ){};
+    explicit NoSuchPhon( const std::string& s ): std::runtime_error( "no such phoneme: " + s ){};
   };
 
   class DuplicateAnnotationError: public std::runtime_error {
   public:
-  DuplicateAnnotationError( const std::string& s ): std::runtime_error( s ){};
+    explicit DuplicateAnnotationError( const std::string& s ): std::runtime_error( s ){};
   };
 
   class DuplicateIDError: public std::runtime_error {
   public:
-  DuplicateIDError( const std::string& s ): std::runtime_error( "duplicate ID : " + s ){};
+    explicit DuplicateIDError( const std::string& s ): std::runtime_error( "duplicate ID : " + s ){};
   };
 
   class NoDefaultError: public std::runtime_error {
   public:
-  NoDefaultError( const std::string& s ): std::runtime_error( "No Default found: " + s ){};
+    explicit NoDefaultError( const std::string& s ): std::runtime_error( "No Default found: " + s ){};
+  };
+
+  class InconsistentText: public std::runtime_error {
+  public:
+    explicit InconsistentText( const std::string& s ): std::runtime_error( "inconsistent text: " + s ){};
+  };
+
+  class UnresolvableTextContent: public std::runtime_error {
+  public:
+    explicit UnresolvableTextContent( const std::string& s ): std::runtime_error( "Unresolvable text: " + s ){};
   };
 
   UnicodeString UTF8ToUnicode( const std::string& );
@@ -138,6 +154,8 @@ namespace folia {
 
   bool isNCName( const std::string& );
 
+  UnicodeString normalize( const UnicodeString& );
+
 } // namespace folia
 
 namespace TiCC {
diff --git a/ltmain.sh b/ltmain.sh
index 147d758..a736cf9 100644
--- a/ltmain.sh
+++ b/ltmain.sh
@@ -31,7 +31,7 @@
 
 PROGRAM=libtool
 PACKAGE=libtool
-VERSION="2.4.6 Debian-2.4.6-0.1"
+VERSION="2.4.6 Debian-2.4.6-2"
 package_revision=2.4.6
 
 
@@ -2068,7 +2068,7 @@ include the following information:
        compiler:       $LTCC
        compiler flags: $LTCFLAGS
        linker:         $LD (gnu? $with_gnu_ld)
-       version:        $progname (GNU libtool) 2.4.6
+       version:        $progname $scriptversion Debian-2.4.6-2
        automake:       `($AUTOMAKE --version) 2>/dev/null |$SED 1q`
        autoconf:       `($AUTOCONF --version) 2>/dev/null |$SED 1q`
 
diff --git a/m4/Makefile.in b/m4/Makefile.in
index 1f2f0ca..9d4cc04 100644
--- a/m4/Makefile.in
+++ b/m4/Makefile.in
@@ -92,11 +92,11 @@ build_triplet = @build@
 host_triplet = @host@
 subdir = m4
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
-am__aclocal_m4_deps = $(top_srcdir)/m4/ax_icu_check.m4 \
-	$(top_srcdir)/m4/ax_pthread.m4 $(top_srcdir)/m4/libtool.m4 \
-	$(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
-	$(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
-	$(top_srcdir)/m4/pkg.m4 $(top_srcdir)/configure.ac
+am__aclocal_m4_deps = $(top_srcdir)/m4/ax_pthread.m4 \
+	$(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
+	$(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
+	$(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/pkg.m4 \
+	$(top_srcdir)/configure.ac
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
 	$(ACLOCAL_M4)
 DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
@@ -157,13 +157,7 @@ EXEEXT = @EXEEXT@
 FGREP = @FGREP@
 GREP = @GREP@
 ICU_CFLAGS = @ICU_CFLAGS@
-ICU_CONFIG = @ICU_CONFIG@
-ICU_CPPSEARCHPATH = @ICU_CPPSEARCHPATH@
-ICU_CXXFLAGS = @ICU_CXXFLAGS@
-ICU_IOLIBS = @ICU_IOLIBS@
-ICU_LIBPATH = @ICU_LIBPATH@
 ICU_LIBS = @ICU_LIBS@
-ICU_VERSION = @ICU_VERSION@
 INSTALL = @INSTALL@
 INSTALL_DATA = @INSTALL_DATA@
 INSTALL_PROGRAM = @INSTALL_PROGRAM@
diff --git a/m4/ax_icu_check.m4 b/m4/ax_icu_check.m4
deleted file mode 100644
index 3ffe425..0000000
--- a/m4/ax_icu_check.m4
+++ /dev/null
@@ -1,86 +0,0 @@
-dnl @synopsis AX_ICU_CHECK([version], [action-if], [action-if-not])
-dnl
-dnl Test for ICU support
-dnl
-dnl This will define ICU_LIBS, ICU_CFLAGS, ICU_CXXFLAGS, ICU_IOLIBS.
-dnl
-dnl Based on ac_check_icu (http://autoconf-archive.cryp.to/ac_check_icu.html)
-dnl by Akos Maroy <darkeye at tyrell.hu>.
-dnl
-dnl Portions Copyright 2005 Akos Maroy <darkeye at tyrell.hu>
-dnl Copying and distribution of this file, with or without modification,
-dnl are permitted in any medium without royalty provided the copyright
-dnl notice and this notice are preserved.
-dnl
-dnl @author Hunter Morris <huntermorris at gmail.com>
-dnl @version 2008-03-18
-AC_DEFUN([AX_ICU_CHECK], [
-  succeeded=no
-
-  if test -z "$ICU_CONFIG"; then
-     AC_PATH_PROG(ICU_CONFIG, icu-config, no)
-  fi
-
-  if test "$ICU_CONFIG" = "no" ; then
-     echo "*** The icu-config script could not be found. Make sure it is"
-     echo "*** in your path, and that taglib is properly installed."
-     echo "*** Or see http://www.icu-project.org/"
-  else
-	ICU_VERSION=`$ICU_CONFIG --version`
-	AC_MSG_CHECKING(for ICU >= $1)
-	VERSION_CHECK=`expr $ICU_VERSION \>\= $1`
-	if test "$VERSION_CHECK" = "1" ; then
-	   AC_MSG_RESULT(yes)
-	   succeeded=yes
-
-	   AC_MSG_CHECKING(ICU_CFLAGS)
-	   ICU_CFLAGS=`$ICU_CONFIG --cflags`
-	   AC_MSG_RESULT($ICU_CFLAGS)
-
-	   AC_MSG_CHECKING(ICU_CPPSEARCHPATH)
-	   ICU_CPPSEARCHPATH=`$ICU_CONFIG --cppflags-searchpath`
-	   AC_MSG_RESULT($ICU_CPPSEARCHPATH)
-
-	   AC_MSG_CHECKING(ICU_CXXFLAGS)
-	   ICU_CXXFLAGS=`$ICU_CONFIG --cxxflags`
-	   AC_MSG_RESULT($ICU_CXXFLAGS)
-	   
-	   AC_MSG_CHECKING(ICU_LIBS)
-	   ICU_LIBS=`$ICU_CONFIG --ldflags-libsonly`
-	   AC_MSG_RESULT($ICU_LIBS)
-
-	   AC_MSG_CHECKING(ICU_LIBPATH)
-	   ICU_LIBPATH=`$ICU_CONFIG --ldflags-searchpath`
-	   AC_MSG_RESULT($ICU_LIBPATH)
-
-	   AC_MSG_CHECKING(ICU_IOLIBS)
-	   ICU_IOLIBS=`$ICU_CONFIG --ldflags-icuio`
-	   AC_MSG_RESULT($ICU_IOLIBS)
-	else
-	   ICU_CFLAGS=""
-	   ICU_CXXFLAGS=""
-	   ICU_CPPSEARCHPATH=""
-	   ICU_LIBPATH=""
-	   ICU_LIBS=""
-	   ICU_IOLIBS=""
-	   ## If we have a custom action on failure, don't print errors, but
-	   ## do set a variable so people can do so.
-	   ifelse([$3], ,echo "can't find ICU >= $1",)
-        fi
-
-	AC_SUBST(ICU_CFLAGS)
-	AC_SUBST(ICU_CXXFLAGS)
-	AC_SUBST(ICU_CPPSEARCHPATH)
-	AC_SUBST(ICU_VERSION)
-	AC_SUBST(ICU_LIBPATH)
-	AC_SUBST(ICU_LIBS)
-	AC_SUBST(ICU_IOLIBS)
-  fi
-
-  if test $succeeded = yes; then
-     ifelse([$2], , :, [$2])
-  else
-     ifelse([$3], , AC_MSG_ERROR([Library requirements (ICU) not met.]), [$3])
-  fi
-])
-
diff --git a/m4/ax_pthread.m4 b/m4/ax_pthread.m4
index d383ad5..4a58fb4 100644
--- a/m4/ax_pthread.m4
+++ b/m4/ax_pthread.m4
@@ -6,6 +6,8 @@
 #
 #   AX_PTHREAD([ACTION-IF-FOUND[, ACTION-IF-NOT-FOUND]])
 #
+# Ko vd Sloot: special hacked version to survive clang's cc-analyser usage
+#
 # DESCRIPTION
 #
 #   This macro figures out how to build C programs using POSIX threads. It
@@ -19,10 +21,10 @@
 #   is necessary on AIX to use the special cc_r compiler alias.)
 #
 #   NOTE: You are assumed to not only compile your program with these flags,
-#   but also link it with them as well. e.g. you should link with
+#   but also to link with them as well. For example, you might link with
 #   $PTHREAD_CC $CFLAGS $PTHREAD_CFLAGS $LDFLAGS ... $PTHREAD_LIBS $LIBS
 #
-#   If you are only building threads programs, you may wish to use these
+#   If you are only building threaded programs, you may wish to use these
 #   variables in your default LIBS, CFLAGS, and CC:
 #
 #     LIBS="$PTHREAD_LIBS $LIBS"
@@ -30,8 +32,8 @@
 #     CC="$PTHREAD_CC"
 #
 #   In addition, if the PTHREAD_CREATE_JOINABLE thread-attribute constant
-#   has a nonstandard name, defines PTHREAD_CREATE_JOINABLE to that name
-#   (e.g. PTHREAD_CREATE_UNDETACHED on AIX).
+#   has a nonstandard name, this macro defines PTHREAD_CREATE_JOINABLE to
+#   that name (e.g. PTHREAD_CREATE_UNDETACHED on AIX).
 #
 #   Also HAVE_PTHREAD_PRIO_INHERIT is defined if pthread is found and the
 #   PTHREAD_PRIO_INHERIT symbol is defined when compiling with
@@ -82,35 +84,47 @@
 #   modified version of the Autoconf Macro, you may extend this special
 #   exception to the GPL to apply to your modified version as well.
 
-#serial 21
+#serial 222
 
 AU_ALIAS([ACX_PTHREAD], [AX_PTHREAD])
 AC_DEFUN([AX_PTHREAD], [
 AC_REQUIRE([AC_CANONICAL_HOST])
+AC_REQUIRE([AC_PROG_CC])
+AC_REQUIRE([AC_PROG_SED])
 AC_LANG_PUSH([C])
 ax_pthread_ok=no
 
+# hack for Clang analyzer
+SUBST="cc-analyzer"
+if test "${CC#*$SUBST}" != $CC; then
+   OLDCC=${CC}
+   CC=clang
+fi
+
 # We used to check for pthread.h first, but this fails if pthread.h
-# requires special compiler flags (e.g. on True64 or Sequent).
+# requires special compiler flags (e.g. on Tru64 or Sequent).
 # It gets checked for in the link test anyway.
 
 # First of all, check if the user has set any of the PTHREAD_LIBS,
 # etcetera environment variables, and if threads linking works using
 # them:
-if test x"$PTHREAD_LIBS$PTHREAD_CFLAGS" != x; then
-        save_CFLAGS="$CFLAGS"
-        CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
-        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])
-        if test x"$ax_pthread_ok" = xno; then
-                PTHREAD_LIBS=""
-                PTHREAD_CFLAGS=""
-        fi
-        LIBS="$save_LIBS"
-        CFLAGS="$save_CFLAGS"
+if test "x$PTHREAD_CFLAGS$PTHREAD_LIBS" != "x"; then
+	ax_pthread_save_CC="$CC"
+	ax_pthread_save_CFLAGS="$CFLAGS"
+	ax_pthread_save_LIBS="$LIBS"
+	AS_IF([test "x$PTHREAD_CC" != "x"], [CC="$PTHREAD_CC"])
+	CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
+	LIBS="$PTHREAD_LIBS $LIBS"
+	AC_MSG_CHECKING([for pthread_join using $CC $PTHREAD_CFLAGS $PTHREAD_LIBS])
+	AC_LINK_IFELSE([AC_LANG_CALL([], [pthread_join])], [ax_pthread_ok=yes])
+	AC_MSG_RESULT([$ax_pthread_ok])
+	if test "x$ax_pthread_ok" = "xno"; then
+		PTHREAD_LIBS=""
+		PTHREAD_CFLAGS=""
+	fi
+	CC="$ax_pthread_save_CC"
+	CFLAGS="$ax_pthread_save_CFLAGS"
+	LIBS="$ax_pthread_save_LIBS"
 fi
 
 # We must check for the threads library under a number of different
@@ -123,7 +137,7 @@ fi
 # which indicates that we try without any flags at all, and "pthread-config"
 # which is a program returning the flags for the Pth emulation library.
 
-ax_pthread_flags="pthreads none -Kthread -kthread lthread -pthread -pthreads -mthreads pthread --thread-safe -mt pthread-config"
+ax_pthread_flags="pthreads none -Kthread -pthread -pthreads -mthreads pthread --thread-safe -mt pthread-config"
 
 # The ordering *is* (sometimes) important.  Some notes on the
 # individual items follow:
@@ -132,186 +146,332 @@ ax_pthread_flags="pthreads none -Kthread -kthread lthread -pthread -pthreads -mt
 # none: in case threads are in libc; should be tried before -Kthread and
 #       other compiler flags to prevent continual compiler warnings
 # -Kthread: Sequent (threads in libc, but -Kthread needed for pthread.h)
-# -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able)
-# lthread: LinuxThreads port on FreeBSD (also preferred to -pthread)
-# -pthread: Linux/gcc (kernel threads), BSD/gcc (userland threads)
-# -pthreads: Solaris/gcc
-# -mthreads: Mingw32/gcc, Lynx/gcc
+# -pthread: Linux/gcc (kernel threads), BSD/gcc (userland threads), Tru64
+#           (Note: HP C rejects this with "bad form for `-t' option")
+# -pthreads: Solaris/gcc (Note: HP C also rejects)
 # -mt: Sun Workshop C (may only link SunOS threads [-lthread], but it
-#      doesn't hurt to check since this sometimes defines pthreads too;
-#      also defines -D_REENTRANT)
-#      ... -mt is also the pthreads flag for HP/aCC
+#      doesn't hurt to check since this sometimes defines pthreads and
+#      -D_REENTRANT too), HP C (must be checked before -lpthread, which
+#      is present but should not be used directly; and before -mthreads,
+#      because the compiler interprets this as "-mt" + "-hreads")
+# -mthreads: Mingw32/gcc, Lynx/gcc
 # pthread: Linux, etcetera
 # --thread-safe: KAI C++
 # pthread-config: use pthread-config program (for GNU Pth library)
 
-case ${host_os} in
-        solaris*)
+case $host_os in
+
+	freebsd*)
+
+	# -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able)
+	# lthread: LinuxThreads port on FreeBSD (also preferred to -pthread)
+
+	ax_pthread_flags="-kthread lthread $ax_pthread_flags"
+	;;
+
+	hpux*)
+
+	# From the cc(1) man page: "[-mt] Sets various -D flags to enable
+	# multi-threading and also sets -lpthread."
+
+	ax_pthread_flags="-mt -pthread pthread $ax_pthread_flags"
+	;;
+
+	openedition*)
 
-        # On Solaris (at least, for some versions), libc contains stubbed
-        # (non-functional) versions of the pthreads routines, so link-based
-        # tests will erroneously succeed.  (We need to link with -pthreads/-mt/
-        # -lpthread.)  (The stubs are missing pthread_cleanup_push, or rather
-        # a function called by this macro, so we could check for that, but
-        # who knows whether they'll stub that too in a future libc.)  So,
-        # we'll just look for -pthreads and -lpthread first:
+	# IBM z/OS requires a feature-test macro to be defined in order to
+	# enable POSIX threads at all, so give the user a hint if this is
+	# not set. (We don't define these ourselves, as they can affect
+	# other portions of the system API in unpredictable ways.)
 
-        ax_pthread_flags="-pthreads pthread -mt -pthread $ax_pthread_flags"
-        ;;
+	AC_EGREP_CPP([AX_PTHREAD_ZOS_MISSING],
+	    [
+#	     if !defined(_OPEN_THREADS) && !defined(_UNIX03_THREADS)
+	     AX_PTHREAD_ZOS_MISSING
+#	     endif
+	    ],
+	    [AC_MSG_WARN([IBM z/OS requires -D_OPEN_THREADS or -D_UNIX03_THREADS to enable pthreads support.])])
+	;;
 
-        darwin*)
-        ax_pthread_flags="-pthread $ax_pthread_flags"
-        ;;
+	solaris*)
+
+	# On Solaris (at least, for some versions), libc contains stubbed
+	# (non-functional) versions of the pthreads routines, so link-based
+	# tests will erroneously succeed. (N.B.: The stubs are missing
+	# pthread_cleanup_push, or rather a function called by this macro,
+	# so we could check for that, but who knows whether they'll stub
+	# that too in a future libc.)  So we'll check first for the
+	# standard Solaris way of linking pthreads (-mt -lpthread).
+
+	ax_pthread_flags="-mt,pthread pthread $ax_pthread_flags"
+	;;
 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
-
-        case $flag in
-                none)
-                AC_MSG_CHECKING([whether pthreads work without any flags])
-                ;;
-
-                -*)
-                AC_MSG_CHECKING([whether pthreads work with $flag])
-                PTHREAD_CFLAGS="$flag"
-                ;;
-
-                pthread-config)
-                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`"
-                ;;
-
-                *)
-                AC_MSG_CHECKING([for the pthreads library -l$flag])
-                PTHREAD_LIBS="-l$flag"
-                ;;
-        esac
-
-        save_LIBS="$LIBS"
-        save_CFLAGS="$CFLAGS"
-        LIBS="$PTHREAD_LIBS $LIBS"
-        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
-        # need a special flag -Kthread to make this header compile.)
-        # We check for pthread_join because it is in -lpthread on IRIX
-        # while pthread_create is in libc.  We check for pthread_attr_init
-        # due to DEC craziness with -lpthreads.  We check for
-        # pthread_cleanup_push because it is one of the few pthread
-        # functions on Solaris that doesn't have a non-functional libc stub.
-        # We try pthread_create on general principles.
-        AC_LINK_IFELSE([AC_LANG_PROGRAM([#include <pthread.h>
-                        static void routine(void *a) { a = 0; }
-                        static void *start_routine(void *a) { return a; }],
-                       [pthread_t th; pthread_attr_t attr;
-                        pthread_create(&th, 0, start_routine, 0);
-                        pthread_join(th, 0);
-                        pthread_attr_init(&attr);
-                        pthread_cleanup_push(routine, 0);
-                        pthread_cleanup_pop(0) /* ; */])],
-                [ax_pthread_ok=yes],
-                [])
-
-        LIBS="$save_LIBS"
-        CFLAGS="$save_CFLAGS"
-
-        AC_MSG_RESULT([$ax_pthread_ok])
-        if test "x$ax_pthread_ok" = xyes; then
-                break;
-        fi
-
-        PTHREAD_LIBS=""
-        PTHREAD_CFLAGS=""
+# GCC generally uses -pthread, or -pthreads on some platforms (e.g. SPARC)
+
+AS_IF([test "x$GCC" = "xyes"],
+      [ax_pthread_flags="-pthread -pthreads $ax_pthread_flags"])
+
+# The presence of a feature test macro requesting re-entrant function
+# definitions is, on some systems, a strong hint that pthreads support is
+# correctly enabled
+
+case $host_os in
+	darwin* | hpux* | linux* | osf* | solaris*)
+	ax_pthread_check_macro="_REENTRANT"
+	;;
+
+	aix* | freebsd*)
+	ax_pthread_check_macro="_THREAD_SAFE"
+	;;
+
+	*)
+	ax_pthread_check_macro="--"
+	;;
+esac
+AS_IF([test "x$ax_pthread_check_macro" = "x--"],
+      [ax_pthread_check_cond=0],
+      [ax_pthread_check_cond="!defined($ax_pthread_check_macro)"])
+
+AC_CACHE_CHECK([whether $CC is Clang],
+    [ax_cv_PTHREAD_CLANG],
+    [ax_cv_PTHREAD_CLANG=no
+     # Note that Autoconf sets GCC=yes for Clang as well as GCC
+     if test "x$GCC" = "xyes"; then
+	AC_EGREP_CPP([AX_PTHREAD_CC_IS_CLANG],
+	    [/* Note: Clang 2.7 lacks __clang_[a-z]+__ */
+#	     if defined(__clang__) && defined(__llvm__)
+	     AX_PTHREAD_CC_IS_CLANG
+#	     endif
+	    ],
+	    [ax_cv_PTHREAD_CLANG=yes])
+     fi
+    ])
+ax_pthread_clang="$ax_cv_PTHREAD_CLANG"
+
+ax_pthread_clang_warning=no
+
+# Clang needs special handling, because older versions handle the -pthread
+# option in a rather... idiosyncratic way
+
+if test "x$ax_pthread_clang" = "xyes"; then
+
+	# Clang takes -pthread; it has never supported any other flag
+
+	# (Note 1: This will need to be revisited if a system that Clang
+	# supports has POSIX threads in a separate library.  This tends not
+	# to be the way of modern systems, but it's conceivable.)
+
+	# (Note 2: On some systems, notably Darwin, -pthread is not needed
+	# to get POSIX threads support; the API is always present and
+	# active.  We could reasonably leave PTHREAD_CFLAGS empty.  But
+	# -pthread does define _REENTRANT, and while the Darwin headers
+	# ignore this macro, third-party headers might not.)
+
+	PTHREAD_CFLAGS="-pthread"
+	PTHREAD_LIBS=
+
+	ax_pthread_ok=yes
+
+	# However, older versions of Clang make a point of warning the user
+	# that, in an invocation where only linking and no compilation is
+	# taking place, the -pthread option has no effect ("argument unused
+	# during compilation").  They expect -pthread to be passed in only
+	# when source code is being compiled.
+	#
+	# Problem is, this is at odds with the way Automake and most other
+	# C build frameworks function, which is that the same flags used in
+	# compilation (CFLAGS) are also used in linking.  Many systems
+	# supported by AX_PTHREAD require exactly this for POSIX threads
+	# support, and in fact it is often not straightforward to specify a
+	# flag that is used only in the compilation phase and not in
+	# linking.  Such a scenario is extremely rare in practice.
+	#
+	# Even though use of the -pthread flag in linking would only print
+	# a warning, this can be a nuisance for well-run software projects
+	# that build with -Werror.  So if the active version of Clang has
+	# this misfeature, we search for an option to squash it.
+
+	AC_CACHE_CHECK([whether Clang needs flag to prevent "argument unused" warning when linking with -pthread],
+	    [ax_cv_PTHREAD_CLANG_NO_WARN_FLAG],
+	    [ax_cv_PTHREAD_CLANG_NO_WARN_FLAG=unknown
+	     # Create an alternate version of $ac_link that compiles and
+	     # links in two steps (.c -> .o, .o -> exe) instead of one
+	     # (.c -> exe), because the warning occurs only in the second
+	     # step
+	     ax_pthread_save_ac_link="$ac_link"
+	     ax_pthread_sed='s/conftest\.\$ac_ext/conftest.$ac_objext/g'
+	     ax_pthread_link_step=`$as_echo "$ac_link" | sed "$ax_pthread_sed"`
+	     ax_pthread_2step_ac_link="($ac_compile) && (echo ==== >&5) && ($ax_pthread_link_step)"
+	     ax_pthread_save_CFLAGS="$CFLAGS"
+	     for ax_pthread_try in '' -Qunused-arguments -Wno-unused-command-line-argument unknown; do
+		AS_IF([test "x$ax_pthread_try" = "xunknown"], [break])
+		CFLAGS="-Werror -Wunknown-warning-option $ax_pthread_try -pthread $ax_pthread_save_CFLAGS"
+		ac_link="$ax_pthread_save_ac_link"
+		AC_LINK_IFELSE([AC_LANG_SOURCE([[int main(void){return 0;}]])],
+		    [ac_link="$ax_pthread_2step_ac_link"
+		     AC_LINK_IFELSE([AC_LANG_SOURCE([[int main(void){return 0;}]])],
+			 [break])
+		    ])
+	     done
+	     ac_link="$ax_pthread_save_ac_link"
+	     CFLAGS="$ax_pthread_save_CFLAGS"
+	     AS_IF([test "x$ax_pthread_try" = "x"], [ax_pthread_try=no])
+	     ax_cv_PTHREAD_CLANG_NO_WARN_FLAG="$ax_pthread_try"
+	    ])
+
+	case "$ax_cv_PTHREAD_CLANG_NO_WARN_FLAG" in
+		no | unknown) ;;
+		*) PTHREAD_CFLAGS="$ax_cv_PTHREAD_CLANG_NO_WARN_FLAG $PTHREAD_CFLAGS" ;;
+	esac
+
+fi # $ax_pthread_clang = yes
+
+if test "x$ax_pthread_ok" = "xno"; then
+for ax_pthread_try_flag in $ax_pthread_flags; do
+
+	case $ax_pthread_try_flag in
+		none)
+		AC_MSG_CHECKING([whether pthreads work without any flags])
+		;;
+
+		-mt,pthread)
+		AC_MSG_CHECKING([whether pthreads work with -mt -lpthread])
+		PTHREAD_CFLAGS="-mt"
+		PTHREAD_LIBS="-lpthread"
+		;;
+
+		-*)
+		AC_MSG_CHECKING([whether pthreads work with $ax_pthread_try_flag])
+		PTHREAD_CFLAGS="$ax_pthread_try_flag"
+		;;
+
+		pthread-config)
+		AC_CHECK_PROG([ax_pthread_config], [pthread-config], [yes], [no])
+		AS_IF([test "x$ax_pthread_config" = "xno"], [continue])
+		PTHREAD_CFLAGS="`pthread-config --cflags`"
+		PTHREAD_LIBS="`pthread-config --ldflags` `pthread-config --libs`"
+		;;
+
+		*)
+		AC_MSG_CHECKING([for the pthreads library -l$ax_pthread_try_flag])
+		PTHREAD_LIBS="-l$ax_pthread_try_flag"
+		;;
+	esac
+
+	ax_pthread_save_CFLAGS="$CFLAGS"
+	ax_pthread_save_LIBS="$LIBS"
+	CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
+	LIBS="$PTHREAD_LIBS $LIBS"
+
+	# Check for various functions.  We must include pthread.h,
+	# since some functions may be macros.  (On the Sequent, we
+	# need a special flag -Kthread to make this header compile.)
+	# We check for pthread_join because it is in -lpthread on IRIX
+	# while pthread_create is in libc.  We check for pthread_attr_init
+	# due to DEC craziness with -lpthreads.  We check for
+	# pthread_cleanup_push because it is one of the few pthread
+	# functions on Solaris that doesn't have a non-functional libc stub.
+	# We try pthread_create on general principles.
+
+	AC_LINK_IFELSE([AC_LANG_PROGRAM([#include <pthread.h>
+#			if $ax_pthread_check_cond
+#			 error "$ax_pthread_check_macro must be defined"
+#			endif
+			static void routine(void *a) { a = 0; }
+			static void *start_routine(void *a) { return a; }],
+		       [pthread_t th; pthread_attr_t attr;
+			pthread_create(&th, 0, start_routine, 0);
+			pthread_join(th, 0);
+			pthread_attr_init(&attr);
+			pthread_cleanup_push(routine, 0);
+			pthread_cleanup_pop(0) /* ; */])],
+	    [ax_pthread_ok=yes],
+	    [])
+
+	CFLAGS="$ax_pthread_save_CFLAGS"
+	LIBS="$ax_pthread_save_LIBS"
+
+	AC_MSG_RESULT([$ax_pthread_ok])
+	AS_IF([test "x$ax_pthread_ok" = "xyes"], [break])
+
+	PTHREAD_LIBS=""
+	PTHREAD_CFLAGS=""
 done
 fi
 
 # Various other checks:
-if test "x$ax_pthread_ok" = xyes; then
-        save_LIBS="$LIBS"
-        LIBS="$PTHREAD_LIBS $LIBS"
-        save_CFLAGS="$CFLAGS"
-        CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
-
-        # Detect AIX lossage: JOINABLE attribute is called UNDETACHED.
-        AC_MSG_CHECKING([for joinable pthread attribute])
-        attr_name=unknown
-        for attr in PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_UNDETACHED; do
-            AC_LINK_IFELSE([AC_LANG_PROGRAM([#include <pthread.h>],
-                           [int attr = $attr; return attr /* ; */])],
-                [attr_name=$attr; break],
-                [])
-        done
-        AC_MSG_RESULT([$attr_name])
-        if test "$attr_name" != PTHREAD_CREATE_JOINABLE; then
-            AC_DEFINE_UNQUOTED([PTHREAD_CREATE_JOINABLE], [$attr_name],
-                               [Define to necessary symbol if this constant
-                                uses a non-standard name on your system.])
-        fi
-
-        AC_MSG_CHECKING([if more special flags are required for pthreads])
-        flag=no
-        case ${host_os} in
-            aix* | freebsd* | darwin*) flag="-D_THREAD_SAFE";;
-            osf* | hpux*) flag="-D_REENTRANT";;
-            solaris*)
-            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])
-        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=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.])])
-
-        LIBS="$save_LIBS"
-        CFLAGS="$save_CFLAGS"
-
-        # 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
+if test "x$ax_pthread_ok" = "xyes"; then
+	ax_pthread_save_CFLAGS="$CFLAGS"
+	ax_pthread_save_LIBS="$LIBS"
+	CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
+	LIBS="$PTHREAD_LIBS $LIBS"
+
+	# Detect AIX lossage: JOINABLE attribute is called UNDETACHED.
+	AC_CACHE_CHECK([for joinable pthread attribute],
+	    [ax_cv_PTHREAD_JOINABLE_ATTR],
+	    [ax_cv_PTHREAD_JOINABLE_ATTR=unknown
+	     for ax_pthread_attr in PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_UNDETACHED; do
+		 AC_LINK_IFELSE([AC_LANG_PROGRAM([#include <pthread.h>],
+						 [int attr = $ax_pthread_attr; return attr /* ; */])],
+				[ax_cv_PTHREAD_JOINABLE_ATTR=$ax_pthread_attr; break],
+				[])
+	     done
+	    ])
+	AS_IF([test "x$ax_cv_PTHREAD_JOINABLE_ATTR" != "xunknown" && \
+	       test "x$ax_cv_PTHREAD_JOINABLE_ATTR" != "xPTHREAD_CREATE_JOINABLE" && \
+	       test "x$ax_pthread_joinable_attr_defined" != "xyes"],
+	      [AC_DEFINE_UNQUOTED([PTHREAD_CREATE_JOINABLE],
+				  [$ax_cv_PTHREAD_JOINABLE_ATTR],
+				  [Define to necessary symbol if this constant
+				   uses a non-standard name on your system.])
+	       ax_pthread_joinable_attr_defined=yes
+	      ])
+
+	AC_CACHE_CHECK([whether more special flags are required for pthreads],
+	    [ax_cv_PTHREAD_SPECIAL_FLAGS],
+	    [ax_cv_PTHREAD_SPECIAL_FLAGS=no
+	     case $host_os in
+	     solaris*)
+	     ax_cv_PTHREAD_SPECIAL_FLAGS="-D_POSIX_PTHREAD_SEMANTICS"
+	     ;;
+	     esac
+	    ])
+	AS_IF([test "x$ax_cv_PTHREAD_SPECIAL_FLAGS" != "xno" && \
+	       test "x$ax_pthread_special_flags_added" != "xyes"],
+	      [PTHREAD_CFLAGS="$ax_cv_PTHREAD_SPECIAL_FLAGS $PTHREAD_CFLAGS"
+	       ax_pthread_special_flags_added=yes])
+
+	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=yes],
+			    [ax_cv_PTHREAD_PRIO_INHERIT=no])
+	    ])
+	AS_IF([test "x$ax_cv_PTHREAD_PRIO_INHERIT" = "xyes" && \
+	       test "x$ax_pthread_prio_inherit_defined" != "xyes"],
+	      [AC_DEFINE([HAVE_PTHREAD_PRIO_INHERIT], [1], [Have PTHREAD_PRIO_INHERIT.])
+	       ax_pthread_prio_inherit_defined=yes
+	      ])
+
+	CFLAGS="$ax_pthread_save_CFLAGS"
+	LIBS="$ax_pthread_save_LIBS"
+
+	# 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
 fi
 
 test -n "$PTHREAD_CC" || PTHREAD_CC="$CC"
@@ -321,12 +481,18 @@ 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])
-        :
+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])
+	:
 else
-        ax_pthread_ok=no
-        $2
+	ax_pthread_ok=no
+	$2
 fi
+
+# undo hack for Clang analyzer
+if test "${OLDCC#*$SUBST}" != ${OLDCC}; then
+   CC=${OLDCC}
+fi
+
 AC_LANG_POP
 ])dnl AX_PTHREAD
diff --git a/src/Makefile.am b/src/Makefile.am
index f06bc94..b9396d3 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -1,11 +1,11 @@
 AM_CPPFLAGS = -I at top_srcdir@/include
-AM_CXXFLAGS = -std=c++0x -g -O3 # -Weffc++
+AM_CXXFLAGS = -std=c++11 -g -O3 -W -Wall -pedantic
 
 
 LDADD = libfolia.la
 
 lib_LTLIBRARIES = libfolia.la
-libfolia_la_LDFLAGS = -version-info 6:0:0
+libfolia_la_LDFLAGS = -version-info 6:3:0
 
 libfolia_la_SOURCES = folia_impl.cxx folia_document.cxx folia_utils.cxx \
 	folia_types.cxx folia_properties.cxx
diff --git a/src/Makefile.in b/src/Makefile.in
index d803637..0a970c0 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -93,11 +93,11 @@ bin_PROGRAMS = folialint$(EXEEXT)
 check_PROGRAMS = simpletest$(EXEEXT)
 subdir = src
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
-am__aclocal_m4_deps = $(top_srcdir)/m4/ax_icu_check.m4 \
-	$(top_srcdir)/m4/ax_pthread.m4 $(top_srcdir)/m4/libtool.m4 \
-	$(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
-	$(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
-	$(top_srcdir)/m4/pkg.m4 $(top_srcdir)/configure.ac
+am__aclocal_m4_deps = $(top_srcdir)/m4/ax_pthread.m4 \
+	$(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
+	$(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
+	$(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/pkg.m4 \
+	$(top_srcdir)/configure.ac
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
 	$(ACLOCAL_M4)
 DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
@@ -427,13 +427,7 @@ EXEEXT = @EXEEXT@
 FGREP = @FGREP@
 GREP = @GREP@
 ICU_CFLAGS = @ICU_CFLAGS@
-ICU_CONFIG = @ICU_CONFIG@
-ICU_CPPSEARCHPATH = @ICU_CPPSEARCHPATH@
-ICU_CXXFLAGS = @ICU_CXXFLAGS@
-ICU_IOLIBS = @ICU_IOLIBS@
-ICU_LIBPATH = @ICU_LIBPATH@
 ICU_LIBS = @ICU_LIBS@
-ICU_VERSION = @ICU_VERSION@
 INSTALL = @INSTALL@
 INSTALL_DATA = @INSTALL_DATA@
 INSTALL_PROGRAM = @INSTALL_PROGRAM@
@@ -537,10 +531,10 @@ top_build_prefix = @top_build_prefix@
 top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 AM_CPPFLAGS = -I at top_srcdir@/include
-AM_CXXFLAGS = -std=c++0x -g -O3 # -Weffc++
+AM_CXXFLAGS = -std=c++11 -g -O3 -W -Wall -pedantic
 LDADD = libfolia.la
 lib_LTLIBRARIES = libfolia.la
-libfolia_la_LDFLAGS = -version-info 6:0:0
+libfolia_la_LDFLAGS = -version-info 6:3:0
 libfolia_la_SOURCES = folia_impl.cxx folia_document.cxx folia_utils.cxx \
 	folia_types.cxx folia_properties.cxx
 
diff --git a/src/folia_document.cxx b/src/folia_document.cxx
index df78402..4773064 100644
--- a/src/folia_document.cxx
+++ b/src/folia_document.cxx
@@ -23,6 +23,7 @@
   or send mail to:
       lamasoftware (at ) science.ru.nl
 */
+#include <cassert>
 #include <cstdlib>
 #include <iostream>
 #include <fstream>
@@ -52,6 +53,17 @@ namespace folia {
     // a NO_OP now
   }
 
+  bool checkNS( xmlNode *n, const string& ns ){
+    string tns = getNS(n);
+    if ( tns == ns )
+      return true;
+    else
+      throw runtime_error( "namespace conflict for tag:" + Name(n)
+			   + ", wanted:" + ns
+			   + " got:" + tns );
+    return false;
+  }
+
   map<string,string> getNS_definitions( const xmlNode *node ){
     map<string,string> result;
     xmlNs *p = node->nsDef;
@@ -76,19 +88,26 @@ namespace folia {
     init();
     KWargs kwargs = getArgs( args );
     setDocumentProps( kwargs );
-    if ( ! foliadoc ){
+    if ( !foliadoc ){
       foliadoc = new FoLiA( kwargs, this );
     }
   }
 
-  string versionstring(){
+  string Document::library_version(){
     stringstream ss;
     ss << MAJOR_VERSION << "." << MINOR_VERSION << "." << SUB_VERSION;
     return ss.str();
   }
 
+  string Document::update_version(){
+    // override the document version with the current library version
+    // return the old value
+    string old = _version;
+    _version = library_version();
+    return old;
+  }
+
   void Document::init(){
-    _metadatatype = "native";
     _metadata = 0;
     _xmldoc = 0;
     foliadoc = 0;
@@ -96,7 +115,8 @@ namespace folia {
     _foliaNsIn_prefix = 0;
     _foliaNsOut = 0;
     debug = 0;
-    version = versionstring();
+    mode = CHECKTEXT;
+    _version = library_version();
     external = false;
   }
 
@@ -107,12 +127,13 @@ namespace folia {
     sindex.clear();
     iindex.clear();
     delete foliadoc;
-    for ( const auto& it : _foreigndata ){
-      delete it;
-    }
     for ( const auto& it : delSet ){
       delete it;
     }
+    delete _metadata;
+    for ( const auto& it : submetadata ){
+      delete it.second;
+    }
   }
 
   bool operator==( const Document& d1, const Document& d2 ){
@@ -147,18 +168,54 @@ namespace folia {
     return true;
   }
 
+  void Document::setmode( const string& ms ){
+    vector<string> modev;
+    TiCC::split_at( ms, modev, "," );
+    for ( const auto& mod : modev ){
+      if ( mod == "permissive" ){
+	mode = Mode( (int)mode | PERMISSIVE );
+      }
+      else if ( mod == "strip" ){
+	mode = Mode( (int)mode | STRIP );
+      }
+      else if ( mod == "nochecktext" ){
+	mode = Mode( int(mode) & ~CHECKTEXT );
+      }
+      else if ( mod == "fixtext" ){
+	mode = Mode( int(mode) | FIXTEXT );
+      }
+      else {
+	throw runtime_error( "FoLiA::Document: unsupported mode value: "+ mod );
+      }
+    }
+  }
+
+  string Document::getmode() const{
+    string result = "mode=";
+    if ( mode == PERMISSIVE ){
+      result += "permissive,";
+    }
+    if ( mode == STRIP ){
+      result += "strip,";
+    }
+    if ( mode == CHECKTEXT ){
+      result += "checktext,";
+    }
+    if ( mode == FIXTEXT ){
+      result += "fixtext,";
+    }
+    return result;
+  }
+
   void Document::setDocumentProps( KWargs& kwargs ){
     bool happy = false;
     auto it = kwargs.find( "debug" );
-    if ( it != kwargs.end() )
+    if ( it != kwargs.end() ){
       debug = stringTo<int>( it->second );
+    }
     it = kwargs.find( "mode" );
     if ( it != kwargs.end() ){
-      mode = it->second;
-      if ( mode != "permissive"
-	   && mode != "strip" ){
-	throw runtime_error( "FoLiA::Document: unsupported mode value: "+mode );
-      }
+      setmode( it->second );
     }
     it = kwargs.find( "external" );
     if ( it != kwargs.end() ){
@@ -169,7 +226,7 @@ namespace folia {
       external = false;
     it = kwargs.find( "version" );
     if ( it != kwargs.end() ){
-      version = it->second;
+      _version = it->second;
       kwargs.erase( it );
     }
     it = kwargs.find( "_id" );
@@ -204,6 +261,24 @@ namespace folia {
     if ( !happy )
       throw runtime_error( "No ID, valid filename or string specified" );
     kwargs.erase( "generator" ); // also delete unused att-val(s)
+    const char *env = getenv( "FOLIA_TEXT_CHECK" );
+    if ( env ){
+      string e = env;
+      cerr << "DETECTED FOLIA_TEXT_CHECK environment variable, value ='"
+	   << e << "'"<< endl;
+      if ( e == "NO" ){
+	mode = Mode( int(mode) & ~CHECKTEXT );
+	cerr << "FOLIA_TEXT_CHECK disabled" << endl;
+      }
+      else if ( e == "YES" ){
+	mode = Mode( int(mode) | CHECKTEXT );
+	cerr << "FOLIA_TEXT_CHECK enabled" << endl;
+      }
+      else {
+	cerr << "FOLIA_TEXT_CHECK unchanged:" << (checktext()?"YES":"NO")
+	     << endl;
+      }
+    }
   }
 
   void Document::addDocIndex( FoliaElement* el, const string& s ){
@@ -270,7 +345,7 @@ namespace folia {
     }
     int cnt = 0;
     xmlSetStructuredErrorFunc( &cnt, (xmlStructuredErrorFunc)error_sink );
-    _xmldoc = xmlReadFile( s.c_str(), 0, XML_PARSE_NOBLANKS|XML_PARSE_HUGE );
+    _xmldoc = xmlReadFile( s.c_str(), 0, XML_PARSE_HUGE );
     if ( _xmldoc ){
       if ( cnt > 0 ){
 	throw XmlError( "document is invalid" );
@@ -278,9 +353,12 @@ namespace folia {
       if ( debug )
 	cout << "read a doc from " << s << endl;
       foliadoc = parseXml();
+      if ( !validate_offsets() ){
+	throw InconsistentText("MEH");
+      }
       if ( debug ){
 	if ( foliadoc ){
-	  cout << "succesful parsed the doc" << endl;
+	  cout << "successful parsed the doc" << endl;
 	}
 	else
 	  cout << "failed to parse the doc" << endl;
@@ -302,7 +380,7 @@ namespace folia {
     int cnt = 0;
     xmlSetStructuredErrorFunc( &cnt, (xmlStructuredErrorFunc)error_sink );
     _xmldoc = xmlReadMemory( s.c_str(), s.length(), 0, 0,
-			    XML_PARSE_NOBLANKS|XML_PARSE_HUGE );
+			    XML_PARSE_HUGE );
     if ( _xmldoc ){
       if ( cnt > 0 ){
 	throw XmlError( "document is invalid" );
@@ -310,9 +388,12 @@ namespace folia {
       if ( debug )
 	cout << "read a doc from string" << endl;
       foliadoc = parseXml();
+      if ( !validate_offsets() ){
+	throw InconsistentText("MEH");
+      }
       if ( debug ){
 	if ( foliadoc ){
-	  cout << "succesful parsed the doc" << endl;
+	  cout << "successful parsed the doc" << endl;
 	}
 	else
 	  cout << "failed to parse the doc" << endl;
@@ -328,7 +409,7 @@ namespace folia {
 
   ostream& operator<<( ostream& os, const Document *d ){
     if ( d ){
-      string s = d->toXml( "", (d->mode == "strip") );
+      string s = d->toXml( "", d->strip() );
       os << s << endl;
     }
     else {
@@ -337,17 +418,17 @@ namespace folia {
     return os;
   }
 
-  bool Document::save( ostream& os, const string& nsLabel, bool kanon ) {
-    string s = toXml( nsLabel, ( kanon || (mode == "strip") ) );
+  bool Document::save( ostream& os, const string& nsLabel, bool kanon ) const {
+    string s = toXml( nsLabel, ( kanon || strip() ) );
     os << s << endl;
     return os.good();
   }
 
-  bool Document::save( const string& fn, const string& nsLabel, bool kanon ) {
+  bool Document::save( const string& fn, const string& nsLabel, bool kanon ) const {
     try {
       if ( match_back( fn, ".bz2" ) ){
 	string tmpname = fn.substr( 0, fn.length() - 3 ) + "tmp";
-	if ( toXml( tmpname, nsLabel, ( kanon || mode == "strip" ) ) ){
+	if ( toXml( tmpname, nsLabel, ( kanon || strip() ) ) ){
 	  bool stat = bz2Compress( tmpname, fn );
 	  remove( tmpname.c_str() );
 	  return stat;
@@ -358,7 +439,7 @@ namespace folia {
       }
       else  if ( match_back( fn, ".gz" ) ){
 	string tmpname = fn.substr( 0, fn.length() - 2 ) + "tmp";
-	if ( toXml( tmpname, nsLabel,  ( kanon || mode == "strip" ) ) ){
+	if ( toXml( tmpname, nsLabel,  ( kanon || strip() ) ) ){
 	  bool stat = gzCompress( tmpname, fn );
 	  remove( tmpname.c_str() );
 	  return stat;
@@ -368,7 +449,7 @@ namespace folia {
 	}
       }
       else {
-	return toXml( fn, nsLabel,  ( kanon || mode == "strip" ) );
+	return toXml( fn, nsLabel,  ( kanon || strip() ) );
       }
     }
     catch ( const exception& e ){
@@ -377,6 +458,17 @@ namespace folia {
     }
   }
 
+  string Document::xmlstring( bool k ) const {
+    xmlDoc *outDoc = to_xmlDoc( "", k );
+    xmlChar *buf; int size;
+    xmlDocDumpFormatMemoryEnc( outDoc, &buf, &size, "UTF-8", 0 ); // no formatting
+    string result = string( (const char *)buf, size );
+    xmlFree( buf );
+    xmlFreeDoc( outDoc );
+    _foliaNsOut = 0;
+    return result;
+  }
+
   int Document::size() const {
     if ( foliadoc )
       return foliadoc->size();
@@ -483,28 +575,49 @@ namespace folia {
       throw range_error( "rparagraphs() index out of range" );
   }
 
+  std::string Document::language() const {
+    string result;
+    if ( _metadata ){
+      result = _metadata->get_val("language");
+    }
+    return result;
+  }
+
+  std::string Document::metadatatype() const {
+    if ( _metadata ){
+      return _metadata->type();
+    }
+    return "native";
+  }
+
+  std::string Document::metadatafile() const {
+    if ( _metadata && _metadata->datatype() == "ExternalMetaData" ){
+      return _metadata->src();
+    }
+    return "";
+  }
+
   void Document::setimdi( xmlNode *node ){
     xmlNode *n = xPath( node, "//imdi:Session/imdi:Title" );
     if ( n ){
-      _title = XmlContent( n );
+      _metadata->add_av( "title", XmlContent( n ) );
     }
     n = xPath( node, "//imdi:Session/imdi:Date" );
     if ( n ){
-      _date = XmlContent( n);
+      _metadata->add_av( "date", XmlContent( n ) );
     }
-
     n = xPath( node, "//imdi:Source/imdi:Access/imdi:Publisher" );
     if ( n ){
-      _publisher = XmlContent( n );
+      _metadata->add_av( "publisher", XmlContent( n ) );
     }
-
     n = xPath( node, "//imdi:Source/imdi:Access/imdi:Availability" );
     if ( n ){
-      _license = XmlContent( n );
+      _metadata->add_av( "licence", XmlContent( n ) );
     }
     n = xPath( node, "//imdi:Languages/imdi:Language/imdi:ID" );
-    if ( n )
-      _language = XmlContent( n );
+    if ( n ){
+      _metadata->add_av( "language", XmlContent( n ) );
+    }
   }
 
   void Document::parsemeta( xmlNode *node ){
@@ -512,86 +625,55 @@ namespace folia {
       KWargs att = getAttributes( node );
       string type = att["id"];
       string val = XmlContent( node );
-      if ( type == "title" ){
-	_title = val;
-      }
-      else if ( type == "date" ){
-	_date = val;
-      }
-      else if ( type == "language" ){
-	_language = val;
-      }
-      else if ( type == "publisher" ){
-	_publisher = val;
-      }
-      else if ( type == "licence" ){
-	_license = val;
-      }
-      else if ( _metadatatype != "native" ){
-	throw runtime_error( "meta tag with id=" + type
-			     + " requires 'native' metadataype." );
-      }
-      else if ( meta_atts[type] != "" ){
+      string get = _metadata->get_val( type );
+      if ( !get.empty() ){
 	throw runtime_error( "meta tag with id=" + type
 			     + " is defined more then once " );
       }
-      else
-	meta_atts[type] = val;
+      _metadata->add_av( type, val );
     }
   }
 
   void Document::set_metadata( const string& type, const string& value ){
-    if ( type == "title" )
-      _title = value;
-    else if ( type == "date" )
-      _date = value;
-    else if ( type == "language" )
-      _language = value;
-    else if ( type == "publisher" )
-      _publisher = value;
-    else if ( type == "licence" )
-      _license = value;
-    else if ( _metadatatype != "native" ){
-      throw runtime_error( "meta tag with id=" + type
-			   + " requires 'native' metadataype." );
+    if ( !_metadata ){
+      _metadata = new NativeMetaData( "native" );
     }
-    else
-      meta_atts[type] = value;
+    else if ( _metadata->datatype() != "NativeMetaData" ){
+      throw MetaDataError( "cannot set '" + type + "=" + value +
+			   "' on " +  _metadata->datatype() + "(" +
+			   _metadata->type() + ")" );
+
+    }
+    _metadata->add_av( type, value );
   }
 
   const string Document::get_metadata( const string& type ) const {
-    if ( type == "title" )
-      return _title;
-    else if ( type == "date" )
-      return _date;
-    else if ( type == "language" )
-      return _language;
-    else if ( type == "publisher" )
-      return _publisher;
-    else if ( type == "licence" )
-      return _license;
-    else {
-      const auto& it = meta_atts.find( type );
-      if ( it != meta_atts.end() )
-	return it->second;
-      else
-	return "";
-    }
+    return _metadata->get_val( type );
   }
 
   void Document::set_foreign_metadata( xmlNode *node ){
+    if ( !_metadata ){
+      _metadata = new ForeignMetaData( "foreign" );
+    }
+    else {
+      if ( _metadata->datatype() != "ForeignMetaData" ){
+	throw MetaDataError( "set_foreign_metadata now allowed for "
+			     + _metadata->datatype() );
+      }
+    }
     ForeignData *add = new ForeignData();
     if ( Name( node ) != "foreign-data" ){
       // we need an extra layer then
       xmlNode *n = XmlNewNode( "foreign-data" );
       xmlAddChild( n, xmlCopyNode( node, 1 ) );
       add->set_data( n );
+      _metadata->add_foreign( n );
       xmlFreeNode (n );
     }
     else {
       add->set_data( node );
+      _metadata->add_foreign( node );
     }
-    _foreigndata.push_back( add );
   }
 
   void Document::parseannotations( xmlNode *node ){
@@ -607,6 +689,7 @@ namespace folia {
 	string a;
 	string t;
 	string d;
+	string alias;
 	auto it = att.find("set" );
 	if ( it != att.end() ){
 	  s = it->second;
@@ -625,24 +708,119 @@ namespace folia {
 	if ( it != att.end() ){
 	  d = parseDate( it->second );
 	}
-	declare( type, s, a, t, d );
+	it = att.find( "alias" );
+	if ( it != att.end() ){
+	  alias = it->second;
+	}
+	declare( type, s, a, t, d, alias );
       }
       n = n->next;
     }
   }
 
-  bool checkNS( xmlNode *n, const string& ns ){
-    string tns = getNS(n);
-    if ( tns == ns )
-      return true;
-    else
-      throw runtime_error( "namespace conflict for tag:" + Name(n)
-			   + ", wanted:" + ns
-			   + " got:" + tns );
-    return false;
+  void Document::parsesubmeta( xmlNode *node ){
+    using TiCC::operator<<;
+    if ( node ){
+      KWargs att = getAttributes( node );
+      string id = att["_id"];
+      if ( id.empty() ){
+	throw MetaDataError( "submetadata without xml:id" );
+      }
+      //      cerr << "parse submetadata, id=" << id << endl;
+      string type = att["type"];
+      //      cerr << "parse submetadata, type=" << type << endl;
+      if ( type.empty() ){
+	type = "native";
+      }
+      string src = att["src"];
+      if ( !src.empty() ){
+	submetadata[id] = new ExternalMetaData( type, src );
+	//	cerr << "created External metadata, id=" << id << endl;
+      }
+      else if ( type == "native" ){
+	submetadata[id] = new NativeMetaData( type );
+	//	cerr << "created Native metadata, id=" << id << endl;
+      }
+      else {
+	submetadata[id] = 0;
+	//	cerr << "set metadata to 0, id=" << id << endl;
+      }
+      xmlNode *p = node->children;
+      while ( p ){
+	if ( p->type == XML_ELEMENT_NODE ){
+	  if ( Name(p) == "meta" &&
+	       checkNS( p, NSFOLIA ) ){
+	    if ( type == "native" ){
+	      string txt = XmlContent( p );
+	      KWargs att = getAttributes( p );
+	      string sid = att["id"];
+	      if ( !txt.empty() ){
+		submetadata[id]->add_av( sid, txt );
+		// cerr << "added node to id=" << id
+		//      << "(" << sid << "," << txt << ")" << endl;
+	      }
+	    }
+	    else {
+	      throw MetaDataError("Encountered a meta element but metadata type is not native!");
+	    }
+	  }
+	  else if ( Name(p) == "foreign-data" &&
+		    checkNS( p, NSFOLIA ) ){
+	    if ( type == "native" ){
+	      throw MetaDataError("Encountered a foreign-data element but metadata type is native!");
+	    }
+	    else if ( submetadata[id] == 0 ){
+	      submetadata[id] = new ForeignMetaData( type );
+	      //	      cerr << "add new Foreign " << id << endl;
+	    }
+	    //	    cerr << "in  Foreign " << submetadata[id]->type() << endl;
+	    submetadata[id]->add_foreign( p );
+	    //	    cerr << "added a foreign id=" << id << endl;
+	  }
+	}
+	p = p->next;
+      }
+    }
+  }
+
+  int Document::compare_to_lib_version( const string& vers ){
+    int majVersion = 0;
+    int minVersion = 0;
+    int subVersion = 0;
+    vector<string> vec;
+    split_at( vers, vec, "." );
+    for ( size_t i=0; i < vec.size(); ++i ){
+      int val = stringTo<int>( vec[i] );
+      if ( i == 0 )
+	majVersion = val;
+      else if ( i == 1 )
+	minVersion = val;
+      else
+	subVersion += val;
+    }
+    if ( majVersion < MAJOR_VERSION ){
+      return -1;
+    }
+    else if ( majVersion > MAJOR_VERSION ){
+      return 1;
+    }
+    else if ( minVersion < MINOR_VERSION ){
+      return -1;
+    }
+    else if ( minVersion > MINOR_VERSION ){
+      return 1;
+    }
+    else if ( subVersion < SUB_VERSION ){
+      return -1;
+    }
+    else if ( subVersion > SUB_VERSION ){
+      return 1;
+    }
+    return 0;
   }
 
-  int check_version( const string& vers ){
+  int check_version( const string& vers, bool& no_textcheck ){
+    no_textcheck = false;
     int majVersion = 0;
     int minVersion = 0;
     int subVersion = 0;
@@ -657,6 +835,11 @@ namespace folia {
       else
 	subVersion += val;
     }
+    if ( ( majVersion < 1 )
+	 || (majVersion == 1 && minVersion < 5 ) ){
+      // don't check text consistency for older documents
+      no_textcheck = true;
+    }
     if ( majVersion < MAJOR_VERSION ){
       return -1;
     }
@@ -695,55 +878,70 @@ namespace folia {
       return 0;
     }
     string vers = att["version"];
-    if ( check_version( vers ) > 0 ){
-      cerr << "WARNING!!! FoLiA Document is a newer version then this library ("
-	   << vers << " vs " << version
+    bool no_textcheck = false;
+    if ( check_version( vers, no_textcheck ) > 0 ){
+      cerr << "WARNING!!! FoLiA Document is a newer version than this library ("
+	   << vers << " vs " << _version
 	   << ")\n\t Any possible subsequent failures in parsing or processing may probably be attributed to this." << endl
 	   << "\t Please upgrade libfolia!" << endl;
     }
+    if ( no_textcheck ){
+      setmode( "nochecktext" );
+    }
     setDocumentProps( att );
     FoliaElement *result = FoliaImpl::createElement( Name(root), this );
-    if ( debug > 2 )
+    if ( debug > 2 ){
       cerr << "created " << root << endl;
+    }
     result->setAttributes( att );
     xmlNode *p = root->children;
     while ( p ){
       if ( p->type == XML_ELEMENT_NODE ){
 	if ( Name(p) == "metadata" &&
 	     checkNS( p, NSFOLIA ) ){
-	  if ( debug > 1 )
+	  if ( debug > 1 ){
 	    cerr << "Found metadata" << endl;
+	  }
 	  KWargs atts = getAttributes( p );
-	  string val = lowercase(atts["type"]);
-	  if ( !val.empty() ){
-	    _metadatatype = val;
-	    if ( val == "imdi" || val == "cmdi" ){
-	      _metadatafile = atts["src"];
-	    }
+	  string type = lowercase(atts["type"]);
+	  if ( type.empty() ){
+	    type = "native";
+	  }
+	  string src = atts["src"];
+	  if ( !src.empty() ){
+	    _metadata = new ExternalMetaData( type, src );
+	  }
+	  else if ( type == "native" ){
+	    _metadata = new NativeMetaData( type );
+	  }
+	  else {
+	    _metadata = 0;
 	  }
 	  xmlNode *m = p->children;
 	  while ( m ){
 	    if ( Name(m)  == "METATRANSCRIPT" ){
-	      if ( !checkNS( m, NSIMDI ) || _metadatatype != "imdi" )
+	      if ( !checkNS( m, NSIMDI ) || type != "imdi" )
 		throw runtime_error( "imdi != imdi " );
-	      if ( debug > 1 )
+	      if ( debug > 1 ){
 		cerr << "found IMDI" << endl;
-	      if ( _metadata ){
-		throw XmlError( "multiple imdi:METATRANSCRIPT nodes!" );
 	      }
-	      _metadata = xmlCopyNodeList(m);
-	      setimdi( _metadata );
+	      if ( !_metadata ){
+		_metadata = new ForeignMetaData( "imdi" );
+	      }
+	      _metadata->add_foreign( xmlCopyNode(m,1) );
 	    }
 	    else if ( Name( m ) == "annotations" &&
 		      checkNS( m, NSFOLIA ) ){
-	      if ( debug > 1 )
+	      if ( debug > 1 ){
 		cerr << "found annotations" << endl;
+	      }
 	      parseannotations( m );
 	    }
 	    else if ( Name( m ) == "meta" &&
 		      checkNS( m, NSFOLIA ) ){
-	      if ( debug > 1 )
+	      if ( debug > 1 ){
 		cerr << "found meta node" << endl;
+	      }
 	      parsemeta( m );
 	    }
 	    else if ( Name(m)  == "foreign-data" &&
@@ -752,24 +950,44 @@ namespace folia {
 	      if ( t ){
 		t = t->parseXml( m );
 		if ( t ){
-		  _foreigndata.push_back( dynamic_cast<ForeignData *>(t) );
+		  if ( _metadata && _metadata->datatype() == "NativeMetaData" ){
+		    cerr << "WARNING: foreign-data found in metadata of type 'native'"  << endl;
+		    cerr << "changing type to 'foreign'" << endl;
+		    type = "foreign";
+		    delete _metadata;
+		    _metadata = new ForeignMetaData( type );
+		  }
+		  if ( !_metadata ){
+		    _metadata = new ForeignMetaData( type );
+		  }
+		  _metadata->add_foreign( m );
 		}
 	      }
 	    }
+	    else if ( Name(m)  == "submetadata" &&
+		      checkNS( m, NSFOLIA ) ){
+	      parsesubmeta( m );
+	    }
 	    m = m->next;
 	  }
+	  if ( _metadata == 0 && type == "imdi" ){
+	    // imdi missing all further info
+	    _metadata = new NativeMetaData( type );
+	  }
 	}
 	else {
 	  if ( p && getNS(p) == NSFOLIA ){
 	    string tag = Name( p );
 	    FoliaElement *t = FoliaImpl::createElement( tag, this );
 	    if ( t ){
-	      if ( debug > 2 )
+	      if ( debug > 2 ){
 		cerr << "created " << t << endl;
+	      }
 	      t = t->parseXml( p );
 	      if ( t ){
-		if ( debug > 2 )
+		if ( debug > 2 ){
 		  cerr << "extend " << result << " met " << tag << endl;
+		}
 		result->append( t );
 	      }
 	    }
@@ -842,6 +1060,60 @@ namespace folia {
     }
   }
 
+  bool Document::validate_offsets() const {
+    set<TextContent*> t_done;
+    for ( const auto& txt : t_offset_validation_buffer ){
+      if ( t_done.find( txt ) != t_done.end() ){
+	continue;
+      }
+      t_done.insert(txt);
+      int offset = txt->offset();
+      if ( offset != -1 ){
+	try {
+	  txt->getreference();
+	}
+	catch( UnresolvableTextContent& e ){
+	  string msg = "Text for " + txt->parent()->xmltag() + ", ID="
+	    + txt->parent()->id() + ", textclass='" + txt->cls()
+	    + "'), has incorrect offset " + TiCC::toString(offset);
+	  string ref = txt->ref();
+	  if ( !ref.empty() ){
+	    msg += " or invalid reference:" + ref;
+	  }
+	  msg += "\n\toriginal msg=";
+	  msg += e.what();
+	  throw UnresolvableTextContent( msg );
+	}
+      }
+    }
+    set<PhonContent*> p_done;
+    for ( const auto& phon : p_offset_validation_buffer ){
+      if ( p_done.find( phon ) != p_done.end() ){
+	continue;
+      }
+      p_done.insert(phon);
+      int offset = phon->offset();
+      if ( offset != -1 ){
+	try {
+	  phon->getreference();
+	}
+	catch( UnresolvableTextContent& e ){
+	  string msg = "Phoneme for " + phon->parent()->xmltag() + ", ID="
+	    + phon->parent()->id() + ", textclass='" + phon->cls()
+	    + "', has incorrect offset " + TiCC::toString(offset);
+	  string ref = phon->ref();
+	  if ( !ref.empty() ){
+	    msg += " or invalid reference:" + ref;
+	  }
+	  msg += "\n\toriginal msg=";
+	  msg += e.what();
+	  throw UnresolvableTextContent( msg );
+	}
+      }
+    }
+    return true;
+  }
+
   FoliaElement* Document::parseXml( ){
     getstyles();
     xmlNode *root = xmlDocGetRootElement( _xmldoc );
@@ -862,7 +1134,7 @@ namespace folia {
       if ( Name( root ) == "FoLiA" ){
 	string ns = getNS( root );
 	if ( ns.empty() ){
-	  if ( mode == "permissive" ){
+	  if ( permissive() ){
 	    _foliaNsIn_href = xmlCharStrdup( NSFOLIA.c_str() );
 	    _foliaNsIn_prefix = 0;
 	    xmlNs *defNs = xmlNewNs( root,
@@ -891,6 +1163,12 @@ namespace folia {
 	    }
 	  }
 	}
+	catch ( InconsistentText& e ){
+	  throw;
+	}
+	catch ( XmlError& e ){
+	  throw;
+	}
 	catch ( exception& e ){
 	  throw XmlError( e.what() );
 	}
@@ -915,13 +1193,15 @@ namespace folia {
     string a = kw["annotator"];
     string t = kw["annotatortype"];
     string d = kw["datetime"];
+    string alias = kw["alias"];
     kw.erase("annotator");
     kw.erase("annotatortype");
     kw.erase("datetime");
+    kw.erase("alias");
     if ( kw.size() != 0 ){
-      throw XmlError( "declaration: expected 'annotator', 'annotatortype' or 'datetime', got '" + kw.begin()->first + "'" );
+      throw XmlError( "declaration: expected 'annotator', 'annotatortype', 'alias' or 'datetime', got '" + kw.begin()->first + "'" );
     }
-    declare( type, st, a, t, d );
+    declare( type, st, a, t, d, alias );
   }
 
   string getNow() {
@@ -935,22 +1215,143 @@ namespace folia {
     return res;
   }
 
+  string Document::unalias( AnnotationType::AnnotationType type,
+			    const string& alias ) const {
+    const auto& ti = alias_set.find(type);
+    if ( ti != alias_set.end() ){
+      const auto& sti = ti->second.find( alias );
+      if ( sti != ti->second.end() ){
+	return sti->second;
+      }
+    }
+    return "";
+  }
+
+  string Document::alias( AnnotationType::AnnotationType type,
+			  const string& st ) const {
+    const auto& ti = set_alias.find(type);
+    if ( ti != set_alias.end() ){
+      const auto& ali = ti->second.find( st );
+      if ( ali != ti->second.end() ){
+	return ali->second;
+      }
+    }
+    return "";
+  }
+
   void Document::declare( AnnotationType::AnnotationType type,
-			  const string& s, const string& a,
-			  const string& t, const string& ds ){
-    if ( !isDeclared( type, s, a, t ) ){
-      string d = ds;
+			  const string& setname,
+			  const string& annotator,
+			  const string& annotator_type,
+			  const string& date_time,
+			  const string& _alias ){
+    if ( !_alias.empty() ){
+      string set_ali = alias(type,setname);
+      if ( !set_ali.empty() ){
+	if ( set_ali != _alias ){
+	  throw XmlError( "setname: " + setname + " already has an alias: "
+			  + set_ali );
+	}
+      }
+      string ali_ali = alias(type,_alias);
+      string ali_set = unalias(type,_alias);
+      if ( !ali_ali.empty() ){
+	if( ali_ali != _alias ){
+	  throw XmlError( "alias: " + _alias +
+			  " is also in use as a setname for set:'"
+			  + ali_set + "'" );
+	}
+      }
+      if ( !ali_set.empty()
+	   && ali_set != setname ){
+	throw XmlError( "alias: " + _alias + " already used for setname: "
+			+ ali_set );
+      }
+    }
+    if ( !isDeclared( type, setname, annotator, annotator_type ) ){
+      if ( !unalias(type,setname).empty()
+	   && unalias(type,setname) != setname ){
+	throw XmlError( "setname: " + setname + " is also in use as an alias" );
+      }
+      string d = date_time;
       if ( d == "now()" ){
 	d = getNow();
       }
-      annotationdefaults[type].insert( make_pair(s, at_t(a,t,d) ) );
-      anno_sort.push_back(make_pair(type,s));
-      //    cerr << "inserted [" << type << "][" << st << "](" << a << "," << t << "," << d ")" << endl;
-      //    cerr << "annotation defaults now: " <<  annotationdefaults << endl;
+      annotationdefaults[type].insert( make_pair( setname,
+						  at_t(annotator,annotator_type,d) ) );
+      anno_sort.push_back(make_pair(type,setname));
+      annotationrefs[type][setname] = 0;
+      if ( !_alias.empty() ){
+	alias_set[type][_alias] = setname;
+	set_alias[type][setname] = _alias;
+      }
+      else {
+	alias_set[type][setname] = setname;
+	set_alias[type][setname] = setname;
+      }
+    }
+  }
 
+  void Document::un_declare( AnnotationType::AnnotationType type,
+			     const string& set_name ){
+    string setname = unalias(type,set_name);
+    if (  annotationrefs[type][setname] != 0 ){
+      throw XmlError( "unable to undeclare " + toString(type) + "-type("
+		      + setname + ") (references remain)" );
+    }
+    auto const adt = annotationdefaults.find(type);
+    if ( adt != annotationdefaults.end() ){
+      auto it = adt->second.begin();
+      while ( it != adt->second.end() ){
+	if ( setname.empty() || it->first == setname ){
+	  it = adt->second.erase(it);
+	}
+	else {
+	  ++it;
+	}
+      }
+      auto it2 = anno_sort.begin();
+      while ( it2 != anno_sort.end() ){
+	if ( it2->first == type && it2->second == setname ){
+	  it2 = anno_sort.erase( it2 );
+	}
+	else {
+	  ++it2;
+	}
+      }
+      auto it3 = alias_set[type].begin();
+      while ( it3 != alias_set[type].end() ){
+	if ( it3->first == setname || it3->second == setname ){
+	  it3 = alias_set[type].erase( it3 );
+	}
+	else {
+	  ++it3;
+	}
+      }
+      auto it4 = set_alias[type].begin();
+      while ( it4 != set_alias[type].end() ){
+	if ( it4->first == setname || it4->second == setname ){
+	  it4 = set_alias[type].erase( it4 );
+	}
+	else {
+	  ++it4;
+	}
+      }
     }
   }
 
+  multimap<AnnotationType::AnnotationType, string> Document::unused_declarations( ) const {
+    multimap<AnnotationType::AnnotationType,string> result;
+    for ( const auto& tit : annotationrefs ){
+      for ( const auto& mit : tit.second ){
+	if ( mit.second == 0 ){
+	  result.insert( make_pair(tit.first, mit.first ) );
+	}
+      }
+    }
+    return result;
+  }
+
   Text* Document::addText( const KWargs& kwargs ){
     Text *res = new Text( kwargs, this );
     foliadoc->append( res );
@@ -963,22 +1364,25 @@ namespace folia {
   }
 
   bool Document::isDeclared( AnnotationType::AnnotationType type,
-			     const string& s,
-			     const string& a,
-			     const string& t){
+			     const string& set_name,
+			     const string& annotator,
+			     const string& annotator_type){
     //
     // We DO NOT check the date. if all parameters match, it is OK
     //
+    if ( set_name.empty() ){
+	throw runtime_error("isDeclared called with empty set.");
+    }
     if ( type == AnnotationType::NO_ANN ){
       return true;
     }
+    string setname = unalias(type,set_name);
+
     const auto& it1 = annotationdefaults.find(type);
     if ( it1 != annotationdefaults.end() ){
-      if ( s.empty() )
-	throw runtime_error("isDeclared with empty set.");
-      auto mit2 = it1->second.lower_bound(s);
-      while ( mit2 != it1->second.upper_bound(s) ){
-	if ( mit2->second.a == a && mit2->second.t == t )
+      auto mit2 = it1->second.lower_bound(setname);
+      while ( mit2 != it1->second.upper_bound(setname) ){
+	if ( mit2->second.a == annotator && mit2->second.t == annotator_type )
 	  return true;
 	++mit2;
       }
@@ -986,16 +1390,36 @@ namespace folia {
     return false;
   }
 
+  void Document::incrRef( AnnotationType::AnnotationType type,
+			  const string& s ){
+    if ( type != AnnotationType::NO_ANN ){
+      string st = s;
+      if ( st.empty() ){
+	st = defaultset(type);
+      }
+      ++annotationrefs[type][st];
+      //      cerr << "increment " << toString(type) << "(" << st << ")" << endl;
+    }
+  }
+
+  void Document::decrRef( AnnotationType::AnnotationType type,
+			  const string& s ){
+    if ( type != AnnotationType::NO_ANN ){
+      --annotationrefs[type][s];
+      //      cerr << "decrement " << toString(type) << "(" << s << ")" << endl;
+    }
+  }
+
   bool Document::isDeclared( AnnotationType::AnnotationType type,
-			     const string& s ){
+			     const string& setname ){
     if ( type == AnnotationType::NO_ANN ){
       return true;
     }
     const auto& mit1 = annotationdefaults.find(type);
     if ( mit1 != annotationdefaults.end() ){
-      if ( s.empty() )
+      if ( setname.empty() )
 	return true;
-      const auto& mit2 = mit1->second.find(s);
+      const auto& mit2 = mit1->second.find(setname);
       return mit2 != mit1->second.end();
     }
     return false;
@@ -1108,7 +1532,7 @@ namespace folia {
 	s = it->second.t;
 	if ( !s.empty() )
 	  args["annotatortype"] = s;
-	if ( mode != "strip" ){
+	if ( !strip() ){
 	  s = it->second.d;
 	  if ( !s.empty() )
 	    args["datetime"] = s;
@@ -1116,6 +1540,13 @@ namespace folia {
 	s = it->first;
 	if ( s != "undefined" ) // the default
 	  args["set"] = s;
+	const auto& ti = set_alias.find(type);
+	if ( ti != set_alias.end() ){
+	  const auto& alias = ti->second.find(s);
+	  if ( alias->second != s ){
+	    args["alias"] = alias->second;
+	  }
+	}
 	xmlNode *n = XmlNewNode( foliaNs(), label );
 	addAttributes( n, args );
 	xmlAddChild( node, n );
@@ -1124,70 +1555,85 @@ namespace folia {
     }
   }
 
-  void Document::setmetadata( xmlNode *node ) const{
-    KWargs atts;
-    atts["type"] = _metadatatype;
-    if ( !_metadatafile.empty() ){
-      atts["src"] = _metadatafile;
-    }
-    addAttributes( node, atts );
-    if ( _metadatatype == "native" ){
-      if ( !_title.empty() ){
-	xmlNode *m = XmlNewNode( foliaNs(), "meta" );
-	xmlAddChild( m, xmlNewText( (const xmlChar*)_title.c_str()) );
-	KWargs atts;
-	atts["id"] = "title";
-	addAttributes( m, atts );
-	xmlAddChild( node, m );
+  void Document::addsubmetadata( xmlNode *node ) const {
+    for ( const auto& it : submetadata ){
+      xmlNode *sm = XmlNewNode( foliaNs(), "submetadata" );
+      KWargs atts;
+      atts["xml:id"] = it.first;
+      addAttributes( sm, atts );
+      MetaData *md = submetadata.find(it.first)->second;
+      string type = md->type();
+      atts.clear();
+      atts["type"] = type;
+      addAttributes( sm, atts );
+      xmlAddChild( node, sm );
+      if ( type == "native" ){
+	atts = it.second->get_avs();
+	// using TiCC::operator<<;
+	// cerr << "atts: " << atts << endl;
+	for ( const auto& av : atts ){
+	  xmlNode *m = XmlNewNode( foliaNs(), "meta" );
+	  KWargs args;
+	  args["id"] = av.first;
+	  addAttributes( m, args );
+	  xmlAddChild( m, xmlNewText( (const xmlChar*)av.second.c_str()) );
+	  xmlAddChild( sm, m );
+	}
       }
-      if ( !_date.empty() ){
-	xmlNode *m = XmlNewNode( foliaNs(), "meta" );
-	xmlAddChild( m, xmlNewText( (const xmlChar*)_date.c_str()) );
-	KWargs atts;
-	atts["id"] = "date";
-	addAttributes( m, atts );
-	xmlAddChild( node, m );
+      else if ( md->datatype() == "ExternalMetaData" ){
+	KWargs args;
+	args["src"] = md->src();
+	addAttributes( sm, args );
       }
-      if ( !_language.empty() ){
-	xmlNode *m = XmlNewNode( foliaNs(), "meta" );
-	xmlAddChild( m, xmlNewText( (const xmlChar*)_language.c_str()) );
-	KWargs atts;
-	atts["id"] = "language";
-	addAttributes( m, atts );
-	xmlAddChild( node, m );
+      else if ( md->datatype() == "ForeignMetaData" ){
+	for ( const auto& foreign : md->get_foreigners() ) {
+	  xmlNode *f = foreign->xml( true, false );
+	  xmlAddChild( sm, f );
+	}
       }
-      if ( !_license.empty() ){
-	xmlNode *m = XmlNewNode( foliaNs(), "meta" );
-	xmlAddChild( m, xmlNewText( (const xmlChar*)_license.c_str()) );
+    }
+  }
+
+  void Document::setmetadata( xmlNode *node ) const{
+    if ( _metadata ){
+      if ( _metadata->datatype() == "ExternalMetaData" ){
 	KWargs atts;
-	atts["id"] = "license";
-	addAttributes( m, atts );
-	xmlAddChild( node, m );
+	atts["type"] = _metadata->type();
+	string src = _metadata->src();
+	if ( !src.empty() ){
+	  atts["src"] = src;
+	}
+	addAttributes( node, atts );
       }
-      if ( !_publisher.empty() ){
-	xmlNode *m = XmlNewNode( foliaNs(), "meta" );
-	xmlAddChild( m, xmlNewText( (const xmlChar*)_publisher.c_str()) );
+      else if ( _metadata->datatype() == "NativeMetaData" ){
 	KWargs atts;
-	atts["id"] = "publisher";
-	addAttributes( m, atts );
-	xmlAddChild( node, m );
+	atts["type"] = _metadata->type();
+	addAttributes( node, atts );
+	for ( const auto& it : _metadata->get_avs() ){
+	  xmlNode *m = XmlNewNode( foliaNs(), "meta" );
+	  xmlAddChild( m, xmlNewText( (const xmlChar*)it.second.c_str()) );
+	  KWargs atts;
+	  atts["id"] = it.first;
+	  addAttributes( m, atts );
+	  xmlAddChild( node, m );
+	}
       }
-      for ( const auto& it : meta_atts ){
-	xmlNode *m = XmlNewNode( foliaNs(), "meta" );
-	xmlAddChild( m, xmlNewText( (const xmlChar*)it.second.c_str()) );
+      else if ( _metadata->datatype() == "ForeignMetaData" ){
 	KWargs atts;
-	atts["id"] = it.first;
-	addAttributes( m, atts );
-	xmlAddChild( node, m );
+	atts["type"] = _metadata->type();
+	addAttributes( node, atts );
+	for ( const auto& foreign : _metadata->get_foreigners() ) {
+	  xmlNode *f = foreign->xml( true, false );
+	  xmlAddChild( node, f );
+	}
       }
     }
     else {
-      xmlAddChild( node, _metadata );
-    }
-    for ( const auto& foreign : _foreigndata ){
-      xmlNode *f = foreign->xml( true, false );
-      xmlAddChild( node, f );
+      KWargs atts;
+      atts["type"] = "native";
+      addAttributes( node, atts );
     }
+    addsubmetadata( node );
   }
 
   void Document::setstyles( xmlDoc* doc ) const {
@@ -1224,14 +1670,14 @@ namespace folia {
     xmlSetNs( root, _foliaNsOut );
     KWargs attribs;
     attribs["_id"] = foliadoc->id(); // sort "id" in front!
-    if ( mode == "strip" ){
+    if ( strip() ){
       attribs["generator"] = "";
       attribs["version"] = "";
     }
     else {
       attribs["generator"] = string("libfolia-v") + VERSION;
-      if ( !version.empty() )
-	attribs["version"] = version;
+      if ( !_version.empty() )
+	attribs["version"] = _version;
     }
     if ( external )
       attribs["external"] = "yes";
diff --git a/src/folia_impl.cxx b/src/folia_impl.cxx
index f506e9c..d4a8dcd 100644
--- a/src/folia_impl.cxx
+++ b/src/folia_impl.cxx
@@ -101,6 +101,14 @@ namespace folia {
     return _props.SPEAKABLE;
   }
 
+  bool FoliaImpl::is_textcontainer() const {
+    return _props.TEXTCONTAINER;
+  }
+
+  bool FoliaImpl::is_phoncontainer() const {
+    return _props.PHONCONTAINER;
+  }
+
   bool FoliaImpl::xlink() const {
     return _props.XLINK;
   }
@@ -117,6 +125,10 @@ namespace folia {
     return _props.AUTO_GENERATE_ID;
   }
 
+  bool is_structure( const FoliaElement *el ){
+    return dynamic_cast<const AbstractStructureElement*>( el ) != 0;
+  }
+
   const string FoliaImpl::href() const {
     auto it = _xlink.find("href");
     if ( it != _xlink.end() ){
@@ -164,7 +176,7 @@ namespace folia {
 
   FoliaImpl::~FoliaImpl( ) {
     // cerr << "delete element id=" << _id << " tag = " << xmltag() << " *= "
-    //  	 << (void*)this << " datasize= " << data.size() << endl;
+    // 	 << (void*)this << " datasize= " << data.size() << endl;
     for ( const auto& el : data ) {
       if ( el->refcount() == 0 ) {
 	// probably only != 0 for words
@@ -178,6 +190,7 @@ namespace folia {
     //	 << (void*)this << " datasize= " << data.size() << endl;
     if ( mydoc ) {
       mydoc->delDocIndex( this, _id );
+      mydoc->decrRef( annotation_type(), _set );
     }
   }
 
@@ -191,7 +204,7 @@ namespace folia {
   void FoliaImpl::setAttributes( const KWargs& kwargs_in ) {
     KWargs kwargs = kwargs_in;
     Attrib supported = required_attributes() | optional_attributes();
-    // if ( element_id() == Reference_t ) {
+    // if ( element_id() == Division_t ) {
     //   cerr << "set attributes: " << kwargs << " on " << classname() << endl;
     //   cerr << "required = " <<  required_attributes() << endl;
     //   cerr << "optional = " <<  optional_attributes() << endl;
@@ -201,8 +214,7 @@ namespace folia {
     //   cerr << "_id=" << _id << endl;
     //   Reference*ref=dynamic_cast<Reference*>(this);
     //   cerr << "id=" << ref->refId << endl;
-
-    //   //   cerr << "AUTH : " << _auth << ", default=" << default_auth() << endl;
+    //   cerr << "AUTH : " << _auth << ", default=" << default_auth() << endl;
     // }
     if ( mydoc && mydoc->debug > 2 ) {
       cerr << "set attributes: " << kwargs << " on " << classname() << endl;
@@ -217,8 +229,9 @@ namespace folia {
       if ( e ) {
 	_id = e->generateId( xmltag() );
       }
-      else
+      else {
 	throw ValueError("Unable to generate an id from ID= " + it->second );
+      }
       kwargs.erase( it );
     }
     else {
@@ -251,14 +264,20 @@ namespace folia {
     it = kwargs.find( "set" );
     string def;
     if ( it != kwargs.end() ) {
+      if ( !mydoc ) {
+	throw ValueError( "Set=" + _set + " is used on a node without a document." );
+      }
       if ( !( (CLASS & supported) || setonly() ) ) {
 	throw ValueError("Set is not supported for " + classname());
       }
       else {
-	_set = it->second;
-      }
-      if ( !mydoc ) {
-	throw ValueError( "Set=" + _set + " is used on a node without a document." );
+	string st = mydoc->unalias( annotation_type(), it->second);
+	if ( st.empty() ){
+	  _set = it->second;
+	}
+	else {
+	  _set = st;
+	}
       }
       if ( !mydoc->isDeclared( annotation_type(), _set ) ) {
 	throw ValueError( "Set " + _set + " is used but has no declaration " +
@@ -278,7 +297,7 @@ namespace folia {
 	throw ValueError("Class is not supported for " + classname() );
       }
       _class = it->second;
-      if ( element_id() != TextContent_t ) {
+      if ( element_id() != TextContent_t && element_id() != PhonContent_t ) {
 	if ( !mydoc ) {
 	  throw ValueError( "Class=" + _class + " is used on a node without a document." );
 	}
@@ -288,6 +307,7 @@ namespace folia {
 	  throw ValueError( "Class " + _class + " is used but has no default declaration " +
 			    "for " + toString( annotation_type() ) + "-annotation" );
 	}
+	mydoc->incrRef( annotation_type(), _set );
       }
       kwargs.erase( it );
     }
@@ -366,7 +386,7 @@ namespace folia {
     it = kwargs.find( "n" );
     if ( it != kwargs.end() ) {
       if ( !(N & supported) ) {
-	throw ValueError("N is not supported for " + classname() );
+	throw ValueError("N attribute is not supported for " + classname() );
       }
       else {
 	_n = it->second;
@@ -442,7 +462,7 @@ namespace folia {
     it = kwargs.find( "datetime" );
     if ( it != kwargs.end() ) {
       if ( !(DATETIME & supported) ) {
-	throw ValueError("datetime is not supported for " + classname() );
+	throw ValueError("datetime attribute is not supported for " + classname() );
       }
       else {
 	string time = parseDate( it->second );
@@ -462,7 +482,7 @@ namespace folia {
     it = kwargs.find( "begintime" );
     if ( it != kwargs.end() ) {
       if ( !(BEGINTIME & supported) ) {
-	throw ValueError( "begintime is not supported for " + classname() );
+	throw ValueError( "begintime attribute is not supported for " + classname() );
       }
       else {
 	string time = parseTime( it->second );
@@ -479,7 +499,7 @@ namespace folia {
     it = kwargs.find( "endtime" );
     if ( it != kwargs.end() ) {
       if ( !(ENDTIME & supported) ) {
-	throw ValueError( "endtime is not supported for " + classname() );
+	throw ValueError( "endtime attribute is not supported for " + classname() );
       }
       else {
 	string time = parseTime( it->second );
@@ -497,7 +517,7 @@ namespace folia {
     it = kwargs.find( "src" );
     if ( it != kwargs.end() ) {
       if ( !(SRC & supported) ) {
-	throw ValueError( "src is not supported for " + classname() );
+	throw ValueError( "src attribute is not supported for " + classname() );
       }
       else {
 	_src = it->second;
@@ -507,10 +527,26 @@ namespace folia {
     else
       _src.clear();
 
+    it = kwargs.find( "metadata" );
+    if ( it != kwargs.end() ) {
+      if ( !(METADATA & supported) ) {
+	throw ValueError( "Metadata attribute is not supported for " + classname() );
+      }
+      else {
+	_metadata = it->second;
+	if ( mydoc && mydoc->get_submetadata( _metadata ) == 0 ){
+	  throw KeyError( "No such metadata defined: " + _metadata );
+	}
+      }
+      kwargs.erase( it );
+    }
+    else
+      _metadata.clear();
+
     it = kwargs.find( "speaker" );
     if ( it != kwargs.end() ) {
       if ( !(SPEAKER & supported) ) {
-	throw ValueError( "speaker is not supported for " + classname() );
+	throw ValueError( "speaker attibute is not supported for " + classname() );
       }
       else {
 	_speaker = it->second;
@@ -520,6 +556,21 @@ namespace folia {
     else {
       _speaker.clear();
     }
+
+    it = kwargs.find( "textclass" );
+    if ( it != kwargs.end() ) {
+      if ( !(TEXTCLASS & supported) ) {
+	throw ValueError( "textclass attribute is not supported for " + classname() );
+      }
+      else {
+	_textclass = it->second;
+      }
+      kwargs.erase( it );
+    }
+    else {
+      _textclass = "current";
+    }
+
     it = kwargs.find( "auth" );
     if ( it != kwargs.end() ) {
       _auth = stringTo<bool>( it->second );
@@ -568,7 +619,13 @@ namespace folia {
     if ( !_set.empty() &&
 	 _set != mydoc->defaultset( annotation_type() ) ) {
       isDefaultSet = false;
-      attribs["set"] = _set;
+      string ali = mydoc->alias( annotation_type(), _set );
+      if ( ali.empty() ){
+	attribs["set"] = _set;
+      }
+      else {
+	attribs["set"] = ali;
+      }
     }
     if ( !_class.empty() ) {
       attribs["class"] = _class;
@@ -628,9 +685,15 @@ namespace folia {
     if ( !_src.empty() ) {
       attribs["src"] = _src;
     }
+    if ( !_metadata.empty() ) {
+      attribs["metadata"] = _metadata;
+    }
     if ( !_speaker.empty() ) {
       attribs["speaker"] = _speaker;
     }
+    if ( !_textclass.empty() && _textclass != "current" ){
+      attribs["textclass"] = _textclass;
+    }
     if ( _annotator_type != UNDEFINED ) {
       AnnotatorType at = stringTo<AnnotatorType>( mydoc->defaultannotatortype( annotation_type(), _set ) );
       if ( (!isDefaultSet || !isDefaultAnn) && _annotator_type != at ) {
@@ -683,6 +746,92 @@ namespace folia {
     return att;
   }
 
+  void FoliaImpl::check_append_text_consistency( const FoliaElement *child ) const {
+    if ( !mydoc || !mydoc->checktext() ){
+      return;
+    }
+    string cls = child->cls();
+    if ( !child->hastext( cls ) ){
+      // no use to proceed. not adding text
+      return;
+    }
+    FoliaElement *parent = this->parent();
+    if ( parent
+	 && parent->element_id() != Correction_t
+	 && parent->hastext( cls ) ){
+      // check text consistency for parents with text
+      // but SKIP Corrections
+      UnicodeString s1 = parent->text( cls, false, true );
+      UnicodeString s2 = child->text( cls, false, true );
+      // no retain tokenization, strict for both
+      s1 = normalize( s1 );
+      s2 = normalize( s2 );
+      bool test_fail = false;
+      if ( isSubClass( Word_t )
+	   || isSubClass( String_t ) ){
+	// Words and Strings are 'per definition' PART of there parents
+	test_fail = ( s1.indexOf( s2 ) < 0 ); // aren't they?
+      }
+      else {
+	// otherwise an exacte match is needed
+	test_fail = ( s1 != s2 );
+      }
+      if ( test_fail ){
+	throw InconsistentText( "text (class="
+				+ cls + ") from node: " + child->xmltag()
+				+ "(" + child->id() + ")"
+				+ " with value '" + UnicodeToUTF8(s2)
+				+ "' to element: " + parent->xmltag() +
+				+ "(" + parent->id() + ") which already has "
+				+ "text in that class and value: '"
+				+ UnicodeToUTF8(s1) + "'" );
+      }
+    }
+  }
+
+  void FoliaImpl::check_text_consistency( ) const {
+    if ( !mydoc || !mydoc->checktext() ){
+      return;
+    }
+    // check if the text associated with all children is compatible with the
+    // parents parental text.
+
+    string cls = this->cls();
+    FoliaElement *parent = this->parent();
+    if ( parent
+	 && parent->element_id() != Correction_t
+	 && parent->hastext( cls ) ){
+      // check text consistency for parents with text
+      // but SKIP Corrections
+      UnicodeString s1 = parent->text( cls, false, true );
+      UnicodeString s2 = this->text( cls, false, false );
+      // no retain tokenization, strict for parent, deeper for child
+      s1 = normalize( s1 );
+      s2 = normalize( s2 );
+      bool test_fail = false;
+      test_fail = ( s1 != s2 );
+      if ( isSubClass( Word_t )
+	   || isSubClass( String_t ) ) {
+	// Words and Strings are 'per definition' PART of there parents
+	test_fail = ( s1.indexOf( s2 ) < 0 ); // aren't they?
+      }
+      else {
+	// otherwise an exacte match is needed
+	test_fail = ( s1 != s2 );
+      }
+     if ( test_fail ){
+	throw InconsistentText( "text (class="
+				+ cls + ") from node: " + xmltag()
+				+ "(" + id() + ")"
+				+ " with value '" + UnicodeToUTF8(s2)
+				+ "' to element: " + parent->xmltag() +
+				+ "(" + parent->id() + ") which already has "
+				+ "text in that class and value: '"
+				+ UnicodeToUTF8(s1) + "'" );
+      }
+    }
+  }
+
   xmlNode *FoliaImpl::xml( bool recursive, bool kanon ) const {
     xmlNode *e = XmlNewNode( foliaNs(), xmltag() );
     KWargs attribs = collectAttributes();
@@ -748,10 +897,12 @@ namespace folia {
 	xmlAddChild( e, cel->xml( recursive, kanon ) );
       }
       for ( const auto& tel : currenttextelements ) {
-	xmlAddChild( e, tel->xml( recursive, kanon ) );
+	xmlAddChild( e, tel->xml( recursive, false ) );
+	// don't change the internal sequences of TextContent elements
       }
       for ( const auto& tel : textelements ) {
-	xmlAddChild( e, tel->xml( recursive, kanon ) );
+	xmlAddChild( e, tel->xml( recursive, false ) );
+	// don't change the internal sequences of TextContent elements
       }
       if ( !kanon ) {
 	for ( const auto& oel : otherelements ) {
@@ -763,6 +914,7 @@ namespace folia {
 	  xmlAddChild( e, oem.second->xml( recursive, kanon ) );
 	}
       }
+      check_text_consistency();
     }
     return e;
   }
@@ -772,7 +924,7 @@ namespace folia {
     // then return the associated text()
     // if this is a PhonContent or it may contain PhonContent
     // then return the associated phon()
-    // otherwise fallback to the tagname.
+    // otherwise return empty string
     UnicodeString us;
     try {
       us = text(cls);
@@ -781,9 +933,8 @@ namespace folia {
       try {
 	us = phon(cls);
       }
-      catch( NoSuchText& e ){
+      catch( NoSuchPhon& e ){
 	// No TextContent or Phone allowed
-	us = xmltag().c_str();
       }
     }
     return UnicodeToUTF8( us );
@@ -834,6 +985,17 @@ namespace folia {
     }
   }
 
+  bool FoliaElement::hasphon( const string& cls ) const {
+    // does this element have a TextContent with class 'cls'
+    // Default is class="current"
+    try {
+      this->phoncontent(cls);
+      return true;
+    } catch (NoSuchPhon& e ) {
+      return false;
+    }
+  }
+
   //#define DEBUG_TEXT
   //#define DEBUG_TEXT_DEL
 
@@ -870,8 +1032,7 @@ namespace folia {
     if ( strict ) {
       return textcontent(cls)->text();
     }
-    else if ( element_id() == TextContent_t
-	      || element_id() == AbstractTextMarkup_t ){ // TEXTCONTAINER property
+    else if ( is_textcontainer() ){
       UnicodeString result;
       for ( const auto& d : data ){
 	if ( !result.isEmpty() ){
@@ -966,12 +1127,26 @@ namespace folia {
     return found_nl > 0;
   }
 
+  bool no_space_at_end( FoliaElement *s ){
+    bool result = false;
+    //    cerr << "no space? s: " << s << endl;
+    if ( s ){
+      vector<Word*> words = s->select<Word>(false);
+      if ( !words.empty() ){
+	Word *last = words.back();
+	//	cerr << "no space? last: " << last << endl;
+	return !last->space();
+      }
+    }
+    return result;
+  }
+
   const UnicodeString FoliaImpl::deeptext( const string& cls,
 					   bool retaintok ) const {
     // get the UnicodeString value of underlying elements
     // default cls="current"
 #ifdef DEBUG_TEXT
-    cerr << "deepTEXT(" << cls << ") op node : " << xmltag() << " id(" << id() << ")" << endl;
+    cerr << "deepTEXT(" << cls << ") op node : " << xmltag() << " id(" << id() << ") cls=" << this->cls() << ")" << endl;
 #endif
 #ifdef DEBUG_TEXT
     cerr << "deeptext: node has " << data.size() << " children." << endl;
@@ -986,7 +1161,11 @@ namespace folia {
 	cerr << "deeptext: node[" << child->xmltag() << "] NOT PRINTABLE! " << endl;
       }
 #endif
-      if ( child->printable() && !child->isinstance( TextContent_t ) ) {
+      if ( child->printable()
+	   && ( is_structure( child )
+		|| child->isSubClass( AbstractSpanAnnotation_t )
+		|| child->isinstance( Correction_t ) )
+	   && !child->isinstance( TextContent_t ) ) {
 #ifdef DEBUG_TEXT
 	cerr << "deeptext:bekijk node[" << child->xmltag() << "]"<< endl;
 #endif
@@ -1003,12 +1182,23 @@ namespace folia {
 	  cerr << "deeptext trimmed '" << tmp << "'" << endl;
 #endif
 	  parts.push_back(tmp);
-	  // get the delimiter
-	  const string& delim = child->getTextDelimiter( retaintok );
+	  if ( child->isinstance( Sentence_t )
+	       && no_space_at_end(child) ){
+	    const string& delim = "";
 #ifdef DEBUG_TEXT
-	  cerr << "deeptext:delimiter van "<< child->xmltag() << " ='" << delim << "'" << endl;
+	    cerr << "deeptext: no delimiter van "<< child->xmltag() << " on"
+		 << " last w of s" << endl;
 #endif
-	  seps.push_back(UTF8ToUnicode(delim));
+	    seps.push_back(UTF8ToUnicode(delim));
+	  }
+	  else {
+	    // get the delimiter
+	    const string& delim = child->getTextDelimiter( retaintok );
+#ifdef DEBUG_TEXT
+	    cerr << "deeptext:delimiter van "<< child->xmltag() << " ='" << delim << "'" << endl;
+#endif
+	    seps.push_back(UTF8ToUnicode(delim));
+	  }
 	} catch ( NoSuchText& e ) {
 #ifdef DEBUG_TEXT
 	  cerr << "HELAAS" << endl;
@@ -1078,14 +1268,22 @@ namespace folia {
     return this->text(cls, true, false );
   }
 
-  TextContent *FoliaImpl::textcontent( const string& cls ) const {
+  const TextContent *FoliaImpl::textcontent( const string& cls ) const {
     // Get the text explicitly associated with this element
     // (of the specified class) the default class is 'current'
     // Returns the TextContent instance rather than the actual text.
+    // (so it might return iself.. ;)
     // Does not recurse into children
     // with sole exception of Correction
     // Raises NoSuchText exception if not found.
-
+    if ( isinstance(TextContent_t) ){
+      if  ( this->cls() == cls ) {
+	return dynamic_cast<const TextContent*>(this);
+      }
+      else {
+	throw NoSuchText( "TextContent::textcontent(" + cls + ")" );
+      }
+    }
     if ( !printable() ) {
       throw NoSuchText( "non-printable element: " +  xmltag() );
     }
@@ -1101,17 +1299,24 @@ namespace folia {
 	}
       }
     }
-    throw NoSuchText( xmltag() + "::textcontent()" );
+    throw NoSuchText( xmltag() + "::textcontent(" + cls + ")" );
   }
 
-  PhonContent *FoliaImpl::phoncontent( const string& cls ) const {
+  const PhonContent *FoliaImpl::phoncontent( const string& cls ) const {
     // Get the phon explicitly associated with this element
     // (of the specified class) the default class is 'current'
     // Returns the PhonContent instance rather than the actual phoneme.
     // Does not recurse into children
     // with sole exception of Correction
     // Raises NoSuchPhon exception if not found.
-
+    if ( isinstance(PhonContent_t) ){
+      if  ( this->cls() == cls ) {
+	return dynamic_cast<const PhonContent*>(this);
+      }
+      else {
+	throw NoSuchPhon( xmltag() + "::phoncontent(" + cls + ")" );
+      }
+    }
     if ( !speakable() ) {
       throw NoSuchPhon( "non-speakable element: " + xmltag() );
     }
@@ -1128,13 +1333,13 @@ namespace folia {
 	}
       }
     }
-    throw NoSuchPhon( xmltag() + "::phoncontent()" );
+    throw NoSuchPhon( xmltag() + "::phoncontent(" + cls + ")" );
   }
 
   //#define DEBUG_PHON
 
   const UnicodeString FoliaImpl::phon( const string& cls,
-				 bool strict ) const {
+				       bool strict ) const {
     // get the UnicodeString value of underlying elements
     // default cls="current"
 #ifdef DEBUG_PHON
@@ -1144,7 +1349,7 @@ namespace folia {
       return phoncontent(cls)->phon();
     }
     else if ( !speakable() ) {
-      throw NoSuchText( "NON speakable element: " + xmltag() );
+      throw NoSuchPhon( "NON speakable element: " + xmltag() );
     }
     else {
       UnicodeString result = deepphon( cls );
@@ -1171,7 +1376,7 @@ namespace folia {
     vector<UnicodeString> seps;
     for ( const auto& child : data ) {
       // try to get text dynamically from children
-      // skip TextContent elements
+      // skip PhonContent elements
 #ifdef DEBUG_PHON
       if ( !child->speakable() ) {
 	cerr << "deepphon: node[" << child->xmltag() << "] NOT SPEAKABLE! " << endl;
@@ -1213,7 +1418,11 @@ namespace folia {
     cerr << "deepphon() for " << xmltag() << " step 3 " << endl;
 #endif
     if ( result.isEmpty() ) {
-      result = phoncontent(cls)->phon();
+      try {
+	result = phoncontent(cls)->phon();
+      }
+      catch ( ... ) {
+      }
     }
 #ifdef DEBUG_TEXT
     cerr << "deepphontext() for " << xmltag() << " result= '" << result << "'" << endl;
@@ -1243,7 +1452,7 @@ namespace folia {
       throw runtime_error( "Unable to replace. Multiple candidates found, unable to choose." );
     }
     else {
-      remove( replace[0], true );
+      this->remove( replace[0], true );
       append( child );
     }
   }
@@ -1263,21 +1472,48 @@ namespace folia {
     return 0;
   }
 
+  void FoliaElement::cleartextcontent( const string& textclass ){
+    for ( size_t i=0; i < size(); ++i ){
+      FoliaElement *p = index(i);
+      if ( p->element_id() == TextContent_t ) {
+	if ( p->cls() == textclass ){
+	  remove(p,true);
+	  break;
+	}
+      }
+    }
+  }
+
   TextContent *FoliaElement::settext( const string& txt,
-				      const string& cls ) {
+				      const string& cls ){
     // create a TextContent child of class 'cls'
     // Default cls="current"
+    if ( doc() && doc()->checktext()
+	 && !isSubClass( Morpheme_t ) && !isSubClass( Phoneme_t) ){
+      UnicodeString deeper_u;
+      try {
+	deeper_u = text( cls, false, false );
+	// get deep original text: no retain tokenization, no strict
+      }
+      catch (...){
+      }
+      deeper_u = normalize( deeper_u );
+      UnicodeString txt_u = UTF8ToUnicode( txt );
+      txt_u = normalize( txt_u );
+      if ( !deeper_u.isEmpty() && txt_u != deeper_u ){
+	throw InconsistentText( "settext(cls=" + cls + "): deeper text differs from attempted\ndeeper='" + UnicodeToUTF8(deeper_u) + "'\nattempted='" + txt + "'" );
+      }
+    }
     KWargs args;
     args["value"] = txt;
     args["class"] = cls;
-    TextContent *node = new TextContent( doc() );
-    node->setAttributes( args );
+    TextContent *node = new TextContent( args, doc() );
     replace( node );
     return node;
   }
 
   TextContent *FoliaElement::setutext( const UnicodeString& txt,
-				       const string& cls ) {
+				       const string& cls ){
     // create a TextContent child of class 'cls'
     // Default cls="current"
     string utf8 = UnicodeToUTF8(txt);
@@ -1286,23 +1522,38 @@ namespace folia {
 
   TextContent *FoliaElement::settext( const string& txt,
 				      int offset,
-				      const string& cls ) {
+				      const string& cls ){
     // create a TextContent child of class 'cls'
     // Default cls="current"
     // sets the offset attribute.
+    if ( doc() && doc()->checktext()
+	 && !isSubClass( Morpheme_t ) && !isSubClass( Phoneme_t) ){
+      UnicodeString deeper_u;
+      try {
+	deeper_u = text( cls, false, false );
+	// get deep original text: no retain tokenization, no strict
+      }
+      catch (...){
+      }
+      deeper_u = normalize( deeper_u );
+      UnicodeString txt_u = UTF8ToUnicode( txt );
+      txt_u = normalize( txt_u );
+      if ( !deeper_u.isEmpty() && txt_u != deeper_u ){
+	throw InconsistentText( "settext(cls=" + cls + "): deeper text differs from attempted\ndeeper='" + UnicodeToUTF8(deeper_u) + "'\nattempted='" + txt + "'" );
+      }
+    }
     KWargs args;
     args["value"] = txt;
     args["class"] = cls;
     args["offset"] = TiCC::toString(offset);
-    TextContent *node = new TextContent( doc() );
-    node->setAttributes( args );
+    TextContent *node = new TextContent( args, doc() );
     replace( node );
     return node;
   }
 
   TextContent *FoliaElement::setutext( const UnicodeString& txt,
 				       int offset,
-				       const string& cls ) {
+				       const string& cls ){
     // create a TextContent child of class 'cls'
     // Default cls="current"
     string utf8 = UnicodeToUTF8(txt);
@@ -1339,7 +1590,7 @@ namespace folia {
       vector<FoliaElement*> v = select( c->element_id(), false );
       size_t count = v.size();
       if ( count >= c->occurrences() ) {
-	throw DuplicateAnnotationError( "Unable to add another object of type " + c->classname() + " to " + classname() + ". There are already " + TiCC::toString(count) + " instances of this class, which is the maximum." );
+	throw DuplicateAnnotationError( "Unable to add another object of type " + c->classname() + " to " + classname() + ". There are already " + TiCC::toString(count) + " instances of this type, which is the maximum." );
       }
     }
     if ( c->occurrences_per_set() > 0 &&
@@ -1347,7 +1598,7 @@ namespace folia {
       vector<FoliaElement*> v = select( c->element_id(), c->sett(), false );
       size_t count = v.size();
       if ( count >= c->occurrences_per_set() ) {
-	throw DuplicateAnnotationError( "Unable to add another object of type " + c->classname() + " to " + classname() + ". There are already " + TiCC::toString(count) + " instances of this class, which is the maximum." );
+	throw DuplicateAnnotationError( "Unable to add another object of type " + c->classname() + " to " + classname() + ". There are already " + TiCC::toString(count) + " instances of this type and set, which is the maximum." );
       }
     }
     if ( c->parent() &&
@@ -1367,10 +1618,10 @@ namespace folia {
       }
     }
     if ( c->element_id() == TextContent_t ){
+      string cls = c->cls();
       string st = c->sett();
       vector<TextContent*> tmp = select<TextContent>( st, false );
       if ( !tmp.empty() ) {
-	string cls = c->cls();
 	for( const auto& t : tmp ){
 	  if ( t->cls() == cls ){
 	    throw DuplicateAnnotationError( "attempt to add <t> with class="
@@ -1379,6 +1630,7 @@ namespace folia {
 	  }
 	}
       }
+      check_append_text_consistency( c );
     }
     return true;
   }
@@ -1453,6 +1705,10 @@ namespace folia {
 	 && ( SRC & required_attributes() ) ) {
       throw ValueError( "attribute 'src' is required for " + classname() );
     }
+    if ( _metadata.empty()
+	 && ( METADATA & required_attributes() ) ) {
+      throw ValueError( "attribute 'metadata' is required for " + classname() );
+    }
     if ( _speaker.empty()
 	 && ( SPEAKER & required_attributes() ) ) {
       throw ValueError( "attribute 'speaker' is required for " + classname() );
@@ -1467,7 +1723,7 @@ namespace folia {
     bool ok = false;
     try {
       ok = child->checkAtts();
-      ok = addable( child );
+      ok &= addable( child );
     }
     catch ( XmlError& ) {
       // don't delete the offending child in case of illegal reconnection
@@ -1495,6 +1751,32 @@ namespace folia {
     return 0;
   }
 
+  FoliaElement *FoliaImpl::postappend( ) {
+    if ( id().empty() && (ID & required_attributes()) && auto_generate_id() ){
+      _id = generateId( xmltag() );
+    }
+    return this;
+  }
+
+  FoliaElement *TextContent::postappend( ) {
+    if ( mydoc ){
+      if ( mydoc->checktext()
+	   && _offset != -1
+	   && ( _parent && parent()->auth() ) ){
+	mydoc->cache_textcontent(this);
+      }
+    }
+    return this;
+  }
+
+  FoliaElement *PhonContent::postappend( ) {
+    if ( mydoc ){
+      if ( mydoc->checktext() && _offset != -1 ){
+	mydoc->cache_phoncontent(this);
+      }
+    }
+    return this;
+  }
 
   void FoliaImpl::remove( FoliaElement *child, bool del ) {
     auto it = std::remove( data.begin(), data.end(), child );
@@ -1585,7 +1867,7 @@ namespace folia {
       if ( !ns.empty() && ns != NSFOLIA ){
 	// skip alien nodes
 	if ( doc() && doc()->debug > 2 ) {
-	  cerr << "skiping non-FoLiA node: " << pref << ":" << Name(p) << endl;
+	  cerr << "skipping non-FoLiA node: " << pref << ":" << Name(p) << endl;
 	}
 	p = p->next;
 	continue;
@@ -1605,7 +1887,7 @@ namespace folia {
 	    append( t );
 	  }
 	}
-	else if ( mydoc || !mydoc->permissive() ){
+	else if ( mydoc && !mydoc->permissive() ){
 	  throw XmlError( "FoLiA parser terminated" );
 	}
       }
@@ -1625,20 +1907,35 @@ namespace folia {
 	  }
 	}
       }
-      else if ( p->type == XML_TEXT_NODE ) {
-	string tag = "_XmlText";
-	FoliaElement *t = createElement( tag, doc() );
-	if ( t ) {
-	  if ( doc() && doc()->debug > 2 ) {
-	    cerr << "created " << t << endl;
+      else if ( p->type == XML_TEXT_NODE ){
+	if ( this->isSubClass( TextContent_t )
+	     || this->isSubClass( PhonContent_t )
+	     || this->isSubClass( AbstractTextMarkup_t ) ){
+	  XmlText *t = new XmlText();
+	  if ( p->content ) {
+	    t->setvalue( (const char*)p->content );
 	  }
-	  try {
-	    t = t->parseXml( p );
+	  if ( doc() && doc()->debug > 2 ) {
+	    cerr << "created " << t << "(" << t->text() << ")" << endl;
+	    cerr << "extend " << this << " met " << t << endl;
 	  }
-	  catch ( ValueError& ){
-	    // ignore empty content
-	    delete t;
-	    t = 0;
+	  append( t );
+	}
+	else {
+	  //most probably this always 'empty space'
+	  string tag = "_XmlText";
+	  FoliaElement *t = createElement( tag, doc() );
+	  if ( t ) {
+	    if ( doc() && doc()->debug > 2 ) {
+	      cerr << "created " << t << endl;
+	    }
+	    try {
+	      t = t->parseXml( p );
+	    }
+	    catch ( ValueError& e ){
+	      delete t;
+	      t = 0;
+	    }
 	  }
 	  if ( t ) {
 	    if ( doc() && doc()->debug > 2 ) {
@@ -1650,6 +1947,51 @@ namespace folia {
       }
       p = p->next;
     }
+    if ( doc() && ( doc()->checktext() || doc()->fixtext() )
+	 && is_structure( this )
+	 && !isSubClass( Morpheme_t ) && !isSubClass( Phoneme_t) ){
+      vector<TextContent*> tv = select<TextContent>( false );
+      // first see which text classes ar present
+      set<string> cls;
+      for ( const auto& it : tv ){
+	cls.insert( it->cls() );
+      }
+      // check the text for every text class
+      for ( const auto& st : cls ){
+	UnicodeString s1, s2;
+	try {
+	  s1 = text( st, false, true );  // no retain tokenization, strict
+	}
+	catch (...){
+	}
+	if ( !s1.isEmpty() ){
+	  try {
+	    s2 = text( st, false, false ); // no retain tokenization, no strict
+	  }
+	  catch (...){
+	  }
+	  s1 = normalize( s1 );
+	  s2 = normalize( s2 );
+	  if ( !s2.isEmpty() && s1 != s2 ){
+	    if ( doc()->fixtext() ){
+	      //	      cerr << "FIX: " << mess << endl;
+	      KWargs args;
+	      args["value"] = UnicodeToUTF8(s2);
+	      args["class"] = st;
+	      TextContent *node = new TextContent( args, doc() );
+	      this->replace( node );
+	    }
+	    else {
+	      string mess = "node " + xmltag() + "(" + id()
+		+ ") has a mismatch for the text in set:" + st
+		+ "\nthe element text ='" + UnicodeToUTF8(s1)
+		+ "'\n" + "the deeper text ='" + UnicodeToUTF8(s2) + "'";
+	      throw( InconsistentText( mess ) );
+	    }
+	  }
+	}
+      }
+    }
     return this;
   }
 
@@ -1845,7 +2187,7 @@ namespace folia {
     }
     catch( DuplicateIDError& e ) {
       delete res;
-      throw e;
+      throw;
     }
     append( res );
     return res;
@@ -1863,7 +2205,7 @@ namespace folia {
     }
     catch( DuplicateIDError& e ) {
       delete res;
-      throw e;
+      throw;
     }
     append( res );
     return res;
@@ -1975,15 +2317,15 @@ namespace folia {
     if ( !w || !w->isinstance( Word_t ) ) {
       throw runtime_error( "insertword(): new word is not a Word " );
     }
-    KWargs kwargs;
-    kwargs["text"] = "dummy";
-    kwargs["id"] = "dummy";
-    Word *tmp = new Word( kwargs );
-    tmp->setParent( this ); // we create a dummy Word as member of the
-    // Sentence. This makes correctWords() happy
     auto it = data.begin();
     while ( it != data.end() ) {
       if ( *it == p ) {
+	KWargs kwargs;
+	kwargs["text"] = "dummy";
+	kwargs["id"] = "dummy";
+	Word *tmp = new Word( kwargs );
+	tmp->setParent( this ); // we create a dummy Word as member of the
+	// Sentence. This makes correctWords() happy
 	it = data.insert( ++it, tmp );
 	break;
       }
@@ -2062,12 +2404,17 @@ namespace folia {
     if ( it != kwargs.end() ) {
       _offset = stringTo<int>(it->second);
       kwargs.erase(it);
+      // if ( doc() && doc()->checktext() ){
+      // 	cerr << "ANOTHER cache " << this << endl;
+      // 	doc()->cache_textcontent(this);
+      // }
     }
     else
       _offset = -1;
     it = kwargs.find( "ref" );
     if ( it != kwargs.end() ) {
-      throw NotImplementedError( "ref attribute in TextContent" );
+      _ref = it->second;
+      kwargs.erase(it);
     }
     it = kwargs.find( "class" );
     if ( it == kwargs.end() ) {
@@ -2096,14 +2443,66 @@ namespace folia {
     FoliaImpl::setAttributes(kwargs);
   }
 
+  FoliaElement *TextContent::finddefaultreference() const {
+    int depth = 0;
+    FoliaElement *p = parent();
+    while ( p ){
+      if ( p->isSubClass( String_t )
+	   || p->isSubClass( AbstractStructureElement_t )
+	   || p->isSubClass( AbstractTokenAnnotation_t ) ){
+	if ( ++depth == 2 ){
+	  return p;
+	}
+      }
+      p = p->parent();
+    }
+    return 0;
+  }
+
+  FoliaElement *TextContent::getreference() const {
+    FoliaElement *ref = 0;
+    if ( _offset == -1 ){
+      return 0;
+    }
+    else if ( !_ref.empty() ){
+      try{
+	ref = (*mydoc)[_ref];
+      }
+      catch (...){
+      }
+    }
+    else {
+      ref = finddefaultreference();
+    }
+    if ( !ref ){
+      throw UnresolvableTextContent( "Default reference for textcontent not found!" );
+    }
+    else if ( !ref->hastext( _class ) ){
+      throw UnresolvableTextContent( "Reference (ID " + _ref + ") has no such text (class=" + _class + ")" );
+    }
+    else if ( mydoc->checktext() ){
+      UnicodeString mt = this->text( this->cls(), false, true );
+      UnicodeString pt = ref->text( this->cls(), false, true );
+      UnicodeString sub( pt, this->offset(), mt.length() );
+      if ( mt != sub ){
+	throw UnresolvableTextContent( "Reference (ID " + ref->id() + ",class='"
+				       + cls() + "') found, but no text match at "
+				       + "offset=" + TiCC::toString(offset())
+				       + " Expected " + UnicodeToUTF8(mt)
+				       + " but got " +  UnicodeToUTF8(sub) );
+      }
+    }
+    return ref;
+  }
+
   KWargs TextContent::collectAttributes() const {
     KWargs attribs = FoliaImpl::collectAttributes();
     if ( _class == "current" ) {
       attribs.erase( "class" );
     }
-    else if ( _class == "original" && parent() && parent()->isinstance( Original_t ) ) {
-      attribs.erase( "class" );
-    }
+    // else if ( _class == "original" && parent() && parent()->isinstance( Original_t ) ) {
+    //   attribs.erase( "class" );
+    // }
 
     if ( _offset >= 0 ) {
       attribs["offset"] = TiCC::toString( _offset );
@@ -2111,6 +2510,57 @@ namespace folia {
     return attribs;
   }
 
+  FoliaElement *PhonContent::finddefaultreference() const {
+    int depth = 0;
+    FoliaElement *p = parent();
+    while ( p ){
+      if ( p->isSubClass( AbstractStructureElement_t )
+	   || p->isSubClass( AbstractTokenAnnotation_t ) ){
+	if ( ++depth == 2 ){
+	  return p;
+	}
+      }
+      p = p->parent();
+    }
+    return 0;
+  }
+
+   FoliaElement *PhonContent::getreference() const {
+    FoliaElement *ref = 0;
+    if ( _offset == -1 ){
+      return 0;
+    }
+    else if ( !_ref.empty() ){
+      try{
+	ref = (*mydoc)[_ref];
+      }
+      catch (...){
+      }
+    }
+    else {
+      ref = finddefaultreference();
+    }
+    if ( !ref ){
+      throw UnresolvableTextContent( "Default reference for phonetic content not found!" );
+    }
+    else if ( !ref->hasphon( _class ) ){
+      throw UnresolvableTextContent( "Reference (ID " + _ref + ") has no such phonetic content (class=" + _class + ")" );
+    }
+    else if ( mydoc->checktext() ){
+      UnicodeString mt = this->phon( this->cls(), false );
+      UnicodeString pt = ref->phon( this->cls(), false );
+      UnicodeString sub( pt, this->offset(), mt.length() );
+      if ( mt != sub ){
+	throw UnresolvableTextContent( "Reference (ID " + ref->id() + ",class="
+				       + cls() + " found, but no text match at "
+				       + "offset=" + TiCC::toString(offset())
+				       + " Expected " + UnicodeToUTF8(mt)
+				       + " but got " +  UnicodeToUTF8(sub) );
+      }
+    }
+    return ref;
+  }
+
   KWargs PhonContent::collectAttributes() const {
     KWargs attribs = FoliaImpl::collectAttributes();
     if ( _class == "current" ) {
@@ -2143,7 +2593,7 @@ namespace folia {
   }
 
   KWargs Linebreak::collectAttributes() const {
-    KWargs atts;
+    KWargs atts = FoliaImpl::collectAttributes();
     if ( ! _linenr.empty() ){
       atts["linenr"] = _linenr;
     }
@@ -2156,15 +2606,6 @@ namespace folia {
     return atts;
   }
 
-  TextContent *TextContent::postappend() {
-    if ( _parent->isinstance( Original_t ) ) {
-      if ( _class == "current" ) {
-	_class = "original";
-      }
-    }
-    return this;
-  }
-
   vector<FoliaElement *>TextContent::findreplacables( FoliaElement *par ) const {
     vector<FoliaElement *> result;
     vector<TextContent*> v = par->FoliaElement::select<TextContent>( _set, false );
@@ -2216,7 +2657,7 @@ namespace folia {
 
   const string AllowGenerateID::generateId( const string& tag ){
     // generate an new ID using my ID
-    // if ni ID, look upward.
+    // if no ID, look upward.
     string nodeId = id();
     // cerr << "node: " << this << endl;
     // cerr << "ID=" << nodeId << endl;
@@ -2225,7 +2666,7 @@ namespace folia {
       if ( !par ){
 	throw XmlError( "unable to generate an ID. No StructureElement parent found?" );
       }
-      // cerr << "call on parent:" << parent << endl;
+      // cerr << "call on parent:" << par << endl;
       return par->generateId( tag );
     }
     else {
@@ -2343,8 +2784,7 @@ namespace folia {
       args2.erase("suggestions" );
       string id = generateId( "correction" );
       args2["id"] = id;
-      corr = new Correction(mydoc );
-      corr->setAttributes( args2 );
+      corr = new Correction( args2, mydoc );
     }
 #ifdef DEBUG_CORRECT
     cerr << "now corr= " << corr << endl;
@@ -2439,7 +2879,7 @@ namespace folia {
 	      cerr << " corr before remove " << corr << endl;
 	      cerr << " remove  " << org << endl;
 #endif
-	      remove( org, false );
+	      this->remove( org, false );
 #ifdef DEBUG_CORRECT
 	      cerr << " corr after remove " << corr << endl;
 #endif
@@ -2512,7 +2952,7 @@ namespace folia {
 		cerr << " corr before remove " << corr << endl;
 		cerr << " remove  " << org << endl;
 #endif
-		remove( org, false );
+		this->remove( org, false );
 #ifdef DEBUG_CORRECT
 		cerr << " corr after remove " << corr << endl;
 #endif
@@ -2533,7 +2973,7 @@ namespace folia {
 #ifdef DEBUG_CORRECT
 	  cerr << " remove cur=" << cur << endl;
 #endif
-	  remove( cur, false );
+	  this->remove( cur, false );
 	}
       }
     }
@@ -3263,7 +3703,7 @@ namespace folia {
   }
 
   void AbstractAnnotationLayer::assignset( FoliaElement *child ) {
-    // If there is no set (yet), try to get the set form the child
+    // If there is no set (yet), try to get the set from the child
     // but not if it is the default set.
     // for a Correction child, we look deeper.
     if ( _set.empty() ) {
@@ -3272,6 +3712,7 @@ namespace folia {
 	if ( !st.empty()
 	     && mydoc->defaultset( child->annotation_type() ) != st ) {
 	  _set = st;
+	  mydoc->incrRef( child->annotation_type(), _set );
 	}
       }
       else if ( child->isinstance(Correction_t) ) {
@@ -3284,6 +3725,7 @@ namespace folia {
 	      if ( !st.empty()
 		   && mydoc->defaultset( el->annotation_type() ) != st ) {
 		_set = st;
+		mydoc->incrRef( el->annotation_type(), _set );
 		return;
 	      }
 	    }
@@ -3298,6 +3740,7 @@ namespace folia {
 	      if ( !st.empty()
 		   && mydoc->defaultset( el->annotation_type() ) != st ) {
 		_set = st;
+		mydoc->incrRef( el->annotation_type(), _set );
 		return;
 	      }
 	    }
@@ -3310,6 +3753,7 @@ namespace folia {
 	    if ( !st.empty()
 		 && mydoc->defaultset( el->annotation_type() ) != st ) {
 	      _set = st;
+	      mydoc->incrRef( el->annotation_type(), _set );
 	      return;
 	    }
 	  }
@@ -3420,27 +3864,26 @@ namespace folia {
 #ifdef DEBUG_TEXT
     cerr << "TEXT(" << cls << ") op node : " << xmltag() << " id ( " << id() << ")" << endl;
 #endif
-    if ( cls == "current" ) {
-      for ( const auto& el : data ) {
+    // we cannot use textcontent() on New, Origibal or Current,
+    // because texcontent doesn't recurse!
+    for ( const auto& el : data ) {
 #ifdef DEBUG_TEXT
-	cerr << "data=" << el << endl;
+      cerr << "data=" << el << endl;
 #endif
-	if ( el->isinstance( New_t ) || el->isinstance( Current_t ) ) {
-	  return el->text( cls, retaintok );
+      if ( el->isinstance( New_t )
+	   ||( el->isinstance( Original_t ) && cls != "current" )
+	   || el->isinstance( Current_t ) ){
+	UnicodeString result;
+	try {
+	  result = el->text( cls, retaintok );
+	  return result;
 	}
-      }
-    }
-    else if ( cls == "original" ) {
-      for ( const auto& el : data ) {
-#ifdef DEBUG_TEXT
-	cerr << "data=" << el << endl;
-#endif
-	if ( el->isinstance( Original_t ) ) {
-	  return el->text( cls, retaintok );
+	catch ( ... ){
+	  // try other nodes
 	}
       }
     }
-    throw NoSuchText("wrong cls");
+    throw NoSuchText( "cls=" + cls );
   }
 
   const string& Correction::getTextDelimiter( bool retaintok ) const {
@@ -3452,37 +3895,48 @@ namespace folia {
     return EMPTY_STRING;
   }
 
-  TextContent *Correction::textcontent( const string& cls ) const {
-    if ( cls == "current" ) {
-      for ( const auto& el : data ) {
-	if ( el->isinstance( New_t ) || el->isinstance( Current_t ) ) {
-	  return el->textcontent( cls );
+  const TextContent *Correction::textcontent( const string& cls ) const {
+    // TODO: this implements correctionhandling::EITHER only
+    for ( const auto& el : data ) {
+      if ( el->isinstance( New_t ) || el->isinstance( Current_t ) ) {
+	const TextContent *res = 0;
+	try {
+	  res = el->textcontent( cls );
+	  return res;
+	}
+	catch (...){
 	}
       }
     }
-    else if ( cls == "original" ) {
-      for ( const auto& el : data ) {
-	if ( el->isinstance( Original_t ) ) {
-	  return el->textcontent( cls );
+    for ( const auto& el : data ) {
+      if ( el->isinstance( Original_t ) ) {
+	const TextContent *res = 0;
+	try {
+	  res =  el->textcontent( cls );
+	  return res;
 	}
+	catch ( ... ){
+	}
+      }
+      else if ( cls == "current" && el->hastext( "original" ) ){
+	cerr << "text(original)= " << el->textcontent( cls )->text()<< endl;
+	// hack for old and erroneous behaviour
+	return el->textcontent( "original" );
       }
     }
     throw NoSuchText("wrong cls");
   }
 
-  PhonContent *Correction::phoncontent( const string& cls ) const {
-    if ( cls == "current" ) {
-      for ( const auto& el: data ) {
-	if ( el->isinstance( New_t ) || el->isinstance( Current_t ) ) {
-	  return el->phoncontent( cls );
-	}
+  const PhonContent *Correction::phoncontent( const string& cls ) const {
+    // TODO: this implements correctionhandling::EITHER only
+    for ( const auto& el: data ) {
+      if ( el->isinstance( New_t ) || el->isinstance( Current_t ) ) {
+	return el->phoncontent( cls );
       }
     }
-    else if ( cls == "original" ) {
-      for ( const auto& el: data ) {
-	if ( el->isinstance( Original_t ) ) {
-	  return el->phoncontent( cls );
-	}
+    for ( const auto& el: data ) {
+      if ( el->isinstance( Original_t ) ) {
+	return el->phoncontent( cls );
       }
     }
     throw NoSuchPhon("wrong cls");
@@ -3653,6 +4107,11 @@ namespace folia {
     return 0;
   }
 
+  bool XmlText::setvalue( const std::string& s ){
+    _value = s;
+    return true;
+  }
+
   const UnicodeString XmlText::text( const string&, bool, bool ) const {
     return UTF8ToUnicode(_value);
   }
@@ -3662,12 +4121,11 @@ namespace folia {
   }
 
   FoliaElement* XmlText::parseXml( const xmlNode *node ) {
-    string tmp;
     if ( node->content ) {
       _value = (const char*)node->content;
-      tmp = trim( _value );
+      _value = trim( _value );
     }
-    if ( tmp.empty() ) {
+    if ( _value.empty() ) {
       throw ValueError( "TextContent may not be empty" );
     }
     return this;
@@ -3888,6 +4346,18 @@ namespace folia {
     return "";
   }
 
+  ForeignMetaData::~ForeignMetaData(){
+    for ( const auto& it : foreigners ){
+      delete it;
+    }
+  }
+
+  void ForeignMetaData::add_foreign( const xmlNode *node ){
+    ForeignData *fd = new ForeignData();
+    fd->set_data( node );
+    foreigners.push_back( fd );
+  }
+
   ForeignData::~ForeignData(){
     xmlFreeNode( _foreign_data );
   }
@@ -3939,6 +4409,38 @@ namespace folia {
     return result;
   }
 
+  const MetaData* FoliaImpl::getmetadata() const {
+    // Get the metadata that applies to this element,
+    // automatically inherited from parent elements
+    if ( !_metadata.empty() && doc() ){
+      return doc()->get_submetadata(_metadata);
+    }
+    else if ( parent() ){
+      return parent()->getmetadata();
+    }
+    else {
+      return 0;
+    }
+  }
+
+  const string FoliaImpl::getmetadata( const std::string& key ) const {
+    // Get the metadata that applies to this element,
+    // automatically inherited from parent elements
+    if ( !_metadata.empty() && doc() ){
+      const MetaData *what = doc()->get_submetadata(_metadata);
+      if ( what && what->datatype() == "NativeMetaData" && !key.empty() ){
+	return what->get_val( key );
+      }
+      return "";
+    }
+    else if ( parent() ){
+      return parent()->getmetadata( key );
+    }
+    else {
+      return "";
+    }
+  }
+
   KWargs AbstractTextMarkup::collectAttributes() const {
     KWargs attribs = FoliaImpl::collectAttributes();
     if ( !idref.empty() ) {
diff --git a/src/folia_properties.cxx b/src/folia_properties.cxx
index 3d9d64e..04b7f21 100644
--- a/src/folia_properties.cxx
+++ b/src/folia_properties.cxx
@@ -6,7 +6,7 @@
 #include "libfolia/folia_properties.h"
 
 //foliaspec:header
-//This file was last updated according to the FoLiA specification for version 1.4.0 on 2017-01-05 13:17:58, using foliaspec.py
+//This file was last updated according to the FoLiA specification for version 1.5.0 on 2017-09-29 20:10:33, using foliaspec.py
 //Code blocks after a foliaspec comment (until the next newline) are automatically generated. **DO NOT EDIT THOSE** and **DO NOT REMOVE ANY FOLIASPEC COMMENTS** !!!
 
 namespace folia {
@@ -19,7 +19,7 @@ namespace folia {
 
   //foliaspec:version_minor:MINOR_VERSION
   //The FoLiA version (minor)
-  const int MINOR_VERSION = 4;
+  const int MINOR_VERSION = 5;
 
   //foliaspec:version_sub:SUB_VERSION
   //The FoLiA version (sub/rev)
@@ -556,7 +556,7 @@ namespace folia {
 //------ AbstractAnnotationLayer -------
     AbstractAnnotationLayer::PROPS.ELEMENT_ID = AbstractAnnotationLayer_t;
     AbstractAnnotationLayer::PROPS.ACCEPTED_DATA += {Comment_t, Correction_t, Description_t, ForeignData_t};
-    AbstractAnnotationLayer::PROPS.OPTIONAL_ATTRIBS = ID|ANNOTATOR|CONFIDENCE|DATETIME|N;
+    AbstractAnnotationLayer::PROPS.OPTIONAL_ATTRIBS = ID|ANNOTATOR|CONFIDENCE|DATETIME|N|TEXTCLASS|METADATA;
     AbstractAnnotationLayer::PROPS.PRINTABLE = false;
     AbstractAnnotationLayer::PROPS.SETONLY = true;
     AbstractAnnotationLayer::PROPS.SPEAKABLE = false;
@@ -570,7 +570,7 @@ namespace folia {
 //------ AbstractSpanAnnotation -------
     AbstractSpanAnnotation::PROPS.ELEMENT_ID = AbstractSpanAnnotation_t;
     AbstractSpanAnnotation::PROPS.ACCEPTED_DATA += {AlignReference_t, Alignment_t, Comment_t, Description_t, ForeignData_t, Metric_t};
-    AbstractSpanAnnotation::PROPS.OPTIONAL_ATTRIBS = ID|CLASS|ANNOTATOR|N|CONFIDENCE|DATETIME|SRC|BEGINTIME|ENDTIME|SPEAKER;
+    AbstractSpanAnnotation::PROPS.OPTIONAL_ATTRIBS = ID|CLASS|ANNOTATOR|N|CONFIDENCE|DATETIME|SRC|BEGINTIME|ENDTIME|SPEAKER|TEXTCLASS|METADATA;
     AbstractSpanAnnotation::PROPS.PRINTABLE = true;
     AbstractSpanAnnotation::PROPS.SPEAKABLE = true;
 //------ AbstractSpanRole -------
@@ -582,15 +582,15 @@ namespace folia {
     AbstractStructureElement::PROPS.ELEMENT_ID = AbstractStructureElement_t;
     AbstractStructureElement::PROPS.ACCEPTED_DATA += {AbstractAnnotationLayer_t, Alignment_t, Alternative_t, AlternativeLayers_t, Comment_t, Correction_t, Description_t, Feature_t, ForeignData_t, Metric_t, Part_t};
     AbstractStructureElement::PROPS.AUTO_GENERATE_ID = true;
-    AbstractStructureElement::PROPS.OPTIONAL_ATTRIBS = ID|CLASS|ANNOTATOR|N|CONFIDENCE|DATETIME|SRC|BEGINTIME|ENDTIME|SPEAKER;
+    AbstractStructureElement::PROPS.OPTIONAL_ATTRIBS = ID|CLASS|ANNOTATOR|N|CONFIDENCE|DATETIME|SRC|BEGINTIME|ENDTIME|SPEAKER|METADATA;
     AbstractStructureElement::PROPS.PRINTABLE = true;
     AbstractStructureElement::PROPS.REQUIRED_ATTRIBS = NO_ATT;
     AbstractStructureElement::PROPS.SPEAKABLE = true;
     AbstractStructureElement::PROPS.TEXTDELIMITER = "\n\n";
 //------ AbstractTextMarkup -------
     AbstractTextMarkup::PROPS.ELEMENT_ID = AbstractTextMarkup_t;
-    AbstractTextMarkup::PROPS.ACCEPTED_DATA += {AbstractTextMarkup_t, Comment_t, Description_t, XmlText_t};
-    AbstractTextMarkup::PROPS.OPTIONAL_ATTRIBS = ID|CLASS|ANNOTATOR|N|CONFIDENCE|DATETIME|SRC|BEGINTIME|ENDTIME|SPEAKER;
+    AbstractTextMarkup::PROPS.ACCEPTED_DATA += {AbstractTextMarkup_t, Comment_t, Description_t, Linebreak_t, XmlText_t};
+    AbstractTextMarkup::PROPS.OPTIONAL_ATTRIBS = ID|CLASS|ANNOTATOR|N|CONFIDENCE|DATETIME|SRC|BEGINTIME|ENDTIME|SPEAKER|METADATA;
     AbstractTextMarkup::PROPS.PRINTABLE = true;
     AbstractTextMarkup::PROPS.TEXTCONTAINER = true;
     AbstractTextMarkup::PROPS.TEXTDELIMITER = "";
@@ -599,7 +599,7 @@ namespace folia {
     AbstractTokenAnnotation::PROPS.ELEMENT_ID = AbstractTokenAnnotation_t;
     AbstractTokenAnnotation::PROPS.ACCEPTED_DATA += {Comment_t, Description_t, Feature_t, ForeignData_t, Metric_t};
     AbstractTokenAnnotation::PROPS.OCCURRENCES_PER_SET = 1;
-    AbstractTokenAnnotation::PROPS.OPTIONAL_ATTRIBS = ID|CLASS|ANNOTATOR|N|CONFIDENCE|DATETIME|SRC|BEGINTIME|ENDTIME|SPEAKER;
+    AbstractTokenAnnotation::PROPS.OPTIONAL_ATTRIBS = ID|CLASS|ANNOTATOR|N|CONFIDENCE|DATETIME|SRC|BEGINTIME|ENDTIME|SPEAKER|TEXTCLASS|METADATA;
     AbstractTokenAnnotation::PROPS.REQUIRED_ATTRIBS = CLASS;
 //------ AbstractExtendedTokenAnnotation -------
     AbstractExtendedTokenAnnotation::PROPS = AbstractTokenAnnotation::PROPS;
@@ -612,7 +612,7 @@ namespace folia {
     Alignment::PROPS.ACCEPTED_DATA += {AlignReference_t, Comment_t, Description_t, Feature_t, ForeignData_t, Metric_t};
     Alignment::PROPS.ANNOTATIONTYPE = AnnotationType::ALIGNMENT;
     Alignment::PROPS.LABEL = "Alignment";
-    Alignment::PROPS.OPTIONAL_ATTRIBS = ID|CLASS|ANNOTATOR|N|CONFIDENCE|DATETIME|SRC|BEGINTIME|ENDTIME|SPEAKER;
+    Alignment::PROPS.OPTIONAL_ATTRIBS = ID|CLASS|ANNOTATOR|N|CONFIDENCE|DATETIME|SRC|BEGINTIME|ENDTIME|SPEAKER|METADATA;
     Alignment::PROPS.PRINTABLE = false;
     Alignment::PROPS.REQUIRED_ATTRIBS = NO_ATT;
     Alignment::PROPS.SPEAKABLE = false;
@@ -623,7 +623,7 @@ namespace folia {
     Alternative::PROPS.ACCEPTED_DATA += {AbstractTokenAnnotation_t, Comment_t, Correction_t, Description_t, ForeignData_t, MorphologyLayer_t, PhonologyLayer_t};
     Alternative::PROPS.AUTH = false;
     Alternative::PROPS.LABEL = "Alternative";
-    Alternative::PROPS.OPTIONAL_ATTRIBS = ID|CLASS|ANNOTATOR|N|CONFIDENCE|DATETIME|SRC|BEGINTIME|ENDTIME|SPEAKER;
+    Alternative::PROPS.OPTIONAL_ATTRIBS = ID|CLASS|ANNOTATOR|N|CONFIDENCE|DATETIME|SRC|BEGINTIME|ENDTIME|SPEAKER|METADATA;
     Alternative::PROPS.PRINTABLE = false;
     Alternative::PROPS.REQUIRED_ATTRIBS = NO_ATT;
     Alternative::PROPS.SPEAKABLE = false;
@@ -633,7 +633,7 @@ namespace folia {
     AlternativeLayers::PROPS.ACCEPTED_DATA += {AbstractAnnotationLayer_t, Comment_t, Description_t, ForeignData_t};
     AlternativeLayers::PROPS.AUTH = false;
     AlternativeLayers::PROPS.LABEL = "Alternative Layers";
-    AlternativeLayers::PROPS.OPTIONAL_ATTRIBS = ID|CLASS|ANNOTATOR|N|CONFIDENCE|DATETIME|SRC|BEGINTIME|ENDTIME|SPEAKER;
+    AlternativeLayers::PROPS.OPTIONAL_ATTRIBS = ID|CLASS|ANNOTATOR|N|CONFIDENCE|DATETIME|SRC|BEGINTIME|ENDTIME|SPEAKER|METADATA;
     AlternativeLayers::PROPS.PRINTABLE = false;
     AlternativeLayers::PROPS.REQUIRED_ATTRIBS = NO_ATT;
     AlternativeLayers::PROPS.SPEAKABLE = false;
@@ -668,14 +668,14 @@ namespace folia {
 //------ Comment -------
     Comment::PROPS.ELEMENT_ID = Comment_t;
     Comment::PROPS.LABEL = "Comment";
-    Comment::PROPS.OPTIONAL_ATTRIBS = ID|ANNOTATOR|CONFIDENCE|DATETIME|N;
+    Comment::PROPS.OPTIONAL_ATTRIBS = ID|ANNOTATOR|CONFIDENCE|DATETIME|N|METADATA;
     Comment::PROPS.XMLTAG = "comment";
 //------ ComplexAlignment -------
     ComplexAlignment::PROPS.ELEMENT_ID = ComplexAlignment_t;
     ComplexAlignment::PROPS.ACCEPTED_DATA += {Alignment_t, Comment_t, Description_t, Feature_t, ForeignData_t, Metric_t};
     ComplexAlignment::PROPS.ANNOTATIONTYPE = AnnotationType::COMPLEXALIGNMENT;
     ComplexAlignment::PROPS.LABEL = "Complex Alignment";
-    ComplexAlignment::PROPS.OPTIONAL_ATTRIBS = ID|CLASS|ANNOTATOR|N|CONFIDENCE|DATETIME|SRC|BEGINTIME|ENDTIME|SPEAKER;
+    ComplexAlignment::PROPS.OPTIONAL_ATTRIBS = ID|CLASS|ANNOTATOR|N|CONFIDENCE|DATETIME|SRC|BEGINTIME|ENDTIME|SPEAKER|METADATA;
     ComplexAlignment::PROPS.PRINTABLE = false;
     ComplexAlignment::PROPS.REQUIRED_ATTRIBS = NO_ATT;
     ComplexAlignment::PROPS.SPEAKABLE = false;
@@ -717,7 +717,7 @@ namespace folia {
     Correction::PROPS.ACCEPTED_DATA += {Comment_t, Current_t, Description_t, ErrorDetection_t, Feature_t, ForeignData_t, Metric_t, New_t, Original_t, Suggestion_t};
     Correction::PROPS.ANNOTATIONTYPE = AnnotationType::CORRECTION;
     Correction::PROPS.LABEL = "Correction";
-    Correction::PROPS.OPTIONAL_ATTRIBS = ID|CLASS|ANNOTATOR|N|CONFIDENCE|DATETIME|SRC|BEGINTIME|ENDTIME|SPEAKER;
+    Correction::PROPS.OPTIONAL_ATTRIBS = ID|CLASS|ANNOTATOR|N|CONFIDENCE|DATETIME|SRC|BEGINTIME|ENDTIME|SPEAKER|METADATA;
     Correction::PROPS.PRINTABLE = true;
     Correction::PROPS.SPEAKABLE = true;
     Correction::PROPS.TEXTDELIMITER = "NONE";
@@ -731,7 +731,7 @@ namespace folia {
 //------ Definition -------
     Definition::PROPS = AbstractStructureElement::PROPS;
     Definition::PROPS.ELEMENT_ID = Definition_t;
-    Definition::PROPS.ACCEPTED_DATA += {AbstractAnnotationLayer_t, AbstractExtendedTokenAnnotation_t, Alignment_t, Alternative_t, AlternativeLayers_t, Comment_t, Correction_t, Description_t, Feature_t, Figure_t, ForeignData_t, List_t, Metric_t, Paragraph_t, Part_t, PhonContent_t, Reference_t, Sentence_t, String_t, Table_t, TextContent_t, Utterance_t, Word_t};
+    Definition::PROPS.ACCEPTED_DATA += {AbstractAnnotationLayer_t, AbstractExtendedTokenAnnotation_t, Alignment_t, Alternative_t, AlternativeLayers_t, Comment_t, Correction_t, Description_t, Feature_t, Figure_t, ForeignData_t, Linebreak_t, List_t, Metric_t, Paragraph_t, Part_t, PhonContent_t, Reference_t, Sentence_t, String_t, Table_t, TextContent_t, Utterance_t, Whitespace_t, Word_t};
     Definition::PROPS.ANNOTATIONTYPE = AnnotationType::DEFINITION;
     Definition::PROPS.LABEL = "Definition";
     Definition::PROPS.XMLTAG = "def";
@@ -759,7 +759,7 @@ namespace folia {
     Description::PROPS.ELEMENT_ID = Description_t;
     Description::PROPS.LABEL = "Description";
     Description::PROPS.OCCURRENCES = 1;
-    Description::PROPS.OPTIONAL_ATTRIBS = ID|ANNOTATOR|CONFIDENCE|DATETIME|N;
+    Description::PROPS.OPTIONAL_ATTRIBS = ID|ANNOTATOR|CONFIDENCE|DATETIME|N|METADATA;
     Description::PROPS.XMLTAG = "desc";
 //------ Division -------
     Division::PROPS = AbstractStructureElement::PROPS;
@@ -806,7 +806,7 @@ namespace folia {
 //------ Event -------
     Event::PROPS = AbstractStructureElement::PROPS;
     Event::PROPS.ELEMENT_ID = Event_t;
-    Event::PROPS.ACCEPTED_DATA += {AbstractAnnotationLayer_t, AbstractExtendedTokenAnnotation_t, ActorFeature_t, Alignment_t, Alternative_t, AlternativeLayers_t, BegindatetimeFeature_t, Comment_t, Correction_t, Description_t, Division_t, EnddatetimeFeature_t, Event_t, Example_t, Feature_t, Figure_t, ForeignData_t, Head_t, Linebreak_t, List_t, Metric_t, Paragraph_t, Part_t, PhonContent_t, Reference_t, Sentence_t, String_t, Table_t, TextContent_t, Utterance_t, Whitespace_t, Word_t};
+    Event::PROPS.ACCEPTED_DATA += {AbstractAnnotationLayer_t, AbstractExtendedTokenAnnotation_t, ActorFeature_t, Alignment_t, Alternative_t, AlternativeLayers_t, BegindatetimeFeature_t, Comment_t, Correction_t, Description_t, Division_t, EnddatetimeFeature_t, Entry_t, Event_t, Example_t, Feature_t, Figure_t, ForeignData_t, Gap_t, Head_t, Linebreak_t, List_t, Metric_t, Note_t, Paragraph_t, Part_t, PhonContent_t, Quote_t, Reference_t, Sentence_t, String_t, Table_t, TextContent_t, Utterance [...]
     Event::PROPS.ANNOTATIONTYPE = AnnotationType::EVENT;
     Event::PROPS.LABEL = "Event";
     Event::PROPS.XMLTAG = "event";
@@ -868,7 +868,7 @@ namespace folia {
     Gap::PROPS.ACCEPTED_DATA += {Comment_t, Content_t, Description_t, Feature_t, ForeignData_t, Metric_t, Part_t};
     Gap::PROPS.ANNOTATIONTYPE = AnnotationType::GAP;
     Gap::PROPS.LABEL = "Gap";
-    Gap::PROPS.OPTIONAL_ATTRIBS = ID|CLASS|ANNOTATOR|N|DATETIME|SRC|BEGINTIME|ENDTIME;
+    Gap::PROPS.OPTIONAL_ATTRIBS = ID|CLASS|ANNOTATOR|N|DATETIME|SRC|BEGINTIME|ENDTIME|METADATA;
     Gap::PROPS.XMLTAG = "gap";
 //------ Head -------
     Head::PROPS = AbstractStructureElement::PROPS;
@@ -892,7 +892,7 @@ namespace folia {
 //------ Label -------
     Label::PROPS = AbstractStructureElement::PROPS;
     Label::PROPS.ELEMENT_ID = Label_t;
-    Label::PROPS.ACCEPTED_DATA += {AbstractAnnotationLayer_t, AbstractExtendedTokenAnnotation_t, Alignment_t, Alternative_t, AlternativeLayers_t, Comment_t, Correction_t, Description_t, Feature_t, ForeignData_t, Metric_t, Part_t, PhonContent_t, Reference_t, String_t, TextContent_t, Word_t};
+    Label::PROPS.ACCEPTED_DATA += {AbstractAnnotationLayer_t, AbstractExtendedTokenAnnotation_t, Alignment_t, Alternative_t, AlternativeLayers_t, Comment_t, Correction_t, Description_t, Feature_t, ForeignData_t, Linebreak_t, Metric_t, Part_t, PhonContent_t, Reference_t, String_t, TextContent_t, Whitespace_t, Word_t};
     Label::PROPS.LABEL = "Label";
     Label::PROPS.XMLTAG = "label";
 //------ LangAnnotation -------
@@ -918,6 +918,7 @@ namespace folia {
     Linebreak::PROPS.ANNOTATIONTYPE = AnnotationType::LINEBREAK;
     Linebreak::PROPS.LABEL = "Linebreak";
     Linebreak::PROPS.TEXTDELIMITER = "";
+    Linebreak::PROPS.XLINK = true;
     Linebreak::PROPS.XMLTAG = "br";
 //------ List -------
     List::PROPS = AbstractStructureElement::PROPS;
@@ -930,7 +931,7 @@ namespace folia {
 //------ ListItem -------
     ListItem::PROPS = AbstractStructureElement::PROPS;
     ListItem::PROPS.ELEMENT_ID = ListItem_t;
-    ListItem::PROPS.ACCEPTED_DATA += {AbstractAnnotationLayer_t, AbstractExtendedTokenAnnotation_t, Alignment_t, Alternative_t, AlternativeLayers_t, Comment_t, Correction_t, Description_t, Event_t, Feature_t, ForeignData_t, Gap_t, Label_t, Linebreak_t, List_t, Metric_t, Note_t, Part_t, PhonContent_t, Reference_t, Sentence_t, String_t, TextContent_t, Whitespace_t};
+    ListItem::PROPS.ACCEPTED_DATA += {AbstractAnnotationLayer_t, AbstractExtendedTokenAnnotation_t, Alignment_t, Alternative_t, AlternativeLayers_t, Comment_t, Correction_t, Description_t, Event_t, Feature_t, ForeignData_t, Gap_t, Label_t, Linebreak_t, List_t, Metric_t, Note_t, Paragraph_t, Part_t, PhonContent_t, Reference_t, Sentence_t, String_t, TextContent_t, Whitespace_t, Word_t};
     ListItem::PROPS.LABEL = "List Item";
     ListItem::PROPS.TEXTDELIMITER = "\n";
     ListItem::PROPS.XMLTAG = "item";
@@ -939,7 +940,7 @@ namespace folia {
     Metric::PROPS.ACCEPTED_DATA += {Comment_t, Description_t, Feature_t, ForeignData_t, ValueFeature_t};
     Metric::PROPS.ANNOTATIONTYPE = AnnotationType::METRIC;
     Metric::PROPS.LABEL = "Metric";
-    Metric::PROPS.OPTIONAL_ATTRIBS = ID|CLASS|ANNOTATOR|N|CONFIDENCE|DATETIME|SRC|BEGINTIME|ENDTIME|SPEAKER;
+    Metric::PROPS.OPTIONAL_ATTRIBS = ID|CLASS|ANNOTATOR|N|CONFIDENCE|DATETIME|SRC|BEGINTIME|ENDTIME|SPEAKER|METADATA;
     Metric::PROPS.XMLTAG = "metric";
 //------ ModalityFeature -------
     ModalityFeature::PROPS = Feature::PROPS;
@@ -1004,7 +1005,7 @@ namespace folia {
 //------ Part -------
     Part::PROPS = AbstractStructureElement::PROPS;
     Part::PROPS.ELEMENT_ID = Part_t;
-    Part::PROPS.ACCEPTED_DATA += {AbstractAnnotationLayer_t, AbstractExtendedTokenAnnotation_t, AbstractStructureElement_t, Alignment_t, Alternative_t, AlternativeLayers_t, Comment_t, Correction_t, Description_t, Feature_t, ForeignData_t, Metric_t, Part_t};
+    Part::PROPS.ACCEPTED_DATA += {AbstractAnnotationLayer_t, AbstractExtendedTokenAnnotation_t, AbstractStructureElement_t, Alignment_t, Alternative_t, AlternativeLayers_t, Comment_t, Correction_t, Description_t, Feature_t, ForeignData_t, Metric_t, Part_t, PhonContent_t, TextContent_t};
     Part::PROPS.ANNOTATIONTYPE = AnnotationType::PART;
     Part::PROPS.LABEL = "Part";
     Part::PROPS.TEXTDELIMITER = "NONE";
@@ -1015,7 +1016,7 @@ namespace folia {
     PhonContent::PROPS.ANNOTATIONTYPE = AnnotationType::PHON;
     PhonContent::PROPS.LABEL = "Phonetic Content";
     PhonContent::PROPS.OCCURRENCES = 0;
-    PhonContent::PROPS.OPTIONAL_ATTRIBS = CLASS|ANNOTATOR|CONFIDENCE|DATETIME;
+    PhonContent::PROPS.OPTIONAL_ATTRIBS = CLASS|ANNOTATOR|CONFIDENCE|DATETIME|METADATA;
     PhonContent::PROPS.PHONCONTAINER = true;
     PhonContent::PROPS.PRINTABLE = false;
     PhonContent::PROPS.SPEAKABLE = true;
@@ -1056,13 +1057,13 @@ namespace folia {
 //------ Quote -------
     Quote::PROPS = AbstractStructureElement::PROPS;
     Quote::PROPS.ELEMENT_ID = Quote_t;
-    Quote::PROPS.ACCEPTED_DATA += {AbstractAnnotationLayer_t, Alignment_t, Alternative_t, AlternativeLayers_t, Comment_t, Correction_t, Description_t, Division_t, Feature_t, ForeignData_t, Gap_t, Metric_t, Paragraph_t, Part_t, Quote_t, Sentence_t, String_t, TextContent_t, Utterance_t, Word_t};
+    Quote::PROPS.ACCEPTED_DATA += {AbstractAnnotationLayer_t, Alignment_t, Alternative_t, AlternativeLayers_t, Comment_t, Correction_t, Description_t, Division_t, Feature_t, ForeignData_t, Gap_t, Metric_t, Paragraph_t, Part_t, Quote_t, Reference_t, Sentence_t, String_t, TextContent_t, Utterance_t, Word_t};
     Quote::PROPS.LABEL = "Quote";
     Quote::PROPS.XMLTAG = "quote";
 //------ Reference -------
     Reference::PROPS = AbstractStructureElement::PROPS;
     Reference::PROPS.ELEMENT_ID = Reference_t;
-    Reference::PROPS.ACCEPTED_DATA += {AbstractAnnotationLayer_t, Alignment_t, Alternative_t, AlternativeLayers_t, Comment_t, Correction_t, Description_t, Feature_t, ForeignData_t, Metric_t, Paragraph_t, Part_t, PhonContent_t, Quote_t, Sentence_t, String_t, TextContent_t, Utterance_t, Word_t};
+    Reference::PROPS.ACCEPTED_DATA += {AbstractAnnotationLayer_t, Alignment_t, Alternative_t, AlternativeLayers_t, Comment_t, Correction_t, Description_t, Feature_t, ForeignData_t, Linebreak_t, Metric_t, Paragraph_t, Part_t, PhonContent_t, Quote_t, Sentence_t, String_t, TextContent_t, Utterance_t, Whitespace_t, Word_t};
     Reference::PROPS.LABEL = "Reference";
     Reference::PROPS.TEXTDELIMITER = "NONE";
     Reference::PROPS.XMLTAG = "ref";
@@ -1159,7 +1160,7 @@ namespace folia {
     String::PROPS.ANNOTATIONTYPE = AnnotationType::STRING;
     String::PROPS.LABEL = "String";
     String::PROPS.OCCURRENCES = 0;
-    String::PROPS.OPTIONAL_ATTRIBS = ID|CLASS|ANNOTATOR|CONFIDENCE|DATETIME|N|SRC|BEGINTIME|ENDTIME;
+    String::PROPS.OPTIONAL_ATTRIBS = ID|CLASS|ANNOTATOR|CONFIDENCE|DATETIME|N|SRC|BEGINTIME|ENDTIME|METADATA;
     String::PROPS.PRINTABLE = true;
     String::PROPS.XMLTAG = "str";
 //------ StyleFeature -------
@@ -1219,14 +1220,14 @@ namespace folia {
 //------ Term -------
     Term::PROPS = AbstractStructureElement::PROPS;
     Term::PROPS.ELEMENT_ID = Term_t;
-    Term::PROPS.ACCEPTED_DATA += {AbstractAnnotationLayer_t, AbstractExtendedTokenAnnotation_t, Alignment_t, Alternative_t, AlternativeLayers_t, Comment_t, Correction_t, Description_t, Event_t, Feature_t, Figure_t, ForeignData_t, Gap_t, List_t, Metric_t, Paragraph_t, Part_t, PhonContent_t, Reference_t, Sentence_t, String_t, Table_t, TextContent_t, Utterance_t, Word_t};
+    Term::PROPS.ACCEPTED_DATA += {AbstractAnnotationLayer_t, AbstractExtendedTokenAnnotation_t, Alignment_t, Alternative_t, AlternativeLayers_t, Comment_t, Correction_t, Description_t, Event_t, Feature_t, Figure_t, ForeignData_t, Gap_t, Linebreak_t, List_t, Metric_t, Paragraph_t, Part_t, PhonContent_t, Reference_t, Sentence_t, String_t, Table_t, TextContent_t, Utterance_t, Whitespace_t, Word_t};
     Term::PROPS.ANNOTATIONTYPE = AnnotationType::TERM;
     Term::PROPS.LABEL = "Term";
     Term::PROPS.XMLTAG = "term";
 //------ Text -------
     Text::PROPS = AbstractStructureElement::PROPS;
     Text::PROPS.ELEMENT_ID = Text_t;
-    Text::PROPS.ACCEPTED_DATA += {AbstractAnnotationLayer_t, AbstractExtendedTokenAnnotation_t, Alignment_t, Alternative_t, AlternativeLayers_t, Comment_t, Correction_t, Description_t, Division_t, Entry_t, Event_t, Example_t, External_t, Feature_t, Figure_t, ForeignData_t, Gap_t, List_t, Metric_t, Note_t, Paragraph_t, Part_t, PhonContent_t, Quote_t, Reference_t, Sentence_t, String_t, Table_t, TextContent_t, Word_t};
+    Text::PROPS.ACCEPTED_DATA += {AbstractAnnotationLayer_t, AbstractExtendedTokenAnnotation_t, Alignment_t, Alternative_t, AlternativeLayers_t, Comment_t, Correction_t, Description_t, Division_t, Entry_t, Event_t, Example_t, External_t, Feature_t, Figure_t, ForeignData_t, Gap_t, Linebreak_t, List_t, Metric_t, Note_t, Paragraph_t, Part_t, PhonContent_t, Quote_t, Reference_t, Sentence_t, String_t, Table_t, TextContent_t, Whitespace_t, Word_t};
     Text::PROPS.LABEL = "Text Body";
     Text::PROPS.TEXTDELIMITER = "\n\n\n";
     Text::PROPS.XMLTAG = "text";
@@ -1236,7 +1237,7 @@ namespace folia {
     TextContent::PROPS.ANNOTATIONTYPE = AnnotationType::TEXT;
     TextContent::PROPS.LABEL = "Text";
     TextContent::PROPS.OCCURRENCES = 0;
-    TextContent::PROPS.OPTIONAL_ATTRIBS = CLASS|ANNOTATOR|CONFIDENCE|DATETIME;
+    TextContent::PROPS.OPTIONAL_ATTRIBS = CLASS|ANNOTATOR|CONFIDENCE|DATETIME|METADATA;
     TextContent::PROPS.PRINTABLE = true;
     TextContent::PROPS.SPEAKABLE = false;
     TextContent::PROPS.TEXTCONTAINER = true;
@@ -1311,6 +1312,7 @@ namespace folia {
     Word::PROPS.ACCEPTED_DATA += {AbstractAnnotationLayer_t, AbstractTokenAnnotation_t, Alignment_t, Alternative_t, AlternativeLayers_t, Comment_t, Correction_t, Description_t, Feature_t, ForeignData_t, Metric_t, Part_t, PhonContent_t, Reference_t, String_t, TextContent_t};
     Word::PROPS.ANNOTATIONTYPE = AnnotationType::TOKEN;
     Word::PROPS.LABEL = "Word/Token";
+    Word::PROPS.OPTIONAL_ATTRIBS = ID|CLASS|ANNOTATOR|N|CONFIDENCE|DATETIME|SRC|BEGINTIME|ENDTIME|SPEAKER|TEXTCLASS|METADATA;
     Word::PROPS.TEXTDELIMITER = " ";
     Word::PROPS.XMLTAG = "w";
 //------ WordReference -------
diff --git a/src/folia_types.cxx b/src/folia_types.cxx
index 16d15f1..673ff02 100644
--- a/src/folia_types.cxx
+++ b/src/folia_types.cxx
@@ -49,9 +49,6 @@ namespace folia {
 
   AnnotationType::AnnotationType stringToAT( const string& st ){
     string s = st;
-    if ( s == "div" ){
-      s = "division";  // fix for old (in fact invalid) FoLiA
-    }
     auto result = s_ant_map.find( s );
     if ( result == s_ant_map.end() ){
       throw logic_error( "Unknown translation for annotationtype: '"
diff --git a/src/folia_utils.cxx b/src/folia_utils.cxx
index a13146b..318e3ee 100644
--- a/src/folia_utils.cxx
+++ b/src/folia_utils.cxx
@@ -86,7 +86,6 @@ namespace folia {
     bool quoted = false;
     bool parseatt = true;
     bool escaped = false;
-    vector<string> parts;
     string att;
     string val;
     for ( const auto& let : s ){
@@ -236,9 +235,8 @@ namespace folia {
   }
 
   int toMonth( const string& ms ){
-    int result = 0;
     try {
-      result = stringTo<int>( ms );
+      int result = stringTo<int>( ms );
       return result - 1;
     }
     catch( exception ){
@@ -287,7 +285,7 @@ namespace folia {
       }
     }
     //    cerr << "found " << num << " parts" << endl;
-    tm *time = new tm();
+    tm time = tm();
     if ( num == 1 || num == 2 ){
       //      cerr << "parse date " << date_time[0] << endl;
       vector<string> date_parts;
@@ -295,15 +293,17 @@ namespace folia {
       switch ( dnum ){
       case 3: {
 	int mday = stringTo<int>( date_parts[2] );
-	time->tm_mday = mday;
+	time.tm_mday = mday;
       }
+	// fall through
       case 2: {
 	int mon = toMonth( date_parts[1] );
-	time->tm_mon = mon;
+	time.tm_mon = mon;
       }
+	// fall through
       case 1: {
 	int year = stringTo<int>( date_parts[0] );
-	time->tm_year = year-1900;
+	time.tm_year = year-1900;
       }
 	break;
       default:
@@ -321,15 +321,17 @@ namespace folia {
 	// ignore
       case 3: {
 	int sec = stringTo<int>( date_parts[2] );
-	time->tm_sec = sec;
+	time.tm_sec = sec;
       }
+	// fall through
       case 2: {
 	int min = stringTo<int>( date_parts[1] );
-	time->tm_min = min;
+	time.tm_min = min;
       }
+	// fall through
       case 1: {
 	int hour = stringTo<int>( date_parts[0] );
-	time->tm_hour = hour;
+	time.tm_hour = hour;
       }
 	break;
       default:
@@ -339,8 +341,7 @@ namespace folia {
     }
     // cerr << "read _date time = " << toString(time) << endl;
     char buf[100];
-    strftime( buf, 100, "%Y-%m-%dT%X", time );
-    delete time;
+    strftime( buf, 100, "%Y-%m-%dT%X", &time );
     return buf;
   }
 
@@ -350,25 +351,23 @@ namespace folia {
     }
     //    cerr << "try to read a time " << s << endl;
     vector<string> time_parts;
-    string mil = "000";
-    tm *time = new tm();
+    tm time = tm();
     int num = TiCC::split_at( s, time_parts, ":" );
     if ( num != 3 ){
       cerr << "failed to read a time " << s << endl;
       return "";
     }
-    time->tm_min = stringTo<int>( time_parts[1] );
-    time->tm_hour = stringTo<int>( time_parts[0] );
+    time.tm_min = stringTo<int>( time_parts[1] );
+    time.tm_hour = stringTo<int>( time_parts[0] );
     string secs = time_parts[2];
     num = TiCC::split_at( secs, time_parts, "." );
-    time->tm_sec = stringTo<int>( time_parts[0] );
+    time.tm_sec = stringTo<int>( time_parts[0] );
     string mil_sec = "000";
     if ( num == 2 ){
       mil_sec = time_parts[1];
     }
     char buf[100];
-    strftime( buf, 100, "%X", time );
-    delete time;
+    strftime( buf, 100, "%X", &time );
     string result = buf;
     result += "." + mil_sec;
     //    cerr << "formatted time = " << result << endl;
@@ -492,4 +491,26 @@ namespace folia {
     return true;
   }
 
+  UnicodeString normalize( const UnicodeString& input ){
+    // substitute \n \r \t by spaces AND all multiple spaces by 1
+    // also trims at back and front.
+    UnicodeString result;
+    bool is_space = false;
+    for ( int i=0; i < input.length(); ++i ){
+      if ( u_isspace( input[i] ) ){
+	if ( is_space ){
+	  continue;
+	}
+	is_space = true;
+	result += " ";
+      }
+      else {
+	is_space = false;
+	result += input[i];
+      }
+    }
+    result.trim(); // remove leading and trailing whitespace;
+    return result;
+  }
+
 } //namespace folia
diff --git a/src/folialint.cxx b/src/folialint.cxx
index cc9174f..00f11d7 100644
--- a/src/folialint.cxx
+++ b/src/folialint.cxx
@@ -28,6 +28,7 @@
 #include <iostream>
 #include <fstream>
 #include <string>
+#include <map>
 #include "ticcutils/CommandLine.h"
 #include "libfolia/folia.h"
 
@@ -35,18 +36,30 @@ using namespace std;
 
 void usage(){
   cerr << "usage: folialint [options] <foliafiles>" << endl;
+  cerr << "options are" << endl;
+  cerr << "\t-h or --help\t\t This help" << endl;
+  cerr << "\t-V or --version\t\t Show versions" << endl;
+  cerr << "\t--strip\t\t\t strip variable items from the FoLiA. Like all dates." << endl;
+  cerr << "\t\t\t\t This is usefull to generate FoLiA that can be diffed." << endl;
+  cerr << "\t--output='file'\t\t name an outputfile. (default is stdout)" << endl;
+  cerr << "\t--nooutput\t\t Suppress output. Only warnings/errors are displayed." << endl;
+  cerr << "\t--nochecktext DO NOT check if text is consistent inside structure tags. Default is to do so." << endl;
+  cerr << "\t--debug=value\t\t Run more verbose." << endl;
+  cerr << "\t--permissive\t\t Accept some unwise constructions." << endl;
 }
 
 int main( int argc, char* argv[] ){
   string outputName;
   bool permissive;
+  bool warn;
   bool strip;
   bool nooutput = false;
+  bool nochecktext = false;
   string debug;
   vector<string> fileNames;
   try {
     TiCC::CL_Options Opts( "hV",
-			   "debug:,permissive,strip,output:,nooutput,help,version");
+			   "nochecktext,debug:,permissive,strip,output:,nooutput,help,warn,version");
     Opts.init(argc, argv );
     if ( Opts.extract( 'h' )
 	 || Opts.extract( "help" ) ){
@@ -55,12 +68,16 @@ int main( int argc, char* argv[] ){
     }
     if ( Opts.extract( 'V' )
 	 || Opts.extract( "version" ) ){
-      cout << "folialint version 0.4" << endl;
+      cout << "folialint version 0.5" << endl;
       cout << "based on [" << folia::VersionName() << "]" << endl;
       return EXIT_SUCCESS;
     }
     permissive = Opts.extract("permissive");
+    warn = Opts.extract("warn");
     nooutput = Opts.extract("nooutput");
+    if ( Opts.extract("nochecktext") ){
+      nochecktext = true;
+    }
     strip = Opts.extract("strip");
     if ( strip && permissive ){
       cerr << "conflicting options: 'permissive' and 'strip'" << endl;
@@ -91,15 +108,31 @@ int main( int argc, char* argv[] ){
     cerr << "FAIL: " << e.what() << endl;
     exit( EXIT_FAILURE );
   }
+
   for ( const auto& inputName : fileNames ){
     try {
       string cmd = "file='" + inputName + "'";
       if ( !debug.empty() )
 	cmd += ", debug='" + debug + "'";
-      if ( permissive )
-	cmd += ", mode='permissive'";
-      else if ( strip )
-	cmd += ", mode='strip'";
+      string mode;
+      if ( permissive ){
+	mode = ", mode='permissive";
+      }
+      else if ( strip ){
+	mode = ", mode='strip";
+      }
+      if ( nochecktext ){
+	if ( mode.empty() ){
+	  mode = ", mode='nochecktext'";
+	}
+	else {
+	  mode += ",nochecktext'";
+	}
+      }
+      else if ( !mode.empty() ){
+	mode += "'";
+      }
+      cmd += mode;
       folia::Document d( cmd );
       if ( !outputName.empty() ){
 	d.save( outputName );
@@ -107,10 +140,24 @@ int main( int argc, char* argv[] ){
       else if ( !nooutput ){
 	cout << d;
       }
+      if ( warn ){
+	if ( folia::Document::compare_to_lib_version(d.version()) ){
+	  cerr << "WARNING: the document had version: " << d.version()
+	       << " and the library is at version: "
+	       <<  folia::Document::library_version() << endl;
+	}
+	multimap<folia::AnnotationType::AnnotationType, string> und = d.unused_declarations();
+	if ( !und.empty() ){
+	  cerr << "the folowing annotationsets are declared but unused: " << endl;
+	  for ( const auto& it : und ){
+	    cerr << folia::toString( it.first )<< "-annotation, set=" << it.second << endl;
+	  }
+	}
+      }
     }
     catch( exception& e ){
-      cerr << "FAIL: " << e.what() << endl;
-      exit( EXIT_FAILURE );
+      cerr << inputName << " failed: " << endl << e.what() << endl;
+      //      exit( EXIT_FAILURE );
     }
   }
   exit( EXIT_SUCCESS );
diff --git a/src/simpletest.cxx b/src/simpletest.cxx
index 0685f9e..304635a 100644
--- a/src/simpletest.cxx
+++ b/src/simpletest.cxx
@@ -83,5 +83,26 @@ int main() {
     return EXIT_FAILURE;
   }
   cout << s->text() << endl;
+  UnicodeString dirty = "    A    dir\ty \n  string\r.\n   ";
+  UnicodeString clean = normalize( dirty );
+  UnicodeString wanted = "A dirty string.";
+  if ( clean != wanted ){
+    cerr << "string normalize failed: got:'" << clean << "'"
+	 << "                but expected:'" << wanted << "'" << endl;
+  }
+  dirty = "\n";
+  clean = normalize( dirty );
+  wanted = " ";
+  if ( clean != wanted ){
+    cerr << "string normalize failed: got:'" << clean << "'"
+	 << "                but expected:'" << wanted << "'" << endl;
+  }
+  dirty = "\r    ";
+  clean = normalize( dirty );
+  wanted = " ";
+  if ( clean != wanted ){
+    cerr << "string normalize failed: got:'" << clean << "'"
+	 << "                but expected:'" << wanted << "'" << endl;
+  }
   return EXIT_SUCCESS;
 }

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/debian-science/packages/libfolia.git



More information about the debian-science-commits mailing list