[sword-svn] r3515 - in branches/sword-1-8-x: . bindings bindings/corba/orbitcpp bindings/java-jni bindings/java-jni/jni bindings/java-jni/src/org/crosswire/android/sword bindings/swig cmake examples/cmdline include locales.d src/keys src/mgr src/modules src/modules/common src/modules/filters src/modules/lexdict/rawld src/modules/lexdict/rawld4 src/modules/lexdict/zld src/utilfuns tests tests/testsuite utilities utilities/diatheke

scribe at crosswire.org scribe at crosswire.org
Wed Nov 1 04:38:10 MST 2017


Author: scribe
Date: 2017-11-01 04:38:09 -0700 (Wed, 01 Nov 2017)
New Revision: 3515

Added:
   branches/sword-1-8-x/bindings/Android/
   branches/sword-1-8-x/bindings/cordova/
   branches/sword-1-8-x/src/mgr/rtranspgdrive.cpp
   branches/sword-1-8-x/tests/testsuite/README
   branches/sword-1-8-x/tests/testsuite/UTF-8-test.txt
   branches/sword-1-8-x/tests/testsuite/gbsReference.imp
   branches/sword-1-8-x/tests/testsuite/gbs_basic.good
   branches/sword-1-8-x/tests/testsuite/gbs_basic.sh
   branches/sword-1-8-x/tests/testsuite/greekaccents.good
   branches/sword-1-8-x/tests/testsuite/greekaccents.sh
   branches/sword-1-8-x/tests/testsuite/greekaccents.txt
   branches/sword-1-8-x/tests/testsuite/utf8basic.good
   branches/sword-1-8-x/tests/testsuite/utf8basic.sh
Removed:
   branches/sword-1-8-x/bindings/java-jni/jni/org_crosswire_android_sword_InstallMgr.h
   branches/sword-1-8-x/bindings/java-jni/jni/org_crosswire_android_sword_SWMgr.h
   branches/sword-1-8-x/bindings/java-jni/jni/org_crosswire_android_sword_SWMgr_ModInfo.h
   branches/sword-1-8-x/bindings/java-jni/jni/org_crosswire_android_sword_SWMgr_SearchHit.h
   branches/sword-1-8-x/bindings/java-jni/jni/org_crosswire_android_sword_SWModule.h
   branches/sword-1-8-x/bindings/java-jni/jni/org_crosswire_android_sword_SWModule_SearchHit.h
   branches/sword-1-8-x/bindings/java-jni/jni/org_crosswire_android_sword_SWModule_SearchProgressReporter.h
Modified:
   branches/sword-1-8-x/
   branches/sword-1-8-x/ChangeLog
   branches/sword-1-8-x/bindings/corba/orbitcpp/webmgr.hpp
   branches/sword-1-8-x/bindings/flatapi.cpp
   branches/sword-1-8-x/bindings/java-jni/Makefile
   branches/sword-1-8-x/bindings/java-jni/README
   branches/sword-1-8-x/bindings/java-jni/jni/swordstub.cpp
   branches/sword-1-8-x/bindings/java-jni/jni/webmgr.hpp
   branches/sword-1-8-x/bindings/java-jni/src/org/crosswire/android/sword/SWMgr.java
   branches/sword-1-8-x/bindings/swig/deprecations.i
   branches/sword-1-8-x/bindings/swig/swconfig.i
   branches/sword-1-8-x/cmake/FindCLucene.cmake
   branches/sword-1-8-x/configure.ac
   branches/sword-1-8-x/examples/cmdline/search.cpp
   branches/sword-1-8-x/include/canon_calvin.h
   branches/sword-1-8-x/include/canon_darbyfr.h
   branches/sword-1-8-x/include/canon_segond.h
   branches/sword-1-8-x/include/filemgr.h
   branches/sword-1-8-x/include/installmgr.h
   branches/sword-1-8-x/include/remotetrans.h
   branches/sword-1-8-x/include/swbuf.h
   branches/sword-1-8-x/include/swconfig.h
   branches/sword-1-8-x/include/swkey.h
   branches/sword-1-8-x/include/swmgr.h
   branches/sword-1-8-x/include/swoptfilter.h
   branches/sword-1-8-x/include/swversion.h
   branches/sword-1-8-x/include/utilstr.h
   branches/sword-1-8-x/locales.d/zh_CN-utf8.conf
   branches/sword-1-8-x/src/keys/treekeyidx.cpp
   branches/sword-1-8-x/src/mgr/Makefile.am
   branches/sword-1-8-x/src/mgr/curlhttpt.cpp
   branches/sword-1-8-x/src/mgr/filemgr.cpp
   branches/sword-1-8-x/src/mgr/installmgr.cpp
   branches/sword-1-8-x/src/mgr/localemgr.cpp
   branches/sword-1-8-x/src/mgr/remotetrans.cpp
   branches/sword-1-8-x/src/mgr/swconfig.cpp
   branches/sword-1-8-x/src/mgr/swlocale.cpp
   branches/sword-1-8-x/src/mgr/swmgr.cpp
   branches/sword-1-8-x/src/mgr/versificationmgr.cpp
   branches/sword-1-8-x/src/modules/common/bz2comprs.cpp
   branches/sword-1-8-x/src/modules/common/rawstr.cpp
   branches/sword-1-8-x/src/modules/common/rawstr4.cpp
   branches/sword-1-8-x/src/modules/common/xzcomprs.cpp
   branches/sword-1-8-x/src/modules/common/zipcomprs.cpp
   branches/sword-1-8-x/src/modules/common/zstr.cpp
   branches/sword-1-8-x/src/modules/filters/gbfstrongs.cpp
   branches/sword-1-8-x/src/modules/filters/gbfwordjs.cpp
   branches/sword-1-8-x/src/modules/filters/greeklexattribs.cpp
   branches/sword-1-8-x/src/modules/filters/osisstrongs.cpp
   branches/sword-1-8-x/src/modules/filters/osiswordjs.cpp
   branches/sword-1-8-x/src/modules/filters/rtfhtml.cpp
   branches/sword-1-8-x/src/modules/filters/thmlstrongs.cpp
   branches/sword-1-8-x/src/modules/filters/thmlwordjs.cpp
   branches/sword-1-8-x/src/modules/filters/utf8greekaccents.cpp
   branches/sword-1-8-x/src/modules/lexdict/rawld/rawld.cpp
   branches/sword-1-8-x/src/modules/lexdict/rawld4/rawld4.cpp
   branches/sword-1-8-x/src/modules/lexdict/zld/zld.cpp
   branches/sword-1-8-x/src/modules/swmodule.cpp
   branches/sword-1-8-x/src/utilfuns/swbuf.cpp
   branches/sword-1-8-x/src/utilfuns/utilstr.cpp
   branches/sword-1-8-x/tests/configtest.cpp
   branches/sword-1-8-x/tests/utf8norm.cpp
   branches/sword-1-8-x/utilities/diatheke/diathekemgr.cpp
   branches/sword-1-8-x/utilities/diatheke/diathekemgr.h
   branches/sword-1-8-x/utilities/imp2vs.cpp
   branches/sword-1-8-x/utilities/installmgr.cpp
   branches/sword-1-8-x/utilities/mod2osis.cpp
Log:
Resync'd 1.8.0 branch with trunk for RC4 release



Property changes on: branches/sword-1-8-x
___________________________________________________________________
Modified: svn:mergeinfo
   - /trunk:3459-3471,3473,3475,3477-3482
   + /trunk:3459-3471,3473,3475,3477-3482,3485-3514

Modified: branches/sword-1-8-x/ChangeLog
===================================================================
--- branches/sword-1-8-x/ChangeLog	2017-11-01 11:33:56 UTC (rev 3514)
+++ branches/sword-1-8-x/ChangeLog	2017-11-01 11:38:09 UTC (rev 3515)
@@ -1,5 +1,13 @@
 API ChangeLog
 
+
+01-Nov-2017	Troy A. Griffitts <scribe at crosswire.org>
+	Added bindings: Android and cordova
+
+01-Sep-2017	Troy A. Griffitts <scribe at crosswire.org>
+	Adding French mapping data.
+		Patch submitted by domcox <dominique at corbex.org>
+
 21-May-2017	Troy A. Griffitts <scribe at crosswire.org>
 	Added --with-icuregex option to use ICU regex engine
 
@@ -19,14 +27,14 @@
 
 18-Dec-2015	Peter von Kaehne <refdoc at crosswire.org>
 	Added image and table handling to TEI xhtml and htmlhref filters
-	contributed by Dominique Corbex <dominique.corbex at gmail.com> 
+		contributed by Dominique Corbex <dominique.corbex at gmail.com> 
 	
 15-Dec-2014	DM Smith <dmsmith at crosswire.org>
 	Fixed endless loop in osis2mod for some inputs.
 
 15-Dec-2014	DM Smith <dmsmith at crosswire.org>
 	Added support for Psalm Book divisions using <div type=majorSection>
-	from GHellings
+		from GHellings
 
 03-Dec-2014	Karl Kleinpaste <charcoal at users.sf.net>
 	Corrected anomalous OSIS highlighting output w/GHellings' patches in

Modified: branches/sword-1-8-x/bindings/corba/orbitcpp/webmgr.hpp
===================================================================
--- branches/sword-1-8-x/bindings/corba/orbitcpp/webmgr.hpp	2017-11-01 11:33:56 UTC (rev 3514)
+++ branches/sword-1-8-x/bindings/corba/orbitcpp/webmgr.hpp	2017-11-01 11:38:09 UTC (rev 3515)
@@ -54,7 +54,7 @@
 		osisWordJS = new OSISWordJS();
 		thmlWordJS = new ThMLWordJS();
 		gbfWordJS = new GBFWordJS();
-		Load();
+		load();
 		osisWordJS->setDefaultModules(defaultGreekLex, defaultHebLex, defaultGreekParse, defaultHebParse);
 		thmlWordJS->setDefaultModules(defaultGreekLex, defaultHebLex, defaultGreekParse, defaultHebParse);
 		gbfWordJS->setDefaultModules(defaultGreekLex, defaultHebLex, defaultGreekParse, defaultHebParse);
@@ -71,7 +71,7 @@
 	}
 
 
-	void AddGlobalOptions(SWModule *module, ConfigEntMap &section, ConfigEntMap::iterator start, ConfigEntMap::iterator end) {
+	void addGlobalOptionFilters(SWModule *module, ConfigEntMap &section) {
 
 		// ThML word stuff needs to process before strongs strip
 		if (module->getMarkup() == FMT_THML) {
@@ -83,7 +83,7 @@
 		}
 
 		// add other module filters
-		SWMgr::AddGlobalOptions(module, section, start, end);
+		SWMgr::addGlobalOptionFilters(module, section);
 
 		// add our special filters
 		if (module->getConfig().has("Feature", "GreekDef")) {

Modified: branches/sword-1-8-x/bindings/flatapi.cpp
===================================================================
--- branches/sword-1-8-x/bindings/flatapi.cpp	2017-11-01 11:33:56 UTC (rev 3514)
+++ branches/sword-1-8-x/bindings/flatapi.cpp	2017-11-01 11:38:09 UTC (rev 3515)
@@ -956,7 +956,7 @@
 		FileMgr::createParent(modsd.c_str());
 		SWConfig config(modsd.c_str());
 		config["Globals"]["HiAndroid"] = "weeee";
-		config.Save();
+		config.save();
 	}
 	return (SWHANDLE) new HandleSWMgr(new WebMgr(confPath.c_str()));
 }
@@ -1283,7 +1283,7 @@
 
 		SWConfig config(confPath.c_str());
 		config["General"]["PassiveFTP"] = "true";
-		config.Save();
+		config.save();
 	}
 	HandleInstMgr *hinstmgr = new HandleInstMgr();
 	hinstmgr->statusReporter.init(statusReporter);

Modified: branches/sword-1-8-x/bindings/java-jni/Makefile
===================================================================
--- branches/sword-1-8-x/bindings/java-jni/Makefile	2017-11-01 11:33:56 UTC (rev 3514)
+++ branches/sword-1-8-x/bindings/java-jni/Makefile	2017-11-01 11:38:09 UTC (rev 3515)
@@ -10,6 +10,8 @@
 	javap -s -classpath classes/ org.crosswire.android.sword.SWModule.SearchHit > SearchHit.txt
 	javap -s -classpath classes/ org.crosswire.android.sword.SWModule.SearchProgressReporter > SearchProgressReporter.txt
 	javap -s -classpath classes/ org.crosswire.android.sword.InstallMgr > InstallMgr.txt
-	cp src/org/crosswire/android/sword/*.java /home/scribe/src/bishop/src/org/crosswire/android/sword/
+	cp src/org/crosswire/android/sword/*.java ../Android/SWORD/app/src/main/java/org/crosswire/android/sword/
 
 
+clean:
+	rm -rf classes jni/org_crosswire_android_sword_*.h *.txt

Modified: branches/sword-1-8-x/bindings/java-jni/README
===================================================================
--- branches/sword-1-8-x/bindings/java-jni/README	2017-11-01 11:33:56 UTC (rev 3514)
+++ branches/sword-1-8-x/bindings/java-jni/README	2017-11-01 11:38:09 UTC (rev 3515)
@@ -1,27 +1,28 @@
-Android Build Instructions
+This folder contains java-jni bindings.  They are 99% generic but have
+some Android-specific code which should eventually be removed.  This
+includes setting a SWLog::setSystemLog(new AndroidLogger()) and an
+org.crosswire.android.sword.* package. This was not changed to
+org.crosswire.sword.* because there are conflicting SWMgr, et. al.
+classes from the crosswire-java project and the CORBA bindings.
+org.crosswire.jni.sword.* is an option but exposing the impl in the
+package name is bad practice.  More thought needed.
 
-You'll need the Android NDK.
+A make in here should produce the JNI wrappers.
+jni/swordstub.cpp is the jni implementation
 
-Then link the sword/bindings/java-jni folder to your project's /jni folder.
-I have a symlink:
+This make also copies the java src/ files to the ../Android binding folder.
+The ../Android binding folder symlinks to the jni cpp file generated here.
 
-~/src/bishop/jni -> ~/src/sword/bindings/java-jni/jni/
+There is an Android Studio project there to build the native libs
 
-~/src/sword is simply a checkout of the current sword svn repository.
-(svn co https://crosswire.org/svn/sword/trunk ~/src/sword)
+The steps to build all of this are usually:
+1) make in this folder
+2) build all in ../Android/SWORD Android Studio project
+3) a make in the ../Android/ folder, which finally copies the binary libs
+	to the ../cordova/ bindings folder to produce a working cordova
+	plugin
 
+Android java bindings can be used after step 2
+cordova javascript bindings can be used after step 3
 
-So, since my $HOME directly is /home/scribe, my configuration looks like this:
-
-/home/scribe/src/sword/
-/home/scribe/src/bishop/
-/home/scribe/android-ndk-r8e/
-
-with:
-
-APP_PROJECT_PATH := $(call my-dir)/../../../src/bishop
-APP_MODULES      := sword swordcore
-APP_PLATFORM     := android-3
-
-
 Hope this helps get you started.  Let me know your progress!

Deleted: branches/sword-1-8-x/bindings/java-jni/jni/org_crosswire_android_sword_InstallMgr.h
===================================================================
--- branches/sword-1-8-x/bindings/java-jni/jni/org_crosswire_android_sword_InstallMgr.h	2017-11-01 11:33:56 UTC (rev 3514)
+++ branches/sword-1-8-x/bindings/java-jni/jni/org_crosswire_android_sword_InstallMgr.h	2017-11-01 11:38:09 UTC (rev 3515)
@@ -1,85 +0,0 @@
-/* DO NOT EDIT THIS FILE - it is machine generated */
-#include <jni.h>
-/* Header for class org_crosswire_android_sword_InstallMgr */
-
-#ifndef _Included_org_crosswire_android_sword_InstallMgr
-#define _Included_org_crosswire_android_sword_InstallMgr
-#ifdef __cplusplus
-extern "C" {
-#endif
-/*
- * Class:     org_crosswire_android_sword_InstallMgr
- * Method:    reInit
- * Signature: ()V
- */
-JNIEXPORT void JNICALL Java_org_crosswire_android_sword_InstallMgr_reInit
-  (JNIEnv *, jobject);
-
-/*
- * Class:     org_crosswire_android_sword_InstallMgr
- * Method:    setUserDisclaimerConfirmed
- * Signature: ()V
- */
-JNIEXPORT void JNICALL Java_org_crosswire_android_sword_InstallMgr_setUserDisclaimerConfirmed
-  (JNIEnv *, jobject);
-
-/*
- * Class:     org_crosswire_android_sword_InstallMgr
- * Method:    syncConfig
- * Signature: ()I
- */
-JNIEXPORT jint JNICALL Java_org_crosswire_android_sword_InstallMgr_syncConfig
-  (JNIEnv *, jobject);
-
-/*
- * Class:     org_crosswire_android_sword_InstallMgr
- * Method:    uninstallModule
- * Signature: (Ljava/lang/String;)I
- */
-JNIEXPORT jint JNICALL Java_org_crosswire_android_sword_InstallMgr_uninstallModule
-  (JNIEnv *, jobject, jstring);
-
-/*
- * Class:     org_crosswire_android_sword_InstallMgr
- * Method:    getRemoteSources
- * Signature: ()[Ljava/lang/String;
- */
-JNIEXPORT jobjectArray JNICALL Java_org_crosswire_android_sword_InstallMgr_getRemoteSources
-  (JNIEnv *, jobject);
-
-/*
- * Class:     org_crosswire_android_sword_InstallMgr
- * Method:    refreshRemoteSource
- * Signature: (Ljava/lang/String;)I
- */
-JNIEXPORT jint JNICALL Java_org_crosswire_android_sword_InstallMgr_refreshRemoteSource
-  (JNIEnv *, jobject, jstring);
-
-/*
- * Class:     org_crosswire_android_sword_InstallMgr
- * Method:    getRemoteModInfoList
- * Signature: (Ljava/lang/String;)[Lorg/crosswire/android/sword/SWMgr/ModInfo;
- */
-JNIEXPORT jobjectArray JNICALL Java_org_crosswire_android_sword_InstallMgr_getRemoteModInfoList
-  (JNIEnv *, jobject, jstring);
-
-/*
- * Class:     org_crosswire_android_sword_InstallMgr
- * Method:    remoteInstallModule
- * Signature: (Ljava/lang/String;Ljava/lang/String;)I
- */
-JNIEXPORT jint JNICALL Java_org_crosswire_android_sword_InstallMgr_remoteInstallModule
-  (JNIEnv *, jobject, jstring, jstring, jobject);
-
-/*
- * Class:     org_crosswire_android_sword_InstallMgr
- * Method:    getRemoteModuleByName
- * Signature: (Ljava/lang/String;Ljava/lang/String;)Lorg/crosswire/android/sword/SWModule;
- */
-JNIEXPORT jobject JNICALL Java_org_crosswire_android_sword_InstallMgr_getRemoteModuleByName
-  (JNIEnv *, jobject, jstring, jstring);
-
-#ifdef __cplusplus
-}
-#endif
-#endif

Deleted: branches/sword-1-8-x/bindings/java-jni/jni/org_crosswire_android_sword_SWMgr.h
===================================================================
--- branches/sword-1-8-x/bindings/java-jni/jni/org_crosswire_android_sword_SWMgr.h	2017-11-01 11:33:56 UTC (rev 3514)
+++ branches/sword-1-8-x/bindings/java-jni/jni/org_crosswire_android_sword_SWMgr.h	2017-11-01 11:38:09 UTC (rev 3515)
@@ -1,158 +0,0 @@
-/* DO NOT EDIT THIS FILE - it is machine generated */
-#include <jni.h>
-/* Header for class org_crosswire_android_sword_SWMgr */
-
-#ifndef _Included_org_crosswire_android_sword_SWMgr
-#define _Included_org_crosswire_android_sword_SWMgr
-#ifdef __cplusplus
-extern "C" {
-#endif
-/*
- * Class:     org_crosswire_android_sword_SWMgr
- * Method:    version
- * Signature: ()Ljava/lang/String;
- */
-JNIEXPORT jstring JNICALL Java_org_crosswire_android_sword_SWMgr_version
-  (JNIEnv *, jobject);
-
-/*
- * Class:     org_crosswire_android_sword_SWMgr
- * Method:    reInit
- * Signature: ()V
- */
-JNIEXPORT void JNICALL Java_org_crosswire_android_sword_SWMgr_reInit
-  (JNIEnv *, jobject);
-
-/*
- * Class:     org_crosswire_android_sword_SWMgr
- * Method:    getModInfoList
- * Signature: ()[Lorg/crosswire/android/sword/SWMgr/ModInfo;
- */
-JNIEXPORT jobjectArray JNICALL Java_org_crosswire_android_sword_SWMgr_getModInfoList
-  (JNIEnv *, jobject);
-
-/*
- * Class:     org_crosswire_android_sword_SWMgr
- * Method:    getModuleByName
- * Signature: (Ljava/lang/String;)Lorg/crosswire/android/sword/SWModule;
- */
-JNIEXPORT jobject JNICALL Java_org_crosswire_android_sword_SWMgr_getModuleByName
-  (JNIEnv *, jobject, jstring);
-
-/*
- * Class:     org_crosswire_android_sword_SWMgr
- * Method:    getPrefixPath
- * Signature: ()Ljava/lang/String;
- */
-JNIEXPORT jstring JNICALL Java_org_crosswire_android_sword_SWMgr_getPrefixPath
-  (JNIEnv *, jobject);
-
-/*
- * Class:     org_crosswire_android_sword_SWMgr
- * Method:    getConfigPath
- * Signature: ()Ljava/lang/String;
- */
-JNIEXPORT jstring JNICALL Java_org_crosswire_android_sword_SWMgr_getConfigPath
-  (JNIEnv *, jobject);
-
-/*
- * Class:     org_crosswire_android_sword_SWMgr
- * Method:    setGlobalOption
- * Signature: (Ljava/lang/String;Ljava/lang/String;)V
- */
-JNIEXPORT void JNICALL Java_org_crosswire_android_sword_SWMgr_setGlobalOption
-  (JNIEnv *, jobject, jstring, jstring);
-
-/*
- * Class:     org_crosswire_android_sword_SWMgr
- * Method:    getGlobalOption
- * Signature: (Ljava/lang/String;)Ljava/lang/String;
- */
-JNIEXPORT jstring JNICALL Java_org_crosswire_android_sword_SWMgr_getGlobalOption
-  (JNIEnv *, jobject, jstring);
-
-/*
- * Class:     org_crosswire_android_sword_SWMgr
- * Method:    getGlobalOptionTip
- * Signature: (Ljava/lang/String;)Ljava/lang/String;
- */
-JNIEXPORT jstring JNICALL Java_org_crosswire_android_sword_SWMgr_getGlobalOptionTip
-  (JNIEnv *, jobject, jstring);
-
-/*
- * Class:     org_crosswire_android_sword_SWMgr
- * Method:    filterText
- * Signature: (Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
- */
-JNIEXPORT jstring JNICALL Java_org_crosswire_android_sword_SWMgr_filterText
-  (JNIEnv *, jobject, jstring, jstring);
-
-/*
- * Class:     org_crosswire_android_sword_SWMgr
- * Method:    getGlobalOptions
- * Signature: ()[Ljava/lang/String;
- */
-JNIEXPORT jobjectArray JNICALL Java_org_crosswire_android_sword_SWMgr_getGlobalOptions
-  (JNIEnv *, jobject);
-
-/*
- * Class:     org_crosswire_android_sword_SWMgr
- * Method:    getGlobalOptionValues
- * Signature: (Ljava/lang/String;)[Ljava/lang/String;
- */
-JNIEXPORT jobjectArray JNICALL Java_org_crosswire_android_sword_SWMgr_getGlobalOptionValues
-  (JNIEnv *, jobject, jstring);
-
-/*
- * Class:     org_crosswire_android_sword_SWMgr
- * Method:    setCipherKey
- * Signature: (Ljava/lang/String;Ljava/lang/String;)V
- */
-JNIEXPORT void JNICALL Java_org_crosswire_android_sword_SWMgr_setCipherKey
-  (JNIEnv *, jobject, jstring, jstring);
-
-/*
- * Class:     org_crosswire_android_sword_SWMgr
- * Method:    setJavascript
- * Signature: (Z)V
- */
-JNIEXPORT void JNICALL Java_org_crosswire_android_sword_SWMgr_setJavascript
-  (JNIEnv *, jobject, jboolean);
-
-/*
- * Class:     org_crosswire_android_sword_SWMgr
- * Method:    getAvailableLocales
- * Signature: ()[Ljava/lang/String;
- */
-JNIEXPORT jobjectArray JNICALL Java_org_crosswire_android_sword_SWMgr_getAvailableLocales
-  (JNIEnv *, jobject);
-
-/*
- * Class:     org_crosswire_android_sword_SWMgr
- * Method:    setDefaultLocale
- * Signature: (Ljava/lang/String;)V
- */
-JNIEXPORT void JNICALL Java_org_crosswire_android_sword_SWMgr_setDefaultLocale
-  (JNIEnv *, jobject, jstring);
-
-/*
- * Class:     org_crosswire_android_sword_SWMgr
- * Method:    sendBibleSyncMessage
- * Signature: (Ljava/lang/String;)V
- */
-JNIEXPORT void JNICALL Java_org_crosswire_android_sword_SWMgr_sendBibleSyncMessage
-  (JNIEnv *, jobject, jstring);
-
-
-/*
- * Class:     org_crosswire_android_sword_SWMgr
- * Method:    registerBibleSyncListener
- * Signature: (Ljava/lang/Object;)V
- */
-JNIEXPORT void JNICALL Java_org_crosswire_android_sword_SWMgr_registerBibleSyncListener
-  (JNIEnv *, jobject, jobject);
-
-#ifdef __cplusplus
-}
-#endif
-#endif

Deleted: branches/sword-1-8-x/bindings/java-jni/jni/org_crosswire_android_sword_SWMgr_ModInfo.h
===================================================================
--- branches/sword-1-8-x/bindings/java-jni/jni/org_crosswire_android_sword_SWMgr_ModInfo.h	2017-11-01 11:33:56 UTC (rev 3514)
+++ branches/sword-1-8-x/bindings/java-jni/jni/org_crosswire_android_sword_SWMgr_ModInfo.h	2017-11-01 11:38:09 UTC (rev 3515)
@@ -1,13 +0,0 @@
-/* DO NOT EDIT THIS FILE - it is machine generated */
-#include <jni.h>
-/* Header for class org_crosswire_android_sword_SWMgr_ModInfo */
-
-#ifndef _Included_org_crosswire_android_sword_SWMgr_ModInfo
-#define _Included_org_crosswire_android_sword_SWMgr_ModInfo
-#ifdef __cplusplus
-extern "C" {
-#endif
-#ifdef __cplusplus
-}
-#endif
-#endif

Deleted: branches/sword-1-8-x/bindings/java-jni/jni/org_crosswire_android_sword_SWMgr_SearchHit.h
===================================================================
--- branches/sword-1-8-x/bindings/java-jni/jni/org_crosswire_android_sword_SWMgr_SearchHit.h	2017-11-01 11:33:56 UTC (rev 3514)
+++ branches/sword-1-8-x/bindings/java-jni/jni/org_crosswire_android_sword_SWMgr_SearchHit.h	2017-11-01 11:38:09 UTC (rev 3515)
@@ -1,13 +0,0 @@
-/* DO NOT EDIT THIS FILE - it is machine generated */
-#include <jni.h>
-/* Header for class org_crosswire_android_sword_SWMgr_SearchHit */
-
-#ifndef _Included_org_crosswire_android_sword_SWMgr_SearchHit
-#define _Included_org_crosswire_android_sword_SWMgr_SearchHit
-#ifdef __cplusplus
-extern "C" {
-#endif
-#ifdef __cplusplus
-}
-#endif
-#endif

Deleted: branches/sword-1-8-x/bindings/java-jni/jni/org_crosswire_android_sword_SWModule.h
===================================================================
--- branches/sword-1-8-x/bindings/java-jni/jni/org_crosswire_android_sword_SWModule.h	2017-11-01 11:33:56 UTC (rev 3514)
+++ branches/sword-1-8-x/bindings/java-jni/jni/org_crosswire_android_sword_SWModule.h	2017-11-01 11:38:09 UTC (rev 3515)
@@ -1,199 +0,0 @@
-/* DO NOT EDIT THIS FILE - it is machine generated */
-#include <jni.h>
-/* Header for class org_crosswire_android_sword_SWModule */
-
-#ifndef _Included_org_crosswire_android_sword_SWModule
-#define _Included_org_crosswire_android_sword_SWModule
-#ifdef __cplusplus
-extern "C" {
-#endif
-#undef org_crosswire_android_sword_SWModule_SEARCHTYPE_REGEX
-#define org_crosswire_android_sword_SWModule_SEARCHTYPE_REGEX 1L
-#undef org_crosswire_android_sword_SWModule_SEARCHTYPE_PHRASE
-#define org_crosswire_android_sword_SWModule_SEARCHTYPE_PHRASE -1L
-#undef org_crosswire_android_sword_SWModule_SEARCHTYPE_MULTIWORD
-#define org_crosswire_android_sword_SWModule_SEARCHTYPE_MULTIWORD -2L
-#undef org_crosswire_android_sword_SWModule_SEARCHTYPE_ENTRYATTR
-#define org_crosswire_android_sword_SWModule_SEARCHTYPE_ENTRYATTR -3L
-#undef org_crosswire_android_sword_SWModule_SEARCHTYPE_LUCENE
-#define org_crosswire_android_sword_SWModule_SEARCHTYPE_LUCENE -4L
-/*
- * Class:     org_crosswire_android_sword_SWModule
- * Method:    terminateSearch
- * Signature: ()V
- */
-JNIEXPORT void JNICALL Java_org_crosswire_android_sword_SWModule_terminateSearch
-  (JNIEnv *, jobject);
-
-/*
- * Class:     org_crosswire_android_sword_SWModule
- * Method:    search
- * Signature: (Ljava/lang/String;IJLjava/lang/String;Lorg/crosswire/android/sword/SWModule/SearchProgressReporter;)[Lorg/crosswire/android/sword/SWModule/SearchHit;
- */
-JNIEXPORT jobjectArray JNICALL Java_org_crosswire_android_sword_SWModule_search
-  (JNIEnv *, jobject, jstring, jint, jlong, jstring, jobject);
-
-/*
- * Class:     org_crosswire_android_sword_SWModule
- * Method:    error
- * Signature: ()C
- */
-JNIEXPORT jchar JNICALL Java_org_crosswire_android_sword_SWModule_error
-  (JNIEnv *, jobject);
-
-/*
- * Class:     org_crosswire_android_sword_SWModule
- * Method:    getEntrySize
- * Signature: ()J
- */
-JNIEXPORT jlong JNICALL Java_org_crosswire_android_sword_SWModule_getEntrySize
-  (JNIEnv *, jobject);
-
-/*
- * Class:     org_crosswire_android_sword_SWModule
- * Method:    getEntryAttribute
- * Signature: (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Z)[Ljava/lang/String;
- */
-JNIEXPORT jobjectArray JNICALL Java_org_crosswire_android_sword_SWModule_getEntryAttribute
-  (JNIEnv *, jobject, jstring, jstring, jstring, jboolean);
-
-/*
- * Class:     org_crosswire_android_sword_SWModule
- * Method:    parseKeyList
- * Signature: (Ljava/lang/String;)[Ljava/lang/String;
- */
-JNIEXPORT jobjectArray JNICALL Java_org_crosswire_android_sword_SWModule_parseKeyList
-  (JNIEnv *, jobject, jstring);
-
-/*
- * Class:     org_crosswire_android_sword_SWModule
- * Method:    setKeyText
- * Signature: (Ljava/lang/String;)V
- */
-JNIEXPORT void JNICALL Java_org_crosswire_android_sword_SWModule_setKeyText
-  (JNIEnv *, jobject, jstring);
-
-/*
- * Class:     org_crosswire_android_sword_SWModule
- * Method:    getKeyText
- * Signature: ()Ljava/lang/String;
- */
-JNIEXPORT jstring JNICALL Java_org_crosswire_android_sword_SWModule_getKeyText
-  (JNIEnv *, jobject);
-
-/*
- * Class:     org_crosswire_android_sword_SWModule
- * Method:    hasKeyChildren
- * Signature: ()Z
- */
-JNIEXPORT jboolean JNICALL Java_org_crosswire_android_sword_SWModule_hasKeyChildren
-  (JNIEnv *, jobject);
-
-/*
- * Class:     org_crosswire_android_sword_SWModule
- * Method:    getKeyChildren
- * Signature: ()[Ljava/lang/String;
- */
-JNIEXPORT jobjectArray JNICALL Java_org_crosswire_android_sword_SWModule_getKeyChildren
-  (JNIEnv *, jobject);
-
-/*
- * Class:     org_crosswire_android_sword_SWModule
- * Method:    getKeyParent
- * Signature: ()Ljava/lang/String;
- */
-JNIEXPORT jstring JNICALL Java_org_crosswire_android_sword_SWModule_getKeyParent
-  (JNIEnv *, jobject);
-
-/*
- * Class:     org_crosswire_android_sword_SWModule
- * Method:    previous
- * Signature: ()V
- */
-JNIEXPORT void JNICALL Java_org_crosswire_android_sword_SWModule_previous
-  (JNIEnv *, jobject);
-
-/*
- * Class:     org_crosswire_android_sword_SWModule
- * Method:    next
- * Signature: ()V
- */
-JNIEXPORT void JNICALL Java_org_crosswire_android_sword_SWModule_next
-  (JNIEnv *, jobject);
-
-/*
- * Class:     org_crosswire_android_sword_SWModule
- * Method:    begin
- * Signature: ()V
- */
-JNIEXPORT void JNICALL Java_org_crosswire_android_sword_SWModule_begin
-  (JNIEnv *, jobject);
-
-/*
- * Class:     org_crosswire_android_sword_SWModule
- * Method:    getStripText
- * Signature: ()Ljava/lang/String;
- */
-JNIEXPORT jstring JNICALL Java_org_crosswire_android_sword_SWModule_getStripText
-  (JNIEnv *, jobject);
-
-/*
- * Class:     org_crosswire_android_sword_SWModule
- * Method:    getRenderHeader
- * Signature: ()Ljava/lang/String;
- */
-JNIEXPORT jstring JNICALL Java_org_crosswire_android_sword_SWModule_getRenderHeader
-  (JNIEnv *, jobject);
-
-/*
- * Class:     org_crosswire_android_sword_SWModule
- * Method:    getRenderText
- * Signature: ()Ljava/lang/String;
- */
-JNIEXPORT jstring JNICALL Java_org_crosswire_android_sword_SWModule_getRenderText
-  (JNIEnv *, jobject);
-
-/*
- * Class:     org_crosswire_android_sword_SWModule
- * Method:    getRawEntry
- * Signature: ()Ljava/lang/String;
- */
-JNIEXPORT jstring JNICALL Java_org_crosswire_android_sword_SWModule_getRawEntry
-  (JNIEnv *, jobject);
-
-/*
- * Class:     org_crosswire_android_sword_SWModule
- * Method:    setRawEntry
- * Signature: (Ljava/lang/String;)V
- */
-JNIEXPORT void JNICALL Java_org_crosswire_android_sword_SWModule_setRawEntry
-  (JNIEnv *, jobject, jstring);
-
-/*
- * Class:     org_crosswire_android_sword_SWModule
- * Method:    getConfigEntry
- * Signature: (Ljava/lang/String;)Ljava/lang/String;
- */
-JNIEXPORT jstring JNICALL Java_org_crosswire_android_sword_SWModule_getConfigEntry
-  (JNIEnv *, jobject, jstring);
-
-/*
- * Class:     org_crosswire_android_sword_SWModule
- * Method:    deleteSearchFramework
- * Signature: ()V
- */
-JNIEXPORT void JNICALL Java_org_crosswire_android_sword_SWModule_deleteSearchFramework
-  (JNIEnv *, jobject);
-
-/*
- * Class:     org_crosswire_android_sword_SWModule
- * Method:    hasSearchFramework
- * Signature: ()Z
- */
-JNIEXPORT jboolean JNICALL Java_org_crosswire_android_sword_SWModule_hasSearchFramework
-  (JNIEnv *, jobject);
-
-#ifdef __cplusplus
-}
-#endif
-#endif

Deleted: branches/sword-1-8-x/bindings/java-jni/jni/org_crosswire_android_sword_SWModule_SearchHit.h
===================================================================
--- branches/sword-1-8-x/bindings/java-jni/jni/org_crosswire_android_sword_SWModule_SearchHit.h	2017-11-01 11:33:56 UTC (rev 3514)
+++ branches/sword-1-8-x/bindings/java-jni/jni/org_crosswire_android_sword_SWModule_SearchHit.h	2017-11-01 11:38:09 UTC (rev 3515)
@@ -1,13 +0,0 @@
-/* DO NOT EDIT THIS FILE - it is machine generated */
-#include <jni.h>
-/* Header for class org_crosswire_android_sword_SWModule_SearchHit */
-
-#ifndef _Included_org_crosswire_android_sword_SWModule_SearchHit
-#define _Included_org_crosswire_android_sword_SWModule_SearchHit
-#ifdef __cplusplus
-extern "C" {
-#endif
-#ifdef __cplusplus
-}
-#endif
-#endif

Deleted: branches/sword-1-8-x/bindings/java-jni/jni/org_crosswire_android_sword_SWModule_SearchProgressReporter.h
===================================================================
--- branches/sword-1-8-x/bindings/java-jni/jni/org_crosswire_android_sword_SWModule_SearchProgressReporter.h	2017-11-01 11:33:56 UTC (rev 3514)
+++ branches/sword-1-8-x/bindings/java-jni/jni/org_crosswire_android_sword_SWModule_SearchProgressReporter.h	2017-11-01 11:38:09 UTC (rev 3515)
@@ -1,13 +0,0 @@
-/* DO NOT EDIT THIS FILE - it is machine generated */
-#include <jni.h>
-/* Header for class org_crosswire_android_sword_SWModule_SearchProgressReporter */
-
-#ifndef _Included_org_crosswire_android_sword_SWModule_SearchProgressReporter
-#define _Included_org_crosswire_android_sword_SWModule_SearchProgressReporter
-#ifdef __cplusplus
-extern "C" {
-#endif
-#ifdef __cplusplus
-}
-#endif
-#endif

Modified: branches/sword-1-8-x/bindings/java-jni/jni/swordstub.cpp
===================================================================
--- branches/sword-1-8-x/bindings/java-jni/jni/swordstub.cpp	2017-11-01 11:33:56 UTC (rev 3514)
+++ branches/sword-1-8-x/bindings/java-jni/jni/swordstub.cpp	2017-11-01 11:38:09 UTC (rev 3515)
@@ -38,8 +38,8 @@
 #include <treekeyidx.h>
 #include <installmgr.h>
 #include <remotetrans.h>
+//#include <android/native_activity.h>
 
-#define BIBLESYNC
 
 #ifdef BIBLESYNC
 #include <biblesync.hh>
@@ -63,9 +63,14 @@
 
 #ifdef BIBLESYNC
 BibleSync *bibleSync = 0;
-#endif
+using std::string;
 jobject bibleSyncListener = 0;
 JNIEnv *bibleSyncListenerEnv = 0;
+#endif
+static SWBuf STORAGE_BASE;
+static char *SWORD_PATH = "/sdcard/sword";
+static char *AND_BIBLE_MODULES_PATH = "/sdcard/Android/data/net.bible.android.activity/files";
+//ANativeActivity *_activity;
 
 class InstallStatusReporter : public StatusReporter {
 public:
@@ -154,29 +159,49 @@
 };
 
 
-static void init() {
+static void init(JNIEnv *env) {
 	if (!mgr) {
 		SWLog::setSystemLog(new AndroidLogger());
 		SWLog::getSystemLog()->setLogLevel(SWLog::LOG_DEBUG);
-		SWBuf baseDir  = "/sdcard/sword";
+SWLog::getSystemLog()->logDebug("libsword: init() begin");
+		SWBuf baseDir  = SWORD_PATH;
 		SWBuf confPath = baseDir + "/mods.d/globals.conf";
 		// be sure we have at least some config file already out there
 		if (!FileMgr::existsFile(confPath.c_str())) {
+			SWLog::getSystemLog()->logDebug("libsword: init() sword config not found, attempting to create parent of: %s", confPath.c_str());
 			FileMgr::createParent(confPath.c_str());
 			remove(confPath.c_str());
 
+			SWLog::getSystemLog()->logDebug("libsword: init() saving basic: %s", confPath.c_str());
 			SWConfig config(confPath.c_str());
 			config["Globals"]["HiAndroid"] = "weeee";
-			config.Save();
+			config.save();
 		}
-		mgr = new WebMgr("/sdcard/sword");
+		if (!FileMgr::existsFile(confPath.c_str())) {
+			baseDir = STORAGE_BASE;
+			confPath = baseDir + "/mods.d/globals.conf";
+SWLog::getSystemLog()->logDebug("libsword: init() sword config STILL not found, attempting to create parent of: %s", confPath.c_str());
+			FileMgr::createParent(confPath.c_str());
+			remove(confPath.c_str());
 
+SWLog::getSystemLog()->logDebug("libsword: init() saving basic: %s", confPath.c_str());
+			SWConfig config(confPath.c_str());
+			config["Globals"]["HiAndroid"] = "weeee";
+			config.save();
+		}
+		confPath = STORAGE_BASE + "/extraConfig.conf";
+		bool exists = FileMgr::existsFile(confPath.c_str());
+SWLog::getSystemLog()->logDebug("libsword: extraConfig %s at path: %s", exists?"Exists":"Absent", confPath.c_str());
+
+SWLog::getSystemLog()->logDebug("libsword: init() creating WebMgr using path: %s", baseDir.c_str());
+		mgr = new WebMgr(baseDir, exists?confPath.c_str():0);
+
+SWLog::getSystemLog()->logDebug("libsword: init() augmenting modules from: %s", AND_BIBLE_MODULES_PATH);
 		// for And Bible modules
-		mgr->augmentModules("/sdcard/Android/data/net.bible.android.activity/files", true);
+		mgr->augmentModules(AND_BIBLE_MODULES_PATH, true);
 	}
 }
 
-
 static void initInstall() {
 
 	if (!installStatusReporter) {
@@ -184,17 +209,27 @@
 	}
 	if (!installMgr) {
 SWLog::getSystemLog()->logDebug("initInstall: installMgr is null");
-		SWBuf baseDir  = "/sdcard/sword/InstallMgr";
+		SWBuf baseDir  = SWORD_PATH;
+		baseDir += "/InstallMgr";
 		SWBuf confPath = baseDir + "/InstallMgr.conf";
 		// be sure we have at least some config file already out there
 SWLog::getSystemLog()->logDebug("initInstall: confPath: %s", confPath.c_str());
 		if (!FileMgr::existsFile(confPath.c_str())) {
-SWLog::getSystemLog()->logDebug("initInstall: file doesn't exist: %s", confPath.c_str());
+			SWLog::getSystemLog()->logDebug("initInstall: file doesn't exist: %s", confPath.c_str());
 			FileMgr::createParent(confPath.c_str());
 			SWConfig config(confPath.c_str());
 			config["General"]["PassiveFTP"] = "true";
-			config.Save();
+			config.save();
 		}
+		if (!FileMgr::existsFile(confPath.c_str())) {
+			baseDir = STORAGE_BASE;
+			confPath = baseDir + "/InstallMgr.conf";
+			SWLog::getSystemLog()->logDebug("initInstall: file STILL doesn't exist, attempting to create parent of: %s", confPath.c_str());
+			FileMgr::createParent(confPath.c_str());
+			SWConfig config(confPath.c_str());
+			config["General"]["PassiveFTP"] = "true";
+			config.save();
+		}
 		installMgr = new InstallMgr(baseDir, installStatusReporter);
 		if (disclaimerConfirmed) installMgr->setUserDisclaimerConfirmed(true);
 SWLog::getSystemLog()->logDebug("initInstall: instantiated InstallMgr with baseDir: %s", baseDir.c_str());
@@ -238,6 +273,7 @@
 }
 #endif
 
+
 static void initBibleSync() {
 #ifdef BIBLESYNC
 	if (!bibleSync) {
@@ -255,7 +291,7 @@
 JNIEXPORT jstring JNICALL Java_org_crosswire_android_sword_SWMgr_version
   (JNIEnv *env, jobject me) {
 
-	init();
+	init(env);
 
 	SWVersion v;
 	return env->NewStringUTF(v.currentVersion);
@@ -268,8 +304,16 @@
  * Signature: ()V
  */
 JNIEXPORT void JNICALL Java_org_crosswire_android_sword_SWMgr_reInit
-  (JNIEnv *, jobject) {
+  (JNIEnv *env, jobject me) {
 
+	jclass swmgrClass = env->GetObjectClass(me);
+	jmethodID getStorageBasePath = env->GetMethodID(swmgrClass, "getStorageBasePath", "()Ljava/lang/String;");
+	jstring basePathJS = (jstring)env->CallObjectMethod(me, getStorageBasePath, NULL);
+
+	const char *basePath = (basePathJS?env->GetStringUTFChars(basePathJS, NULL):0);
+	STORAGE_BASE = basePath;
+	SWLog::getSystemLog()->logDebug("setting STORAGE_BASE to: %s", STORAGE_BASE.c_str());
+
 	delete mgr;
 	mgr = 0;
 }
@@ -278,7 +322,7 @@
 JNIEXPORT jstring JNICALL Java_org_crosswire_android_sword_SWMgr_getPrefixPath
   (JNIEnv *env, jobject me) {
 
-	init();
+	init(env);
 
 	return env->NewStringUTF(mgr->prefixPath);
 }
@@ -286,7 +330,7 @@
 JNIEXPORT jstring JNICALL Java_org_crosswire_android_sword_SWMgr_getConfigPath
   (JNIEnv *env, jobject me) {
 
-	init();
+	init(env);
 
 	return env->NewStringUTF(mgr->configPath);
 }
@@ -295,7 +339,7 @@
 JNIEXPORT jobjectArray JNICALL Java_org_crosswire_android_sword_SWMgr_getModInfoList
   (JNIEnv *env, jobject) {
 
-	init();
+	init(env);
 
 	int size = 0;
 	for (sword::ModMap::iterator it = mgr->Modules.begin(); it != mgr->Modules.end(); ++it) {
@@ -352,7 +396,7 @@
 JNIEXPORT jobject JNICALL Java_org_crosswire_android_sword_SWMgr_getModuleByName
   (JNIEnv *env, jobject me, jstring modNameJS) {
 
-	init();
+	init(env);
 
 	jobject retVal = 0;
 
@@ -383,7 +427,7 @@
 JNIEXPORT void JNICALL Java_org_crosswire_android_sword_SWMgr_setGlobalOption
   (JNIEnv *env, jobject me, jstring optionJS, jstring valueJS) {
 
-	init();
+	init(env);
 
      const char *option = env->GetStringUTFChars(optionJS, NULL);
      const char *value  = env->GetStringUTFChars(valueJS, NULL);
@@ -403,7 +447,7 @@
 JNIEXPORT jstring JNICALL Java_org_crosswire_android_sword_SWMgr_getGlobalOption
   (JNIEnv *env, jobject me, jstring optionJS) {
 
-	init();
+	init(env);
 
      const char *option = env->GetStringUTFChars(optionJS, NULL);
 
@@ -423,7 +467,7 @@
 JNIEXPORT jstring JNICALL Java_org_crosswire_android_sword_SWMgr_getGlobalOptionTip
   (JNIEnv *env, jobject me, jstring optionJS) {
 
-	init();
+	init(env);
 
      const char *option = env->GetStringUTFChars(optionJS, NULL);
 
@@ -443,7 +487,7 @@
 JNIEXPORT jstring JNICALL Java_org_crosswire_android_sword_SWMgr_filterText
   (JNIEnv *env, jobject me, jstring filterNameJS, jstring textJS) {
 
-	init();
+	init(env);
 
      const char *filterName = env->GetStringUTFChars(filterNameJS, NULL);
      const char *text  = env->GetStringUTFChars(textJS, NULL);
@@ -466,9 +510,9 @@
  * Signature: ()[Ljava/lang/String;
  */
 JNIEXPORT jobjectArray JNICALL Java_org_crosswire_android_sword_SWMgr_getGlobalOptions
-  (JNIEnv *env, jobject me) {
+		(JNIEnv *env, jobject me) {
 
-	init();
+	init(env);
 
 	sword::StringList options = mgr->getGlobalOptions();
 	int count = 0;
@@ -490,13 +534,233 @@
 
 /*
  * Class:     org_crosswire_android_sword_SWMgr
+ * Method:    getExtraConfigSections
+ * Signature: ()[Ljava/lang/String;
+ */
+JNIEXPORT jobjectArray JNICALL Java_org_crosswire_android_sword_SWMgr_getExtraConfigSections
+		(JNIEnv *env, jobject me) {
+
+	init(env);
+
+	SWBuf baseDir = STORAGE_BASE;
+	SWBuf confPath = baseDir + "/extraConfig.conf";
+	int count = 0;
+	bool exists = FileMgr::existsFile(confPath.c_str());
+	jclass clazzString = env->FindClass("java/lang/String");
+	jobjectArray ret;
+	SWLog::getSystemLog()->logDebug("libsword: extraConfig %s at path: %s", exists?"Exists":"Absent", confPath.c_str());
+	if (exists) {
+		SWConfig config(confPath.c_str());
+		SectionMap::const_iterator sit;
+		for (sit = config.getSections().begin(); sit != config.getSections().end(); ++sit) {
+			count++;
+		}
+		SWLog::getSystemLog()->logDebug("libsword: %d sections found in extraConfig", count);
+		ret = (jobjectArray) env->NewObjectArray(count, clazzString, NULL);
+		count = 0;
+		for (sit = config.getSections().begin(); sit != config.getSections().end(); ++sit) {
+			env->SetObjectArrayElement(ret, count++, env->NewStringUTF(assureValidUTF8(sit->first.c_str())));
+		}
+	}
+	else {
+		ret = (jobjectArray) env->NewObjectArray(0, clazzString, NULL);
+	}
+
+	return ret;
+}
+
+
+/*
+ * Class:     org_crosswire_android_sword_SWMgr
+ * Method:    getExtraConfigKeys
+ * Signature: (Ljava/lang/String;)[Ljava/lang/String;
+ */
+JNIEXPORT jobjectArray JNICALL Java_org_crosswire_android_sword_SWMgr_getExtraConfigKeys
+		(JNIEnv *env, jobject me, jstring section) {
+
+	init(env);
+
+	const char *s = env->GetStringUTFChars(section, NULL);
+
+	SWBuf mySection = s;
+
+	env->ReleaseStringUTFChars(section, s);
+
+	SWBuf baseDir = STORAGE_BASE;
+	SWBuf confPath = baseDir + "/extraConfig.conf";
+	int count = 0;
+	bool exists = FileMgr::existsFile(confPath.c_str());
+	jclass clazzString = env->FindClass("java/lang/String");
+	jobjectArray ret;
+	if (exists) {
+		SWConfig config(confPath.c_str());
+		SectionMap::const_iterator sit = config.getSections().find(mySection.c_str());
+		if (sit != config.getSections().end()) {
+			ConfigEntMap::const_iterator it;
+			for (it = sit->second.begin(); it != sit->second.end(); ++it) {
+				count++;
+			}
+			ret = (jobjectArray) env->NewObjectArray(count, clazzString, NULL);
+			count = 0;
+			for (it = sit->second.begin(); it != sit->second.end(); ++it) {
+				env->SetObjectArrayElement(ret, count++,
+				                           env->NewStringUTF(assureValidUTF8(it->first.c_str())));
+			}
+		}
+		else {
+			ret = (jobjectArray) env->NewObjectArray(0, clazzString, NULL);
+		}
+	}
+	else {
+		ret = (jobjectArray) env->NewObjectArray(0, clazzString, NULL);
+	}
+
+	return ret;
+}
+
+
+/*
+ * Class:     org_crosswire_android_sword_SWMgr
+ * Method:    getExtraConfigValue
+ * Signature: (Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
+ */
+JNIEXPORT jstring JNICALL Java_org_crosswire_android_sword_SWMgr_getExtraConfigValue
+		(JNIEnv *env, jobject me, jstring section, jstring key) {
+
+	init(env);
+
+	const char *s = env->GetStringUTFChars(section, NULL);
+
+	SWBuf mySection = s;
+
+	env->ReleaseStringUTFChars(section, s);
+
+	const char *k = env->GetStringUTFChars(key, NULL);
+
+	SWBuf myKey = k;
+
+	env->ReleaseStringUTFChars(key, k);
+
+	jstring ret = 0;
+
+	SWBuf baseDir = STORAGE_BASE;
+	SWBuf confPath = baseDir + "/extraConfig.conf";
+	bool exists = FileMgr::existsFile(confPath.c_str());
+	if (exists) {
+		SWConfig config(confPath.c_str());
+		SectionMap::const_iterator sit = config.getSections().find(mySection.c_str());
+		if (sit != config.getSections().end()) {
+			ConfigEntMap::const_iterator it = sit->second.find(myKey.c_str());
+			if (it != sit->second.end()) {
+				ret = env->NewStringUTF(assureValidUTF8(it->second.c_str()));
+			}
+		}
+	}
+
+	return ret;
+}
+
+
+/*
+ * Class:     org_crosswire_android_sword_SWMgr
+ * Method:    setExtraConfigValue
+ * Signature: (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+ */
+JNIEXPORT void JNICALL Java_org_crosswire_android_sword_SWMgr_setExtraConfigValue
+		(JNIEnv *env, jobject me, jstring section, jstring key, jstring value) {
+
+	init(env);
+
+	const char *s = env->GetStringUTFChars(section, NULL);
+
+	SWBuf mySection = s;
+
+	env->ReleaseStringUTFChars(section, s);
+
+	const char *k = env->GetStringUTFChars(key, NULL);
+
+	SWBuf myKey = k;
+
+	env->ReleaseStringUTFChars(key, k);
+
+	const char *v = env->GetStringUTFChars(value, NULL);
+
+	SWBuf myValue = v;
+
+	env->ReleaseStringUTFChars(value, v);
+
+	SWBuf baseDir = STORAGE_BASE;
+	SWBuf confPath = baseDir + "/extraConfig.conf";
+	SWConfig config(confPath.c_str());
+	config[mySection][myKey] = myValue;
+	config.save();
+
+	Java_org_crosswire_android_sword_SWMgr_reInit(env, me);
+
+}
+
+
+/*
+ * Class:     org_crosswire_android_sword_SWMgr
+ * Method:    addExtraConfig
+ * Signature: (Ljava/lang/String;)[Ljava/lang/String;
+ */
+JNIEXPORT jobjectArray JNICALL Java_org_crosswire_android_sword_SWMgr_addExtraConfig
+		(JNIEnv *env, jobject me, jstring blob) {
+
+	init(env);
+
+	const char *b = env->GetStringUTFChars(blob, NULL);
+
+	SWBuf myBlob = b;
+
+	env->ReleaseStringUTFChars(blob, b);
+
+	jobjectArray ret;
+
+	int count = 0;
+	jclass clazzString = env->FindClass("java/lang/String");
+
+	SWBuf baseDir = STORAGE_BASE;
+	SWBuf tmpConfPath = baseDir + "/tmpConfig.conf";
+	FileMgr::removeFile(tmpConfPath.c_str());
+	FileDesc *fd = FileMgr::getSystemFileMgr()->open(tmpConfPath.c_str(), FileMgr::CREAT|FileMgr::WRONLY, FileMgr::IREAD|FileMgr::IWRITE);
+	fd->getFd();
+	fd->write(myBlob.c_str(), myBlob.size());
+	FileMgr::getSystemFileMgr()->close(fd);
+
+	SWConfig newConfig(tmpConfPath.c_str());
+	FileMgr::removeFile(tmpConfPath.c_str());
+	SectionMap::const_iterator sit;
+	for (sit = newConfig.getSections().begin(); sit != newConfig.getSections().end(); ++sit) {
+		count++;
+	}
+	ret = (jobjectArray) env->NewObjectArray(count, clazzString, NULL);
+	count = 0;
+	for (sit = newConfig.getSections().begin(); sit != newConfig.getSections().end(); ++sit) {
+		env->SetObjectArrayElement(ret, count++, env->NewStringUTF(assureValidUTF8(sit->first.c_str())));
+	}
+
+	SWBuf confPath = baseDir + "/extraConfig.conf";
+	SWConfig config(confPath.c_str());
+	config.augment(newConfig);
+	config.save();
+
+	Java_org_crosswire_android_sword_SWMgr_reInit(env, me);
+
+	return ret;
+}
+
+
+/*
+ * Class:     org_crosswire_android_sword_SWMgr
  * Method:    getGlobalOptionValues
  * Signature: (Ljava/lang/String;)[Ljava/lang/String;
  */
 JNIEXPORT jobjectArray JNICALL Java_org_crosswire_android_sword_SWMgr_getGlobalOptionValues
   (JNIEnv *env, jobject me, jstring optionJS) {
 
-	init();
+	init(env);
 
      const char *option = env->GetStringUTFChars(optionJS, NULL);
 
@@ -528,7 +792,7 @@
 JNIEXPORT void JNICALL Java_org_crosswire_android_sword_SWMgr_setCipherKey
   (JNIEnv *env, jobject me , jstring modNameJS, jstring keyJS) {
 
-	init();
+	init(env);
 
      const char *modName = env->GetStringUTFChars(modNameJS, NULL);
      const char *key     = env->GetStringUTFChars(keyJS, NULL);
@@ -548,7 +812,7 @@
 JNIEXPORT void JNICALL Java_org_crosswire_android_sword_SWMgr_setJavascript
   (JNIEnv *env, jobject me, jboolean val) {
 
-	init();
+	init(env);
 
 	mgr->setJavascript(val == JNI_TRUE);
 }
@@ -562,7 +826,7 @@
 JNIEXPORT jobjectArray JNICALL Java_org_crosswire_android_sword_SWMgr_getAvailableLocales
   (JNIEnv *env, jobject me) {
 
-	init();
+	init(env);
 
 	sword::StringList localeNames = LocaleMgr::getSystemLocaleMgr()->getAvailableLocales();
 	int count = 0;
@@ -589,7 +853,7 @@
 JNIEXPORT void JNICALL Java_org_crosswire_android_sword_SWMgr_setDefaultLocale
   (JNIEnv *env, jobject me, jstring localeNameJS) {
 
-	init();
+	init(env);
 
      const char *localeName = env->GetStringUTFChars(localeNameJS, NULL);
 
@@ -605,7 +869,7 @@
 
 SWModule *getModule(JNIEnv *env, jobject me) {
 
-	init(); 
+	init(env);
 
 	SWModule *module = 0;
 	jclass clazzSWModule = env->FindClass("org/crosswire/android/sword/SWModule");
@@ -637,7 +901,7 @@
 JNIEXPORT void JNICALL Java_org_crosswire_android_sword_SWModule_setKeyText
   (JNIEnv *env, jobject me, jstring keyTextJS) {
 
-	init();
+	init(env);
 
 	SWModule *module = getModule(env, me);
 
@@ -675,7 +939,7 @@
 JNIEXPORT jstring JNICALL Java_org_crosswire_android_sword_SWModule_getKeyText
   (JNIEnv *env, jobject me) {
 
-	init();
+	init(env);
 
 	SWModule *module = getModule(env, me);
 
@@ -695,7 +959,7 @@
 JNIEXPORT jstring JNICALL Java_org_crosswire_android_sword_SWModule_getRenderText
   (JNIEnv *env, jobject me) {
 
-	init();
+	init(env);
 
 	SWModule *module = getModule(env, me);
 
@@ -715,7 +979,7 @@
 JNIEXPORT jstring JNICALL Java_org_crosswire_android_sword_SWModule_getRenderHeader
   (JNIEnv *env, jobject me) {
 
-	init();
+	init(env);
 
 	SWModule *module = getModule(env, me);
 
@@ -735,7 +999,7 @@
 JNIEXPORT void JNICALL Java_org_crosswire_android_sword_SWModule_terminateSearch
   (JNIEnv *env, jobject me) {
 
-	init(); 
+	init(env);
 
 	SWModule *module = getModule(env, me);
 
@@ -753,7 +1017,7 @@
 JNIEXPORT jchar JNICALL Java_org_crosswire_android_sword_SWModule_error
   (JNIEnv *env, jobject me) {
 
-	init(); 
+	init(env);
 
 	SWModule *module = getModule(env, me);
 	
@@ -770,7 +1034,7 @@
 JNIEXPORT jlong JNICALL Java_org_crosswire_android_sword_SWModule_getEntrySize
   (JNIEnv *env, jobject me) {
 
-	init(); 
+	init(env);
 
 	SWModule *module = getModule(env, me);
 
@@ -786,7 +1050,7 @@
 JNIEXPORT jobjectArray JNICALL Java_org_crosswire_android_sword_SWModule_getEntryAttribute
   (JNIEnv *env, jobject me, jstring level1JS, jstring level2JS, jstring level3JS, jboolean filteredJS) {
 
-	init(); 
+	init(env);
 
 	const char *level1 = env->GetStringUTFChars(level1JS, NULL);
 	const char *level2 = env->GetStringUTFChars(level2JS, NULL);
@@ -895,7 +1159,7 @@
 JNIEXPORT jobjectArray JNICALL Java_org_crosswire_android_sword_SWModule_parseKeyList
   (JNIEnv *env, jobject me, jstring keyListTextJS) {
 
-	init(); 
+	init(env);
 
 	const char *keyListText = env->GetStringUTFChars(keyListTextJS, NULL);
 
@@ -940,7 +1204,7 @@
 JNIEXPORT jboolean JNICALL Java_org_crosswire_android_sword_SWModule_hasKeyChildren
   (JNIEnv *env, jobject me) {
 
-	init(); 
+	init(env);
 
 
 	SWModule *module = getModule(env, me);
@@ -965,7 +1229,7 @@
 JNIEXPORT jobjectArray JNICALL Java_org_crosswire_android_sword_SWModule_getKeyChildren
   (JNIEnv *env, jobject me) {
 
-	init(); 
+	init(env);
 
 
 	jclass clazzString = env->FindClass("java/lang/String");
@@ -1024,8 +1288,8 @@
 				}
 			}
 		}
-		return ret;
 	}
+	return ret;
 }
 
 
@@ -1037,7 +1301,7 @@
 JNIEXPORT jstring JNICALL Java_org_crosswire_android_sword_SWModule_getKeyParent
   (JNIEnv *env, jobject me) {
 
-	init(); 
+	init(env);
 
 
 	SWBuf retVal = "";
@@ -1067,7 +1331,7 @@
 JNIEXPORT void JNICALL Java_org_crosswire_android_sword_SWModule_previous
   (JNIEnv *env, jobject me) {
 
-	init(); 
+	init(env);
 
 
 	SWModule *module = getModule(env, me);
@@ -1086,7 +1350,7 @@
 JNIEXPORT void JNICALL Java_org_crosswire_android_sword_SWModule_next
   (JNIEnv *env, jobject me) {
 
-	init(); 
+	init(env);
 
 
 	SWModule *module = getModule(env, me);
@@ -1105,7 +1369,7 @@
 JNIEXPORT void JNICALL Java_org_crosswire_android_sword_SWModule_begin
   (JNIEnv *env, jobject me) {
 
-	init(); 
+	init(env);
 
 
 	SWModule *module = getModule(env, me);
@@ -1124,7 +1388,7 @@
 JNIEXPORT jstring JNICALL Java_org_crosswire_android_sword_SWModule_getStripText
   (JNIEnv *env, jobject me) {
 
-	init(); 
+	init(env);
 
 
 	SWBuf retVal = "";
@@ -1147,7 +1411,7 @@
 JNIEXPORT jstring JNICALL Java_org_crosswire_android_sword_SWModule_getRawEntry
   (JNIEnv *env, jobject me) {
 
-	init(); 
+	init(env);
 
 
 	SWBuf retVal = "";
@@ -1170,7 +1434,7 @@
 JNIEXPORT void JNICALL Java_org_crosswire_android_sword_SWModule_setRawEntry
   (JNIEnv *env, jobject me, jstring newEntryTextJS) {
 
-	init(); 
+	init(env);
 
 
 	const char *newEntryText = env->GetStringUTFChars(newEntryTextJS, NULL);
@@ -1212,7 +1476,7 @@
 JNIEXPORT jstring JNICALL Java_org_crosswire_android_sword_SWModule_getConfigEntry
   (JNIEnv *env, jobject me, jstring configKeyJS) {
 
-	init(); 
+	init(env);
 
 
 	jstring retVal = 0;
@@ -1242,7 +1506,7 @@
 JNIEXPORT void JNICALL Java_org_crosswire_android_sword_SWModule_deleteSearchFramework
   (JNIEnv *env, jobject me) {
 
-	init(); 
+	init(env);
 
 
 	SWModule *module = getModule(env, me);
@@ -1261,7 +1525,7 @@
 JNIEXPORT jboolean JNICALL Java_org_crosswire_android_sword_SWModule_hasSearchFramework
   (JNIEnv *env, jobject me) {
 
-	init(); 
+	init(env);
 
 
 	SWModule *module = getModule(env, me);
@@ -1304,7 +1568,7 @@
 JNIEXPORT jobjectArray JNICALL Java_org_crosswire_android_sword_SWModule_search
   (JNIEnv *env, jobject me, jstring expressionJS, jint srchType, jlong flags, jstring scopeJS, jobject progressReporter) {
 
-	init(); 
+	init(env);
 
 	const int MAX_RETURN_COUNT = 999999;
 
@@ -1417,7 +1681,7 @@
 JNIEXPORT jint JNICALL Java_org_crosswire_android_sword_InstallMgr_uninstallModule
   (JNIEnv *env, jobject me, jstring modNameJS) {
 
-	init();
+	init(env);
 	initInstall();
 
 	const char *modName = env->GetStringUTFChars(modNameJS, NULL);
@@ -1498,7 +1762,7 @@
   (JNIEnv *env, jobject me, jstring sourceNameJS) {
 
 SWLog::getSystemLog()->logDebug("getRemoteModInfoList\n");
-	init();
+	init(env);
 	initInstall();
 
 	const char *sourceName = env->GetStringUTFChars(sourceNameJS, NULL);
@@ -1571,7 +1835,7 @@
 JNIEXPORT jint JNICALL Java_org_crosswire_android_sword_InstallMgr_remoteInstallModule
   (JNIEnv *env, jobject me, jstring sourceNameJS, jstring modNameJS, jobject progressReporter) {
 
-	init();
+	init(env);
 	initInstall();
 
 	installStatusReporter->init(env, progressReporter);
@@ -1704,12 +1968,13 @@
  */
 JNIEXPORT void JNICALL Java_org_crosswire_android_sword_SWMgr_registerBibleSyncListener
   (JNIEnv *env, jobject me, jobject bibleSyncListener) {
+
+#ifdef BIBLESYNC
 SWLog::getSystemLog()->logDebug("registerBibleSyncListener");
 	::bibleSyncListener = bibleSyncListener;
 	::bibleSyncListenerEnv = env;
 SWLog::getSystemLog()->logDebug("registerBibleSyncListener - calling init");
 	initBibleSync();
-#ifdef BIBLESYNC
 SWLog::getSystemLog()->logDebug("registerBibleSyncListener - starting while listener");
 	while(::bibleSyncListener) {
 SWLog::getSystemLog()->logDebug("bibleSyncListener - while loop iteration");

Modified: branches/sword-1-8-x/bindings/java-jni/jni/webmgr.hpp
===================================================================
--- branches/sword-1-8-x/bindings/java-jni/jni/webmgr.hpp	2017-11-01 11:33:56 UTC (rev 3514)
+++ branches/sword-1-8-x/bindings/java-jni/jni/webmgr.hpp	2017-11-01 11:38:09 UTC (rev 3515)
@@ -41,15 +41,18 @@
 	SWModule *defaultHebLex;
 	SWModule *defaultGreekParse;
 	SWModule *defaultHebParse;
+	char *extraConf;
 
 public:
 //	WebMgr(SWConfig *sysConf) : SWMgr(0, sysConf, false, new MarkupFilterMgr(FMT_WEBIF)) {
-	WebMgr(const char *path) : SWMgr(path, false, new MarkupFilterMgr(FMT_WEBIF)) {
+	WebMgr(const char *path, const char *extraConfPath) : extraConf(0), SWMgr(path, false, new MarkupFilterMgr(FMT_XHTML)) {
 		defaultGreekLex   = 0;
 		defaultHebLex     = 0;
 		defaultGreekParse = 0;
 		defaultHebParse   = 0;
 
+		stdstr(&extraConf, extraConfPath);
+
 		osisWordJS = new OSISWordJS();
 		thmlWordJS = new ThMLWordJS();
 		gbfWordJS = new GBFWordJS();
@@ -67,9 +70,21 @@
 		delete osisWordJS;
 		delete thmlWordJS;
 		delete gbfWordJS;
+		delete extraConf;
 	}
 
+	void createAllModules(bool multiMod) {
 
+		if (extraConf) {
+			bool exists = FileMgr::existsFile(extraConf);
+			if (exists) {
+				SWConfig addConfig(extraConf);
+				this->config->augment(addConfig);
+			}
+		}
+		SWMgr::createAllModules(multiMod);
+	}
+
 	void AddGlobalOptions(SWModule *module, ConfigEntMap &section, ConfigEntMap::iterator start, ConfigEntMap::iterator end) {
 
 		// ThML word stuff needs to process before strongs strip

Modified: branches/sword-1-8-x/bindings/java-jni/src/org/crosswire/android/sword/SWMgr.java
===================================================================
--- branches/sword-1-8-x/bindings/java-jni/src/org/crosswire/android/sword/SWMgr.java	2017-11-01 11:33:56 UTC (rev 3514)
+++ branches/sword-1-8-x/bindings/java-jni/src/org/crosswire/android/sword/SWMgr.java	2017-11-01 11:38:09 UTC (rev 3515)
@@ -37,6 +37,12 @@
 		public String delta;
 	}
 
+	public SWMgr() {
+		reInit();
+	}
+	public SWMgr(boolean init) {
+		if (init) reInit();
+	}
 
 	public native String version();
 	public native void reInit();
@@ -55,6 +61,31 @@
 	public native void        setJavascript(boolean val);
 	public native String[]    getAvailableLocales();
 	public native void        setDefaultLocale(String name);
+
+	/**
+	 * add a conf snippet to extraConfig.  This is useful for adding a config section
+	 * sent from a module unlock key app.
+	 * @param blob
+	 * @return an array of section names which were contained in the blob
+	 */
+	public native String[]    addExtraConfig(String blob);
+	public native void        setExtraConfigValue(String section, String key, String value);
+	public native String[]    getExtraConfigSections();
+	public native String[]    getExtraConfigKeys(String section);
+	public native String      getExtraConfigValue(String section, String key);
+
+	public static interface BibleSyncListener {
+		public void messageReceived(String osisRef);
+	}
+	public native void        sendBibleSyncMessage(String osisRef);
+	public native void        registerBibleSyncListener(BibleSyncListener listener);
+	public String             getStorageBasePath() {
+		return ".";
+/*
+		Context context = app.getApplicationContext();
+		return context.getFilesDir().getAbsolutePath();
+*/
+	}
 }
 
 

Modified: branches/sword-1-8-x/bindings/swig/deprecations.i
===================================================================
--- branches/sword-1-8-x/bindings/swig/deprecations.i	2017-11-01 11:33:56 UTC (rev 3514)
+++ branches/sword-1-8-x/bindings/swig/deprecations.i	2017-11-01 11:38:09 UTC (rev 3515)
@@ -10,10 +10,11 @@
 %ignore sword::VerseTreeKey::operator const char *;
 %ignore sword::XMLTag::operator const char *;
 
-%ignore sword::StatusReporter::statusUpdate;
 
 %ignore sword::SWDisplay::Display(SWModule&);
 
+%ignore sword::StatusReporter::statusUpdate(double ,double);
+
 %ignore sword::SWKey::Error();
 %ignore sword::SWKey::Persist() const;
 %ignore sword::SWKey::Persist(signed char);
@@ -60,3 +61,20 @@
 %ignore sword::VerseKey::TestamentIndex() const;
 %ignore sword::VerseKey::UpperBound;
 %ignore sword::VerseKey::Verse;
+
+%ignore sword::SWMgr::CreateMods(bool);
+%ignore sword::SWMgr::DeleteMods();
+%ignore sword::SWMgr::AddGlobalOptions(SWModule *, ConfigEntMap &, ConfigEntMap::iterator, ConfigEntMap::iterator);
+%ignore sword::SWMgr::AddLocalOptions(SWModule *, ConfigEntMap &, ConfigEntMap::iterator, ConfigEntMap::iterator);
+%ignore sword::SWMgr::AddEncodingFilters(SWModule *, ConfigEntMap &);
+%ignore sword::SWMgr::AddRenderFilters(SWModule *, ConfigEntMap &);
+%ignore sword::SWMgr::AddStripFilters(SWModule *, ConfigEntMap &);
+%ignore sword::SWMgr::AddStripFilters(SWModule *, ConfigEntMap &, ConfigEntMap::iterator, ConfigEntMap::iterator);
+%ignore sword::SWMgr::AddRawFilters(SWModule *, ConfigEntMap &);
+%ignore sword::SWMgr::getHomeDir();
+%ignore sword::SWMgr::Load();
+
+%ignore sword::SWConfig::Sections;
+%ignore sword::SWConfig::filename;
+%ignore sword::SWConfig::Load();
+%ignore sword::SWConfig::Save();

Modified: branches/sword-1-8-x/bindings/swig/swconfig.i
===================================================================
--- branches/sword-1-8-x/bindings/swig/swconfig.i	2017-11-01 11:33:56 UTC (rev 3514)
+++ branches/sword-1-8-x/bindings/swig/swconfig.i	2017-11-01 11:38:09 UTC (rev 3515)
@@ -5,21 +5,21 @@
 %ignore sword::SWConfig::operator[];
 %ignore sword::SWConfig::operator+=;
 %ignore sword::SWConfig::sections;
-%ignore sword::SWConfig::Sections;
+%ignore sword::SWConfig::getSections();
 
 %include "swconfig.h"
 
 
 %extend sword::SWConfig {
   void set(const char* group, const char* entry, const char* value) {
-	self->Sections[group][entry] = value;
+	self->getSection(group)[entry] = value;
   };
   const char* get(const char* group, const char* entry) {
-	return self->Sections[group][entry].c_str();
+	return self->getSection(group)[entry].c_str();
   };
   PySectionMap /*std::map < sword::SWBuf, std::multimap <sword::SWBuf, sword::SWBuf> > */
   *getSections() {
-    return (PySectionMap* /*std::map < sword::SWBuf, std::multimap < sword::SWBuf, sword::SWBuf > > * */) &self->Sections;
+    return (PySectionMap* /*std::map < sword::SWBuf, std::multimap < sword::SWBuf, sword::SWBuf > > * */) &self->getSections();
   }
 }
 

Modified: branches/sword-1-8-x/cmake/FindCLucene.cmake
===================================================================
--- branches/sword-1-8-x/cmake/FindCLucene.cmake	2017-11-01 11:33:56 UTC (rev 3514)
+++ branches/sword-1-8-x/cmake/FindCLucene.cmake	2017-11-01 11:38:09 UTC (rev 3515)
@@ -46,6 +46,7 @@
 	/opt/local/lib${LIB_SUFFIX}
 	/usr/lib${LIB_SUFFIX}
 	/usr/lib64
+	${LIB_INSTALL_DIR}
 	/sw/lib${LIB_SUFFIX}
 	/usr/pkg/lib${LIB_SUFFIX}
 	${WIN_CLUCENE_SEARCH_PATH}

Modified: branches/sword-1-8-x/configure.ac
===================================================================
--- branches/sword-1-8-x/configure.ac	2017-11-01 11:33:56 UTC (rev 3514)
+++ branches/sword-1-8-x/configure.ac	2017-11-01 11:38:09 UTC (rev 3515)
@@ -5,7 +5,7 @@
 # Version change: Change line 8 only !
 # Change it immediately after a release
 
-AC_INIT(sword, 1.7.903, sword-bugs at crosswire.org, sword, http://crosswire.org/sword)
+AC_INIT(sword, 1.7.904, sword-bugs at crosswire.org, sword, http://crosswire.org/sword)
 AC_CONFIG_SRCDIR(sword.bmp)
 AC_PREREQ(2.52)
 AC_REVISION($Revision: 1.45 $)
@@ -115,8 +115,8 @@
     AM_CXXFLAGS="-O0 -Wall -Werror -Woverloaded-virtual"
   fi
 else
-  AM_CFLAGS="-O3"
-  AM_CXXFLAGS="-O3"
+  AM_CFLAGS="-Ofast"
+  AM_CXXFLAGS="-Ofast"
 fi
 
 AM_CFLAGS="$AM_CFLAGS -fPIC"

Modified: branches/sword-1-8-x/examples/cmdline/search.cpp
===================================================================
--- branches/sword-1-8-x/examples/cmdline/search.cpp	2017-11-01 11:33:56 UTC (rev 3514)
+++ branches/sword-1-8-x/examples/cmdline/search.cpp	2017-11-01 11:38:09 UTC (rev 3515)
@@ -46,7 +46,7 @@
 	 *			-5  - multilemma window; set 'flags' param to window size (NOT DONE)
 	 */
 
-char SEARCH_TYPE=0;
+char SEARCH_TYPE=-2;
 int flags = 0
 // for case insensitivity
 | REG_ICASE

Modified: branches/sword-1-8-x/include/canon_calvin.h
===================================================================
--- branches/sword-1-8-x/include/canon_calvin.h	2017-11-01 11:33:56 UTC (rev 3514)
+++ branches/sword-1-8-x/include/canon_calvin.h	2017-11-01 11:38:09 UTC (rev 3515)
@@ -3,7 +3,7 @@
  *  canon_calvin.h -	Versification data for French Bibles de Genève
  *                      (Bibles de Genève, Épée, Martin, Ostervald)
  *
- * $Id: canon_calvin.h 2015-08-22 10:53:22 domcox $
+ *  $Id$
  *
  * Copyright 1998-2013 CrossWire Bible Society (http://www.crosswire.org)
  *	CrossWire Bible Society
@@ -289,6 +289,107 @@
   27, 21
 };
 
+unsigned char mappings_calvin[] = {
+    0,
+    4,   13,  1,   0,   12,  16,  0,
+    4,   13,  2,   0,   13,  1,   0,
+    4,   30,  1,   0,   29,  40,  0,
+    4,   30,  2,   0,   30,  1,   0,
+    9,   20,  43,  0,   20,  42,  0,
+    9,   24,  1,   0,   23,  29,  0,
+    9,   24,  2,   0,   24,  1,   0,
+    11,  22,  44,  0,   22,  43,  0,
+    18,  39,  1,   0,   38,  39,  0,
+    18,  39,  4,   0,   39,  1,   0,
+    18,  39,  34,  0,   40,  1,   0,
+    18,  40,  1,   0,   40,  6,   0,
+    18,  40,  20,  0,   41,  1,   0,
+    18,  41,  1,   0,   41,  10,  0,
+    19,  3,   2,   0,   3,   1,   0,
+    19,  4,   2,   0,   4,   1,   0,
+    19,  5,   2,   0,   5,   1,   0,
+    19,  6,   2,   0,   6,   1,   0,
+    19,  7,   2,   0,   7,   1,   0,
+    19,  8,   2,   0,   8,   1,   0,
+    19,  9,   2,   0,   9,   1,   0,
+    19,  12,  2,   0,   12,  1,   0,
+    19,  18,  2,   0,   18,  1,   0,
+    19,  19,  2,   0,   19,  1,   0,
+    19,  20,  2,   0,   20,  1,   0,
+    19,  21,  2,   0,   21,  1,   0,
+    19,  22,  2,   0,   22,  1,   0,
+    19,  30,  2,   0,   30,  1,   0,
+    19,  31,  2,   0,   31,  1,   0,
+    19,  34,  2,   0,   34,  1,   0,
+    19,  36,  2,   0,   36,  1,   0,
+    19,  38,  2,   0,   38,  1,   0,
+    19,  39,  2,   0,   39,  1,   0,
+    19,  40,  2,   0,   40,  1,   0,
+    19,  41,  2,   0,   41,  1,   0,
+    19,  42,  2,   0,   42,  1,   0,
+    19,  44,  2,   0,   44,  1,   0,
+    19,  45,  2,   0,   45,  1,   0,
+    19,  46,  2,   0,   46,  1,   0,
+    19,  47,  2,   0,   47,  1,   0,
+    19,  48,  2,   0,   48,  1,   0,
+    19,  49,  2,   0,   49,  1,   0,
+    19,  51,  2,   0,   51,  1,   0,
+    19,  51,  3,   0,   51,  1,   0,
+    19,  52,  2,   0,   52,  1,   0,
+    19,  52,  3,   0,   52,  1,   0,
+    19,  53,  2,   0,   53,  1,   0,
+    19,  54,  3,   0,   54,  1,   0,
+    19,  55,  2,   0,   55,  1,   0,
+    19,  56,  2,   0,   56,  1,   0,
+    19,  57,  2,   0,   57,  1,   0,
+    19,  58,  2,   0,   58,  1,   0,
+    19,  59,  2,   0,   59,  1,   0,
+    19,  60,  2,   0,   60,  1,   0,
+    19,  60,  3,   0,   60,  1,   0,
+    19,  61,  2,   0,   61,  1,   0,
+    19,  62,  2,   0,   62,  1,   0,
+    19,  63,  2,   0,   63,  1,   0,
+    19,  64,  2,   0,   64,  1,   0,
+    19,  65,  2,   0,   65,  1,   0,
+    19,  67,  2,   0,   67,  1,   0,
+    19,  68,  2,   0,   68,  1,   0,
+    19,  69,  2,   0,   69,  1,   0,
+    19,  70,  2,   0,   70,  1,   0,
+    19,  75,  2,   0,   75,  1,   0,
+    19,  76,  2,   0,   76,  1,   0,
+    19,  77,  2,   0,   77,  1,   0,
+    19,  80,  2,   0,   80,  1,   0,
+    19,  81,  2,   0,   81,  1,   0,
+    19,  83,  2,   0,   83,  1,   0,
+    19,  84,  2,   0,   84,  1,   0,
+    19,  85,  2,   0,   85,  1,   0,
+    19,  88,  2,   0,   88,  1,   0,
+    19,  89,  2,   0,   89,  1,   0,
+    19,  92,  2,   0,   92,  1,   0,
+    19,  102, 2,   0,   102, 1,   0,
+    19,  108, 2,   0,   108, 1,   0,
+    19,  140, 2,   0,   140, 1,   0,
+    19,  142, 2,   0,   142, 1,   0,
+    21,  12,  1,   0,   11,  9,   0,
+    21,  12,  3,   0,   12,  1,   0,
+    23,  8,   23,  0,   9,   1,   0,
+    23,  9,   1,   0,   9,   2,   0,
+    26,  21,  1,   0,   20,  45,  0,
+    26,  21,  6,   0,   21,  1,   0,
+    28,  12,  1,   0,   11,  12,  0,
+    28,  12,  2,   0,   12,  1,   0,
+    32,  2,   1,   0,   1,   17,  0,
+    32,  2,   2,   0,   2,   1,   0,
+    41,  9,   51,  0,   9,   50,  0,
+    41,  10,  53,  0,   10,  52,  0,
+    44,  19,  40,  0,   19,  41,  0,
+    45,  3,   23,  0,   3,   24,  0,
+    46,  3,   22,  0,   3,   23,  0,
+    64,  1,   15,  0,   1,   14,  0,
+    66,  12,  18,  0,   13,  1,   0,
+    0
+};
+
 SWORD_NAMESPACE_END
 
 #endif

Modified: branches/sword-1-8-x/include/canon_darbyfr.h
===================================================================
--- branches/sword-1-8-x/include/canon_darbyfr.h	2017-11-01 11:33:56 UTC (rev 3514)
+++ branches/sword-1-8-x/include/canon_darbyfr.h	2017-11-01 11:38:09 UTC (rev 3515)
@@ -2,7 +2,7 @@
  *
  *  canon_darbyfr.h -	Versification data for the French Darby Bibles
  *
- * $Id: canon_darbyfr.h 2015-08-22 22:30:20 domcox $
+ *  $Id$
  *
  * Copyright 1998-2015 CrossWire Bible Society (http://www.crosswire.org)
  *	CrossWire Bible Society
@@ -271,6 +271,41 @@
   27, 21
 };
 
+unsigned char mappings_darbyfr[] = {
+    0,
+    3,   5,   20,  0,   6,   1,   0,
+    3,   6,   1,   0,   6,   8,   0,
+    4,   13,  1,   0,   12,  16,  0,
+    4,   13,  2,   0,   13,  1,   0,
+    4,   30,  2,   0,   30,  1,   0,
+    5,   28,  69,  0,   29,  1,   0,
+    5,   29,  1,   0,   29,  2,   0,
+    9,   20,  43,  0,   20,  42,  0,
+    9,   24,  1,   0,   23,  29,  0,
+    9,   24,  2,   0,   24,  1,   0,
+    11,  22,  44,  0,   22,  43,  0,
+    18,  39,  1,   0,   38,  39,  0,
+    18,  39,  4,   0,   39,  1,   0,
+    18,  39,  34,  0,   40,  1,   0,
+    18,  40,  1,   0,   40,  6,   0,
+    18,  40,  20,  0,   41,  1,   0,
+    18,  41,  1,   0,   41,  9,   0,
+    18,  41,  1,   0,   41,  10,  0,
+    19,  13,  1,   0,   13,  2,   0,
+    26,  21,  1,   0,   20,  45,  0,
+    26,  21,  6,   0,   21,  1,   0,
+    28,  12,  1,   0,   11,  12,  0,
+    28,  12,  2,   0,   12,  1,   0,
+    32,  2,   1,   0,   1,   17,  0,
+    32,  2,   2,   0,   2,   1,   0,
+    41,  9,   51,  0,   9,   50,  0,
+    43,  1,   39,  0,   1,   38,  0,
+    47,  13,  13,  0,   13,  14,  0,
+    64,  1,   15,  0,   1,   14,  0,
+    66,  12,  18,  0,   13,  1,   0,
+    0
+};
+
 SWORD_NAMESPACE_END
 
 #endif

Modified: branches/sword-1-8-x/include/canon_segond.h
===================================================================
--- branches/sword-1-8-x/include/canon_segond.h	2017-11-01 11:33:56 UTC (rev 3514)
+++ branches/sword-1-8-x/include/canon_segond.h	2017-11-01 11:38:09 UTC (rev 3515)
@@ -3,7 +3,7 @@
  *  canon_segond.h -	Versification data for French Louis Segond original
  *                      and revised Bibles
  *
- * $Id: canon_segond.h 2015-08-22 22:52:34 domcox $
+ *  $Id$
  *
  * Copyright 1998-2013 CrossWire Bible Society (http://www.crosswire.org)
  *	CrossWire Bible Society
@@ -272,6 +272,119 @@
   27, 21
 };
 
+unsigned char mappings_segond[] = {
+    0,
+    2,   7,   26,  0,   8,   1,   0,
+    2,   8,   1,   0,   8,   5,   0,
+    3,   5,   20,  0,   6,   1,   0,
+    3,   6,   1,   0,   6,   8,   0,
+    4,   30,  1,   0,   29,  40,  0,
+    4,   30,  2,   0,   30,  1,   0,
+    9,   20,  43,  0,   20,  42,  0,
+    9,   24,  1,   0,   23,  29,  0,
+    9,   24,  2,   0,   24,  1,   0,
+    11,  22,  44,  0,   22,  43,  0,
+    18,  39,  1,   0,   38,  39,  0,
+    18,  39,  4,   0,   39,  1,   0,
+    18,  39,  34,  0,   40,  1,   0,
+    18,  40,  1,   0,   40,  6,   0,
+    18,  40,  20,  0,   41,  1,   0,
+    18,  41,  1,   0,   41,  10,  0,
+    19,  3,   2,   0,   3,   1,   0,
+    19,  4,   2,   0,   4,   1,   0,
+    19,  5,   2,   0,   5,   1,   0,
+    19,  6,   2,   0,   6,   1,   0,
+    19,  7,   2,   0,   7,   1,   0,
+    19,  8,   2,   0,   8,   1,   0,
+    19,  9,   2,   0,   9,   1,   0,
+    19,  12,  2,   0,   12,  1,   0,
+    19,  18,  2,   0,   18,  1,   0,
+    19,  19,  2,   0,   19,  1,   0,
+    19,  20,  2,   0,   20,  1,   0,
+    19,  21,  2,   0,   21,  1,   0,
+    19,  22,  2,   0,   22,  1,   0,
+    19,  30,  2,   0,   30,  1,   0,
+    19,  31,  2,   0,   31,  1,   0,
+    19,  34,  2,   0,   34,  1,   0,
+    19,  36,  2,   0,   36,  1,   0,
+    19,  38,  2,   0,   38,  1,   0,
+    19,  39,  2,   0,   39,  1,   0,
+    19,  40,  2,   0,   40,  1,   0,
+    19,  41,  2,   0,   41,  1,   0,
+    19,  42,  2,   0,   42,  1,   0,
+    19,  44,  2,   0,   44,  1,   0,
+    19,  45,  2,   0,   45,  1,   0,
+    19,  46,  2,   0,   46,  1,   0,
+    19,  47,  2,   0,   47,  1,   0,
+    19,  48,  2,   0,   48,  1,   0,
+    19,  49,  2,   0,   49,  1,   0,
+    19,  51,  2,   0,   51,  1,   0,
+    19,  51,  3,   0,   51,  1,   0,
+    19,  52,  2,   0,   52,  1,   0,
+    19,  52,  3,   0,   52,  1,   0,
+    19,  53,  2,   0,   53,  1,   0,
+    19,  54,  3,   0,   54,  1,   0,
+    19,  55,  2,   0,   55,  1,   0,
+    19,  56,  2,   0,   56,  1,   0,
+    19,  57,  2,   0,   57,  1,   0,
+    19,  58,  2,   0,   58,  1,   0,
+    19,  59,  2,   0,   59,  1,   0,
+    19,  60,  2,   0,   60,  1,   0,
+    19,  60,  3,   0,   60,  1,   0,
+    19,  61,  2,   0,   61,  1,   0,
+    19,  62,  2,   0,   62,  1,   0,
+    19,  63,  2,   0,   63,  1,   0,
+    19,  64,  2,   0,   64,  1,   0,
+    19,  65,  2,   0,   65,  1,   0,
+    19,  67,  2,   0,   67,  1,   0,
+    19,  68,  2,   0,   68,  1,   0,
+    19,  69,  2,   0,   69,  1,   0,
+    19,  70,  2,   0,   70,  1,   0,
+    19,  75,  2,   0,   75,  1,   0,
+    19,  76,  2,   0,   76,  1,   0,
+    19,  77,  2,   0,   77,  1,   0,
+    19,  80,  2,   0,   80,  1,   0,
+    19,  81,  2,   0,   81,  1,   0,
+    19,  83,  2,   0,   83,  1,   0,
+    19,  84,  2,   0,   84,  1,   0,
+    19,  85,  2,   0,   85,  1,   0,
+    19,  88,  2,   0,   88,  1,   0,
+    19,  89,  2,   0,   89,  1,   0,
+    19,  92,  2,   0,   92,  1,   0,
+    19,  102, 2,   0,   102, 1,   0,
+    19,  108, 2,   0,   108, 1,   0,
+    19,  140, 2,   0,   140, 1,   0,
+    19,  142, 2,   0,   142, 1,   0,
+    21,  4,   17,  0,   5,   1,   0,
+    21,  5,   1,   0,   5,   2,   0,
+    21,  12,  1,   0,   11,  9,   0,
+    21,  12,  3,   0,   12,  1,   0,
+    22,  7,   1,   0,   6,   13,  0,
+    22,  7,   2,   0,   7,   1,   0,
+    23,  8,   23,  0,   9,   1,   0,
+    23,  9,   1,   0,   9,   2,   0,
+    23,  63,  19,  0,   64,  1,   0,
+    23,  64,  2,   0,   64,  3,   0,
+    26,  21,  1,   0,   20,  45,  0,
+    26,  21,  6,   0,   21,  1,   0,
+    28,  2,   1,   0,   1,   10,  0,
+    28,  2,   3,   0,   2,   1,   0,
+    28,  12,  1,   0,   11,  12,  0,
+    28,  12,  2,   0,   12,  1,   0,
+    32,  2,   1,   0,   1,   17,  0,
+    32,  2,   2,   0,   2,   1,   0,
+    33,  4,   14,  0,   5,   1,   0,
+    33,  5,   1,   0,   5,   2,   0,
+    34,  2,   1,   0,   1,   15,  0,
+    34,  2,   2,   0,   2,   1,   0,
+    41,  9,   51,  0,   9,   50,  0,
+    44,  19,  40,  0,   19,  41,  0,
+    47,  13,  12,  0,   13,  13,  0,
+    64,  1,   15,  0,   1,   14,  0,
+    66,  12,  18,  0,   13,  1,   0,
+    0
+};
+
 SWORD_NAMESPACE_END
 
 #endif

Modified: branches/sword-1-8-x/include/filemgr.h
===================================================================
--- branches/sword-1-8-x/include/filemgr.h	2017-11-01 11:33:56 UTC (rev 3514)
+++ branches/sword-1-8-x/include/filemgr.h	2017-11-01 11:38:09 UTC (rev 3515)
@@ -32,7 +32,7 @@
 
 SWORD_NAMESPACE_START
 
-class SWDLLEXPORT FileMgr;
+class SWDLLEXPORT FileDesc;
 
 struct SWDLLEXPORT DirEntry {
 public:
@@ -40,49 +40,23 @@
 	unsigned long size;
 	bool isDirectory;
 };
-/**
-* This class represents one file. It works with the FileMgr object.
-*/
-class SWDLLEXPORT FileDesc {
 
-	friend class FileMgr;
-
-	long offset;
-	int fd;			// -77 closed;
-	FileMgr *parent;
-	FileDesc *next;
-
-	FileDesc(FileMgr * parent, const char *path, int mode, int perms, bool tryDowngrade);
-	virtual ~FileDesc();
-
-public:
-	/** @return File handle.
-	*/
-	int getFd();
-
-	long seek(long offset, int whence);
-	long read(void *buf, long count);
-	long write(const void *buf, long count);
-
-	/** Path to file.
-	*/
-	char *path;
-	/** File access mode.
-	*/
-	int mode;
-	/** File permissions.
-	*/
-	int perms;
-	/**
-	*/
-	bool tryDowngrade;
-};
-
 /**
-*	This class ist used make file access operations easier.
-* It keeps a list of all open files internally and closes them
-* when the destructor is called.
-*/
+ * This class isolates all file io for SWORD, making OS
+ * level quirks easier to fix.  This class is typically
+ * copied and replaced if necessary to get SWORD to run on
+ * a specific platform (e.g., Windows Mobile), but in
+ * the future, statics should be removed to make possible to
+ * instead simply subclass and override necessary methods.
+ *
+ * This class also provides many convenience methods which
+ * make working with data storage easier.
+ *
+ * Conceptually, this factory exposes an interface which
+ * allows SWORD to 'open' every file it wants, without
+ * worrying about OS limits, and takes care of opening and
+ * closing the actual file descriptors when necessary.
+ */
 class SWDLLEXPORT FileMgr : public SWCacher {
 
 	friend class FileDesc;
@@ -184,8 +158,65 @@
 	static int removeFile(const char *fName);
 	static char getLine(FileDesc *fDesc, SWBuf &line);
 
+	/**
+	 * Determines where SWORD looks for the user's home folder.  This is
+	 * typically used as a place to find any additional personal SWORD
+	 * modules which a user might wish to be added to a system-wide
+	 * library (e.g., added from ~/.sword/mods.d/ or ~/sword/mods.d/)
+	 *
+	 * or if a user or UI wishes to override SWORD system configuration
+	 * settings (e.g., /etc/sword.conf) with a custom configuration
+	 * (e.g., ~/.sword/sword.conf)
+	 */
+	SWBuf getHomeDir();
+
 };
 
+/**
+* This class represents one file. It works with the FileMgr object.
+*/
+class SWDLLEXPORT FileDesc {
 
+	friend class FileMgr;
+
+	long offset;
+	int fd;			// -77 closed;
+	FileMgr *parent;
+	FileDesc *next;
+
+	FileDesc(FileMgr * parent, const char *path, int mode, int perms, bool tryDowngrade);
+	virtual ~FileDesc();
+
+public:
+	/** @return File handle.
+	 * NOTE: magic file descriptor -77 = closed to avoid os limits
+	*/
+	inline int getFd() {
+		if (fd == -77)
+			fd = parent->sysOpen(this);
+//		if ((fd < -1) && (fd != -77))  // kludge to handle ce
+//			return 777;
+		return fd;
+	}
+
+	long seek(long offset, int whence);
+	long read(void *buf, long count);
+	long write(const void *buf, long count);
+
+	/** Path to file.
+	*/
+	char *path;
+	/** File access mode.
+	*/
+	int mode;
+	/** File permissions.
+	*/
+	int perms;
+	/**
+	*/
+	bool tryDowngrade;
+};
+
+
 SWORD_NAMESPACE_END
 #endif

Modified: branches/sword-1-8-x/include/installmgr.h
===================================================================
--- branches/sword-1-8-x/include/installmgr.h	2017-11-01 11:33:56 UTC (rev 3514)
+++ branches/sword-1-8-x/include/installmgr.h	2017-11-01 11:38:09 UTC (rev 3515)
@@ -76,6 +76,7 @@
 	StatusReporter *statusReporter;
 	bool passive;
 	SWBuf u, p;
+	bool unverifiedPeerAllowed;
 
 	/** override this method and provide your own custom RemoteTransport subclass
          */
@@ -236,15 +237,19 @@
 	return false;
 }
 	*/
-		virtual bool getCipherCode(const char *modName, SWConfig *config) { (void) modName; (void) config; return false; }
 
+	virtual bool getCipherCode(const char *modName, SWConfig *config) { (void) modName; (void) config; return false; }
 
 
+
 	/** whether or not to use passive mode when doing ftp transfers
          */
 	void setFTPPassive(bool passive) { this->passive = passive; }
 	bool isFTPPassive() { return passive; }
 
+	void setUnverifiedPeerAllowed(bool allowed) { this->unverifiedPeerAllowed = allowed; }
+	bool isUnverifiedPeerAllowed() { return unverifiedPeerAllowed; }
+
         /** call from another thread to terminate the installation process
          */
 	void terminate();

Modified: branches/sword-1-8-x/include/remotetrans.h
===================================================================
--- branches/sword-1-8-x/include/remotetrans.h	2017-11-01 11:33:56 UTC (rev 3514)
+++ branches/sword-1-8-x/include/remotetrans.h	2017-11-01 11:38:09 UTC (rev 3515)
@@ -53,6 +53,7 @@
 	StatusReporter *statusReporter;
 	bool passive;
 	bool term;
+	bool unverifiedPeerAllowed;
 	SWBuf host;
 	SWBuf u;
 	SWBuf p;
@@ -68,13 +69,23 @@
 	 */
 	virtual char getURL(const char *destPath, const char *sourceURL, SWBuf *destBuf = 0);
 
+	/***********
+	 * override this method in your real impl
+	 *
+	 * if sourceBuf then read from buffer instead of file
+	 */
+	virtual char putURL(const char *destURL, const char *sourcePath, SWBuf *sourceBuf = 0);
 
+
 	int copyDirectory(const char *urlPrefix, const char *dir, const char *dest, const char *suffix);
 
 	virtual std::vector<struct DirEntry> getDirList(const char *dirURL);
 	void setPassive(bool passive) { this->passive = passive; }
+	bool isPassive() { return passive; }
 	void setUser(const char *user) { u = user; }
 	void setPasswd(const char *passwd) { p = passwd; }
+	void setUnverifiedPeerAllowed(bool val) { this->unverifiedPeerAllowed = val; }
+	bool isUnverifiedPeerAllowed() { return unverifiedPeerAllowed; }
 	void terminate() { term = true; }
 };
 

Modified: branches/sword-1-8-x/include/swbuf.h
===================================================================
--- branches/sword-1-8-x/include/swbuf.h	2017-11-01 11:33:56 UTC (rev 3514)
+++ branches/sword-1-8-x/include/swbuf.h	2017-11-01 11:38:09 UTC (rev 3515)
@@ -90,28 +90,41 @@
 		init(0);
 	}
 
-	/**
-	* SWBuf Constructor - Creates an SWBuf initialized
+	/******************************************************************************
+	* SWBuf Constructor - Creates an empty SWBuf object or an SWBuf initialized
 	* 		to a value from a const char *
- 	*
- 	*/
-	SWBuf(const char *initVal, unsigned long initSize = 0);
-//	SWBuf(unsigned long initSize);
+	*
+	*/
+	inline SWBuf(const char *initVal, unsigned long initSize = 0) {
+		init(initSize);
+		if (initVal)
+			set(initVal);
+	}
 
-	/**
+	/******************************************************************************
 	* SWBuf Constructor - Creates an SWBuf initialized
-	* 		to a value from a char
+	* 		to a value from another SWBuf
 	*
 	*/
-	SWBuf(char initVal, unsigned long initSize = 0);
+	inline SWBuf(const SWBuf &other, unsigned long initSize = 0) {
+		init(initSize);
+		set(other);
+	}
 
-	/**
+	/******************************************************************************
 	* SWBuf Constructor - Creates an SWBuf initialized
-	* 		to a value from another SWBuf
+	* 		to a value from a char
 	*
 	*/
-	SWBuf(const SWBuf &other, unsigned long initSize = 0);
+	inline SWBuf(char initVal, unsigned long initSize = 0) {
+		init(initSize+1);
+		*buf = initVal;
+		end = buf+1;
+		*end = 0;
+	}
+//	SWBuf(unsigned long initSize);
 
+
 	/******************************************************************************
 	* SWBuf Destructor - Cleans up instance of SWBuf
 	*/
@@ -220,7 +233,13 @@
 	* SWBuf::setSize - Size this buffer to a specific length.
 	* @param len The new size of the buffer. One byte for the null will be added.
 	*/
-	void setSize(unsigned long len);
+	inline void setSize(unsigned long len) {
+		assureSize(len+1);
+		if ((unsigned)(end - buf) < len)
+			memset(end, fillByte, len - (end-buf));
+		end = buf + len;
+		*end = 0;
+	}
 	/**
 	* SWBuf::resize - Resize this buffer to a specific length.
 	* @param len The new size of the buffer. One byte for the null will be added.
@@ -233,7 +252,17 @@
 	* @param str Append this.
 	* @param max Append only max chars.
 	*/
-	SWBuf &append(const char *str, long max = -1);
+	inline SWBuf &append(const char *str, long max = -1) {
+	//	if (!str) //A null string was passed
+	//		return;
+		if (max < 0)
+			max = strlen(str);
+		assureMore(max+1);
+		for (;((max)&&(*str));max--)
+			*end++ = *str++;
+		*end = 0;
+		return *this;
+	}
 
 	/**
 	* SWBuf::append - appends a value to the current value of this SWBuf

Modified: branches/sword-1-8-x/include/swconfig.h
===================================================================
--- branches/sword-1-8-x/include/swconfig.h	2017-11-01 11:33:56 UTC (rev 3514)
+++ branches/sword-1-8-x/include/swconfig.h	2017-11-01 11:38:09 UTC (rev 3515)
@@ -39,51 +39,106 @@
 *
 */
 class SWDLLEXPORT SWConfig {
-private:
-	char getline(int fd, SWBuf &line);
 public:
-	/** The filename used by this SWConfig object
-	*
-	*/
-	SWBuf filename;
 	/** Map of available sections
 	* The map of available sections.
 	*/
-	SectionMap Sections;
 
 	/** Constructor of SWConfig
-	* @param ifilename The file, which should be used for this config.
-	*/
-	SWConfig(const char *ifilename);
+	 * @param fileName The storage path for this config.
+	 */
+	SWConfig(const char *fileName);
 	SWConfig();
 	virtual ~SWConfig();
 
-	/** Load from disk
-	* Load the content from disk.
-	*/
-	virtual void Load();
+	/** Get the section map for the config
+	 */
+	virtual SectionMap &getSections();
+	const SectionMap &getSections() const { return const_cast<SWConfig *>(this)->getSections(); }
 
-	/** Save to disk
-	* Save the content of this config object to disk.
-	*/
-	virtual void Save();
+	/** Load the content from datastore
+	 */
+	virtual void load();
 
-	/** Merges the values of addFrom
-	* @param addFrom The config which values should be merged to this config object. Already existing values will be overwritten.
-	*/
+	/** Save the content of this config object to the datastore
+	 */
+	virtual void save() const;
+
+	/** Merges into this config the values from addFrom
+	 * @param addFrom The config which values should be merged to this config object. Already existing values will be overwritten.
+	 */
 	virtual void augment(SWConfig &addFrom);
-	virtual SWConfig & operator +=(SWConfig &addFrom) { augment(addFrom); return *this; }
 
-	/** Get a section
-	* This is an easy way to get and store config values.
-	* The following will work:\n
-	*
-	* @code
-	* SWConfig config("/home/user/.setttings");
-	* config["Colors"]["Background"] = "red";
-	* @endcode
-	*/
-	virtual ConfigEntMap & operator [](const char *section);
-	};
+	/** Get a specified section from config, creating the section if needed
+	 * There is no const version of this method because it returns a ConfigEntMap reference, creating the requested section if it doesn't exist.
+	 * @param section section name to retrieve
+	 */
+	ConfigEntMap &getSection(const char *section) { return getSections()[section]; }
+
+
+	/** This operator provides a conventient syntax to get and store config values
+	 *
+	 * config[section][key] = value;
+	 * value = config[section][key];
+	 *
+	 * The following will work:\n
+	 *
+	 * @code
+	 * SWConfig config("/home/user/.settings");
+	 * config["Colors"]["Background"] = "red";
+	 * @endcode
+	 */
+	ConfigEntMap &operator [](const char *section) { return getSection(section); }
+
+	/** shorthand operator for augment
+	 */
+	SWConfig &operator +=(SWConfig &addFrom) { augment(addFrom); return *this; }
+
+	/** get a value from a [section] key=value
+	 * @param section  the section name containing the key
+	 * @param key      the key to which the value is associated
+	 * @return         the value associated with the key in the provided section
+	 */
+	SWBuf getValue(const char *section, const char *key) {
+		return (*this)[section][key];
+	}
+
+	/** set a value for a specified key in a [section]
+	 * @param section  the section name to contain the key
+	 * @param key      the key to which to associate the value
+	 * @param value    the value to associated with the key
+	 */
+	void setValue(const char *section, const char *key, const char *value) {
+		(*this)[section][key] = value;
+	}
+
+	/** The storage path used by this SWConfig object
+	 */
+	SWBuf getFileName() const;
+
+
+	// ****** Deprecated methods for removal in 2.0
+
+	/**
+	 * @deprecated Use getSections() instead.
+	 */
+	SWDEPRECATED SectionMap Sections;
+
+	/**
+	 * @deprecated Use getFileName() instead.
+	 */
+	SWDEPRECATED SWBuf filename;
+
+	/**
+	 * @deprecated Use load() instead.
+	 */
+	SWDEPRECATED void Load() { load(); }
+
+	/**
+	 * @deprecated Use save() instead.
+	 */
+	SWDEPRECATED void Save() { save(); }
+
+};
 SWORD_NAMESPACE_END
 #endif

Modified: branches/sword-1-8-x/include/swkey.h
===================================================================
--- branches/sword-1-8-x/include/swkey.h	2017-11-01 11:33:56 UTC (rev 3514)
+++ branches/sword-1-8-x/include/swkey.h	2017-11-01 11:38:09 UTC (rev 3515)
@@ -159,6 +159,7 @@
 	 */
 	SWDEPRECATED char Error() { return popError(); }
 	virtual char popError();
+	virtual char getError() { return error; }
 	virtual void setError(char err) { error = err; }
 
 	/** Sets this SWKey with a character string

Modified: branches/sword-1-8-x/include/swmgr.h
===================================================================
--- branches/sword-1-8-x/include/swmgr.h	2017-11-01 11:33:56 UTC (rev 3514)
+++ branches/sword-1-8-x/include/swmgr.h	2017-11-01 11:38:09 UTC (rev 3515)
@@ -101,9 +101,11 @@
 	SWConfig *myconfig;		//made protected because because BibleTime needs it
 	SWConfig *mysysconfig;
 	SWConfig *homeConfig;
-	void CreateMods(bool multiMod = false);
-	virtual SWModule *createModule(const char *name, const char *driver, ConfigEntMap &section);
-	void DeleteMods();
+	/**
+	 * Deprecated. Use createAllModules instead
+	 */
+	SWDEPRECATED void CreateMods(bool multiMod = false) { createAllModules(multiMod); };
+	SWDEPRECATED void DeleteMods() { deleteAllModules(); }
 	char configType;		// 0 = file; 1 = directory
 	OptionFilterMap optionFilters;
 	FilterMap cipherFilters;
@@ -115,49 +117,152 @@
 	FilterList cleanupFilters;
 	FilterMap extraFilters;
 	StringList options;
-	virtual void init(); // use to initialize before loading modules
-	virtual char AddModToConfig(FileDesc *conffd, const char *fname);
-	virtual void loadConfigDir(const char *ipath);
-	virtual void AddGlobalOptions(SWModule *module, ConfigEntMap &section, ConfigEntMap::iterator start, ConfigEntMap::iterator end);
-	virtual void AddLocalOptions(SWModule *module, ConfigEntMap &section, ConfigEntMap::iterator start, ConfigEntMap::iterator end);
-	StringList augPaths;
+	/**
+	 * method to create all modules from configuration.
+	 *
+	 * Override to add any special processing before or after
+	 * calling SWMgr::createAllModules
+	 *
+	 * e.g., augmenting a localConfig.conf to SWMgr::config
+	 * that might store CipheyKey or Font preferences per module
+	 * before actual construction of modules
+	 *
+	 */
+	virtual void createAllModules(bool multiMod = false);
+	/**
+	 * called to delete all contructed modules.  Undoes createAllModules
+	 * override to clean anything up before or after all modules are
+	 * deleted
+	 */
+	virtual void deleteAllModules();
 
 	/**
-	 * Called to add appropriate Encoding Filters to a module.  Override to do special actions,
-	 *	if desired.	See the module.conf Encoding= entry.
-	 * @param module module to which to add Encoding Filters
-	 * @param section configuration information from module.conf
+	 * called to create exactly one module from a config entry
+	 * override to do any extra work before or after each module
+	 * is created
 	 */
-	virtual void AddEncodingFilters(SWModule *module, ConfigEntMap &section);
+	virtual SWModule *createModule(const char *name, const char *driver, ConfigEntMap &section);
 
 	/**
-	 * Called to add appropriate Render Filters to a module.  Override to do special actions,
-	 *	if desired.	See the module.conf SourceType= entry.
-	 * @param module module to which to add Render Filters
-	 * @param section configuration information from module.conf
+	 * call by every constructor to initialize SWMgr object
+	 * override to include any addition common initialization
 	 */
-	virtual void AddRenderFilters(SWModule *module, ConfigEntMap &section);
+	virtual void init();
 
+
 	/**
-	 * Called to add appropriate Strip Filters to a module.  Override to do special actions,
-	 *	if desired.	See the module.conf SourceType= entry.
-	 * @param module module to which to add Strip Filters
-	 * @param section configuration information from module.conf
+	 * Deprecated.  Use addGlobalOptionFilters instead.
 	 */
-	virtual void AddStripFilters(SWModule *module, ConfigEntMap &section);
+	SWDEPRECATED virtual void AddGlobalOptions(SWModule *module, ConfigEntMap &section, ConfigEntMap::iterator start, ConfigEntMap::iterator end) { addGlobalOptionFilters(module, section); }
+	/**
+	 * Adds appropriate global option filters to a module.  Override to add any special
+	 *	global option filters. Global option filters typically update SourceType markup
+	 *	to turn on and off specific features of a text when a user has optionally chosen
+	 *	to show or hide that feature, e.g. Strongs, Footnotes, Headings, etc.
+	 *	Global options can also have more than On and Off values, but these are the most
+	 *	common.
+	 *	A set of all global options included from an entire library of installed modules
+	 *	can be obtained from getGlobalOptions and presented to the user.  Values to
+	 *	which each global option may be set can be obtain from getGlobalOptionValues,
+	 *	and similar.  See that family of methods for more information.
+	 * See the module.conf GlobalOptionFilter= entries.
+	 * @param module module to which to add encoding filters
+	 * @param section configuration information for module
+	 */
+	virtual void addGlobalOptionFilters(SWModule *module, ConfigEntMap &section);
 
-	// ones manually specified in .conf file
-	virtual void AddStripFilters(SWModule *module, ConfigEntMap &section, ConfigEntMap::iterator start, ConfigEntMap::iterator end);
+	/**
+	 * Deprecated.  Use addLocalOptionFilters instead.
+	 */
+	SWDEPRECATED virtual void AddLocalOptions(SWModule *module, ConfigEntMap &section, ConfigEntMap::iterator start, ConfigEntMap::iterator end) { addLocalOptionFilters(module, section); }
+	/**
+	 * Adds appropriate local option filters to a module.  Override to add any special
+	 *	local option filters.  Local options are similar to global options in that
+	 *	they may be toggled on or off or set to some value from a range of choices
+	 *	but local option
+	 * See the module.conf LocalOptionFilter= entries.
+	 * @param module module to which to add encoding filters
+	 * @param section configuration information for module
+	 */
+	virtual void addLocalOptionFilters(SWModule *module, ConfigEntMap &section);
 
 	/**
-	 * Called to add appropriate Raw Filters to a module.  Override to do special actions,
-	 *	if desired.	See the module.conf CipherKey= entry.
-	 * @param module module to which to add Raw Filters
-	 * @param section configuration information from module.conf
+	 * Deprecated.  Use addEncodingFilters instead
 	 */
-	virtual void AddRawFilters(SWModule *module, ConfigEntMap &section);
+	SWDEPRECATED virtual void AddEncodingFilters(SWModule *module, ConfigEntMap &section) { addEncodingFilters(module, section); }
+	/**
+	 * Adds appropriate encoding filters to a module.  Override to add any special
+	 *	encoding filters.
+	 * See the module.conf Encoding= entry.
+	 * @param module module to which to add encoding filters
+	 * @param section configuration information for module
+	 */
+	virtual void addEncodingFilters(SWModule *module, ConfigEntMap &section);
 
+	/**
+	 * Deprecated.  Use addRenderFilters instead.
+	 */
+	SWDEPRECATED virtual void AddRenderFilters(SWModule *module, ConfigEntMap &section) { addRenderFilters(module, section); }
+	/**
+	 * Add appropriate render filters to a module.  Override to add any special
+	 *	render filters. Render filters are used for preparing a text for
+	 *	display and typically convert markup from SourceType
+	 *	to desired display markup.
+	 * See the module.conf SourceType= entry.
+	 * @param module module to which to add render filters
+	 * @param section configuration information for module
+	 */
+	virtual void addRenderFilters(SWModule *module, ConfigEntMap &section);
 
+	/**
+	 * Deprecated.  Use addStripFilters instead.
+	 */
+	SWDEPRECATED virtual void AddStripFilters(SWModule *module, ConfigEntMap &section) { addStripFilters(module, section); }
+	/**
+	 * Adds appropriate strip filters to a module.  Override to add any special
+	 *	strip filters. Strip filters are used for preparing text for searching
+	 *	and typically strip out all markup and leave only searchable words
+	 * See the module.conf SourceType= entry.
+	 * @param module module to which to add strip filters
+	 * @param section configuration information for module
+	 */
+	virtual void addStripFilters(SWModule *module, ConfigEntMap &section);
+
+	/**
+	 * Deprecated.  Use addLocalStripFilters instead.
+	 */
+	SWDEPRECATED virtual void AddStripFilters(SWModule *module, ConfigEntMap &section, ConfigEntMap::iterator start, ConfigEntMap::iterator end) { addLocalStripFilters(module, section); }
+	/**
+	 * Adds manually specified strip filters specified in module configuration
+	 * as LocalStripFilters.  These might take care of special cases of preparation
+	 * for searching, e.g., removing ()[] and underdot symbols from manuscript modules
+	 * @param module module to which to add local strip filters
+	 * @param section configuration information for module
+	 */
+	virtual void addLocalStripFilters(SWModule *module, ConfigEntMap &section);
+
+	/**
+	 * Deprecated.  Use addRawFilters instead.
+	 */
+	SWDEPRECATED virtual void AddRawFilters(SWModule *module, ConfigEntMap &section) { addRawFilters(module, section); }
+	/**
+	 * Add appropriate raw filters to a module.  Override to add any special
+	 *	raw filters.  Raw filters are used to manipulate a buffer
+	 *	immediately after it has been read from storage.  For example,
+	 *	any decryption that might need to be done.
+	 * See the module.conf CipherKey= entry.
+	 * @param module module to which to add raw filters
+	 * @param section configuration information for module
+	 */
+	virtual void addRawFilters(SWModule *module, ConfigEntMap &section);
+
+
+	// still to be normalized below ...
+	//
+	StringList augPaths;
+	virtual char AddModToConfig(FileDesc *conffd, const char *fname);
+	virtual void loadConfigDir(const char *ipath);
+
 public:
 
 	// constants which represent module types used in SWModule::getType
@@ -170,14 +275,32 @@
 
 	static bool isICU;
 	static const char *globalConfPath;
-	static SWBuf getHomeDir();
 
 	/**
-	 *
+	 * Deprecated.  Used FileMgr::getSystemFileMgr()->getHomeDir() instead.
 	 */
+	SWDEPRECATED static SWBuf getHomeDir();
+
+	/**
+	 * Perform all the logic to discover a SWORD configuration and libraries on a system
+	 */
 	static void findConfig(char *configType, char **prefixPath, char **configPath, StringList *augPaths = 0, SWConfig **providedSysConf = 0);
 
+	/**
+	 * The configuration of a loaded library of SWORD modules
+	 * e.g., from /usr/share/sword/mods.d/
+	 * 	augmented with ~/.sword/mods.d/
+	 * 
+	 * This represents all discovered modules and their configuration
+	 * compiled into a single SWConfig object with each [section]
+	 * representing each module. e.g. [KJV]
+	 */
 	SWConfig *config;
+
+	/**
+	 * The configuration file for SWORD
+	 * e.g., /etc/sword.conf
+	 */
 	SWConfig *sysConfig;
 
 	/** The path to main module set and locales
@@ -188,36 +311,43 @@
 	 */
 	char *configPath;
 
+
+	/**
+	 * Deprecated.  Use getModules instead.
+	 */
+	ModMap Modules;
 	/** The map of available modules.
 	 *	This map exposes the installed modules.
-	 *	Here's an example how to iterate over the map and check the module type of each module.
 	 *
-	 *@code
-	 * ModMap::iterator it;
-	 * SWModule *curMod = 0;
+	 *	Here's an example how to iterate over all
+	 *	the installed modules and check the module name
+	 *	and type of each module and do something special
+	 *	if the module type is a Bible.
 	 *
-	 * for (it = Modules.begin(); it != Modules.end(); it++) {
-	 *      curMod = (*it).second;
-	 *      if (!strcmp(curMod->Type(), "Biblical Texts")) {
-	 *           // do something with curMod
-	 *      }
-	 *      else if (!strcmp(curMod->Type(), "Commentaries")) {
-	 *           // do something with curMod
-	 *      }
-	 *      else if (!strcmp(curMod->Type(), "Lexicons / Dictionaries")) {
-	 *           // do something with curMod
-	 *      }
+	 * @code
+	 *
+	 * for (ModMap::iterator it = getModules().begin(); it != getModules().end(); ++it) {
+	 *
+	 * 	SWBuf modName = it->first;
+	 * 	SWModule *mod = it->second;
+	 *
+	 * 	SWBuf modType = mod->getType();
+	 *
+	 * 	if (modType == SWMgr::MODTYPE_BIBLES) {
+	 * 		// do something with mod
+	 * 	}
 	 * }
 	 * @endcode
 	 */
-	ModMap Modules;
+	ModMap &getModules();
+	const ModMap &getModules() const { return const_cast<SWMgr *>(this)->getModules(); }
 
 	/** Gets a specific module by name.  e.g. SWModule *kjv = myManager.getModule("KJV");
 	 * @param modName the name of the module to retrieve
 	 * @return the module, if found, otherwise 0
 	 */
-	SWModule *getModule(const char *modName) { ModMap::iterator it = Modules.find(modName); return ((it != Modules.end()) ? it->second : 0); }
-	const SWModule *getModule(const char *modName) const { ModMap::const_iterator it = Modules.find(modName); return ((it != Modules.end()) ? it->second : 0); }
+	SWModule *getModule(const char *modName) { ModMap::iterator it = getModules().find(modName); return ((it != getModules().end()) ? it->second : 0); }
+	const SWModule *getModule(const char *modName) const { ModMap::const_iterator it = getModules().find(modName); return ((it != getModules().end()) ? it->second : 0); }
 
 
 	/** Constructs an instance of SWMgr
@@ -226,7 +356,7 @@
 	 *	using a complex hierarchical search.  See README for detailed specifics.
 	 * @param isysconfig
 	 * @param autoload whether or not to immediately load modules on construction of this SWMgr.
-	 *	If you reimplemented SWMgr you can set this to false and call SWMgr::Load() after you have
+	 *	If you reimplemented SWMgr you can set this to false and call SWMgr::load() after you have
 	 *	completed the contruction and setup of your SWMgr subclass.
 	 * @param filterMgr an SWFilterMgr subclass to use to manager filters on modules
 	 *	SWMgr TAKES OWNERSHIP FOR DELETING THIS OBJECT
@@ -271,12 +401,20 @@
 	 */
 	virtual void InstallScan(const char *dir);
 
-	/** Load all modules.  Should only be manually called if SWMgr was constructed
+	/**
+	 * Deprecated.  Use load
+	 */
+	SWDEPRECATED virtual signed char Load() { return load(); }
+	/** Loads installed library of SWORD modules.
+	 * Should only be manually called if SWMgr was constructed
 	 *	without autoload; otherwise, this will be called on SWMgr construction
 	 * Reimplement this function to supply special functionality when modules are
-	 * initially loaded.
+	 * initially loaded. This includes
+	 * discovery of config path with SWMgr::fileconfig,
+	 * loading of composite SWMgr::config,
+	 * and construction of all modules from config using SWMgr::createAllModules
 	 */
-	virtual signed char Load();
+	virtual signed char load();
 
 	/** Change the values of global options (e.g. Footnotes, Strong's Number, etc.)
 	 * @param option The name of the option, for which you want to change the
@@ -322,43 +460,53 @@
 	/**
 	 * Sets the cipher key for the given module. This function updates the key
 	 * at runtime, but it does not write to the config file.
-	 * To write the new unlock key to the config file use code like this:
+	 * This method is NOT the recommended means for applying a CipherKey
+	 * to a module.
 	 *
+	 * Typically CipherKey entries and other per module user configuration
+	 * settings are all saved in a separate localConfig.conf that is updated
+	 * by a UI or other client of the library. e.g.,
+	 *
+	 *
+	 * [KJV]
+	 * Font=Arial
+	 * LocalOptionFilter=SomeSpecialFilterMyUIAppliesToTheKJV
+	 *
+	 * [ISV]
+	 * CipherKey=xyzzy
+	 *
+	 * [StrongsGreek]
+	 * SomeUISetting=false
+	 *
+	 *
+	 * Then these extra config settings in this separate file are applied
+	 * just before module creation by overriding SWMgr::createAllModules and
+	 * augmenting SWMgr::config with code like this:
+	 *
 	 * @code
-	 * SectionMap::iterator section;
-	 * ConfigEntMap::iterator entry;
-	 * DIR *dir = opendir(configPath);
-	 * struct dirent *ent;
-	 * char* modFile;
-	 * if (dir) {    // find and update .conf file
-	 *   rewinddir(dir);
-	 *   while ((ent = readdir(dir)))
-	 *   {
-	 *     if ((strcmp(ent->d_name, ".")) && (strcmp(ent->d_name, "..")))
-	 *     {
-	 *       modFile = m_backend->configPath;
-	 *       modFile += "/";
-	 *       modFile += ent->d_name;
-	 *       SWConfig *myConfig = new SWConfig( modFile );
-	 *       section = myConfig->Sections.find( m_module->Name() );
-	 *       if ( section != myConfig->Sections.end() )
-	 *       {
-	 *         entry = section->second.find("CipherKey");
-	 *         if (entry != section->second.end())
-	 *         {
-	 *           entry->second = unlockKey;//set cipher key
-	 *           myConfig->Save();//save config file
-	 *         }
-	 *       }
-	 *       delete myConfig;
-	 *     }
-	 *   }
+	 * void createAllModules(bool multiMod) {
+	 *
+	 * 	// after SWMgr::config is loaded
+	 *	// see if we have our own local settings
+	 * 	SWBuf myExtraConf = "~/.myapp/localConf.conf";
+	 * 	bool exists = FileMgr::existsFile(extraConf);
+	 * 	if (exists) {
+	 * 		SWConfig addConfig(extraConf);
+	 * 		this->config->augment(addConfig);
+	 * 	}
+	 *
+	 * 	// now that we've augmented SWMgr::config with our own custom
+	 * 	// settings, proceed on with creating modules
+	 *
+	 * 	SWMgr::createAllModules(multiMod);
+	 *
 	 * }
-	 * closedir(dir);
 	 * @endcode
 	 *
+	 * The above convention is preferred to using this setCipherKey method
+	 *
 	 * @param modName For this module we change the unlockKey
-	 * @param key This is the new unlck key we use for te module.
+	 * @param key This is the new unlock key we use for the module.
 	 */
 	virtual signed char setCipherKey(const char *modName, const char *key);
 };

Modified: branches/sword-1-8-x/include/swoptfilter.h
===================================================================
--- branches/sword-1-8-x/include/swoptfilter.h	2017-11-01 11:33:56 UTC (rev 3514)
+++ branches/sword-1-8-x/include/swoptfilter.h	2017-11-01 11:38:09 UTC (rev 3515)
@@ -80,7 +80,7 @@
 	virtual const char *getOptionValue();
 
 	/** sets the value of the option of this filter,
-	 * e.g maybe a strong's filter mioght be set to "on" / "off" -
+	 * e.g maybe a strong's filter might be set to "On" / "Off" -
 	 * that would mean to show or not to show the strongs in the text,
 	 * see also getOptionValues()
 	 * @param ival the new option value

Modified: branches/sword-1-8-x/include/swversion.h
===================================================================
--- branches/sword-1-8-x/include/swversion.h	2017-11-01 11:33:56 UTC (rev 3514)
+++ branches/sword-1-8-x/include/swversion.h	2017-11-01 11:38:09 UTC (rev 3515)
@@ -24,11 +24,11 @@
 #ifndef SWVERSION_H
 #define SWVERSION_H
 
-#define SWORD_VERSION_NUM 107903000
-#define SWORD_VERSION_STR "1.7.903"
+#define SWORD_VERSION_NUM 107904000
+#define SWORD_VERSION_STR "1.7.904"
 #define SWORD_VERSION_MAJOR 1
 #define SWORD_VERSION_MINOR 7
-#define SWORD_VERSION_MICRO 903
+#define SWORD_VERSION_MICRO 904
 #define SWORD_VERSION_NANO 0
 
 #include <defs.h>

Modified: branches/sword-1-8-x/include/utilstr.h
===================================================================
--- branches/sword-1-8-x/include/utilstr.h	2017-11-01 11:33:56 UTC (rev 3514)
+++ branches/sword-1-8-x/include/utilstr.h	2017-11-01 11:38:09 UTC (rev 3515)
@@ -29,9 +29,29 @@
 
 SWORD_NAMESPACE_START
 
-/** stdstr - clone a string
-*/
-SWDLLEXPORT char *stdstr (char **iistr, const char *istr, unsigned int memPadFactor = 1);
+
+/******************************************************************************
+ * stdstr - clones a string
+ *
+ * ENT:	ipstr	- pointer to a string pointer to set if necessary
+ *	istr	- string to set to *ipstr
+ *			0 - only get
+ *
+ * RET:	*ipstr
+ */
+
+inline char *stdstr(char **ipstr, const char *istr, unsigned int memPadFactor = 1) {
+	if (*ipstr)
+		delete [] *ipstr;
+	if (istr) {
+		int len = (int)strlen(istr) + 1;
+		*ipstr = new char [ len * memPadFactor ];
+		memcpy(*ipstr, istr, len);
+	}
+	else *ipstr = 0;
+	return *ipstr;
+}
+
 SWDLLEXPORT char *strstrip (char *istr);
 SWDLLEXPORT const char *stristr (const char *s1, const char *s2);
 SWDLLEXPORT int strnicmp(const char *s1, const char *s2, int len);
@@ -55,9 +75,82 @@
  * 		unicode codepoint value (0 with buf incremented is invalid UTF8 byte
  */
 
-__u32 getUniCharFromUTF8(const unsigned char **buf);
 
+/******************************************************************************
+ * getUniCharFromUTF8 - retrieves the next Unicode codepoint from a UTF8 string
+ * 					and increments buf to start of next codepoint
+ *
+ * ENT:	buf - address of a utf8 buffer
+ *
+ * RET:	buf - incremented past last byte used in computing the current codepoint
+ * 		unicode codepoint value (0 with buf incremented is invalid UTF8 byte
+ */
 
+inline __u32 getUniCharFromUTF8(const unsigned char **buf, bool skipValidation = false) {
+	__u32 ch = 0;
+
+	//case: We're at the end
+	if (!(**buf)) {
+		return ch;
+	}
+
+	//case: ANSI
+	if (!(**buf & 128)) {
+		ch = **buf;
+		(*buf)++;
+		return ch;
+	}
+
+	//case: Invalid UTF-8 (illegal continuing byte in initial position)
+	if ((**buf >> 6) == 2) {
+		(*buf)++;
+		return ch;
+	}
+
+
+	//case: 2+ byte codepoint
+	int subsequent = 1;
+	if ((**buf & 32) == 0) { subsequent = 1; }
+	else if ((**buf & 16) == 0) { subsequent = 2; }
+	else if ((**buf &  8) == 0) { subsequent = 3; }
+	else if ((**buf &  4) == 0) { subsequent = 4; }
+	else if ((**buf &  2) == 0) { subsequent = 5; }
+	else if ((**buf &  1) == 0) { subsequent = 6; }
+	else subsequent = 7; // is this legal?
+
+	ch = **buf & (0xFF>>(subsequent + 1));
+
+	for (int i = 1; i <= subsequent; ++i) {
+		// subsequent byte did not begin with 10XXXXXX
+		// move our buffer to here and error out
+		// this also catches our null if we hit the string terminator
+		if (((*buf)[i] >> 6) != 2) {
+			*buf += i;
+			return 0;
+		}
+		ch <<= 6;
+		ch |= (*buf)[i] & 63;
+	}
+	*buf += (subsequent+1);
+
+	if (!skipValidation) {
+		// I THINK THIS IS STUPID BUT THE SPEC SAYS NO MORE THAN 4 BYTES
+		if (subsequent > 3) ch = 0;
+		// AGAIN stupid, but spec says UTF-8 can't use more than 21 bits
+		if (ch > 0x1FFFFF) ch = 0;
+		// This would be out of Unicode bounds
+		if (ch > 0x10FFFF) ch = 0;
+		// these would be values which could be represented in less bytes
+		if (ch < 0x80 && subsequent > 0) ch = 0;
+		if (ch < 0x800 && subsequent > 1) ch = 0;
+		if (ch < 0x10000 && subsequent > 2) ch = 0;
+		if (ch < 0x200000 && subsequent > 3) ch = 0;
+	}
+
+	return ch;
+}
+
+
 /******************************************************************************
  * getUTF8FromUniChar - retrieves us UTF8 string from a
  * 					Unicode codepoint
@@ -66,11 +159,95 @@
  *
  * RET:	buf - a UTF8 string which consists of the proper UTF8 sequence of
  * 				bytes for the given Unicode codepoint
+ * NOTE: for speed and thread safety, this method now requires a buffer
+ * 		to work with
  */
 
-SWBuf getUTF8FromUniChar(__u32 uchar);
+inline SWBuf *getUTF8FromUniChar(__u32 uchar, SWBuf *appendTo) {
+	unsigned long base = appendTo->size();
 
+	// This would be out of Unicode bounds
+	if (uchar > 0x10FFFF) uchar = 0xFFFD;
+	char bytes = uchar < 0x80 ? 1 : uchar < 0x800 ? 2 : uchar < 0x10000 ? 3 : 4;
+	appendTo->setSize(base+bytes);
+	switch (bytes) {
+	case 1:
+		(*appendTo)[base  ] = (unsigned char)uchar;
+		break;
+	case 2:
+		(*appendTo)[base+1] = (unsigned char)(0x80 | (uchar & 0x3f));
+		uchar >>= 6;
+		(*appendTo)[base  ] = (unsigned char)(0xc0 | (uchar & 0x1f));
+		break;
+	case 3:
+		(*appendTo)[base+2] = (unsigned char)(0x80 | (uchar & 0x3f));
+		uchar >>= 6;
+		(*appendTo)[base+1] = (unsigned char)(0x80 | (uchar & 0x3f));
+		uchar >>= 6;
+		(*appendTo)[base  ] = (unsigned char)(0xe0 | (uchar & 0x0f));
+		break;
+	case 4:
+		(*appendTo)[base+3] = (unsigned char)(0x80 | (uchar & 0x3f));
+		uchar >>= 6;
+		(*appendTo)[base+2] = (unsigned char)(0x80 | (uchar & 0x3f));
+		uchar >>= 6;
+		(*appendTo)[base+1] = (unsigned char)(0x80 | (uchar & 0x3f));
+		uchar >>= 6;
+		(*appendTo)[base  ] = (unsigned char)(0xf0 | (uchar & 0x07));
+		break;
+	}
+/*
+	else if (uchar < 0x4000000) {
+		appendTo->setSize(base+5);
+		i = uchar & 0x3f;
+		(*appendTo)[base+4] = (unsigned char)(0x80 | i);
+		uchar >>= 6;
 
+		i = uchar & 0x3f;
+		(*appendTo)[base+3] = (unsigned char)(0x80 | i);
+		uchar >>= 6;
+
+		i = uchar & 0x3f;
+		(*appendTo)[base+2] = (unsigned char)(0x80 | i);
+		uchar >>= 6;
+
+		i = uchar & 0x3f;
+		(*appendTo)[base+1] = (unsigned char)(0x80 | i);
+		uchar >>= 6;
+
+		i = uchar & 0x03;
+		(*appendTo)[base] = (unsigned char)(0xf8 | i);
+	}
+	else if (uchar < 0x80000000) {
+		appendTo->setSize(base+6);
+		i = uchar & 0x3f;
+		(*appendTo)[base+5] = (unsigned char)(0x80 | i);
+		uchar >>= 6;
+
+		i = uchar & 0x3f;
+		(*appendTo)[base+4] = (unsigned char)(0x80 | i);
+		uchar >>= 6;
+
+		i = uchar & 0x3f;
+		(*appendTo)[base+3] = (unsigned char)(0x80 | i);
+		uchar >>= 6;
+
+		i = uchar & 0x3f;
+		(*appendTo)[base+2] = (unsigned char)(0x80 | i);
+		uchar >>= 6;
+
+		i = uchar & 0x3f;
+		(*appendTo)[base+1] = (unsigned char)(0x80 | i);
+		uchar >>= 6;
+
+		i = uchar & 0x01;
+		(*appendTo)[base] = (unsigned char)(0xfc | i);
+	}
+*/
+	return appendTo;
+}
+
+
 /******************************************************************************
  * assureValidUTF8 - iterates the supplied UTF-8 buffer and checks for validity
  * 					replacing invalid bytes if necessary and returning a

Modified: branches/sword-1-8-x/locales.d/zh_CN-utf8.conf
===================================================================
--- branches/sword-1-8-x/locales.d/zh_CN-utf8.conf	2017-11-01 11:33:56 UTC (rev 3514)
+++ branches/sword-1-8-x/locales.d/zh_CN-utf8.conf	2017-11-01 11:38:09 UTC (rev 3515)
@@ -74,68 +74,134 @@
 [Book Abbrevs]
 
 创世记=Gen
+创=Gen
 出埃及记=Exod
+出=Exod
 利未记=Lev
+利=Lev
 æ°‘æ•°è®°=Num
+æ°‘=Num
 申命记=Deut
+申=Deut
 约书亚记=Josh
+书=Josh
 士师记=Judg
+士=Judg
 路得记=Ruth
+å¾—=Ruth
 撒母耳记上=1Sam
+撒上=1Sam
 撒母耳记下=2Sam
+撒下=2Sam
 列王记上=1Kgs
+王上=1Kgs
 列王记下=2Kgs
+王下=2Kgs
 历代志上=1Chr
+代上=1Chr
 历代志下=2Chr
+代下=2Chr
 以斯拉记=Ezra
+拉=Ezra
 尼希米记=Neh
+å°¼=Neh
 以斯帖记=Esth
+æ–¯=Esth
 约伯记=Job
+伯=Job
 诗篇=Ps
+诗=Ps
 箴言=Prov
+ç®´=Prov
 传道书=Eccl
+ä¼ =Eccl
 雅歌=Song
-以賽亚书=Isa
+歌=Song
+以赛亚书=Isa
+èµ›=Isa
 耶利米书=Jer
+耶=Jer
 耶利米哀歌=Lam
-以西結书=Ezek
+å“€=Lam
+以西结书=Ezek
+结=Ezek
 但以理书=Dan
+但=Dan
 何西阿书=Hos
+何=Hos
 约珥书=Joel
+珥=Joel
 阿摩司书=Amos
+æ‘©=Amos
 俄巴底亚书=Obad
+ä¿„=Obad
 约拿书=Jonah
+æ‹¿=Jonah
 弥迦书=Mic
-那鴻书=Nah
+å¼¥=Mic
+那鸿书=Nah
+鸿=Nah
 哈巴谷书=Hab
+哈=Hab
 西番雅书=Zeph
-哈該书=Hag
+番=Zeph
+哈该书=Hag
+该=Hag
 撒迦利亚书=Zech
+亚=Zech
 玛拉基书=Mal
+玛=Mal
 马太福音=Matt
+太=Matt
 马可福音=Mark
+可=Mark
 路加福音=Luke
+è·¯=Luke
 约翰福音=John
+约=John
 使徒行传=Acts
+å¾’=Acts
 罗马书=Rom
+ç½—=Rom
 哥林多前书=1Cor
+林前=1Cor
 哥林多后书=2Cor
+林后=2Cor
 加拉太书=Gal
+加=Gal
 以弗所书=Eph
+å¼—=Eph
 腓立比书=Phil
+è…“=Phil
 歌罗西书=Col
+西=Col
 帖撒罗尼迦前书=1Thess
+帖前=1Thess
 帖撒罗尼迦后书=2Thess
+帖后=2Thess
 提摩太前书=1Tim
+提前=1Tim
 提摩太后书=2Tim
+提后=2Tim
 提多书=Titus
+多=Titus
 腓利门书=Phlm
-希伯來书=Heb
+é—¨=Phlm
+希伯来书=Heb
+来=Heb
 雅各书=Jas
+é›…=Jas
 彼得前书=1Pet
+彼前=1Pet
 彼得后书=2Pet
+彼后=2Pet
 约翰一书=1John
+约壹=1John
 约翰二书=2John
+约贰=2John
 约翰三书=3John
+约叁=3John
 犹大书=Jude
+犹=Jude
 启示录=Rev
+启=Rev

Modified: branches/sword-1-8-x/src/keys/treekeyidx.cpp
===================================================================
--- branches/sword-1-8-x/src/keys/treekeyidx.cpp	2017-11-01 11:33:56 UTC (rev 3514)
+++ branches/sword-1-8-x/src/keys/treekeyidx.cpp	2017-11-01 11:38:09 UTC (rev 3515)
@@ -62,7 +62,7 @@
 	buf.setFormatted("%s.dat", path);
 	datfd = FileMgr::getSystemFileMgr()->open(buf, fileMode, true);
 
-	if (datfd <= 0) {
+	if (!datfd || datfd->getFd() < 0) {
 		SWLog::getSystemLog()->logError("%d", errno);
 		error = errno;
 	}
@@ -332,7 +332,7 @@
 	__s32  tmp;
 	__u16  tmp2;
 
-	if (datfd > 0) {
+	if (datfd && datfd->getFd() >= 0) {
 
 		datfd->seek(ioffset, SEEK_SET);
 
@@ -386,21 +386,19 @@
 	}
 
 	node->offset = (__s32)ioffset;
-	if (idxfd > 0) {
-		if (idxfd->getFd() > 0) {
-			idxfd->seek(ioffset, SEEK_SET);
+	if (idxfd && idxfd->getFd() >= 0) {
+		idxfd->seek(ioffset, SEEK_SET);
+		if (idxfd->read(&offset, 4) == 4) {
+			offset = swordtoarch32(offset);
+			error = (error == 77) ? KEYERR_OUTOFBOUNDS : 0;
+			getTreeNodeFromDatOffset(offset, node);
+		}
+		else {
+			idxfd->seek(-4, SEEK_END);
 			if (idxfd->read(&offset, 4) == 4) {
 				offset = swordtoarch32(offset);
-				error = (error == 77) ? KEYERR_OUTOFBOUNDS : 0;
 				getTreeNodeFromDatOffset(offset, node);
 			}
-			else {
-				idxfd->seek(-4, SEEK_END);
-				if (idxfd->read(&offset, 4) == 4) {
-					offset = swordtoarch32(offset);
-					getTreeNodeFromDatOffset(offset, node);
-				}
-			}
 		}
 	}
 	return error;
@@ -423,7 +421,7 @@
 	long datOffset = 0;
 	__s32 tmp;
 
-	if (idxfd > 0) {
+	if (idxfd && idxfd->getFd() >= 0) {
 		idxfd->seek(node->offset, SEEK_SET);
 		if (idxfd->read(&tmp, 4) != 4) {
 			datOffset = datfd->seek(0, SEEK_END);
@@ -489,7 +487,7 @@
 void TreeKeyIdx::saveTreeNode(TreeNode *node) {
 	long datOffset = 0;
 	__s32 tmp;
-	if (idxfd > 0) {
+	if (idxfd && idxfd->getFd() >= 0) {
 
 		idxfd->seek(node->offset, SEEK_SET);
 		datOffset = datfd->seek(0, SEEK_END);

Modified: branches/sword-1-8-x/src/mgr/Makefile.am
===================================================================
--- branches/sword-1-8-x/src/mgr/Makefile.am	2017-11-01 11:33:56 UTC (rev 3514)
+++ branches/sword-1-8-x/src/mgr/Makefile.am	2017-11-01 11:38:09 UTC (rev 3515)
@@ -15,6 +15,9 @@
 else
 FTP_SOURCES = $(mgrdir)/ftplibftpt.cpp
 endif
+if WITHGAPI
+FTP_SOURCES += $(mgrdir)/rtranspgdrive.cpp
+endif
 
 libsword_la_SOURCES += $(FTP_SOURCES)
 libsword_la_SOURCES += $(mgrdir)/swconfig.cpp

Modified: branches/sword-1-8-x/src/mgr/curlhttpt.cpp
===================================================================
--- branches/sword-1-8-x/src/mgr/curlhttpt.cpp	2017-11-01 11:33:56 UTC (rev 3514)
+++ branches/sword-1-8-x/src/mgr/curlhttpt.cpp	2017-11-01 11:38:09 UTC (rev 3515)
@@ -141,7 +141,9 @@
 		curl_easy_setopt(session, CURLOPT_CONNECTTIMEOUT, 45);
 		
 		/* Disable checking host certificate */
-		curl_easy_setopt(session, CURLOPT_SSL_VERIFYPEER, false);
+		if (isUnverifiedPeerAllowed()) {
+			curl_easy_setopt(session, CURLOPT_SSL_VERIFYPEER, false);
+		}
 
 		/* FTP connection settings */
 

Modified: branches/sword-1-8-x/src/mgr/filemgr.cpp
===================================================================
--- branches/sword-1-8-x/src/mgr/filemgr.cpp	2017-11-01 11:33:56 UTC (rev 3514)
+++ branches/sword-1-8-x/src/mgr/filemgr.cpp	2017-11-01 11:38:09 UTC (rev 3515)
@@ -24,6 +24,7 @@
 #include <filemgr.h>
 #include <utilstr.h>
 
+#include <stdlib.h>
 #include <dirent.h>
 #include <fcntl.h>
 #include <sys/stat.h>
@@ -131,15 +132,6 @@
 }
 
 
-int FileDesc::getFd() {
-	if (fd == -77)
-		fd = parent->sysOpen(this);
-//	if ((fd < -1) && (fd != -77))  // kludge to hand ce
-//		return 777;
-	return fd;
-}
-
-
 long FileDesc::seek(long offset, int whence) {
 	return lseek(getFd(), offset, whence);
 }
@@ -583,4 +575,22 @@
 }
 
 
+SWBuf FileMgr::getHomeDir() {
+
+	// figure out 'home' directory for app data
+	SWBuf homeDir = getenv("HOME");
+	if (!homeDir.length()) {
+		// silly windows
+		homeDir = getenv("APPDATA");
+	}
+	if (homeDir.length()) {
+		if ((homeDir[homeDir.length()-1] != '\\') && (homeDir[homeDir.length()-1] != '/')) {
+			homeDir += "/";
+		}
+	}
+
+	return homeDir;
+}
+
+
 SWORD_NAMESPACE_END

Modified: branches/sword-1-8-x/src/mgr/installmgr.cpp
===================================================================
--- branches/sword-1-8-x/src/mgr/installmgr.cpp	2017-11-01 11:33:56 UTC (rev 3514)
+++ branches/sword-1-8-x/src/mgr/installmgr.cpp	2017-11-01 11:38:09 UTC (rev 3515)
@@ -101,6 +101,8 @@
 
 InstallMgr::InstallMgr(const char *privatePath, StatusReporter *sr, SWBuf u, SWBuf p) {
 	userDisclaimerConfirmed = false;
+	passive=true;
+	unverifiedPeerAllowed=true;
 	statusReporter = sr;
 	this->u = u;
 	this->p = p;
@@ -145,12 +147,13 @@
 	clearSources();
 	
 	setFTPPassive(stricmp((*installConf)["General"]["PassiveFTP"].c_str(), "false") != 0);
+	setUnverifiedPeerAllowed(stricmp((*installConf)["General"]["UnverifiedPeerAllowed"].c_str(), "false") != 0);
 
-	SectionMap::iterator confSection = installConf->Sections.find("Sources");
+	SectionMap::iterator confSection = installConf->getSections().find("Sources");
 	ConfigEntMap::iterator sourceBegin;
 	ConfigEntMap::iterator sourceEnd;
 
-	if (confSection != installConf->Sections.end()) {
+	if (confSection != installConf->getSections().end()) {
 
 		sourceBegin = confSection->second.lower_bound("FTPSource");
 		sourceEnd = confSection->second.upper_bound("FTPSource");
@@ -204,8 +207,8 @@
 	}
 
 	defaultMods.clear();
-	confSection = installConf->Sections.find("General");
-	if (confSection != installConf->Sections.end()) {
+	confSection = installConf->getSections().find("General");
+	if (confSection != installConf->getSections().end()) {
 		sourceBegin = confSection->second.lower_bound("DefaultMod");
 		sourceEnd = confSection->second.upper_bound("DefaultMod");
 
@@ -219,16 +222,17 @@
 
 void InstallMgr::saveInstallConf() {
 
-	installConf->Sections["Sources"].clear();
+	installConf->getSection("Sources").clear();
 
 	for (InstallSourceMap::iterator it = sources.begin(); it != sources.end(); ++it) {
 		if (it->second) {
-			installConf->Sections["Sources"].insert(ConfigEntMap::value_type(it->second->type + "Source", it->second->getConfEnt().c_str()));
+			installConf->getSection("Sources").insert(ConfigEntMap::value_type(it->second->type + "Source", it->second->getConfEnt().c_str()));
 		}
 	}
 	(*installConf)["General"]["PassiveFTP"] = (isFTPPassive()) ? "true" : "false";
+	(*installConf)["General"]["UnverifiedPeerAllowed"] = (isUnverifiedPeerAllowed()) ? "true" : "false";
 
-	installConf->Save();
+	installConf->save();
 }
 
 
@@ -243,9 +247,9 @@
 	// save our own copy, cuz when we remove the module from the SWMgr
 	// it's likely we'll free the memory passed to us in moduleName
 	SWBuf modName = moduleName;
-	module = manager->config->Sections.find(modName);
+	module = manager->config->getSections().find(modName);
 
-	if (module != manager->config->Sections.end()) {
+	if (module != manager->config->getSections().end()) {
 		// to be sure all files are closed
 		// this does not remove the .conf information from SWMgr
 		manager->deleteModule(modName);
@@ -285,7 +289,7 @@
 						modFile += "/";
 						modFile += ent->d_name;
 						SWConfig *config = new SWConfig(modFile.c_str());
-						if (config->Sections.find(modName) != config->Sections.end()) {
+						if (config->getSections().find(modName) != config->getSections().end()) {
 							delete config;
 							FileMgr::removeFile(modFile.c_str());
 						}
@@ -332,6 +336,8 @@
 		trans->setPasswd(p);
 	}
 
+	trans->setUnverifiedPeerAllowed(unverifiedPeerAllowed);
+
 	SWBuf urlPrefix;
 	if (is->type == "HTTP") {
 		urlPrefix = (SWBuf) "http://";
@@ -421,9 +427,9 @@
 
 	SWMgr mgr(sourceDir.c_str());
 	
-	module = mgr.config->Sections.find(modName);
+	module = mgr.config->getSections().find(modName);
 
-	if (module != mgr.config->Sections.end()) {
+	if (module != mgr.config->getSections().end()) {
 	
 		entry = module->second.find("CipherKey");
 		if (entry != module->second.end())
@@ -523,7 +529,7 @@
 						modFile = confDir;
 						modFile += ent->d_name;
 						SWConfig *config = new SWConfig(modFile.c_str());
-						if (config->Sections.find(modName) != config->Sections.end()) {
+						if (config->getSections().find(modName) != config->getSections().end()) {
 							SWBuf targetFile = destMgr->configPath; //"./mods.d/";
 							removeTrailingSlash(targetFile);
 							targetFile += "/";
@@ -536,7 +542,7 @@
 									aborted = true;
 								}
 								else {
-									config->Save();
+									config->save();
 									retVal = FileMgr::copyFile(modFile.c_str(), targetFile.c_str());
 								}
 							}
@@ -662,8 +668,8 @@
 	int errorCode = remoteCopy(&is, masterRepoList, masterRepoListPath.c_str(), false);
 	if (!errorCode) { //sucessfully downloaded the repo list
 		SWConfig masterList(masterRepoListPath);
-		SectionMap::iterator sections = masterList.Sections.find("Repos");
-		if (sections != masterList.Sections.end()) {
+		SectionMap::iterator sections = masterList.getSections().find("Repos");
+		if (sections != masterList.getSections().end()) {
 			for (ConfigEntMap::iterator actions = sections->second.begin(); actions != sections->second.end(); actions++) {
 				// Search through our current sources and see if we have a matching UID
 				InstallSourceMap::iterator it;

Modified: branches/sword-1-8-x/src/mgr/localemgr.cpp
===================================================================
--- branches/sword-1-8-x/src/mgr/localemgr.cpp	2017-11-01 11:33:56 UTC (rev 3514)
+++ branches/sword-1-8-x/src/mgr/localemgr.cpp	2017-11-01 11:38:09 UTC (rev 3515)
@@ -85,7 +85,7 @@
 		SWLog::getSystemLog()->logDebug("LOOKING UP LOCALE DIRECTORY...");
 		SWMgr::findConfig(&configType, &prefixPath, &configPath, &augPaths, &sysConf);
 		if (sysConf) {
-			if ((entry = sysConf->Sections["Install"].find("LocalePath")) != sysConf->Sections["Install"].end()) {
+			if ((entry = sysConf->getSection("Install").find("LocalePath")) != sysConf->getSection("Install").end()) {
 				configType = 9;	// our own
 				stdstr(&prefixPath, (char *)entry->second.c_str());
 				SWLog::getSystemLog()->logDebug("LocalePath provided in sysConfig.");

Modified: branches/sword-1-8-x/src/mgr/remotetrans.cpp
===================================================================
--- branches/sword-1-8-x/src/mgr/remotetrans.cpp	2017-11-01 11:33:56 UTC (rev 3514)
+++ branches/sword-1-8-x/src/mgr/remotetrans.cpp	2017-11-01 11:38:09 UTC (rev 3515)
@@ -65,6 +65,8 @@
 	u = "ftp";
 	p = "installmgr at user.com";
 	term = false;
+	passive = true;
+	unverifiedPeerAllowed = true;
 }
 
 
@@ -74,14 +76,22 @@
 
 // override this method in your real transport class
 char RemoteTransport::getURL(const char *destPath, const char *sourceURL, SWBuf *destBuf) {
-	char retVal = 0;
+	SWLog::getSystemLog()->logWarning("RemoteTransport::getURL called but unsupported");
+	char retVal = -1;
 	return retVal;
 }
 
+// override this method in your real transport class
+char RemoteTransport::putURL(const char *destURL, const char *sourcePath, SWBuf *sourceBuf) {
+	SWLog::getSystemLog()->logWarning("RemoteTransport::putURL called but unsupported");
+	char retVal = -1;
+	return retVal;
+}
 
+
 vector<struct DirEntry> RemoteTransport::getDirList(const char *dirURL) {
 
-SWLog::getSystemLog()->logDebug("RemoteTransport::getDirList(%s)", dirURL);
+	SWLog::getSystemLog()->logDebug("RemoteTransport::getDirList(%s)", dirURL);
 	vector<struct DirEntry> dirList;
 	
 	SWBuf dirBuf;

Copied: branches/sword-1-8-x/src/mgr/rtranspgdrive.cpp (from rev 3513, trunk/src/mgr/rtranspgdrive.cpp)
===================================================================
--- branches/sword-1-8-x/src/mgr/rtranspgdrive.cpp	                        (rev 0)
+++ branches/sword-1-8-x/src/mgr/rtranspgdrive.cpp	2017-11-01 11:38:09 UTC (rev 3515)
@@ -0,0 +1,174 @@
+/*****************************************************************************
+ *
+ *  rtranspgdrive.cpp -	RTransportGDrive
+ *
+ * $Id$
+ *
+ * Copyright 2004-2013 CrossWire Bible Society (http://www.crosswire.org)
+ *	CrossWire Bible Society
+ *	P. O. Box 2528
+ *	Tempe, AZ  85280-2528
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation version 2.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ */
+
+#include <rtranspgdrive.h>
+
+#include <fcntl.h>
+
+#include <swlog.h>
+
+
+SWORD_NAMESPACE_START
+
+namespace {
+
+	struct FtpFile {
+		const char *filename;
+		FILE *stream;
+		SWBuf *destBuf;
+	};
+
+
+	// initialize/cleanup SYSTEMWIDE library with life of this static.
+	static class RTransportGDrive_init {
+	public:
+		RTransportGDrive_init() {
+		}
+
+		~RTransportGDrive_init() {
+		}
+	} _rTransportGDrive_init;
+
+
+	static int my_fwrite(void *buffer, size_t size, size_t nmemb, void *stream) {
+		struct FtpFile *out=(struct FtpFile *)stream;
+		if (out && !out->stream && !out->destBuf) {
+			/* open file for writing */
+			out->stream=fopen(out->filename, "wb");
+			if (!out->stream)
+				return -1; /* failure, can't open file to write */
+		}
+		if (out->destBuf) {
+			int s = (int)out->destBuf->size();
+			out->destBuf->size(s+(size*nmemb));
+			memcpy(out->destBuf->getRawData()+s, buffer, size*nmemb);
+			return (int)nmemb;
+		}
+		return (int)fwrite(buffer, size, nmemb, out->stream);
+	}
+
+
+	struct MyProgressData {
+		StatusReporter *sr;
+		bool *term;
+	};
+
+
+	static int my_fprogress(void *clientp, double dltotal, double dlnow, double ultotal, double ulnow) {
+		if (clientp) {
+			MyProgressData *pd = (MyProgressData *)clientp;
+			SWLog::getSystemLog()->logDebug("CURLFTPTransport report progress: totalSize: %ld; xfered: %ld\n", (long)dltotal, (long)dlnow);
+			if (pd->sr) {
+				if (dltotal < 0) dltotal = 0;
+				if (dlnow < 0) dlnow = 0;
+				if (dlnow > dltotal) dlnow = dltotal;
+				pd->sr->update(dltotal, dlnow);
+			}
+			if (*(pd->term)) return 1;
+		}
+		return 0;
+	}
+}
+
+
+RTransportGDrive::RTransportGDrive(const char *host, StatusReporter *sr) : RemoteTransport(host, sr) {
+	// session open
+}
+
+
+RTransportGDrive::~RTransportGDrive() {
+	// session cleanup
+}
+
+
+char RTransportGDrive::putURL(const char *destURL, const char *sourcePath, SWBuf *sourceBuf) {
+	return RemoteTransport::putURL();
+}
+char RTransportGDrive::getURL(const char *destPath, const char *sourceURL, SWBuf *destBuf) {
+	signed char retVal = 0;
+	struct FtpFile ftpfile = {destPath, 0, destBuf};
+#if 0
+	
+	if (session) {
+
+		CURLcode res;
+
+		struct MyProgressData pd;
+		pd.sr = statusReporter;
+		pd.term = &term;
+
+		curl_easy_setopt(session, CURLOPT_URL, sourceURL);
+	
+		SWBuf credentials = u + ":" + p;
+		curl_easy_setopt(session, CURLOPT_USERPWD, credentials.c_str());
+		curl_easy_setopt(session, CURLOPT_WRITEFUNCTION, my_fwrite);
+		if (!passive)
+			curl_easy_setopt(session, CURLOPT_FTPPORT, "-");
+		curl_easy_setopt(session, CURLOPT_NOPROGRESS, 0);
+		curl_easy_setopt(session, CURLOPT_PROGRESSDATA, &pd);
+		curl_easy_setopt(session, CURLOPT_PROGRESSFUNCTION, my_fprogress);
+		curl_easy_setopt(session, CURLOPT_DEBUGFUNCTION, my_trace);
+		/* Set a pointer to our struct to pass to the callback */
+		curl_easy_setopt(session, CURLOPT_FILE, &ftpfile);
+
+		/* Switch on full protocol/debug output */
+		curl_easy_setopt(session, CURLOPT_VERBOSE, true);
+		curl_easy_setopt(session, CURLOPT_CONNECTTIMEOUT, 45);
+		
+		/* FTP connection settings */
+
+#if (LIBCURL_VERSION_MAJOR > 7) || \
+   ((LIBCURL_VERSION_MAJOR == 7) && (LIBCURL_VERSION_MINOR > 10)) || \
+   ((LIBCURL_VERSION_MAJOR == 7) && (LIBCURL_VERSION_MINOR == 10) && (LIBCURL_VERSION_PATCH >= 5))
+#      define EPRT_AVAILABLE 1
+#endif
+
+#ifdef EPRT_AVAILABLE
+		curl_easy_setopt(session, CURLOPT_FTP_USE_EPRT, 0);
+		SWLog::getSystemLog()->logDebug("***** using CURLOPT_FTP_USE_EPRT\n");
+#endif
+
+		
+		SWLog::getSystemLog()->logDebug("***** About to perform curl easy action. \n");
+		SWLog::getSystemLog()->logDebug("***** destPath: %s \n", destPath);
+		SWLog::getSystemLog()->logDebug("***** sourceURL: %s \n", sourceURL);
+		res = curl_easy_perform(session);
+		SWLog::getSystemLog()->logDebug("***** Finished performing curl easy action. \n");
+
+		// it seems CURL tries to use this option data later for some reason, so we unset here
+		curl_easy_setopt(session, CURLOPT_PROGRESSDATA, (void*)NULL);
+
+		if(CURLE_OK != res) {
+			retVal = -1;
+		}
+	}
+#endif
+
+	if (ftpfile.stream)
+		fclose(ftpfile.stream); /* close the local file */
+
+	return retVal;
+}
+
+
+SWORD_NAMESPACE_END
+

Modified: branches/sword-1-8-x/src/mgr/swconfig.cpp
===================================================================
--- branches/sword-1-8-x/src/mgr/swconfig.cpp	2017-11-01 11:33:56 UTC (rev 3514)
+++ branches/sword-1-8-x/src/mgr/swconfig.cpp	2017-11-01 11:38:09 UTC (rev 3515)
@@ -29,14 +29,18 @@
 
 SWORD_NAMESPACE_START
 
+#if defined(__GNUC__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
+#endif
 
 SWConfig::SWConfig() {
 }
 
 
-SWConfig::SWConfig(const char * ifilename) {
+SWConfig::SWConfig(const char *ifilename) {
 	filename = ifilename;
-	Load();
+	load();
 }
 
 
@@ -44,10 +48,14 @@
 }
 
 
-void SWConfig::Load() {
+#if defined(__GNUC__)
+#pragma GCC diagnostic pop
+#endif
 
-	if (!filename.size()) return;	// assert we have a filename
+void SWConfig::load() {
 
+	if (!getFileName().size()) return;	// assert we have a filename
+
 	FileDesc *cfile;
 	char *buf, *data;
 	SWBuf line;
@@ -55,9 +63,9 @@
 	SWBuf sectname;
 	bool first = true;
 	
-	Sections.erase(Sections.begin(), Sections.end());
+	getSections().erase(getSections().begin(), getSections().end());
 	
-	cfile = FileMgr::getSystemFileMgr()->open(filename.c_str(), FileMgr::RDONLY);
+	cfile = FileMgr::getSystemFileMgr()->open(getFileName().c_str(), FileMgr::RDONLY);
 	if (cfile->getFd() > 0) {
 		bool goodLine = FileMgr::getLine(cfile, line);
 
@@ -76,7 +84,7 @@
 				strcpy(buf, line.c_str());
 				if (*strstrip(buf) == '[') {
 					if (!first)
-						Sections.insert(SectionMap::value_type(sectname, cursect));
+						getSections().insert(SectionMap::value_type(sectname, cursect));
 					else first = false;
 					
 					cursect.erase(cursect.begin(), cursect.end());
@@ -97,32 +105,32 @@
 			goodLine = FileMgr::getLine(cfile, line);
 		}
 		if (!first)
-			Sections.insert(SectionMap::value_type(sectname, cursect));
+			getSections().insert(SectionMap::value_type(sectname, cursect));
 
 		FileMgr::getSystemFileMgr()->close(cfile);
 	}
 }
 
 
-void SWConfig::Save() {
+void SWConfig::save() const {
 
-	if (!filename.size()) return;	// assert we have a filename
+	if (!getFileName().size()) return;	// assert we have a filename
 
 	FileDesc *cfile;
 	SWBuf buf;
-	SectionMap::iterator sit;
-	ConfigEntMap::iterator entry;
+	SectionMap::const_iterator sit;
+	ConfigEntMap::const_iterator entry;
 	SWBuf sectname;
 	
-	cfile = FileMgr::getSystemFileMgr()->open(filename.c_str(), FileMgr::RDWR|FileMgr::CREAT|FileMgr::TRUNC);
+	cfile = FileMgr::getSystemFileMgr()->open(getFileName().c_str(), FileMgr::RDWR|FileMgr::CREAT|FileMgr::TRUNC);
 	if (cfile->getFd() > 0) {
 		
-		for (sit = Sections.begin(); sit != Sections.end(); sit++) {
+		for (sit = getSections().begin(); sit != getSections().end(); ++sit) {
 			buf =  "\n[";
 			buf += (*sit).first.c_str();
 			buf += "]\n";
 			cfile->write(buf.c_str(), buf.length());
-			for (entry = (*sit).second.begin(); entry != (*sit).second.end(); entry++) {
+			for (entry = (*sit).second.begin(); entry != (*sit).second.end(); ++entry) {
 				buf = (*entry).first.c_str();
 				buf += "=";
 				buf += (*entry).second.c_str();
@@ -142,32 +150,45 @@
 	SectionMap::iterator section;
 	ConfigEntMap::iterator entry, start, end;
 
-	for (section = addFrom.Sections.begin(); section != addFrom.Sections.end(); section++) {
-		for (entry = (*section).second.begin(); entry != (*section).second.end(); entry++) {
-			start = Sections[section->first].lower_bound(entry->first);
-			end   = Sections[section->first].upper_bound(entry->first);
+	for (section = addFrom.getSections().begin(); section != addFrom.getSections().end(); ++section) {
+		for (entry = (*section).second.begin(); entry != (*section).second.end(); ++entry) {
+			start = getSections()[section->first].lower_bound(entry->first);
+			end   = getSections()[section->first].upper_bound(entry->first);
 			if (start != end) {
 				if (((++start) != end)
-						|| ((++(addFrom.Sections[section->first].lower_bound(entry->first))) != addFrom.Sections[section->first].upper_bound(entry->first))) {
-					for (--start; start != end; start++) {
+						|| ((++(addFrom.getSections()[section->first].lower_bound(entry->first))) != addFrom.getSections()[section->first].upper_bound(entry->first))) {
+					for (--start; start != end; ++start) {
 						if (!strcmp(start->second.c_str(), entry->second.c_str()))
 							break;
 					}
 					if (start == end)
-						Sections[(*section).first].insert(ConfigEntMap::value_type((*entry).first, (*entry).second));
+						getSections()[(*section).first].insert(ConfigEntMap::value_type((*entry).first, (*entry).second));
 				}
-				else	Sections[section->first][entry->first.c_str()] = entry->second.c_str();
+				else	getSections()[section->first][entry->first.c_str()] = entry->second.c_str();
 			}		
-			else	Sections[section->first][entry->first.c_str()] = entry->second.c_str();
+			else	getSections()[section->first][entry->first.c_str()] = entry->second.c_str();
 		}
 	}
 }
 
 
-ConfigEntMap & SWConfig::operator [] (const char *section) {
-    return Sections[section];
-}
+#if defined(__GNUC__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
+#endif
 
+// TODO: use deprecated public 'Sections' property for now until we remove deprecation
+// and store in private property
+SectionMap &SWConfig::getSections() { return Sections; }
 
+// TODO: use deprecated public 'filename' property for now until we remove deprecation
+// and store in private property
+	
+SWBuf SWConfig::getFileName() const { return filename; }
+
+#if defined(__GNUC__)
+#pragma GCC diagnostic pop
+#endif
+
 SWORD_NAMESPACE_END
 

Modified: branches/sword-1-8-x/src/mgr/swlocale.cpp
===================================================================
--- branches/sword-1-8-x/src/mgr/swlocale.cpp	2017-11-01 11:33:56 UTC (rev 3514)
+++ branches/sword-1-8-x/src/mgr/swlocale.cpp	2017-11-01 11:38:09 UTC (rev 3515)
@@ -69,16 +69,16 @@
 		for (abbrevsCnt = 0; builtin_abbrevs[abbrevsCnt].osis[0]; abbrevsCnt++);
 	}
 
-	confEntry = localeSource->Sections["Meta"].find("Name");
-	if (confEntry != localeSource->Sections["Meta"].end())
+	confEntry = localeSource->getSection("Meta").find("Name");
+	if (confEntry != localeSource->getSection("Meta").end())
 		stdstr(&name, (*confEntry).second.c_str());
 	
-	confEntry = localeSource->Sections["Meta"].find("Description");
-	if (confEntry != localeSource->Sections["Meta"].end())
+	confEntry = localeSource->getSection("Meta").find("Description");
+	if (confEntry != localeSource->getSection("Meta").end())
 		stdstr(&description, (*confEntry).second.c_str());
 
-	confEntry = localeSource->Sections["Meta"].find("Encoding"); //Either empty (==Latin1) or UTF-8
-	if (confEntry != localeSource->Sections["Meta"].end())
+	confEntry = localeSource->getSection("Meta").find("Encoding"); //Either empty (==Latin1) or UTF-8
+	if (confEntry != localeSource->getSection("Meta").end())
 		stdstr(&encoding, (*confEntry).second.c_str());
 }
 
@@ -110,8 +110,8 @@
 
 	if (entry == p->lookupTable.end()) {
 		ConfigEntMap::iterator confEntry;
-		confEntry = localeSource->Sections["Text"].find(text);
-		if (confEntry == localeSource->Sections["Text"].end())
+		confEntry = localeSource->getSection("Text").find(text);
+		if (confEntry == localeSource->getSection("Text").end())
 			p->lookupTable.insert(LookupMap::value_type(text, text));
 		else {//valid value found
 			/*
@@ -169,8 +169,8 @@
 		for (int j = 0; builtin_abbrevs[j].osis[0]; j++) {
 			p->mergedAbbrevs[builtin_abbrevs[j].ab] = builtin_abbrevs[j].osis;
 		}
-		ConfigEntMap::iterator it = localeSource->Sections["Book Abbrevs"].begin();
-		ConfigEntMap::iterator end = localeSource->Sections["Book Abbrevs"].end();
+		ConfigEntMap::iterator it = localeSource->getSection("Book Abbrevs").begin();
+		ConfigEntMap::iterator end = localeSource->getSection("Book Abbrevs").end();
 		for (; it != end; it++) {
 			p->mergedAbbrevs[it->first.c_str()] = it->second.c_str();
 		}

Modified: branches/sword-1-8-x/src/mgr/swmgr.cpp
===================================================================
--- branches/sword-1-8-x/src/mgr/swmgr.cpp	2017-11-01 11:33:56 UTC (rev 3514)
+++ branches/sword-1-8-x/src/mgr/swmgr.cpp	2017-11-01 11:38:09 UTC (rev 3515)
@@ -300,24 +300,11 @@
 }
 
 
-SWBuf SWMgr::getHomeDir() {
-
-	// figure out 'home' directory for app data
-	SWBuf homeDir = getenv("HOME");
-	if (!homeDir.length()) {
-		// silly windows
-		homeDir = getenv("APPDATA");
-	}
-	if (homeDir.length()) {
-		if ((homeDir[homeDir.length()-1] != '\\') && (homeDir[homeDir.length()-1] != '/')) {
-			homeDir += "/";
-		}
-	}
-
-	return homeDir;
-}
-
-
+// TODO: because we're still calling deprecated virtual Load. Removed in 2.0
+#if defined(__GNUC__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
+#endif
 void SWMgr::commonInit(SWConfig *iconfig, SWConfig *isysconfig, bool autoload, SWFilterMgr *filterMgr, bool multiMod) {
 
 	init();
@@ -341,6 +328,9 @@
 	if (autoload)
 		Load();
 }
+#if defined(__GNUC__)
+#pragma GCC diagnostic pop
+#endif
 
 
 SWMgr::SWMgr(SWFilterMgr *filterMgr, bool multiMod) {
@@ -353,6 +343,10 @@
 }
 
 
+#if defined(__GNUC__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
+#endif
 SWMgr::SWMgr(const char *iConfigPath, bool autoload, SWFilterMgr *filterMgr, bool multiMod, bool augmentHome) {
 
 	init();
@@ -370,19 +364,20 @@
 	int len = (int)path.length();
 	if ((len < 1) || ((iConfigPath[len-1] != '\\') && (iConfigPath[len-1] != '/')))
 		path += "/";
+	SWLog::getSystemLog()->logDebug("Checking at provided path: %s...", path.c_str());
 	if (FileMgr::existsFile(path.c_str(), "mods.conf")) {
 		stdstr(&prefixPath, path.c_str());
 		path += "mods.conf";
 		stdstr(&configPath, path.c_str());
 	}
-	else {
-		if (FileMgr::existsDir(path.c_str(), "mods.d")) {
-			stdstr(&prefixPath, path.c_str());
-			path += "mods.d";
-			stdstr(&configPath, path.c_str());
-			configType = 1;
-		}
+	else if (FileMgr::existsDir(path.c_str(), "mods.d")) {
+		SWLog::getSystemLog()->logDebug("Found mods.d/");
+		stdstr(&prefixPath, path.c_str());
+		path += "mods.d";
+		stdstr(&configPath, path.c_str());
+		configType = 1;
 	}
+	else SWLog::getSystemLog()->logDebug("Config not found at provided path.");
 
 	config = 0;
 	sysConfig = 0;
@@ -390,11 +385,14 @@
 	if (autoload && configPath)
 		Load();
 }
+#if defined(__GNUC__)
+#pragma GCC diagnostic pop
+#endif
 
 
 SWMgr::~SWMgr() {
 
-	DeleteMods();
+	deleteAllModules();
 
 	for (FilterList::iterator it = cleanupFilters.begin(); it != cleanupFilters.end(); it++)
 		delete (*it);
@@ -430,7 +428,7 @@
 
 	*configType = 0;
 
-	SWBuf homeDir = getHomeDir();
+	SWBuf homeDir = FileMgr::getSystemFileMgr()->getHomeDir();
 
 	// check for a sysConf passed in to us
 	SWLog::getSystemLog()->logDebug("Checking for provided SWConfig(\"sword.conf\")...");
@@ -447,7 +445,7 @@
 			SWLog::getSystemLog()->logDebug("Overriding any systemwide or ~/.sword/ sword.conf with one found in current directory.");
 			sysConfPath = "./sword.conf";
 			sysConf = new SWConfig(sysConfPath);
-			if ((entry = sysConf->Sections["Install"].find("DataPath")) != sysConf->Sections["Install"].end()) {
+			if ((entry = sysConf->getSection("Install").find("DataPath")) != sysConf->getSection("Install").end()) {
 				sysConfDataPath = (*entry).second;
 			}
 			if (providedSysConf) {
@@ -559,7 +557,7 @@
 	}
 
 	if (sysConf) {
-		if ((entry = sysConf->Sections["Install"].find("DataPath")) != sysConf->Sections["Install"].end()) {
+		if ((entry = sysConf->getSection("Install").find("DataPath")) != sysConf->getSection("Install").end()) {
 			sysConfDataPath = (*entry).second;
 		}
 		if (sysConfDataPath.size()) {
@@ -594,8 +592,8 @@
 	if (sysConf) {
 		if (augPaths) {
 			augPaths->clear();
-			entry     = sysConf->Sections["Install"].lower_bound("AugmentPath");
-			lastEntry = sysConf->Sections["Install"].upper_bound("AugmentPath");
+			entry     = sysConf->getSection("Install").lower_bound("AugmentPath");
+			lastEntry = sysConf->getSection("Install").upper_bound("AugmentPath");
 			for (;entry != lastEntry; entry++) {
 				path = entry->second;
 				if ((entry->second.c_str()[strlen(entry->second.c_str())-1] != '\\') && (entry->second.c_str()[strlen(entry->second.c_str())-1] != '/'))
@@ -644,7 +642,7 @@
 
 	SWLog::getSystemLog()->logDebug("Checking $HOME/Library/Application Support/Sword/...");
 
-	SWBuf pathCheck = getHomeDir();
+	SWBuf pathCheck = FileMgr::getSystemFileMgr()->getHomeDir();
 	if (pathCheck.length()) {
 		SWLog::getSystemLog()->logDebug("found (%s).", pathCheck.c_str());
 		path = pathCheck;
@@ -762,8 +760,8 @@
 			// fix config's Section names to rename modules which are available more than once
 			// find out which sections are in both config objects
 			// inserting all configs first is not good because that overwrites old keys and new modules would share the same config
-			for (SectionMap::iterator it = config->Sections.begin(); it != config->Sections.end();) {
-				if (saveConfig->Sections.find( (*it).first ) != saveConfig->Sections.end()) { //if the new section is already present rename it
+			for (SectionMap::iterator it = config->getSections().begin(); it != config->getSections().end();) {
+				if (saveConfig->getSections().find((*it).first) != saveConfig->getSections().end()) { //if the new section is already present rename it
 					ConfigEntMap entMap((*it).second);
 					
 					SWBuf name;
@@ -771,17 +769,17 @@
 					do { //module name already used?
 						name.setFormatted("%s_%d", (*it).first.c_str(), i);
 						i++;
-					} while (config->Sections.find(name) != config->Sections.end());
+					} while (config->getSections().find(name) != config->getSections().end());
 					
-					config->Sections.insert(SectionMap::value_type(name, entMap) );
+					config->getSections().insert(SectionMap::value_type(name, entMap) );
 					SectionMap::iterator toErase = it++;
-					config->Sections.erase(toErase);
+					config->getSections().erase(toErase);
 				}
 				else ++it;
 			}
 		}
 		
-		CreateMods(multiMod);
+		createAllModules(multiMod);
 
 		stdstr(&prefixPath, savePrefixPath);
 		delete []savePrefixPath;
@@ -797,13 +795,13 @@
 
 
 /***********************************************************************
- * SWMgr::Load - loads actual modules
+ * SWMgr::load - loads actual modules
  *
  * RET: status - 0 = ok; -1 no config found; 1 = no modules installed
  *
  */
 
-signed char SWMgr::Load() {
+signed char SWMgr::load() {
 	signed char ret = 0;
 
 	if (!config) {	// If we weren't passed a config object at construction, find a config file
@@ -825,9 +823,9 @@
 		SectionMap::iterator Sectloop, Sectend;
 		ConfigEntMap::iterator Entryloop, Entryend;
 
-		DeleteMods();
+		deleteAllModules();
 
-		for (Sectloop = config->Sections.lower_bound("Globals"), Sectend = config->Sections.upper_bound("Globals"); Sectloop != Sectend; Sectloop++) {		// scan thru all 'Globals' sections
+		for (Sectloop = config->getSections().lower_bound("Globals"), Sectend = config->getSections().upper_bound("Globals"); Sectloop != Sectend; Sectloop++) {		// scan thru all 'Globals' sections
 			for (Entryloop = (*Sectloop).second.lower_bound("AutoInstall"), Entryend = (*Sectloop).second.upper_bound("AutoInstall"); Entryloop != Entryend; Entryloop++)	// scan thru all AutoInstall entries
 				InstallScan((*Entryloop).second.c_str());		// Scan AutoInstall entry directory for new modules and install
 		}		
@@ -836,16 +834,16 @@
 			config = myconfig = 0;
 			loadConfigDir(configPath);
 		}
-		else	config->Load();
+		else	config->load();
 
-		CreateMods(mgrModeMultiMod);
+		createAllModules(mgrModeMultiMod);
 
 		for (std::list<SWBuf>::iterator pathIt = augPaths.begin(); pathIt != augPaths.end(); pathIt++) {
 			augmentModules(pathIt->c_str(), mgrModeMultiMod);
 		}
 		if (augmentHome) {
 			// augment config with ~/.sword/mods.d if it exists ---------------------
-			SWBuf homeDir = getHomeDir();
+			SWBuf homeDir = FileMgr::getSystemFileMgr()->getHomeDir();
 			if (homeDir.length() && configType != 2) { // 2 = user only
 				SWBuf path = homeDir;
 				path += ".sword/";
@@ -856,7 +854,7 @@
 			}
 		}
 // -------------------------------------------------------------------------
-		if (!Modules.size()) // config exists, but no modules
+		if (!getModules().size()) // config exists, but no modules
 			ret = 1;
 
 	}
@@ -1100,8 +1098,11 @@
 }
 
 
-void SWMgr::AddGlobalOptions(SWModule *module, ConfigEntMap &section, ConfigEntMap::iterator start, ConfigEntMap::iterator end) {
+void SWMgr::addGlobalOptionFilters(SWModule *module, ConfigEntMap &section) {
 
+	ConfigEntMap::iterator start = section.lower_bound("GlobalOptionFilter");
+	ConfigEntMap::iterator end   = section.upper_bound("GlobalOptionFilter");
+
 	for (;start != end; ++start) {
 		OptionFilterMap::iterator it;
 		SWBuf filterName = start->second;
@@ -1149,8 +1150,7 @@
 }
 
 
-char SWMgr::filterText(const char *filterName, SWBuf &text, const SWKey *key, const SWModule *module)
-{
+char SWMgr::filterText(const char *filterName, SWBuf &text, const SWKey *key, const SWModule *module) {
 	char retVal = -1;
 	// why didn't we use find here?
 	for (OptionFilterMap::iterator it = optionFilters.begin(); it != optionFilters.end(); it++) {
@@ -1173,8 +1173,11 @@
 }
 
 
-void SWMgr::AddLocalOptions(SWModule *module, ConfigEntMap &section, ConfigEntMap::iterator start, ConfigEntMap::iterator end)
-{
+void SWMgr::addLocalOptionFilters(SWModule *module, ConfigEntMap &section) {
+
+	ConfigEntMap::iterator start = section.lower_bound("LocalOptionFilter");
+	ConfigEntMap::iterator end   = section.upper_bound("LocalOptionFilter");
+
 	for (;start != end; start++) {
 		OptionFilterMap::iterator it;
 		it = optionFilters.find((*start).second);
@@ -1189,8 +1192,11 @@
 
 
 // manually specified StripFilters for special cases, like Papyri marks and such
-void SWMgr::AddStripFilters(SWModule *module, ConfigEntMap &section, ConfigEntMap::iterator start, ConfigEntMap::iterator end)
-{
+void SWMgr::addLocalStripFilters(SWModule *module, ConfigEntMap &section) {
+
+	ConfigEntMap::iterator start = section.lower_bound("LocalStripFilter");
+	ConfigEntMap::iterator end   = section.upper_bound("LocalStripFilter");
+
 	for (;start != end; start++) {
 		OptionFilterMap::iterator it;
 		it = optionFilters.find((*start).second);
@@ -1201,7 +1207,7 @@
 }
 
 
-void SWMgr::AddRawFilters(SWModule *module, ConfigEntMap &section) {
+void SWMgr::addRawFilters(SWModule *module, ConfigEntMap &section) {
 	SWBuf sourceformat, cipherKey;
 	ConfigEntMap::iterator entry;
 
@@ -1218,13 +1224,13 @@
 }
 
 
-void SWMgr::AddEncodingFilters(SWModule *module, ConfigEntMap &section) {
+void SWMgr::addEncodingFilters(SWModule *module, ConfigEntMap &section) {
 	if (filterMgr)
 		filterMgr->AddEncodingFilters(module, section);
 }
 
 
-void SWMgr::AddRenderFilters(SWModule *module, ConfigEntMap &section) {
+void SWMgr::addRenderFilters(SWModule *module, ConfigEntMap &section) {
 	SWBuf sourceformat;
 	ConfigEntMap::iterator entry;
 
@@ -1250,7 +1256,7 @@
 }
 
 
-void SWMgr::AddStripFilters(SWModule *module, ConfigEntMap &section)
+void SWMgr::addStripFilters(SWModule *module, ConfigEntMap &section)
 {
 	SWBuf sourceformat;
 	ConfigEntMap::iterator entry;
@@ -1283,81 +1289,6 @@
 }
 
 
-void SWMgr::CreateMods(bool multiMod) {
-	SectionMap::iterator it;
-	ConfigEntMap::iterator start;
-	ConfigEntMap::iterator end;
-	ConfigEntMap::iterator entry;
-	SWModule *newmod;
-	SWBuf driver, misc1;
-	for (it = config->Sections.begin(); it != config->Sections.end(); it++) {
-		ConfigEntMap &section = (*it).second;
-		newmod = 0;
-		
-		driver = ((entry = section.find("ModDrv")) != section.end()) ? (*entry).second : (SWBuf)"";
-		if (driver.length()) {
-			newmod = createModule((*it).first, driver, section);
-			if (newmod) {
-				// Filters to add for this module and globally announce as an option to the user
-				// e.g. translit, strongs, redletterwords, etc, so users can turn these on and off globally
-				start = section.lower_bound("GlobalOptionFilter");
-				end   = section.upper_bound("GlobalOptionFilter");
-				AddGlobalOptions(newmod, section, start, end);
-
-				// Only add the option to the module, don't announce it's availability
-				// These are useful for like: filters that parse special entryAttribs in a text
-				// or whatever you might want to happen on entry lookup
-				start = section.lower_bound("LocalOptionFilter");
-				end   = section.upper_bound("LocalOptionFilter");
-				AddLocalOptions(newmod, section, start, end);
-
-				//STRIP FILTERS
-
-				// add all basic ones for for the modtype
-				AddStripFilters(newmod, section);
-
-				// Any special processing for this module when searching:
-				// e.g. for papyri, removed all [](). notation
-				start = section.lower_bound("LocalStripFilter");
-				end   = section.upper_bound("LocalStripFilter");
-				AddStripFilters(newmod, section, start, end);
-
-				AddRawFilters(newmod, section);
-				AddRenderFilters(newmod, section);
-				AddEncodingFilters(newmod, section);
-				
-				SWModule *oldmod = Modules[newmod->getName()];
-				if (oldmod) {
-					delete oldmod;
-				}
-				
-				Modules[newmod->getName()] = newmod;
-			}
-		}
-	}
-}
-
-
-void SWMgr::DeleteMods() {
-
-	ModMap::iterator it;
-
-	for (it = Modules.begin(); it != Modules.end(); it++)
-		delete (*it).second;
-
-	Modules.clear();
-}
-
-
-void SWMgr::deleteModule(const char *modName) {
-	ModMap::iterator it = Modules.find(modName);
-	if (it != Modules.end()) {
-		delete (*it).second;
-		Modules.erase(it);
-	}
-}
-
-
 void SWMgr::InstallScan(const char *dirname)
 {
    DIR *dir;
@@ -1390,8 +1321,8 @@
 					// mods.conf
 					else {
 						if (!conffd) {
-							conffd = FileMgr::getSystemFileMgr()->open(config->filename.c_str(), FileMgr::WRONLY|FileMgr::APPEND);
-							if (conffd > 0)
+							conffd = FileMgr::getSystemFileMgr()->open(config->getFileName().c_str(), FileMgr::WRONLY|FileMgr::APPEND);
+							if (conffd && conffd->getFd() >= 0)
 								conffd->seek(0L, SEEK_END);
 							else {
 								FileMgr::getSystemFileMgr()->close(conffd);
@@ -1484,7 +1415,92 @@
 	return options;
 }
 
+#if defined(__GNUC__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
+#endif
 
+// TODO: use deprecated public 'Modules' property for now until we remove deprecation
+// and store in private property
+// also old deprecated virtuals so client overrides still are called
+
+void SWMgr::createAllModules(bool multiMod) {
+	SectionMap::iterator it;
+	ConfigEntMap::iterator entry;
+	SWModule *newmod;
+	SWBuf driver, misc1;
+	for (it = config->getSections().begin(); it != config->getSections().end(); it++) {
+		ConfigEntMap &section = (*it).second;
+		newmod = 0;
+		
+		driver = ((entry = section.find("ModDrv")) != section.end()) ? (*entry).second : (SWBuf)"";
+		if (driver.length()) {
+			newmod = createModule((*it).first, driver, section);
+			if (newmod) {
+				// Filters to add for this module and globally announce as an option to the user
+				// e.g. translit, strongs, redletterwords, etc, so users can turn these on and off globally
+				// TODO: addGlobalOptionFilters(newmod, section);
+				AddGlobalOptions(newmod, section, section.lower_bound("GlobalOptionFilter"), section.upper_bound("GlobalOptionFilter"));
+
+				// Only add the option to the module, don't announce it's availability
+				// These are useful for like: filters that parse special entryAttribs in a text
+				// or whatever you might want to happen on entry lookup
+				// TODO: addLocalOptionFilters(newmod, section);
+				AddLocalOptions(newmod, section, section.lower_bound("LocalOptionFilter"), section.upper_bound("LocalOptionFilter"));
+
+				//STRIP FILTERS
+
+				// add all basic strip filters for for the modtype
+				// TODO: addStripFilters(newmod, section);
+				AddStripFilters(newmod, section);
+
+				// Any module-specific processing specified in module config
+				// as entries LocalStripFilter=
+				// e.g. for papyri, removed all [](). notation
+				// TODO: addLocalStripFilters(newmod, section);
+				AddStripFilters(newmod, section, section.lower_bound("LocalStripFilter"), section.upper_bound("LocalStripFilter"));
+
+				// TODO: addRawFilters(newmod, section);
+				AddRawFilters(newmod, section);
+				// TODO: addRenderFilters(newmod, section);
+				AddRenderFilters(newmod, section);
+				// TODO: addEncodingFilters(newmod, section);
+				AddEncodingFilters(newmod, section);
+				
+				// place our module in module container, removing first if one
+				// already exists by our same name
+				SWModule *oldmod = getModule(newmod->getName());
+				if (oldmod) {
+					delete oldmod;
+				}
+				
+				Modules[newmod->getName()] = newmod;
+			}
+		}
+	}
+}
+
+
+void SWMgr::deleteAllModules() {
+
+	ModMap::iterator it;
+
+	for (it = getModules().begin(); it != getModules().end(); ++it) {
+		delete (*it).second;
+	}
+
+	Modules.clear();
+}
+
+
+void SWMgr::deleteModule(const char *modName) {
+	ModMap::iterator it = Modules.find(modName);
+	if (it != Modules.end()) {
+		delete (*it).second;
+		Modules.erase(it);
+	}
+}
+
 signed char SWMgr::setCipherKey(const char *modName, const char *key) {
 	FilterMap::iterator it;
 	ModMap::iterator it2;
@@ -1510,5 +1526,13 @@
 }
 
 
+ModMap &SWMgr::getModules() { return Modules; }
+
+SWBuf SWMgr::getHomeDir() { return FileMgr::getSystemFileMgr()->getHomeDir(); }
+
+#if defined(__GNUC__)
+#pragma GCC diagnostic pop
+#endif
+
 SWORD_NAMESPACE_END
 

Modified: branches/sword-1-8-x/src/mgr/versificationmgr.cpp
===================================================================
--- branches/sword-1-8-x/src/mgr/versificationmgr.cpp	2017-11-01 11:33:56 UTC (rev 3514)
+++ branches/sword-1-8-x/src/mgr/versificationmgr.cpp	2017-11-01 11:38:09 UTC (rev 3515)
@@ -76,9 +76,9 @@
 		systemVersificationMgr->registerVersificationSystem("Catholic2", otbooks_catholic2, ntbooks, vm_catholic2);
 		systemVersificationMgr->registerVersificationSystem("LXX", otbooks_lxx, ntbooks, vm_lxx);
 		systemVersificationMgr->registerVersificationSystem("Orthodox", otbooks_orthodox, ntbooks, vm_orthodox);
-		systemVersificationMgr->registerVersificationSystem("Calvin", otbooks, ntbooks, vm_calvin);
-		systemVersificationMgr->registerVersificationSystem("DarbyFr", otbooks, ntbooks, vm_darbyfr);
-		systemVersificationMgr->registerVersificationSystem("Segond", otbooks, ntbooks, vm_segond);
+		systemVersificationMgr->registerVersificationSystem("Calvin", otbooks, ntbooks, vm_calvin, mappings_calvin);
+		systemVersificationMgr->registerVersificationSystem("DarbyFr", otbooks, ntbooks, vm_darbyfr, mappings_darbyfr);
+		systemVersificationMgr->registerVersificationSystem("Segond", otbooks, ntbooks, vm_segond, mappings_segond);
 	}
 	return systemVersificationMgr;
 }

Modified: branches/sword-1-8-x/src/modules/common/bz2comprs.cpp
===================================================================
--- branches/sword-1-8-x/src/modules/common/bz2comprs.cpp	2017-11-01 11:33:56 UTC (rev 3514)
+++ branches/sword-1-8-x/src/modules/common/bz2comprs.cpp	2017-11-01 11:38:09 UTC (rev 3515)
@@ -138,7 +138,7 @@
 			case BZ_MEM_ERROR: fprintf(stderr, "ERROR: not enough memory during decompression.\n"); break;
 			case BZ_OUTBUFF_FULL: fprintf(stderr, "ERROR: not enough room in the out buffer during decompression.\n"); break;
 			case BZ_DATA_ERROR: fprintf(stderr, "ERROR: corrupt data during decompression.\n"); break;
-			default: fprintf(stderr, "ERROR: an unknown error occured during decompression.\n"); break;
+			default: fprintf(stderr, "ERROR: an unknown error occurred during decompression.\n"); break;
 		}
 		delete [] buf;
 	}

Modified: branches/sword-1-8-x/src/modules/common/rawstr.cpp
===================================================================
--- branches/sword-1-8-x/src/modules/common/rawstr.cpp	2017-11-01 11:33:56 UTC (rev 3514)
+++ branches/sword-1-8-x/src/modules/common/rawstr.cpp	2017-11-01 11:38:09 UTC (rev 3515)
@@ -74,7 +74,7 @@
 	buf.setFormatted("%s.dat", path);
 	datfd = FileMgr::getSystemFileMgr()->open(buf, fileMode, true);
 
-	if (datfd < 0) {
+	if (!datfd || datfd->getFd() < 0) {
 		SWLog::getSystemLog()->logError("%d", errno);
 	}
 
@@ -111,7 +111,7 @@
 {
 	int size;
 	char ch;
-	if (datfd > 0) {
+	if (datfd && datfd->getFd() >= 0) {
 		datfd->seek(ioffset, SEEK_SET);
 		for (size = 0; datfd->read(&ch, 1) == 1; size++) {
 			if ((ch == '\\') || (ch == 10) || (ch == 13))
@@ -145,7 +145,7 @@
 {
 	__u32 offset;
 	
-	if (idxfd > 0) {
+	if (idxfd && idxfd->getFd() >= 0) {
 		idxfd->seek(ioffset, SEEK_SET);
 		idxfd->read(&offset, 4);
 

Modified: branches/sword-1-8-x/src/modules/common/rawstr4.cpp
===================================================================
--- branches/sword-1-8-x/src/modules/common/rawstr4.cpp	2017-11-01 11:33:56 UTC (rev 3514)
+++ branches/sword-1-8-x/src/modules/common/rawstr4.cpp	2017-11-01 11:38:09 UTC (rev 3515)
@@ -74,7 +74,7 @@
 	buf.setFormatted("%s.dat", path);
 	datfd = FileMgr::getSystemFileMgr()->open(buf, fileMode, true);
 
-	if (datfd < 0) {
+	if (!datfd || datfd->getFd() < 0) {
 		SWLog::getSystemLog()->logError("%d", errno);
 	}
 
@@ -111,7 +111,7 @@
 {
 	int size;
 	char ch;
-	if (datfd > 0) {
+	if ((unsigned long)datfd > 0) {
 		datfd->seek(ioffset, SEEK_SET);
 		for (size = 0; datfd->read(&ch, 1) == 1; size++) {
 			if ((ch == '\\') || (ch == 10) || (ch == 13))
@@ -145,7 +145,7 @@
 {
 	__u32 offset;
 	
-	if (idxfd > 0) {
+	if ((unsigned long)idxfd > 0) {
 		idxfd->seek(ioffset, SEEK_SET);
 
 		idxfd->read(&offset, 4);

Modified: branches/sword-1-8-x/src/modules/common/xzcomprs.cpp
===================================================================
--- branches/sword-1-8-x/src/modules/common/xzcomprs.cpp	2017-11-01 11:33:56 UTC (rev 3514)
+++ branches/sword-1-8-x/src/modules/common/xzcomprs.cpp	2017-11-01 11:38:09 UTC (rev 3515)
@@ -110,7 +110,7 @@
 			case LZMA_MEM_ERROR: fprintf(stderr, "ERROR: not enough memory during compression.\n"); break;
 			case LZMA_DATA_ERROR: fprintf(stderr, "ERROR: corrupt data during compression.\n"); break;
 			case LZMA_PROG_ERROR: fprintf(stderr, "ERROR: program error encountered during decompression.\n"); break;
-			default: fprintf(stderr, "ERROR: an unknown error occured during compression.\n"); break;
+			default: fprintf(stderr, "ERROR: an unknown error occurred during compression.\n"); break;
 		}
 	}
 	else
@@ -169,7 +169,7 @@
 			case LZMA_MEM_ERROR: fprintf(stderr, "ERROR: not enough memory during decompression.\n"); break;
 			case LZMA_BUF_ERROR: fprintf(stderr, "ERROR: not enough room in the out buffer during decompression.\n"); break;
 			case LZMA_PROG_ERROR: fprintf(stderr, "ERROR: program error encountered during decompression.\n"); break;
-			default: fprintf(stderr, "ERROR: an unknown error occured during decompression.\n"); break;
+			default: fprintf(stderr, "ERROR: an unknown error occurred during decompression.\n"); break;
 		}
 		delete [] buf;
 	}

Modified: branches/sword-1-8-x/src/modules/common/zipcomprs.cpp
===================================================================
--- branches/sword-1-8-x/src/modules/common/zipcomprs.cpp	2017-11-01 11:33:56 UTC (rev 3514)
+++ branches/sword-1-8-x/src/modules/common/zipcomprs.cpp	2017-11-01 11:38:09 UTC (rev 3515)
@@ -173,7 +173,7 @@
 			case Z_MEM_ERROR: fprintf(stderr, "ERROR: not enough memory during decompression.\n"); break;
 			case Z_BUF_ERROR: fprintf(stderr, "ERROR: not enough room in the out buffer during decompression.\n"); break;
 			case Z_DATA_ERROR: fprintf(stderr, "ERROR: corrupt data during decompression.\n"); break;
-			default: fprintf(stderr, "ERROR: an unknown error occured during decompression.\n"); break;
+			default: fprintf(stderr, "ERROR: an unknown error occurred during decompression.\n"); break;
 		}
 		delete [] buf;
 	}

Modified: branches/sword-1-8-x/src/modules/common/zstr.cpp
===================================================================
--- branches/sword-1-8-x/src/modules/common/zstr.cpp	2017-11-01 11:33:56 UTC (rev 3514)
+++ branches/sword-1-8-x/src/modules/common/zstr.cpp	2017-11-01 11:38:09 UTC (rev 3515)
@@ -83,7 +83,7 @@
 	buf.setFormatted("%s.zdt", path);
 	zdtfd = FileMgr::getSystemFileMgr()->open(buf, fileMode, true);
 
-	if (datfd <= 0) {
+	if (!datfd || datfd->getFd() < 0) {
 		SWLog::getSystemLog()->logError("%d", errno);
 	}
 
@@ -133,7 +133,7 @@
 {
 	int size;
 	char ch;
-	if (datfd > 0) {
+	if (datfd && datfd->getFd() >= 0) {
 		datfd->seek(ioffset, SEEK_SET);
 		for (size = 0; datfd->read(&ch, 1) == 1; size++) {
 			if ((ch == '\\') || (ch == 10) || (ch == 13))
@@ -167,7 +167,7 @@
 {
 	__u32 offset;
 	
-	if (idxfd > 0) {
+	if (idxfd && idxfd->getFd() >= 0) {
 		idxfd->seek(ioffset, SEEK_SET);
 		idxfd->read(&offset, 4);
 		offset = swordtoarch32(offset);
@@ -295,7 +295,7 @@
 				*idxoff = tryoff;
 
 
-			if (((laststart != start) || (lastsize != size)) && (start >= 0) && (size)) 
+			if (((laststart != start) || (lastsize != size)) && size)
 				away += (away < 0) ? 1 : -1;
 		}
 	

Modified: branches/sword-1-8-x/src/modules/filters/gbfstrongs.cpp
===================================================================
--- branches/sword-1-8-x/src/modules/filters/gbfstrongs.cpp	2017-11-01 11:33:56 UTC (rev 3514)
+++ branches/sword-1-8-x/src/modules/filters/gbfstrongs.cpp	2017-11-01 11:38:09 UTC (rev 3515)
@@ -58,7 +58,7 @@
 	bool lastspace = false;
 	int word = 1;
 	char val[128];
-	char wordstr[5];
+	char wordstr[11];
 	char *valto;
 	unsigned int textStart = 0, textEnd = 0;
 	bool newText = false;

Modified: branches/sword-1-8-x/src/modules/filters/gbfwordjs.cpp
===================================================================
--- branches/sword-1-8-x/src/modules/filters/gbfwordjs.cpp	2017-11-01 11:33:56 UTC (rev 3514)
+++ branches/sword-1-8-x/src/modules/filters/gbfwordjs.cpp	2017-11-01 11:38:09 UTC (rev 3515)
@@ -137,7 +137,7 @@
 				text += token;
 				text += '>';
 				if (needWordOut) {
-					char wstr[10];
+					char wstr[11];
 					sprintf(wstr, "%03d", word-2);
 					AttributeValue *wAttrs = &(module->getEntryAttributes()["Word"][wstr]);
 					needWordOut = false;
@@ -234,7 +234,7 @@
 			}
 		}
 
-		char wstr[10];
+		char wstr[11];
 		sprintf(wstr, "%03d", word-1);
 		AttributeValue *wAttrs = &(module->getEntryAttributes()["Word"][wstr]);
 		needWordOut = false;

Modified: branches/sword-1-8-x/src/modules/filters/greeklexattribs.cpp
===================================================================
--- branches/sword-1-8-x/src/modules/filters/greeklexattribs.cpp	2017-11-01 11:33:56 UTC (rev 3514)
+++ branches/sword-1-8-x/src/modules/filters/greeklexattribs.cpp	2017-11-01 11:38:09 UTC (rev 3515)
@@ -44,7 +44,7 @@
 		string phrase;
 		string freq;
 		char val[128], *valto;
-		char wordstr[7];
+		char wordstr[11];
 		const char *currentPhrase = 0;
 		const char *currentPhraseEnd = 0;
 		int number = 0;

Modified: branches/sword-1-8-x/src/modules/filters/osisstrongs.cpp
===================================================================
--- branches/sword-1-8-x/src/modules/filters/osisstrongs.cpp	2017-11-01 11:33:56 UTC (rev 3514)
+++ branches/sword-1-8-x/src/modules/filters/osisstrongs.cpp	2017-11-01 11:38:09 UTC (rev 3515)
@@ -57,7 +57,7 @@
 	SWBuf token;
 	bool intoken = false;
 	int wordNum = 1;
-	char wordstr[5];
+	char wordstr[11];
 	const char *wordStart = 0;
 	SWBuf page = "";		// some modules include <seg> page info, so we add these to the words
 

Modified: branches/sword-1-8-x/src/modules/filters/osiswordjs.cpp
===================================================================
--- branches/sword-1-8-x/src/modules/filters/osiswordjs.cpp	2017-11-01 11:33:56 UTC (rev 3514)
+++ branches/sword-1-8-x/src/modules/filters/osiswordjs.cpp	2017-11-01 11:38:09 UTC (rev 3515)
@@ -66,7 +66,7 @@
 		int tokpos = 0;
 		bool intoken = false;
 		int wordNum = 1;
-		char wordstr[5];
+		char wordstr[11];
 		SWBuf modName = (module)?module->getName():"";
 		// add TR to w src in KJV then remove this next line
 		SWBuf wordSrcPrefix = (modName == "KJV")?SWBuf("TR"):modName;

Modified: branches/sword-1-8-x/src/modules/filters/rtfhtml.cpp
===================================================================
--- branches/sword-1-8-x/src/modules/filters/rtfhtml.cpp	2017-11-01 11:33:56 UTC (rev 3514)
+++ branches/sword-1-8-x/src/modules/filters/rtfhtml.cpp	2017-11-01 11:38:09 UTC (rev 3515)
@@ -55,7 +55,7 @@
 				num.append(from, end-from);
 				__s16 n = atoi(num.c_str());
 				__u32 u = (__u16)n;
-				text.append(getUTF8FromUniChar(u));
+				getUTF8FromUniChar(u, &text);
 				from += (end-from);
 				continue;
 			}

Modified: branches/sword-1-8-x/src/modules/filters/thmlstrongs.cpp
===================================================================
--- branches/sword-1-8-x/src/modules/filters/thmlstrongs.cpp	2017-11-01 11:33:56 UTC (rev 3514)
+++ branches/sword-1-8-x/src/modules/filters/thmlstrongs.cpp	2017-11-01 11:38:09 UTC (rev 3515)
@@ -60,7 +60,7 @@
 	bool lastspace = false;
 	int word = 1;
 	char val[128];
-	char wordstr[5];
+	char wordstr[11];
 	char *valto;
 	char *ch;
 	unsigned int textStart = 0, textEnd = 0;

Modified: branches/sword-1-8-x/src/modules/filters/thmlwordjs.cpp
===================================================================
--- branches/sword-1-8-x/src/modules/filters/thmlwordjs.cpp	2017-11-01 11:33:56 UTC (rev 3514)
+++ branches/sword-1-8-x/src/modules/filters/thmlwordjs.cpp	2017-11-01 11:38:09 UTC (rev 3515)
@@ -68,7 +68,7 @@
 		char val[128];
 		char *valto;
 		char *ch;
-		char wordstr[5];
+		char wordstr[11];
 		unsigned int textStart = 0, lastAppendLen = 0, textEnd = 0;
 		SWBuf tmp;
 		bool newText = false;
@@ -151,7 +151,7 @@
 				text += token;
 				text += '>';
 				if (needWordOut) {
-					char wstr[10];
+					char wstr[11];
 					sprintf(wstr, "%03d", word-2);
 					AttributeValue *wAttrs = &(module->getEntryAttributes()["Word"][wstr]);
 					needWordOut = false;
@@ -248,7 +248,7 @@
 			}
 		}
 
-		char wstr[10];
+		char wstr[11];
 		sprintf(wstr, "%03d", word-1);
 		AttributeValue *wAttrs = &(module->getEntryAttributes()["Word"][wstr]);
 		needWordOut = false;

Modified: branches/sword-1-8-x/src/modules/filters/utf8greekaccents.cpp
===================================================================
--- branches/sword-1-8-x/src/modules/filters/utf8greekaccents.cpp	2017-11-01 11:33:56 UTC (rev 3514)
+++ branches/sword-1-8-x/src/modules/filters/utf8greekaccents.cpp	2017-11-01 11:38:09 UTC (rev 3515)
@@ -22,8 +22,10 @@
  */
 
 #include <stdlib.h>
+#include <map>
 #include <stdio.h>
 #include <utf8greekaccents.h>
+#include <utilstr.h>
 
 
 #ifdef _ICU_
@@ -31,6 +33,7 @@
 sword::UTF8NFKD decompose;
 #endif
 
+using std::map;
 
 SWORD_NAMESPACE_START
 
@@ -44,6 +47,297 @@
 		static const StringList oVals(&choices[0], &choices[2]);
 		return &oVals;
 	}
+
+	std::map<__u32, SWBuf> converters;
+	class converters_init {
+	public:
+		converters_init() {
+			SWBuf myBuf = "";
+			//first just remove combining characters
+			converters[0x2019] = "";	// RIGHT SINGLE QUOTATION MARK
+			converters[0x1FBF] = "";	// GREEK PSILI
+			converters[0x2CFF] = "";	// COPTIC MORPHOLOGICAL DIVIDER
+			converters[0xFE24] = "";	// COMBINING MACRON LEFT HALF
+			converters[0xFE25] = "";	// COMBINING MACRON RIGHT HALF
+			converters[0xFE26] = "";	// COMBINING CONJOINING MACRON
+			converters[0x0300] = "";	// COMBINING GRAVE ACCENT
+			converters[0x0301] = "";	// COMBINING ACUTE ACCENT
+			converters[0x0302] = "";	// COMBINING CIRCUMFLEX ACCENT
+			converters[0x0308] = "";	// COMBINING DIAERESIS
+			converters[0x0313] = "";	// COMBINING COMMA ABOVE
+			converters[0x0314] = "";	// COMBINING REVERSED COMMA ABOVE
+			converters[0x037A] = "";	// GREEK YPOGEGRAMMENI
+			converters[0x0342] = "";	// COMBINING GREEK PERISPOMENI
+			// Now converted pre-composed characters to their alphabetic bases, discarding the accents
+			// Greek
+			// UPPER case
+			converters[0x0386] = *getUTF8FromUniChar(0x0391, &myBuf); myBuf.setSize(0);	// GREEK CAPITAL LETTER ALPHA WITH TONOS
+			converters[0x0388] = *getUTF8FromUniChar(0x0395, &myBuf); myBuf.setSize(0);	// GREEK CAPITAL LETTER EPSILON WITH TONOS
+			converters[0x0389] = *getUTF8FromUniChar(0x0397, &myBuf); myBuf.setSize(0);	// GREEK CAPITAL LETTER ETA WITH TONOS
+			converters[0x038A] = *getUTF8FromUniChar(0x0399, &myBuf); myBuf.setSize(0);	// GREEK CAPITAL LETTER IOTA WITH TONOS
+			converters[0x03AA] = *getUTF8FromUniChar(0x0399, &myBuf); myBuf.setSize(0);	// GREEK CAPITAL LETTER IOTA WITH DIALYTIKA
+			converters[0x038C] = *getUTF8FromUniChar(0x039F, &myBuf); myBuf.setSize(0);	// GREEK CAPITAL LETTER OMICRON WITH TONOS
+			converters[0x038E] = *getUTF8FromUniChar(0x03A5, &myBuf); myBuf.setSize(0);	// GREEK CAPITAL LETTER UPSILON WITH TONOS
+			converters[0x03AB] = *getUTF8FromUniChar(0x03A5, &myBuf); myBuf.setSize(0);	// GREEK CAPITAL LETTER UPSILON WITH DIALYTIKA
+			converters[0x038F] = *getUTF8FromUniChar(0x03A9, &myBuf); myBuf.setSize(0);	// GREEK CAPITAL LETTER OMEGA WITH TONOS
+
+			// lower case
+			converters[0x03AC] = *getUTF8FromUniChar(0x03B1, &myBuf); myBuf.setSize(0);	// GREEK SMALL LETTER ALPHA WITH TONOS
+			converters[0x03AD] = *getUTF8FromUniChar(0x03B5, &myBuf); myBuf.setSize(0);	// GREEK SMALL LETTER EPSILON WITH TONOS
+			converters[0x03AE] = *getUTF8FromUniChar(0x03B7, &myBuf); myBuf.setSize(0);	// GREEK SMALL LETTER ETA WITH TONOS
+			converters[0x03AF] = *getUTF8FromUniChar(0x03B9, &myBuf); myBuf.setSize(0);	// GREEK SMALL LETTER IOTA WITH TONOS
+			converters[0x03CA] = *getUTF8FromUniChar(0x03B9, &myBuf); myBuf.setSize(0);	// GREEK SMALL LETTER IOTA WITH DIALYTIKA
+			converters[0x03CC] = *getUTF8FromUniChar(0x03BF, &myBuf); myBuf.setSize(0);	// GREEK SMALL LETTER OMICRON WITH TONOS
+			converters[0x03CD] = *getUTF8FromUniChar(0x03C5, &myBuf); myBuf.setSize(0);	// GREEK SMALL LETTER UPSILON WITH TONOS
+			converters[0x03CB] = *getUTF8FromUniChar(0x03C5, &myBuf); myBuf.setSize(0);	// GREEK SMALL LETTER UPSILON WITH DIALYTIKA
+			converters[0x03CE] = *getUTF8FromUniChar(0x03C9, &myBuf); myBuf.setSize(0);	// GREEK SMALL LETTER OMEGA WITH TONOS
+
+			// Extended Greek
+			// UPPER case
+			converters[0x1F08] = *getUTF8FromUniChar(0x0391, &myBuf); myBuf.setSize(0);	// GREEK CAPITAL LETTER ALPHA WITH PSILI
+			converters[0x1F09] = *getUTF8FromUniChar(0x0391, &myBuf); myBuf.setSize(0);	// GREEK CAPITAL LETTER ALPHA WITH DASIA
+			converters[0x1F0A] = *getUTF8FromUniChar(0x0391, &myBuf); myBuf.setSize(0);	// GREEK CAPITAL LETTER ALPHA WITH PSILI AND VARIA
+			converters[0x1F0B] = *getUTF8FromUniChar(0x0391, &myBuf); myBuf.setSize(0);	// GREEK CAPITAL LETTER ALPHA WITH DASIA AND VARIA
+			converters[0x1F0C] = *getUTF8FromUniChar(0x0391, &myBuf); myBuf.setSize(0);	// GREEK CAPITAL LETTER ALPHA WITH PSILI AND OXIA
+			converters[0x1F0D] = *getUTF8FromUniChar(0x0391, &myBuf); myBuf.setSize(0);	// GREEK CAPITAL LETTER ALPHA WITH DASIA AND OXIA
+			converters[0x1F0E] = *getUTF8FromUniChar(0x0391, &myBuf); myBuf.setSize(0);	// GREEK CAPITAL LETTER ALPHA WITH PSILI AND PERISPOMENI
+			converters[0x1F0F] = *getUTF8FromUniChar(0x0391, &myBuf); myBuf.setSize(0);	// GREEK CAPITAL LETTER ALPHA WITH DASIA AND PERISPOMENI
+			converters[0x1F88] = *getUTF8FromUniChar(0x0391, &myBuf); myBuf.setSize(0);	// GREEK CAPITAL LETTER ALPHA WITH PSILI AND PROSGEGRAMMENI
+			converters[0x1F89] = *getUTF8FromUniChar(0x0391, &myBuf); myBuf.setSize(0);	// GREEK CAPITAL LETTER ALPHA WITH DASIA AND PROSGEGRAMMENI
+			converters[0x1F8A] = *getUTF8FromUniChar(0x0391, &myBuf); myBuf.setSize(0);	// GREEK CAPITAL LETTER ALPHA WITH PSILI AND VARIA AND PROSGEGRAMMENI
+			converters[0x1F8B] = *getUTF8FromUniChar(0x0391, &myBuf); myBuf.setSize(0);	// GREEK CAPITAL LETTER ALPHA WITH DASIA AND VARIA AND PROSGEGRAMMENI
+			converters[0x1F8C] = *getUTF8FromUniChar(0x0391, &myBuf); myBuf.setSize(0);	// GREEK CAPITAL LETTER ALPHA WITH PSILI AND OXIA AND PROSGEGRAMMENI
+			converters[0x1F8D] = *getUTF8FromUniChar(0x0391, &myBuf); myBuf.setSize(0);	// GREEK CAPITAL LETTER ALPHA WITH DASIA AND OXIA AND PROSGEGRAMMENI
+			converters[0x1F8E] = *getUTF8FromUniChar(0x0391, &myBuf); myBuf.setSize(0);	// GREEK CAPITAL LETTER ALPHA WITH PSILI AND PERISPOMENI AND PROSGEGRAMMENI
+			converters[0x1F8F] = *getUTF8FromUniChar(0x0391, &myBuf); myBuf.setSize(0);	// GREEK CAPITAL LETTER ALPHA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI
+			converters[0x1FB8] = *getUTF8FromUniChar(0x0391, &myBuf); myBuf.setSize(0);	// GREEK CAPITAL LETTER ALPHA WITH VRACHY
+			converters[0x1FB9] = *getUTF8FromUniChar(0x0391, &myBuf); myBuf.setSize(0);	// GREEK CAPITAL LETTER ALPHA WITH MACRON
+			converters[0x1FBA] = *getUTF8FromUniChar(0x0391, &myBuf); myBuf.setSize(0);	// GREEK CAPITAL LETTER ALPHA WITH VARIA
+			converters[0x1FBB] = *getUTF8FromUniChar(0x0391, &myBuf); myBuf.setSize(0);	// GREEK CAPITAL LETTER ALPHA WITH OXIA
+			converters[0x1FBC] = *getUTF8FromUniChar(0x0391, &myBuf); myBuf.setSize(0);	// GREEK CAPITAL LETTER ALPHA WITH PROSGEGRAMMENI
+			
+			converters[0x1F18] = *getUTF8FromUniChar(0x0395, &myBuf); myBuf.setSize(0);	// GREEK CAPITAL LETTER EPSILON WITH PSILI
+			converters[0x1F19] = *getUTF8FromUniChar(0x0395, &myBuf); myBuf.setSize(0);	// GREEK CAPITAL LETTER EPSILON WITH DASIA
+			converters[0x1F1A] = *getUTF8FromUniChar(0x0395, &myBuf); myBuf.setSize(0);	// GREEK CAPITAL LETTER EPSILON WITH PSILI AND VARIA
+			converters[0x1F1B] = *getUTF8FromUniChar(0x0395, &myBuf); myBuf.setSize(0);	// GREEK CAPITAL LETTER EPSILON WITH DASIA AND VARIA
+			converters[0x1F1C] = *getUTF8FromUniChar(0x0395, &myBuf); myBuf.setSize(0);	// GREEK CAPITAL LETTER EPSILON WITH PSILI AND OXIA
+			converters[0x1F1D] = *getUTF8FromUniChar(0x0395, &myBuf); myBuf.setSize(0);	// GREEK CAPITAL LETTER EPSILON WITH DASIA AND OXIA
+			converters[0x1FC8] = *getUTF8FromUniChar(0x0395, &myBuf); myBuf.setSize(0);	// GREEK CAPITAL LETTER EPSILON WITH VARIA
+			converters[0x1FC9] = *getUTF8FromUniChar(0x0395, &myBuf); myBuf.setSize(0);	// GREEK CAPITAL LETTER EPSILON WITH OXIA
+
+			converters[0x1F28] = *getUTF8FromUniChar(0x0397, &myBuf); myBuf.setSize(0);	// GREEK CAPITAL LETTER ETA WITH PSILI
+			converters[0x1F29] = *getUTF8FromUniChar(0x0397, &myBuf); myBuf.setSize(0);	// GREEK CAPITAL LETTER ETA WITH DASIA
+			converters[0x1F2A] = *getUTF8FromUniChar(0x0397, &myBuf); myBuf.setSize(0);	// GREEK CAPITAL LETTER ETA WITH PSILI AND VARIA
+			converters[0x1F2B] = *getUTF8FromUniChar(0x0397, &myBuf); myBuf.setSize(0);	// GREEK CAPITAL LETTER ETA WITH DASIA AND VARIA
+			converters[0x1F2C] = *getUTF8FromUniChar(0x0397, &myBuf); myBuf.setSize(0);	// GREEK CAPITAL LETTER ETA WITH PSILI AND OXIA
+			converters[0x1F2D] = *getUTF8FromUniChar(0x0397, &myBuf); myBuf.setSize(0);	// GREEK CAPITAL LETTER ETA WITH DASIA AND OXIA
+			converters[0x1F2E] = *getUTF8FromUniChar(0x0397, &myBuf); myBuf.setSize(0);	// GREEK CAPITAL LETTER ETA WITH PSILI AND PERISPOMENI
+			converters[0x1F2F] = *getUTF8FromUniChar(0x0397, &myBuf); myBuf.setSize(0);	// GREEK CAPITAL LETTER ETA WITH DASIA AND PERISPOMENI
+			converters[0x1F98] = *getUTF8FromUniChar(0x0397, &myBuf); myBuf.setSize(0);	// GREEK CAPITAL LETTER ETA WITH PSILI AND PROSGEGRAMMENI
+			converters[0x1F99] = *getUTF8FromUniChar(0x0397, &myBuf); myBuf.setSize(0);	// GREEK CAPITAL LETTER ETA WITH DASIA AND PROSGEGRAMMENI
+			converters[0x1F9A] = *getUTF8FromUniChar(0x0397, &myBuf); myBuf.setSize(0);	// GREEK CAPITAL LETTER ETA WITH PSILI AND VARIA AND PROSGEGRAMMENI
+			converters[0x1F9B] = *getUTF8FromUniChar(0x0397, &myBuf); myBuf.setSize(0);	// GREEK CAPITAL LETTER ETA WITH DASIA AND VARIA AND PROSGEGRAMMENI
+			converters[0x1F9C] = *getUTF8FromUniChar(0x0397, &myBuf); myBuf.setSize(0);	// GREEK CAPITAL LETTER ETA WITH PSILI AND OXIA AND PROSGEGRAMMENI
+			converters[0x1F9D] = *getUTF8FromUniChar(0x0397, &myBuf); myBuf.setSize(0);	// GREEK CAPITAL LETTER ETA WITH DASIA AND OXIA AND PROSGEGRAMMENI
+			converters[0x1F9E] = *getUTF8FromUniChar(0x0397, &myBuf); myBuf.setSize(0);	// GREEK CAPITAL LETTER ETA WITH PSILI AND PERISPOMENI AND PROSGEGRAMMENI
+			converters[0x1F9F] = *getUTF8FromUniChar(0x0397, &myBuf); myBuf.setSize(0);	// GREEK CAPITAL LETTER ETA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI
+			converters[0x1FCA] = *getUTF8FromUniChar(0x0397, &myBuf); myBuf.setSize(0);	// GREEK CAPITAL LETTER ETA WITH VARIA
+			converters[0x1FCB] = *getUTF8FromUniChar(0x0397, &myBuf); myBuf.setSize(0);	// GREEK CAPITAL LETTER ETA WITH OXIA
+			converters[0x1FCC] = *getUTF8FromUniChar(0x0397, &myBuf); myBuf.setSize(0);	// GREEK CAPITAL LETTER ETA WITH PROSGEGRAMMENI
+
+			converters[0x1F38] = *getUTF8FromUniChar(0x0399, &myBuf); myBuf.setSize(0);	// GREEK CAPITAL LETTER IOTA WITH PSILI
+			converters[0x1F39] = *getUTF8FromUniChar(0x0399, &myBuf); myBuf.setSize(0);	// GREEK CAPITAL LETTER IOTA WITH DASIA
+			converters[0x1F3A] = *getUTF8FromUniChar(0x0399, &myBuf); myBuf.setSize(0);	// GREEK CAPITAL LETTER IOTA WITH PSILI AND VARIA
+			converters[0x1F3B] = *getUTF8FromUniChar(0x0399, &myBuf); myBuf.setSize(0);	// GREEK CAPITAL LETTER IOTA WITH DASIA AND VARIA
+			converters[0x1F3C] = *getUTF8FromUniChar(0x0399, &myBuf); myBuf.setSize(0);	// GREEK CAPITAL LETTER IOTA WITH PSILI AND OXIA
+			converters[0x1F3D] = *getUTF8FromUniChar(0x0399, &myBuf); myBuf.setSize(0);	// GREEK CAPITAL LETTER IOTA WITH DASIA AND OXIA
+			converters[0x1F3E] = *getUTF8FromUniChar(0x0399, &myBuf); myBuf.setSize(0);	// GREEK CAPITAL LETTER IOTA WITH PSILI AND PERISPOMENI
+			converters[0x1F3F] = *getUTF8FromUniChar(0x0399, &myBuf); myBuf.setSize(0);	// GREEK CAPITAL LETTER IOTA WITH DASIA AND PERISPOMENI
+			converters[0x1FD8] = *getUTF8FromUniChar(0x0399, &myBuf); myBuf.setSize(0);	// GREEK CAPITAL LETTER IOTA WITH VRACHY
+			converters[0x1FD9] = *getUTF8FromUniChar(0x0399, &myBuf); myBuf.setSize(0);	// GREEK CAPITAL LETTER IOTA WITH MACRON
+			converters[0x1FDA] = *getUTF8FromUniChar(0x0399, &myBuf); myBuf.setSize(0);	// GREEK CAPITAL LETTER IOTA WITH VARIA
+			converters[0x1FDB] = *getUTF8FromUniChar(0x0399, &myBuf); myBuf.setSize(0);	// GREEK CAPITAL LETTER IOTA WITH OXIA
+
+			converters[0x1F48] = *getUTF8FromUniChar(0x039F, &myBuf); myBuf.setSize(0);	// GREEK CAPITAL LETTER OMICRON WITH PSILI
+			converters[0x1F49] = *getUTF8FromUniChar(0x039F, &myBuf); myBuf.setSize(0);	// GREEK CAPITAL LETTER OMICRON WITH DASIA
+			converters[0x1F4A] = *getUTF8FromUniChar(0x039F, &myBuf); myBuf.setSize(0);	// GREEK CAPITAL LETTER OMICRON WITH PSILI AND VARIA
+			converters[0x1F4B] = *getUTF8FromUniChar(0x039F, &myBuf); myBuf.setSize(0);	// GREEK CAPITAL LETTER OMICRON WITH DASIA AND VARIA
+			converters[0x1F4C] = *getUTF8FromUniChar(0x039F, &myBuf); myBuf.setSize(0);	// GREEK CAPITAL LETTER OMICRON WITH PSILI AND OXIA
+			converters[0x1F4D] = *getUTF8FromUniChar(0x039F, &myBuf); myBuf.setSize(0);	// GREEK CAPITAL LETTER OMICRON WITH DASIA AND OXIA
+			converters[0x1FF8] = *getUTF8FromUniChar(0x039F, &myBuf); myBuf.setSize(0);	// GREEK CAPITAL LETTER OMICRON WITH VARIA
+			converters[0x1FF9] = *getUTF8FromUniChar(0x039F, &myBuf); myBuf.setSize(0);	// GREEK CAPITAL LETTER OMICRON WITH OXIA
+
+			converters[0x1F59] = *getUTF8FromUniChar(0x03A5, &myBuf); myBuf.setSize(0);	// GREEK CAPITAL LETTER UPSILON WITH DASIA
+			converters[0x1F5A] = *getUTF8FromUniChar(0x03A5, &myBuf); myBuf.setSize(0);	// GREEK CAPITAL LETTER UPSILON WITH PSILI AND VARIA
+			converters[0x1F5B] = *getUTF8FromUniChar(0x03A5, &myBuf); myBuf.setSize(0);	// GREEK CAPITAL LETTER UPSILON WITH DASIA AND VARIA
+			converters[0x1F5C] = *getUTF8FromUniChar(0x03A5, &myBuf); myBuf.setSize(0);	// GREEK CAPITAL LETTER UPSILON WITH PSILI AND OXIA
+			converters[0x1F5D] = *getUTF8FromUniChar(0x03A5, &myBuf); myBuf.setSize(0);	// GREEK CAPITAL LETTER UPSILON WITH DASIA AND OXIA
+			converters[0x1F5E] = *getUTF8FromUniChar(0x03A5, &myBuf); myBuf.setSize(0);	// GREEK CAPITAL LETTER UPSILON WITH PSILI AND PERISPOMENI
+			converters[0x1F5F] = *getUTF8FromUniChar(0x03A5, &myBuf); myBuf.setSize(0);	// GREEK CAPITAL LETTER UPSILON WITH DASIA AND PERISPOMENI
+			converters[0x1FE8] = *getUTF8FromUniChar(0x03A5, &myBuf); myBuf.setSize(0);	// GREEK CAPITAL LETTER UPSILON WITH VRACHY
+			converters[0x1FE9] = *getUTF8FromUniChar(0x03A5, &myBuf); myBuf.setSize(0);	// GREEK CAPITAL LETTER UPSILON WITH MACRON
+			converters[0x1FEA] = *getUTF8FromUniChar(0x03A5, &myBuf); myBuf.setSize(0);	// GREEK CAPITAL LETTER UPSILON WITH VARIA
+			converters[0x1FEB] = *getUTF8FromUniChar(0x03A5, &myBuf); myBuf.setSize(0);	// GREEK CAPITAL LETTER UPSILON WITH OXIA
+
+			converters[0x1F68] = *getUTF8FromUniChar(0x03A9, &myBuf); myBuf.setSize(0);	// GREEK CAPITAL LETTER OMEGA WITH PSILI
+			converters[0x1F69] = *getUTF8FromUniChar(0x03A9, &myBuf); myBuf.setSize(0);	// GREEK CAPITAL LETTER OMEGA WITH DASIA
+			converters[0x1F6A] = *getUTF8FromUniChar(0x03A9, &myBuf); myBuf.setSize(0);	// GREEK CAPITAL LETTER OMEGA WITH PSILI AND VARIA
+			converters[0x1F6B] = *getUTF8FromUniChar(0x03A9, &myBuf); myBuf.setSize(0);	// GREEK CAPITAL LETTER OMEGA WITH DASIA AND VARIA
+			converters[0x1F6C] = *getUTF8FromUniChar(0x03A9, &myBuf); myBuf.setSize(0);	// GREEK CAPITAL LETTER OMEGA WITH PSILI AND OXIA
+			converters[0x1F6D] = *getUTF8FromUniChar(0x03A9, &myBuf); myBuf.setSize(0);	// GREEK CAPITAL LETTER OMEGA WITH DASIA AND OXIA
+			converters[0x1F6E] = *getUTF8FromUniChar(0x03A9, &myBuf); myBuf.setSize(0);	// GREEK CAPITAL LETTER OMEGA WITH PSILI AND PERISPOMENI
+			converters[0x1F6F] = *getUTF8FromUniChar(0x03A9, &myBuf); myBuf.setSize(0);	// GREEK CAPITAL LETTER OMEGA WITH DASIA AND PERISPOMENI
+			converters[0x1FA8] = *getUTF8FromUniChar(0x03A9, &myBuf); myBuf.setSize(0);	// GREEK CAPITAL LETTER OMEGA WITH PSILI AND PROSGEGRAMMENI
+			converters[0x1FA9] = *getUTF8FromUniChar(0x03A9, &myBuf); myBuf.setSize(0);	// GREEK CAPITAL LETTER OMEGA WITH DASIA AND PROSGEGRAMMENI
+			converters[0x1FAA] = *getUTF8FromUniChar(0x03A9, &myBuf); myBuf.setSize(0);	// GREEK CAPITAL LETTER OMEGA WITH PSILI AND VARIA AND PROSGEGRAMMENI
+			converters[0x1FAB] = *getUTF8FromUniChar(0x03A9, &myBuf); myBuf.setSize(0);	// GREEK CAPITAL LETTER OMEGA WITH DASIA AND VARIA AND PROSGEGRAMMENI
+			converters[0x1FAC] = *getUTF8FromUniChar(0x03A9, &myBuf); myBuf.setSize(0);	// GREEK CAPITAL LETTER OMEGA WITH PSILI AND OXIA AND PROSGEGRAMMENI
+			converters[0x1FAD] = *getUTF8FromUniChar(0x03A9, &myBuf); myBuf.setSize(0);	// GREEK CAPITAL LETTER OMEGA WITH DASIA AND OXIA AND PROSGEGRAMMENI
+			converters[0x1FAE] = *getUTF8FromUniChar(0x03A9, &myBuf); myBuf.setSize(0);	// GREEK CAPITAL LETTER OMEGA WITH PSILI AND PERISPOMENI AND PROSGEGRAMMENI
+			converters[0x1FAF] = *getUTF8FromUniChar(0x03A9, &myBuf); myBuf.setSize(0);	// GREEK CAPITAL LETTER OMEGA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI
+			converters[0x1FFA] = *getUTF8FromUniChar(0x03A9, &myBuf); myBuf.setSize(0);	// GREEK CAPITAL LETTER OMEGA WITH VARIA
+			converters[0x1FFB] = *getUTF8FromUniChar(0x03A9, &myBuf); myBuf.setSize(0);	// GREEK CAPITAL LETTER OMEGA WITH OXIA
+			converters[0x1FFC] = *getUTF8FromUniChar(0x03A9, &myBuf); myBuf.setSize(0);	// GREEK CAPITAL LETTER OMEGA WITH PROSGEGRAMMENI
+
+			converters[0x1FEC] = *getUTF8FromUniChar(0x03A1, &myBuf); myBuf.setSize(0);	// GREEK CAPITAL LETTER RHO WITH DASIA
+
+			// lower case
+			//alpha
+			converters[0x1F00] = *getUTF8FromUniChar(0x03B1, &myBuf); myBuf.setSize(0);	// GREEK SMALL LETTER ALPHA WITH PSILI
+			converters[0x1F01] = *getUTF8FromUniChar(0x03B1, &myBuf); myBuf.setSize(0);	// GREEK SMALL LETTER ALPHA WITH DASIA
+			converters[0x1F02] = *getUTF8FromUniChar(0x03B1, &myBuf); myBuf.setSize(0);	// GREEK SMALL LETTER ALPHA WITH PSILI AND VARIA
+			converters[0x1F03] = *getUTF8FromUniChar(0x03B1, &myBuf); myBuf.setSize(0);	// GREEK SMALL LETTER ALPHA WITH DASIA AND VARIA
+			converters[0x1F04] = *getUTF8FromUniChar(0x03B1, &myBuf); myBuf.setSize(0);	// GREEK SMALL LETTER ALPHA WITH PSILI AND OXIA
+			converters[0x1F05] = *getUTF8FromUniChar(0x03B1, &myBuf); myBuf.setSize(0);	// GREEK SMALL LETTER ALPHA WITH DASIA AND OXIA
+			converters[0x1F06] = *getUTF8FromUniChar(0x03B1, &myBuf); myBuf.setSize(0);	// GREEK SMALL LETTER ALPHA WITH PSILI AND PERISPOMENI
+			converters[0x1F07] = *getUTF8FromUniChar(0x03B1, &myBuf); myBuf.setSize(0);	// GREEK SMALL LETTER ALPHA WITH DASIA AND PERISPOMENI
+			converters[0x1F80] = *getUTF8FromUniChar(0x03B1, &myBuf); myBuf.setSize(0);	// GREEK SMALL LETTER ALPHA WITH PSILI AND YPOGEGRAMMENI
+			converters[0x1F81] = *getUTF8FromUniChar(0x03B1, &myBuf); myBuf.setSize(0);	// GREEK SMALL LETTER ALPHA WITH DASIA AND YPOGEGRAMMENI
+			converters[0x1F82] = *getUTF8FromUniChar(0x03B1, &myBuf); myBuf.setSize(0);	// GREEK SMALL LETTER ALPHA WITH PSILI AND VARIA AND YPOGEGRAMMENI
+			converters[0x1F83] = *getUTF8FromUniChar(0x03B1, &myBuf); myBuf.setSize(0);	// GREEK SMALL LETTER ALPHA WITH DASIA AND VARIA AND YPOGEGRAMMENI
+			converters[0x1F84] = *getUTF8FromUniChar(0x03B1, &myBuf); myBuf.setSize(0);	// GREEK SMALL LETTER ALPHA WITH PSILI AND OXIA AND YPOGEGRAMMENI
+			converters[0x1F85] = *getUTF8FromUniChar(0x03B1, &myBuf); myBuf.setSize(0);	// GREEK SMALL LETTER ALPHA WITH DASIA AND OXIA AND YPOGEGRAMMENI
+			converters[0x1F86] = *getUTF8FromUniChar(0x03B1, &myBuf); myBuf.setSize(0);	// GREEK SMALL LETTER ALPHA WITH PSILI AND PERISPOMENI AND YPOGEGRAMMENI
+			converters[0x1F87] = *getUTF8FromUniChar(0x03B1, &myBuf); myBuf.setSize(0);	// GREEK SMALL LETTER ALPHA WITH DASIA AND PERISPOMENI AND YPOGEGRAMMENI
+			converters[0x1F70] = *getUTF8FromUniChar(0x03B1, &myBuf); myBuf.setSize(0);	// GREEK SMALL LETTER ALPHA WITH VARIA
+			converters[0x1F71] = *getUTF8FromUniChar(0x03B1, &myBuf); myBuf.setSize(0);	// GREEK SMALL LETTER ALPHA WITH OXIA
+			converters[0x1FB0] = *getUTF8FromUniChar(0x03B1, &myBuf); myBuf.setSize(0);	// GREEK SMALL LETTER ALPHA WITH VRACHY
+			converters[0x1FB1] = *getUTF8FromUniChar(0x03B1, &myBuf); myBuf.setSize(0);	// GREEK SMALL LETTER ALPHA WITH MACRON
+			converters[0x1FB2] = *getUTF8FromUniChar(0x03B1, &myBuf); myBuf.setSize(0);	// GREEK SMALL LETTER ALPHA WITH VARIA AND YPOGEGRAMMENI
+			converters[0x1FB3] = *getUTF8FromUniChar(0x03B1, &myBuf); myBuf.setSize(0);	// GREEK SMALL LETTER ALPHA WITH YPOGEGRAMMENI
+			converters[0x1FB4] = *getUTF8FromUniChar(0x03B1, &myBuf); myBuf.setSize(0);	// GREEK SMALL LETTER ALPHA WITH OXIA AND YPOGEGRAMMENI
+			converters[0x1FB5] = *getUTF8FromUniChar(0x03B1, &myBuf); myBuf.setSize(0);	// unused?
+			converters[0x1FB6] = *getUTF8FromUniChar(0x03B1, &myBuf); myBuf.setSize(0);	// GREEK SMALL LETTER ALPHA WITH PERISPOMENI
+			converters[0x1FB7] = *getUTF8FromUniChar(0x03B1, &myBuf); myBuf.setSize(0);	// GREEK SMALL LETTER ALPHA WITH PERISPOMENI AND YPOGEGRAMMENI
+
+			converters[0x1F10] = *getUTF8FromUniChar(0x03B5, &myBuf); myBuf.setSize(0);	// GREEK SMALL LETTER EPSILON WITH PSILI
+			converters[0x1F11] = *getUTF8FromUniChar(0x03B5, &myBuf); myBuf.setSize(0);	// GREEK SMALL LETTER EPSILON WITH DASIA
+			converters[0x1F12] = *getUTF8FromUniChar(0x03B5, &myBuf); myBuf.setSize(0);	// GREEK SMALL LETTER EPSILON WITH PSILI AND VARIA
+			converters[0x1F13] = *getUTF8FromUniChar(0x03B5, &myBuf); myBuf.setSize(0);	// GREEK SMALL LETTER EPSILON WITH DASIA AND VARIA
+			converters[0x1F14] = *getUTF8FromUniChar(0x03B5, &myBuf); myBuf.setSize(0);	// GREEK SMALL LETTER EPSILON WITH PSILI AND OXIA
+			converters[0x1F15] = *getUTF8FromUniChar(0x03B5, &myBuf); myBuf.setSize(0);	// GREEK SMALL LETTER EPSILON WITH DASIA AND OXIA
+			converters[0x1F72] = *getUTF8FromUniChar(0x03B5, &myBuf); myBuf.setSize(0);	// GREEK SMALL LETTER EPSILON WITH VARIA
+			converters[0x1F73] = *getUTF8FromUniChar(0x03B5, &myBuf); myBuf.setSize(0);	// GREEK SMALL LETTER EPSILON WITH OXIA
+
+			converters[0x1F90] = *getUTF8FromUniChar(0x03B7, &myBuf); myBuf.setSize(0);	// GREEK SMALL LETTER ETA WITH PSILI AND YPOGEGRAMMENI
+			converters[0x1F91] = *getUTF8FromUniChar(0x03B7, &myBuf); myBuf.setSize(0);	// GREEK SMALL LETTER ETA WITH DASIA AND YPOGEGRAMMENI
+			converters[0x1F92] = *getUTF8FromUniChar(0x03B7, &myBuf); myBuf.setSize(0);	// GREEK SMALL LETTER ETA WITH PSILI AND VARIA AND YPOGEGRAMMENI
+			converters[0x1F93] = *getUTF8FromUniChar(0x03B7, &myBuf); myBuf.setSize(0);	// GREEK SMALL LETTER ETA WITH DASIA AND VARIA AND YPOGEGRAMMENI
+			converters[0x1F94] = *getUTF8FromUniChar(0x03B7, &myBuf); myBuf.setSize(0);	// GREEK SMALL LETTER ETA WITH PSILI AND OXIA AND YPOGEGRAMMENI
+			converters[0x1F95] = *getUTF8FromUniChar(0x03B7, &myBuf); myBuf.setSize(0);	// GREEK SMALL LETTER ETA WITH DASIA AND OXIA AND YPOGEGRAMMENI
+			converters[0x1F96] = *getUTF8FromUniChar(0x03B7, &myBuf); myBuf.setSize(0);	// GREEK SMALL LETTER ETA WITH PSILI AND PERISPOMENI AND YPOGEGRAMMENI
+			converters[0x1F97] = *getUTF8FromUniChar(0x03B7, &myBuf); myBuf.setSize(0);	// GREEK SMALL LETTER ETA WITH DASIA AND PERISPOMENI AND YPOGEGRAMMENI
+			converters[0x1F20] = *getUTF8FromUniChar(0x03B7, &myBuf); myBuf.setSize(0);	// GREEK SMALL LETTER ETA WITH PSILI
+			converters[0x1F21] = *getUTF8FromUniChar(0x03B7, &myBuf); myBuf.setSize(0);	// GREEK SMALL LETTER ETA WITH DASIA
+			converters[0x1F22] = *getUTF8FromUniChar(0x03B7, &myBuf); myBuf.setSize(0);	// GREEK SMALL LETTER ETA WITH PSILI AND VARIA
+			converters[0x1F23] = *getUTF8FromUniChar(0x03B7, &myBuf); myBuf.setSize(0);	// GREEK SMALL LETTER ETA WITH DASIA AND VARIA
+			converters[0x1F24] = *getUTF8FromUniChar(0x03B7, &myBuf); myBuf.setSize(0);	// GREEK SMALL LETTER ETA WITH PSILI AND OXIA
+			converters[0x1F25] = *getUTF8FromUniChar(0x03B7, &myBuf); myBuf.setSize(0);	// GREEK SMALL LETTER ETA WITH DASIA AND OXIA
+			converters[0x1F26] = *getUTF8FromUniChar(0x03B7, &myBuf); myBuf.setSize(0);	// GREEK SMALL LETTER ETA WITH PSILI AND PERISPOMENI
+			converters[0x1F27] = *getUTF8FromUniChar(0x03B7, &myBuf); myBuf.setSize(0);	// GREEK SMALL LETTER ETA WITH DASIA AND PERISPOMENI
+			converters[0x1FC2] = *getUTF8FromUniChar(0x03B7, &myBuf); myBuf.setSize(0);	// GREEK SMALL LETTER ETA WITH VARIA AND YPOGEGRAMMENI
+			converters[0x1FC3] = *getUTF8FromUniChar(0x03B7, &myBuf); myBuf.setSize(0);	// GREEK SMALL LETTER ETA WITH YPOGEGRAMMENI
+			converters[0x1FC4] = *getUTF8FromUniChar(0x03B7, &myBuf); myBuf.setSize(0);	// GREEK SMALL LETTER ETA WITH OXIA AND YPOGEGRAMMENI
+			converters[0x1FC5] = *getUTF8FromUniChar(0x03B7, &myBuf); myBuf.setSize(0);	// unused?
+			converters[0x1FC6] = *getUTF8FromUniChar(0x03B7, &myBuf); myBuf.setSize(0);	// GREEK SMALL LETTER ETA WITH PERISPOMENI
+			converters[0x1FC7] = *getUTF8FromUniChar(0x03B7, &myBuf); myBuf.setSize(0);	// GREEK SMALL LETTER ETA WITH PERISPOMENI AND YPOGEGRAMMENI
+			converters[0x1F74] = *getUTF8FromUniChar(0x03B7, &myBuf); myBuf.setSize(0);	// GREEK SMALL LETTER ETA WITH VARIA
+			converters[0x1F75] = *getUTF8FromUniChar(0x03B7, &myBuf); myBuf.setSize(0);	// GREEK SMALL LETTER ETA WITH OXIA
+
+			converters[0x1F30] = *getUTF8FromUniChar(0x03B9, &myBuf); myBuf.setSize(0);	// GREEK SMALL LETTER IOTA WITH PSILI
+			converters[0x1F31] = *getUTF8FromUniChar(0x03B9, &myBuf); myBuf.setSize(0);	// GREEK SMALL LETTER IOTA WITH DASIA
+			converters[0x1F32] = *getUTF8FromUniChar(0x03B9, &myBuf); myBuf.setSize(0);	// GREEK SMALL LETTER IOTA WITH PSILI AND VARIA
+			converters[0x1F33] = *getUTF8FromUniChar(0x03B9, &myBuf); myBuf.setSize(0);	// GREEK SMALL LETTER IOTA WITH DASIA AND VARIA
+			converters[0x1F34] = *getUTF8FromUniChar(0x03B9, &myBuf); myBuf.setSize(0);	// GREEK SMALL LETTER IOTA WITH PSILI AND OXIA
+			converters[0x1F35] = *getUTF8FromUniChar(0x03B9, &myBuf); myBuf.setSize(0);	// GREEK SMALL LETTER IOTA WITH DASIA AND OXIA
+			converters[0x1F36] = *getUTF8FromUniChar(0x03B9, &myBuf); myBuf.setSize(0);	// GREEK SMALL LETTER IOTA WITH PSILI AND PERISPOMENI
+			converters[0x1F37] = *getUTF8FromUniChar(0x03B9, &myBuf); myBuf.setSize(0);	// GREEK SMALL LETTER IOTA WITH DASIA AND PERISPOMENI
+			converters[0x1F76] = *getUTF8FromUniChar(0x03B9, &myBuf); myBuf.setSize(0);	// GREEK SMALL LETTER IOTA WITH VARIA
+			converters[0x1F77] = *getUTF8FromUniChar(0x03B9, &myBuf); myBuf.setSize(0);	// GREEK SMALL LETTER IOTA WITH OXIA
+			converters[0x1FD0] = *getUTF8FromUniChar(0x03B9, &myBuf); myBuf.setSize(0);	// GREEK SMALL LETTER IOTA WITH VRACHY
+			converters[0x1FD1] = *getUTF8FromUniChar(0x03B9, &myBuf); myBuf.setSize(0);	// GREEK SMALL LETTER IOTA WITH MACRON
+			converters[0x1FD2] = *getUTF8FromUniChar(0x03B9, &myBuf); myBuf.setSize(0);	// GREEK SMALL LETTER IOTA WITH DIALYTIKA AND VARIA
+			converters[0x1FD3] = *getUTF8FromUniChar(0x03B9, &myBuf); myBuf.setSize(0);	// GREEK SMALL LETTER IOTA WITH DIALYTIKA AND OXIA
+			converters[0x1FD4] = *getUTF8FromUniChar(0x03B9, &myBuf); myBuf.setSize(0);	// unused?
+			converters[0x1FD5] = *getUTF8FromUniChar(0x03B9, &myBuf); myBuf.setSize(0);	// unused?
+			converters[0x1FD6] = *getUTF8FromUniChar(0x03B9, &myBuf); myBuf.setSize(0);	// GREEK SMALL LETTER IOTA WITH PERISPOMENI
+			converters[0x1FD7] = *getUTF8FromUniChar(0x03B9, &myBuf); myBuf.setSize(0);	// GREEK SMALL LETTER IOTA WITH DIALYTIKA AND PERISPOMENI
+
+			converters[0x1F40] = *getUTF8FromUniChar(0x03BF, &myBuf); myBuf.setSize(0);	// GREEK SMALL LETTER OMICRON WITH PSILI
+			converters[0x1F41] = *getUTF8FromUniChar(0x03BF, &myBuf); myBuf.setSize(0);	// GREEK SMALL LETTER OMICRON WITH DASIA
+			converters[0x1F42] = *getUTF8FromUniChar(0x03BF, &myBuf); myBuf.setSize(0);	// GREEK SMALL LETTER OMICRON WITH PSILI AND VARIA
+			converters[0x1F43] = *getUTF8FromUniChar(0x03BF, &myBuf); myBuf.setSize(0);	// GREEK SMALL LETTER OMICRON WITH DASIA AND VARIA
+			converters[0x1F44] = *getUTF8FromUniChar(0x03BF, &myBuf); myBuf.setSize(0);	// GREEK SMALL LETTER OMICRON WITH PSILI AND OXIA
+			converters[0x1F45] = *getUTF8FromUniChar(0x03BF, &myBuf); myBuf.setSize(0);	// GREEK SMALL LETTER OMICRON WITH DASIA AND OXIA
+			converters[0x1F78] = *getUTF8FromUniChar(0x03BF, &myBuf); myBuf.setSize(0);	// GREEK SMALL LETTER OMICRON WITH VARIA
+			converters[0x1F79] = *getUTF8FromUniChar(0x03BF, &myBuf); myBuf.setSize(0);	// GREEK SMALL LETTER OMICRON WITH OXIA
+
+			converters[0x1F50] = *getUTF8FromUniChar(0x03C5, &myBuf); myBuf.setSize(0);	// GREEK SMALL LETTER UPSILON WITH PSILI
+			converters[0x1F51] = *getUTF8FromUniChar(0x03C5, &myBuf); myBuf.setSize(0);	// GREEK SMALL LETTER UPSILON WITH DASIA
+			converters[0x1F52] = *getUTF8FromUniChar(0x03C5, &myBuf); myBuf.setSize(0);	// GREEK SMALL LETTER UPSILON WITH PSILI AND VARIA
+			converters[0x1F53] = *getUTF8FromUniChar(0x03C5, &myBuf); myBuf.setSize(0);	// GREEK SMALL LETTER UPSILON WITH DASIA AND VARIA
+			converters[0x1F54] = *getUTF8FromUniChar(0x03C5, &myBuf); myBuf.setSize(0);	// GREEK SMALL LETTER UPSILON WITH PSILI AND OXIA
+			converters[0x1F55] = *getUTF8FromUniChar(0x03C5, &myBuf); myBuf.setSize(0);	// GREEK SMALL LETTER UPSILON WITH DASIA AND OXIA
+			converters[0x1F56] = *getUTF8FromUniChar(0x03C5, &myBuf); myBuf.setSize(0);	// GREEK SMALL LETTER UPSILON WITH PSILI AND PERISPOMENI
+			converters[0x1F57] = *getUTF8FromUniChar(0x03C5, &myBuf); myBuf.setSize(0);	// GREEK SMALL LETTER UPSILON WITH DASIA AND PERISPOMENI
+			converters[0x1F7A] = *getUTF8FromUniChar(0x03C5, &myBuf); myBuf.setSize(0);	// GREEK SMALL LETTER UPSILON WITH VARIA
+			converters[0x1F7B] = *getUTF8FromUniChar(0x03C5, &myBuf); myBuf.setSize(0);	// GREEK SMALL LETTER UPSILON WITH OXIA
+			converters[0x1FE0] = *getUTF8FromUniChar(0x03C5, &myBuf); myBuf.setSize(0);	// GREEK SMALL LETTER UPSILON WITH VRACHY
+			converters[0x1FE1] = *getUTF8FromUniChar(0x03C5, &myBuf); myBuf.setSize(0);	// GREEK SMALL LETTER UPSILON WITH MACRON
+			converters[0x1FE2] = *getUTF8FromUniChar(0x03C5, &myBuf); myBuf.setSize(0);	// GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND VARIA
+			converters[0x1FE3] = *getUTF8FromUniChar(0x03C5, &myBuf); myBuf.setSize(0);	// GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND OXIA
+			converters[0x1FE6] = *getUTF8FromUniChar(0x03C5, &myBuf); myBuf.setSize(0);	// GREEK SMALL LETTER UPSILON WITH PERISPOMENI
+			converters[0x1FE7] = *getUTF8FromUniChar(0x03C5, &myBuf); myBuf.setSize(0);	// GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND PERISPOMENI
+
+			converters[0x1F60] = *getUTF8FromUniChar(0x03C9, &myBuf); myBuf.setSize(0);	// GREEK SMALL LETTER OMEGA WITH PSILI
+			converters[0x1F61] = *getUTF8FromUniChar(0x03C9, &myBuf); myBuf.setSize(0);	// GREEK SMALL LETTER OMEGA WITH DASIA
+			converters[0x1F62] = *getUTF8FromUniChar(0x03C9, &myBuf); myBuf.setSize(0);	// GREEK SMALL LETTER OMEGA WITH PSILI AND VARIA
+			converters[0x1F63] = *getUTF8FromUniChar(0x03C9, &myBuf); myBuf.setSize(0);	// GREEK SMALL LETTER OMEGA WITH DASIA AND VARIA
+			converters[0x1F64] = *getUTF8FromUniChar(0x03C9, &myBuf); myBuf.setSize(0);	// GREEK SMALL LETTER OMEGA WITH PSILI AND OXIA
+			converters[0x1F65] = *getUTF8FromUniChar(0x03C9, &myBuf); myBuf.setSize(0);	// GREEK SMALL LETTER OMEGA WITH DASIA AND OXIA
+			converters[0x1F66] = *getUTF8FromUniChar(0x03C9, &myBuf); myBuf.setSize(0);	// GREEK SMALL LETTER OMEGA WITH PSILI AND PERISPOMENI
+			converters[0x1F67] = *getUTF8FromUniChar(0x03C9, &myBuf); myBuf.setSize(0);	// GREEK SMALL LETTER OMEGA WITH DASIA AND PERISPOMENI
+			converters[0x1F7C] = *getUTF8FromUniChar(0x03C9, &myBuf); myBuf.setSize(0);	// GREEK SMALL LETTER OMEGA WITH VARIA
+			converters[0x1F7D] = *getUTF8FromUniChar(0x03C9, &myBuf); myBuf.setSize(0);	// GREEK SMALL LETTER OMEGA WITH OXIA
+			converters[0x1FA0] = *getUTF8FromUniChar(0x03C9, &myBuf); myBuf.setSize(0);	// GREEK SMALL LETTER OMEGA WITH PSILI AND YPOGEGRAMMENI
+			converters[0x1FA1] = *getUTF8FromUniChar(0x03C9, &myBuf); myBuf.setSize(0);	// GREEK SMALL LETTER OMEGA WITH DASIA AND YPOGEGRAMMENI
+			converters[0x1FA2] = *getUTF8FromUniChar(0x03C9, &myBuf); myBuf.setSize(0);	// GREEK SMALL LETTER OMEGA WITH PSILI AND VARIA AND YPOGEGRAMMENI
+			converters[0x1FA3] = *getUTF8FromUniChar(0x03C9, &myBuf); myBuf.setSize(0);	// GREEK SMALL LETTER OMEGA WITH DASIA AND VARIA AND YPOGEGRAMMENI
+			converters[0x1FA4] = *getUTF8FromUniChar(0x03C9, &myBuf); myBuf.setSize(0);	// GREEK SMALL LETTER OMEGA WITH PSILI AND OXIA AND YPOGEGRAMMENI
+			converters[0x1FA5] = *getUTF8FromUniChar(0x03C9, &myBuf); myBuf.setSize(0);	// GREEK SMALL LETTER OMEGA WITH DASIA AND OXIA AND YPOGEGRAMMENI
+			converters[0x1FA6] = *getUTF8FromUniChar(0x03C9, &myBuf); myBuf.setSize(0);	// GREEK SMALL LETTER OMEGA WITH PSILI AND PERISPOMENI AND YPOGEGRAMMENI
+			converters[0x1FA7] = *getUTF8FromUniChar(0x03C9, &myBuf); myBuf.setSize(0);	// GREEK SMALL LETTER OMEGA WITH DASIA AND PERISPOMENI AND YPOGEGRAMMENI
+			converters[0x1FF2] = *getUTF8FromUniChar(0x03C9, &myBuf); myBuf.setSize(0);	// GREEK SMALL LETTER OMEGA WITH VARIA AND YPOGEGRAMMENI
+			converters[0x1FF3] = *getUTF8FromUniChar(0x03C9, &myBuf); myBuf.setSize(0);	// GREEK SMALL LETTER OMEGA WITH YPOGEGRAMMENI
+			converters[0x1FF4] = *getUTF8FromUniChar(0x03C9, &myBuf); myBuf.setSize(0);	// GREEK SMALL LETTER OMEGA WITH OXIA AND YPOGEGRAMMENI
+			converters[0x1FF5] = *getUTF8FromUniChar(0x03C9, &myBuf); myBuf.setSize(0);	// unused?
+			converters[0x1FF6] = *getUTF8FromUniChar(0x03C9, &myBuf); myBuf.setSize(0);	// GREEK SMALL LETTER OMEGA WITH PERISPOMENI
+			converters[0x1FF7] = *getUTF8FromUniChar(0x03C9, &myBuf); myBuf.setSize(0);	// GREEK SMALL LETTER OMEGA WITH PERISPOMENI AND YPOGEGRAMMENI
+
+			converters[0x1FE4] = *getUTF8FromUniChar(0x03C1, &myBuf); myBuf.setSize(0);	// GREEK SMALL LETTER RHO WITH PSILI
+			converters[0x1FE5] = *getUTF8FromUniChar(0x03C1, &myBuf); myBuf.setSize(0);	// GREEK SMALL LETTER RHO WITH DASIA
+		}
+	} __converters_init;
 }
 
 
@@ -57,229 +351,24 @@
 char UTF8GreekAccents::processText(SWBuf &text, const SWKey *key, const SWModule *module) {
 
 	if (!option) { //we don't want greek accents
-    		//unsigned char *to, *from;
-		//to = (unsigned char*)text;
-		//for (from = (unsigned char*)text; *from; from++) {
-#ifdef _ICU_
-		decompose.processText(text, (SWKey *)2);  // note the hack of 2 to mimic a real key. TODO: remove all hacks
-#endif
-		
 		SWBuf orig = text;
 		const unsigned char* from = (unsigned char*)orig.c_str();
-		for (text = ""; *from; from++) {		
-			//first just remove combining characters
-			if (*from == 0xE2 && *(from + 1) == 0x80 && *(from + 2) == 0x99) {
-				from += 2;
-			}
-			else if (*from == 0xCC && *(from + 1)) {
-				if (*(from + 1) == 0x80 || *(from + 1) == 0x81 || *(from + 1) == 0x82 || *(from + 1) == 0x88 || *(from + 1) == 0x93 || *(from + 1) == 0x94) {
-					from++;
-				}
-			}
-			else if (*from == 0xCD && (*(from + 1) == 0xBA || *(from + 1) == 0x82)) {
-				from++;
-			}
-			//now converted pre-composed characters to their alphabetic bases, discarding the accents
+		text = "";
+		map<__u32, SWBuf>::const_iterator it = converters.end();
+		while (*from) {		
+			__u32 ch = getUniCharFromUTF8(&from, true);
+			// if ch is bad, then convert to replacement char
+			if (!ch) ch = 0xFFFD;
 
-			//Greek
-			//capital alpha
-			else if ((*from == 0xCE && *(from + 1) == 0x86)) {
-				text += 0xCE;
-				text += 0x91;
-				from++;
+			it = converters.find(ch);
+			if (it == converters.end()) {
+				getUTF8FromUniChar(ch, &text);
 			}
-			//capital epsilon
-			else if ((*from == 0xCE && *(from + 1) == 0x88)) {
-				text += 0xCE;
-				text += 0x95;
-				from++;
-			}
-			//capital eta
-			else if ((*from == 0xCE && *(from + 1) == 0x89)) {
-				text += 0xCE;
-				text += 0x97;
-				from++;
-			}
-			//capital iota
-			else if ((*from == 0xCE && (*(from + 1) == 0x8A || *(from + 1) == 0xAA))) {
-				text += 0xCE;
-				text += 0x99;
-				from++;
-			}
-			//capital omicron
-			else if ((*from == 0xCE && *(from + 1) == 0x8C)) {
-				text += 0xCE;
-				text += 0x9F;
-				from++;
-			}
-			//capital upsilon
-			else if ((*from == 0xCE && (*(from + 1) == 0x8E || *(from + 1) == 0xAB))) {
-				text += 0xCE;
-				text += 0xA5;
-				from++;
-			}
-			//capital omega
-			else if ((*from == 0xCE && *(from + 1) == 0x8F)) {
-				text += 0xCE;
-				text += 0xA9;
-				from++;
-			}
-
-			//alpha
-			else if ((*from == 0xCE && *(from + 1) == 0xAC)) {
-				text += 0xCE;
-				text += 0xB1;
-				from++;
-			}
-			//epsilon
-			else if ((*from == 0xCE && *(from + 1) == 0xAD)) {
-				text += 0xCE;
-				text += 0xB5;
-				from++;
-			}
-			//eta
-			else if ((*from == 0xCE && *(from + 1) == 0xAE)) {
-				text += 0xCE;
-				text += 0xB7;
-				from++;
-			}
-			//iota
-			else if ((*from == 0xCE && *(from + 1) == 0xAF) || (*from == 0xCF && *(from + 1) == 0x8A)) {
-				text += 0xCE;
-				text += 0xB9;
-				from++;
-			}
-			//omicron
-			else if ((*from == 0xCF && *(from + 1) == 0x8C)) {
-				text += 0xCE;
-				text += 0xBF;
-				from++;
-			}
-			//upsilon
-			else if ((*from == 0xCE && *(from + 1) == 0x88) || (*from == 0xCF && (*(from + 1) == 0x8B || *(from + 1) == 0x8D))) {
-				text += 0xCF;
-				text += 0x85;
-				from++;
-			}
-			//omega
-			else if ((*from == 0xCF && *(from + 1) == 0x8E)) {
-				text += 0xCF;
-				text += 0x89;
-				from++;
-			}
-
-			//Extended Greek
-			//capital alpha
-			else if (*from == 0xE1 && (((*(from + 1) == 0xBC || *(from + 1) == 0xBE) && *(from + 2) >= 0x88 && *(from + 2) <= 0x8F) || (*(from + 1) == 0xBE && *(from + 2) >= 0xB8 && *(from + 2) <= 0xBC))) {
-				text += 0xCE;
-				text += 0x91;
-				from+=2;
-			}
-			//capital epsilon
-			else if (*from == 0xE1 && ((*(from + 1) == 0xBC && *(from + 2) >= 0x98 && *(from + 2) <= 0x9D) || (*(from + 1) == 0xBF && (*(from + 2) == 0x88 || *(from + 2) == 0x89)))) {
-				text += 0xCE;
-				text += 0x95;
-				from+=2;
-			}
-			//capital eta
-			else if (*from == 0xE1 && ((*(from + 1) == 0xBC && *(from + 2) >= 0xA8 && *(from + 2) <= 0xAF) || (*(from + 1) == 0xBE && *(from + 2) >= 0x98 && *(from + 2) <= 0x9F) || (*(from + 1) == 0xBF && *(from + 2) >= 0x8A && *(from + 2) <= 0x8C))) {
-				text += 0xCE;
-				text += 0x97;
-				from+=2;
-			}
-			//capital iota
-			else if (*from == 0xE1 && ((*(from + 1) == 0xBC && *(from + 2) >= 0xB8 && *(from + 2) <= 0xBF) || (*(from + 1) == 0xBF && *(from + 2) >= 0x98 && *(from + 2) <= 0x9B))) {
-				text += 0xCE;
-				text += 0x99;
-				from+=2;
-			}
-			//capital omicron
-			else if (*from == 0xE1 && (((*(from + 1) == 0xBD && *(from + 2) >= 0x88 && *(from + 2) <= 0x8D)) || ((*(from + 1) == 0xBF && (*(from + 2) == 0xB8 || *(from + 2) == 0xB9))))) {
-				text += 0xCE;
-				text += 0x9F;
-				from+=2;
-			}
-			//capital upsilon
-			else if (*from == 0xE1 && ((*(from + 1) == 0xBD && *(from + 2) >= 0x99 && *(from + 2) <= 0x9F) || (*(from + 1) == 0xBF && *(from + 2) >= 0xA8 && *(from + 2) <= 0xAB))) {
-				text += 0xCE;
-				text += 0xA5;
-				from+=2;
-			}
-			//capital omega
-			else if (*from == 0xE1 && (((*(from + 1) == 0xBD || *(from + 1) == 0xBE) && *(from + 2) >= 0xA8 && *(from + 2) <= 0xAF) || (*(from + 1) == 0xBF && *(from + 2) >= 0xBA && *(from + 2) <= 0xBC))) {
-				text += 0xCE;
-				text += 0xA9;
-				from+=2;
-			}
-			//capital rho
-			else if (*from == 0xE1 && *(from + 1) == 0xBF && *(from + 2) == 0xAC) {
-				text += 0xCE;
-				text += 0xA1;
-				from+=2;
-			}
-
-			//alpha
-			else if (*from == 0xE1 && (
-                            ((*(from + 1) == 0xBC || *(from + 1) == 0xBE) && *(from + 2) >= 0x80 && *(from + 2) <= 0x87)
-                         || (*(from + 1) == 0xBD && (*(from + 2) == 0xB0 || *(from + 2) == 0xB1))
-                         || (*(from + 1) == 0xBE && *(from + 2) >= 0xB0 && *(from + 2) <= 0xB7))) {
-				text += 0xCE;
-				text += 0xB1;
-				from+=2;
-			}
-			//epsilon
-			else if (*from == 0xE1 && ((*(from + 1) == 0xBC && *(from + 2) >= 0x90 && *(from + 2) <= 0x95) || (*(from + 1) == 0xBD && (*(from + 2) == 0xB2 || *(from + 2) == 0xB3)))) {
-				text += 0xCE;
-				text += 0xB5;
-				from+=2;
-			}
-			//eta
-			else if (*from == 0xE1 && ((*(from + 1) == 0xBE && *(from + 2) >= 0x90 && *(from + 2) <= 0x97) || (*(from + 1) == 0xBC && *(from + 2) >= 0xA0 && *(from + 2) <= 0xA7) || (*(from + 1) == 0xBF && *(from + 2) >= 0x82 && *(from + 2) <= 0x87) || (*(from + 1) == 0xBD && (*(from + 2) == 0xB4 || *(from + 2) == 0xB5)))) {
-				text += 0xCE;
-				text += 0xB7;
-				from+=2;
-			}
-			//iota
-			else if (*from == 0xE1 && ((*(from + 1) == 0xBC && *(from + 2) >= 0xB0 && *(from + 2) <= 0xB7) || (*(from + 1) == 0xBD && (*(from + 2) == 0xB6 || *(from + 2) == 0xB7)) || (*(from + 1) == 0xBF && *(from + 2) >= 0x90 && *(from + 2) <= 0x97))) {
-				text += 0xCE;
-				text += 0xB9;
-				from+=2;
-			}
-			//omicron
-			else if (*from == 0xE1 && (*(from + 1) == 0xBD && ((*(from + 2) >= 0x80 && *(from + 2) <= 0x85) || (*(from + 2) == 0xB8 || *(from + 2) == 0xB9)))) {
-				text += 0xCE;
-				text += 0xBF;
-				from+=2;
-			}
-			//upsilon
-			else if (*from == 0xE1 && ((*(from + 1) == 0xBD && ((*(from + 2) >= 0x90 && *(from + 2) <= 0x97) || *(from + 2) == 0xBA || *(from + 2) == 0xBB)) || (*(from + 1) == 0xBF && ((*(from + 2) >= 0xA0 && *(from + 2) <= 0xA3) || *(from + 2) == 0xA6 || *(from + 2) == 0xA7)))) {
-				text += 0xCF;
-				text += 0x85;
-				from+=2;
-			}
-			//omega
-			else if (*from == 0xE1 && ((*(from + 1) == 0xBD && ((*(from + 2) >= 0xA0 && *(from + 2) <= 0xA7) || (*(from + 2) == 0xBC || *(from + 2) == 0xBD))) || (*(from + 1) == 0xBE && (*(from + 2) >= 0xA0 && *(from + 2) <= 0xA7)) || (*(from + 1) == 0xBF && *(from + 2) >= 0xB2 && *(from + 2) <= 0xB7))) {
-				text += 0xCF;
-				text += 0x89;
-				from+=2;
-			}
-			//rho
-			else if (*from == 0xE1 && *(from + 1) == 0xBF && (*(from + 2) == 0xA4 && *(from + 2) == 0xA5)) {
-				text += 0xCF;
-				text += 0x81;
-				from+=2;
-			}
-			else { //no characters we filter
-				text += *from;
-			}
+			else text.append((const char *)it->second, it->second.size());	// save a strlen, since we know our size
 		}
 	}
 	return 0;
 }
 
 
-
-
-
-
 SWORD_NAMESPACE_END

Modified: branches/sword-1-8-x/src/modules/lexdict/rawld/rawld.cpp
===================================================================
--- branches/sword-1-8-x/src/modules/lexdict/rawld/rawld.cpp	2017-11-01 11:33:56 UTC (rev 3514)
+++ branches/sword-1-8-x/src/modules/lexdict/rawld/rawld.cpp	2017-11-01 11:38:09 UTC (rev 3515)
@@ -189,7 +189,7 @@
 
 
 long RawLD::getEntryCount() const {
-	if (idxfd < 0) return 0;
+	if (!idxfd || idxfd->getFd() < 0) return 0;
 	return idxfd->seek(0, SEEK_END) / IDXENTRYSIZE;
 }
 

Modified: branches/sword-1-8-x/src/modules/lexdict/rawld4/rawld4.cpp
===================================================================
--- branches/sword-1-8-x/src/modules/lexdict/rawld4/rawld4.cpp	2017-11-01 11:33:56 UTC (rev 3514)
+++ branches/sword-1-8-x/src/modules/lexdict/rawld4/rawld4.cpp	2017-11-01 11:38:09 UTC (rev 3515)
@@ -187,7 +187,7 @@
 
 
 long RawLD4::getEntryCount() const {
-	if (idxfd < 0) return 0;
+	if (!idxfd || idxfd->getFd() < 0) return 0;
 	return idxfd->seek(0, SEEK_END) / IDXENTRYSIZE;
 }
 

Modified: branches/sword-1-8-x/src/modules/lexdict/zld/zld.cpp
===================================================================
--- branches/sword-1-8-x/src/modules/lexdict/zld/zld.cpp	2017-11-01 11:33:56 UTC (rev 3514)
+++ branches/sword-1-8-x/src/modules/lexdict/zld/zld.cpp	2017-11-01 11:38:09 UTC (rev 3515)
@@ -187,7 +187,7 @@
 
 long zLD::getEntryCount() const
 {
-	if (idxfd < 0) return 0;
+	if (!idxfd || idxfd->getFd() < 0) return 0;
 	return idxfd->seek(0, SEEK_END) / IDXENTRYSIZE;
 }
 

Modified: branches/sword-1-8-x/src/modules/swmodule.cpp
===================================================================
--- branches/sword-1-8-x/src/modules/swmodule.cpp	2017-11-01 11:33:56 UTC (rev 3514)
+++ branches/sword-1-8-x/src/modules/swmodule.cpp	2017-11-01 11:38:09 UTC (rev 3515)
@@ -303,7 +303,7 @@
 	if (oldKey)
 		delete oldKey;
 
-	return error = key->popError();
+	return error = key->getError();
 }
 
 

Modified: branches/sword-1-8-x/src/utilfuns/swbuf.cpp
===================================================================
--- branches/sword-1-8-x/src/utilfuns/swbuf.cpp	2017-11-01 11:33:56 UTC (rev 3514)
+++ branches/sword-1-8-x/src/utilfuns/swbuf.cpp	2017-11-01 11:38:09 UTC (rev 3515)
@@ -32,39 +32,7 @@
 
 char *SWBuf::nullStr = (char *)"";
 
-/******************************************************************************
-* SWBuf Constructor - Creates an empty SWBuf object or an SWBuf initialized
-* 		to a value from a const char *
-*
-*/
-SWBuf::SWBuf(const char *initVal, unsigned long initSize) {
-	init(initSize);
-	if (initVal)
-		set(initVal);
-}
 
-/******************************************************************************
-* SWBuf Constructor - Creates an SWBuf initialized
-* 		to a value from another SWBuf
-*
-*/
-SWBuf::SWBuf(const SWBuf &other, unsigned long initSize) {
-	init(initSize);
-	set(other);
-}
-
-/******************************************************************************
-* SWBuf Constructor - Creates an SWBuf initialized
-* 		to a value from a char
-*
-*/
-SWBuf::SWBuf(char initVal, unsigned long initSize) {
-	init(initSize+1);
-	*buf = initVal;
-	end = buf+1;
-	*end = 0;
-}
-
 /*
 SWBuf::SWBuf(unsigned long initSize) {
 	init(initSize);
@@ -97,33 +65,6 @@
 }
 
 /******************************************************************************
-* SWBuf::append - appends a value to the current value of this SWBuf
-* 
-*/
-SWBuf &SWBuf::append(const char *str, long max) {
-//	if (!str) //A null string was passed
-//		return;
-	if (max < 0)
-		max = strlen(str);
-	assureMore(max+1);
-	for (;((max)&&(*str));max--)
-		*end++ = *str++;
-	*end = 0;
-	return *this;
-}
-
-/******************************************************************************
-* SWBuf::setSize - Size this buffer to a specific length
-*/
-void SWBuf::setSize(unsigned long len) {
-	assureSize(len+1);
-	if ((unsigned)(end - buf) < len)
-		memset(end, fillByte, len - (end-buf));
-	end = buf + len;
-	*end = 0;
-}
-
-/******************************************************************************
 * SWBuf::appendFormatted - appends formatted strings to the current value of this SWBuf
 * WARNING: This function can only write at most
 * JUNKBUFSIZE to the string per call.

Modified: branches/sword-1-8-x/src/utilfuns/utilstr.cpp
===================================================================
--- branches/sword-1-8-x/src/utilfuns/utilstr.cpp	2017-11-01 11:33:56 UTC (rev 3514)
+++ branches/sword-1-8-x/src/utilfuns/utilstr.cpp	2017-11-01 11:38:09 UTC (rev 3515)
@@ -67,29 +67,7 @@
 };
 
 
-/******************************************************************************
- * stdstr - clones a string
- *
- * ENT:	ipstr	- pointer to a string pointer to set if necessary
- *	istr	- string to set to *ipstr
- *			0 - only get
- *
- * RET:	*ipstr
- */
 
-char *stdstr(char **ipstr, const char *istr, unsigned int memPadFactor) {
-	if (*ipstr)
-		delete [] *ipstr;
-	if (istr) {
-		int len = (int)strlen(istr) + 1;
-		*ipstr = new char [ len * memPadFactor ];
-		memcpy(*ipstr, istr, len);
-	}
-	else *ipstr = 0;
-	return *ipstr;
-}
-
-
 /******************************************************************************
  * strstrip - Removes leading and trailing spaces from a string
  *
@@ -187,163 +165,6 @@
 }
 
 
-/******************************************************************************
- * getUniCharFromUTF8 - retrieves the next Unicode codepoint from a UTF8 string
- * 					and increments buf to start of next codepoint
- *
- * ENT:	buf - address of a utf8 buffer
- *
- * RET:	buf - incremented past last byte used in computing the current codepoint
- * 		unicode codepoint value (0 with buf incremented is invalid UTF8 byte
- */
-
-__u32 getUniCharFromUTF8(const unsigned char **buf) {
-	__u32 ch = 0;
-	unsigned char multibuf[7];
-
-	//case: We're at the end
-	if (!(**buf)) {
-		return ch;
-	}
-
-	//case: ANSI
-	if (!(**buf & 128)) {
-		ch = **buf;
-		(*buf)++;
-		return ch;
-	}
-
-	//case: Invalid UTF-8 (illegal continuing byte in initial position)
-	if ((**buf & 128) && (!(**buf & 64))) {
-		(*buf)++;
-		return ch;
-	}
-
-	//case: 2+ byte codepoint
-	multibuf[0] = **buf;
-	multibuf[0] <<= 1;
-	int subsequent;
-	for (subsequent = 1; (multibuf[0] & 128) && (subsequent < 7); subsequent++) {
-		multibuf[0] <<= 1;
-		multibuf[subsequent] = (*buf)[subsequent];
-		multibuf[subsequent] &= 63;
-		// subsequent byte did not begin with 10XXXXXX
-		// move our buffer to here and error out
-		if (((*buf)[subsequent] - multibuf[subsequent]) != 128) {
-			*buf += subsequent;
-			return 0;
-		}
-		ch <<= 6;
-		ch |= multibuf[subsequent];
-	}
-	subsequent--;
-	multibuf[0] <<= 1;
-	char significantFirstBits = 8 - (2+subsequent);
-	
-	ch |= (((__s16)multibuf[0]) << (((6*subsequent)+significantFirstBits)-8));
-	*buf += (subsequent+1);
-	return ch;
-}
-
-
-SWBuf getUTF8FromUniChar(__u32 uchar) {
-	SWBuf retVal("", 7);
-	unsigned int i;
-
-	if (uchar < 0x80) {
-		retVal.append((unsigned char)uchar);
-		retVal.setSize(1);
-	}
-	else if (uchar < 0x800) {
-		retVal.setSize(2);
-		i = uchar & 0x3f;
-		retVal[1] = (unsigned char)(0x80 | i);
-		uchar >>= 6;
-
-		i = uchar & 0x1f;
-		retVal[0] = (unsigned char)(0xc0 | i);
-	}
-	else if (uchar < 0x10000) {
-		retVal.setSize(3);
-		i = uchar & 0x3f;
-		retVal[2] = (unsigned char)(0x80 | i);
-		uchar >>= 6;
-
-		i = uchar & 0x3f;
-		retVal[1] = (unsigned char)(0x80 | i);
-		uchar >>= 6;
-
-		i = uchar & 0x0f;
-		retVal[0] = (unsigned char)(0xe0 | i);
-	}
-	else if (uchar < 0x200000) {
-		retVal.setSize(4);
-		i = uchar & 0x3f;
-		retVal[3] = (unsigned char)(0x80 | i);
-		uchar >>= 6;
-
-		i = uchar & 0x3f;
-		retVal[2] = (unsigned char)(0x80 | i);
-		uchar >>= 6;
-
-		i = uchar & 0x3f;
-		retVal[1] = (unsigned char)(0x80 | i);
-		uchar >>= 6;
-
-		i = uchar & 0x07;
-		retVal[0] = (unsigned char)(0xf0 | i);
-	}
-	else if (uchar < 0x4000000) {
-		retVal.setSize(5);
-		i = uchar & 0x3f;
-		retVal[4] = (unsigned char)(0x80 | i);
-		uchar >>= 6;
-
-		i = uchar & 0x3f;
-		retVal[3] = (unsigned char)(0x80 | i);
-		uchar >>= 6;
-
-		i = uchar & 0x3f;
-		retVal[2] = (unsigned char)(0x80 | i);
-		uchar >>= 6;
-
-		i = uchar & 0x3f;
-		retVal[1] = (unsigned char)(0x80 | i);
-		uchar >>= 6;
-
-		i = uchar & 0x03;
-		retVal[0] = (unsigned char)(0xf8 | i);
-	}
-	else if (uchar < 0x80000000) {
-		retVal.setSize(6);
-		i = uchar & 0x3f;
-		retVal[5] = (unsigned char)(0x80 | i);
-		uchar >>= 6;
-
-		i = uchar & 0x3f;
-		retVal[4] = (unsigned char)(0x80 | i);
-		uchar >>= 6;
-
-		i = uchar & 0x3f;
-		retVal[3] = (unsigned char)(0x80 | i);
-		uchar >>= 6;
-
-		i = uchar & 0x3f;
-		retVal[2] = (unsigned char)(0x80 | i);
-		uchar >>= 6;
-
-		i = uchar & 0x3f;
-		retVal[1] = (unsigned char)(0x80 | i);
-		uchar >>= 6;
-
-		i = uchar & 0x01;
-		retVal[0] = (unsigned char)(0xfc | i);
-	}
-
-	return retVal;
-}
-
-
 SWBuf assureValidUTF8(const char *buf) {
 
 	SWBuf myCopy = buf;
@@ -404,7 +225,7 @@
 
 	SWBuf utf8Buf;
 	while (*buf) {
-		utf8Buf.append(getUTF8FromUniChar(*buf++));
+		getUTF8FromUniChar(*buf++, &utf8Buf);
 	}
 	return utf8Buf;
 }

Modified: branches/sword-1-8-x/tests/configtest.cpp
===================================================================
--- branches/sword-1-8-x/tests/configtest.cpp	2017-11-01 11:33:56 UTC (rev 3514)
+++ branches/sword-1-8-x/tests/configtest.cpp	2017-11-01 11:38:09 UTC (rev 3515)
@@ -31,7 +31,7 @@
     config["Section1"]["Entry1"] = "Value1";
     config["Section1"]["Entry2"] = "oops";
     config["Section1"]["Entry2"] = "Value2";
-    config.Save();
+    config.save();
     SWConfig config2("./test1.conf");
     std::cout << "Should be Value2: " << config2["Section1"]["Entry2"] << std::endl;
     return 0;

Copied: branches/sword-1-8-x/tests/testsuite/README (from rev 3513, trunk/tests/testsuite/README)
===================================================================
--- branches/sword-1-8-x/tests/testsuite/README	                        (rev 0)
+++ branches/sword-1-8-x/tests/testsuite/README	2017-11-01 11:38:09 UTC (rev 3515)
@@ -0,0 +1,24 @@
+All tests are represented by a <test>.sh / <test>.good file pair.
+
+To run a test:
+
+./runtest.sh test
+
+This will run test.sh > test.try and compare test.try to test.good and report any differences (failures)
+
+To run all tests:
+
+./runall.sh
+
+===================================
+
+To create a new test, do whatever you want in your new mytest.sh file,
+call, executables, do anything you'd like and output results which
+matter for a good test.
+
+When all is running fine, output your .good file with:
+
+./mytest.sh > mytest.good
+
+That's it.  Simple right?  :)  So make more unit tests!
+

Copied: branches/sword-1-8-x/tests/testsuite/UTF-8-test.txt (from rev 3513, trunk/tests/testsuite/UTF-8-test.txt)
===================================================================
--- branches/sword-1-8-x/tests/testsuite/UTF-8-test.txt	                        (rev 0)
+++ branches/sword-1-8-x/tests/testsuite/UTF-8-test.txt	2017-11-01 11:38:09 UTC (rev 3515)
@@ -0,0 +1,300 @@
+UTF-8 decoder capability and stress test
+----------------------------------------
+
+Markus Kuhn <http://www.cl.cam.ac.uk/~mgk25/> - 2015-08-28 - CC BY 4.0
+
+This test file can help you examine, how your UTF-8 decoder handles
+various types of correct, malformed, or otherwise interesting UTF-8
+sequences. This file is not meant to be a conformance test. It does
+not prescribe any particular outcome. Therefore, there is no way to
+"pass" or "fail" this test file, even though the text does suggest a
+preferable decoder behaviour at some places. Its aim is, instead, to
+help you think about, and test, the behaviour of your UTF-8 decoder on a
+systematic collection of unusual inputs. Experience so far suggests
+that most first-time authors of UTF-8 decoders find at least one
+serious problem in their decoder using this file.
+
+The test lines below cover boundary conditions, malformed UTF-8
+sequences, as well as correctly encoded UTF-8 sequences of Unicode code
+points that should never occur in a correct UTF-8 file.
+
+According to ISO 10646-1:2000, sections D.7 and 2.3c, a device
+receiving UTF-8 shall interpret a "malformed sequence in the same way
+that it interprets a character that is outside the adopted subset" and
+"characters that are not within the adopted subset shall be indicated
+to the user" by a receiving device. One commonly used approach in
+UTF-8 decoders is to replace any malformed UTF-8 sequence by a
+replacement character (U+FFFD), which looks a bit like an inverted
+question mark, or a similar symbol. It might be a good idea to
+visually distinguish a malformed UTF-8 sequence from a correctly
+encoded Unicode character that is just not available in the current
+font but otherwise fully legal, even though ISO 10646-1 doesn't
+mandate this. In any case, just ignoring malformed sequences or
+unavailable characters does not conform to ISO 10646, will make
+debugging more difficult, and can lead to user confusion.
+
+Please check, whether a malformed UTF-8 sequence is (1) represented at
+all, (2) represented by exactly one single replacement character (or
+equivalent signal), and (3) the following quotation mark after an
+illegal UTF-8 sequence is correctly displayed, i.e. proper
+resynchronization takes place immediately after any malformed
+sequence. This file says "THE END" in the last line, so if you don't
+see that, your decoder crashed somehow before, which should always be
+cause for concern.
+
+All lines in this file are exactly 79 characters long (plus the line
+feed). In addition, all lines end with "|", except for the two test
+lines 2.1.1 and 2.2.1, which contain non-printable ASCII controls
+U+0000 and U+007F. If you display this file with a fixed-width font,
+these "|" characters should all line up in column 79 (right margin).
+This allows you to test quickly, whether your UTF-8 decoder finds the
+correct number of characters in every line, that is whether each
+malformed sequences is replaced by a single replacement character.
+
+Note that, as an alternative to the notion of malformed sequence used
+here, it is also a perfectly acceptable (and in some situations even
+preferable) solution to represent each individual byte of a malformed
+sequence with a replacement character. If you follow this strategy in
+your decoder, then please ignore the "|" column.
+
+
+Here come the tests:                                                          |
+                                                                              |
+1  Some correct UTF-8 text                                                    |
+                                                                              |
+You should see the Greek word 'kosme':       "κόσμε"                          |
+                                                                              |
+2  Boundary condition test cases                                              |
+                                                                              |
+2.1  First possible sequence of a certain length                              |
+                                                                              |
+2.1.1  1 byte  (U-00000000):        "^@" // SWORD: removed. we don't support null mid-string, <- that's a literal <caret at>
+2.1.2  2 bytes (U-00000080):        "€"                                       |
+2.1.3  3 bytes (U-00000800):        "à €"                                       |
+2.1.4  4 bytes (U-00010000):        "𐀀"                                       |
+2.1.5  5 bytes (U-00200000):        "øˆ€€€"                                       |
+2.1.6  6 bytes (U-04000000):        "ü„€€€€"                                       |
+                                                                              |
+2.2  Last possible sequence of a certain length                               |
+                                                                              |
+2.2.1  1 byte  (U-0000007F):        ""                                        
+2.2.2  2 bytes (U-000007FF):        "ß¿"                                       |
+2.2.3  3 bytes (U-0000FFFF):        "ï¿¿"                                       |
+2.2.4  4 bytes (U-001FFFFF):        "÷¿¿¿"                                       |
+2.2.5  5 bytes (U-03FFFFFF):        "û¿¿¿¿"                                       |
+2.2.6  6 bytes (U-7FFFFFFF):        "ý¿¿¿¿¿"                                       |
+                                                                              |
+2.3  Other boundary conditions                                                |
+                                                                              |
+2.3.1  U-0000D7FF = ed 9f bf = "퟿"                                            |
+2.3.2  U-0000E000 = ee 80 80 = ""                                            |
+2.3.3  U-0000FFFD = ef bf bd = "�"                                            |
+2.3.4  U-0010FFFF = f4 8f bf bf = "􏿿"                                         |
+2.3.5  U-00110000 = f4 90 80 80 = "ô€€"                                         |
+                                                                              |
+3  Malformed sequences                                                        |
+                                                                              |
+3.1  Unexpected continuation bytes                                            |
+                                                                              |
+Each unexpected continuation byte should be separately signalled as a         |
+malformed sequence of its own.                                                |
+                                                                              |
+3.1.1  First continuation byte 0x80: "€"                                      |
+3.1.2  Last  continuation byte 0xbf: "¿"                                      |
+                                                                              |
+3.1.3  2 continuation bytes: "€¿"                                             |
+3.1.4  3 continuation bytes: "€¿€"                                            |
+3.1.5  4 continuation bytes: "€¿€¿"                                           |
+3.1.6  5 continuation bytes: "€¿€¿€"                                          |
+3.1.7  6 continuation bytes: "€¿€¿€¿"                                         |
+3.1.8  7 continuation bytes: "€¿€¿€¿€"                                        |
+                                                                              |
+3.1.9  Sequence of all 64 possible continuation bytes (0x80-0xbf):            |
+                                                                              |
+   "€‚ƒ„…†‡ˆ‰Š‹ŒŽ                                                          |
+    ‘’“”•–—˜™š›œžŸ                                                          |
+     ¡¢£¤¥¦§¨©ª«¬­®¯                                                          |
+    °±²³´µ¶·¸¹º»¼½¾¿"                                                         |
+                                                                              |
+3.2  Lonely start characters                                                  |
+                                                                              |
+3.2.1  All 32 first bytes of 2-byte sequences (0xc0-0xdf),                    |
+       each followed by a space character:                                    |
+                                                                              |
+   "À Á Â Ã Ä Å Æ Ç È É Ê Ë Ì Í Î Ï                                           |
+    Ð Ñ Ò Ó Ô Õ Ö × Ø Ù Ú Û Ü Ý Þ ß "                                         |
+                                                                              |
+3.2.2  All 16 first bytes of 3-byte sequences (0xe0-0xef),                    |
+       each followed by a space character:                                    |
+                                                                              |
+   "à á â ã ä å æ ç è é ê ë ì í î ï "                                         |
+                                                                              |
+3.2.3  All 8 first bytes of 4-byte sequences (0xf0-0xf7),                     |
+       each followed by a space character:                                    |
+                                                                              |
+   "ð ñ ò ó ô õ ö ÷ "                                                         |
+                                                                              |
+3.2.4  All 4 first bytes of 5-byte sequences (0xf8-0xfb),                     |
+       each followed by a space character:                                    |
+                                                                              |
+   "ø ù ú û "                                                                 |
+                                                                              |
+3.2.5  All 2 first bytes of 6-byte sequences (0xfc-0xfd),                     |
+       each followed by a space character:                                    |
+                                                                              |
+   "ü ý "                                                                     |
+                                                                              |
+3.3  Sequences with last continuation byte missing                            |
+                                                                              |
+All bytes of an incomplete sequence should be signalled as a single           |
+malformed sequence, i.e., you should see only a single replacement            |
+character in each of the next 10 tests. (Characters as in section 2)          |
+                                                                              |
+3.3.1  2-byte sequence with last byte missing (U+0000):     "À"               |
+3.3.2  3-byte sequence with last byte missing (U+0000):     "à€"               |
+3.3.3  4-byte sequence with last byte missing (U+0000):     "ð€€"               |
+3.3.4  5-byte sequence with last byte missing (U+0000):     "ø€€€"               |
+3.3.5  6-byte sequence with last byte missing (U+0000):     "ü€€€€"               |
+3.3.6  2-byte sequence with last byte missing (U-000007FF): "ß"               |
+3.3.7  3-byte sequence with last byte missing (U-0000FFFF): "ï¿"               |
+3.3.8  4-byte sequence with last byte missing (U-001FFFFF): "÷¿¿"               |
+3.3.9  5-byte sequence with last byte missing (U-03FFFFFF): "û¿¿¿"               |
+3.3.10 6-byte sequence with last byte missing (U-7FFFFFFF): "ý¿¿¿¿"               |
+                                                                              |
+3.4  Concatenation of incomplete sequences                                    |
+                                                                              |
+All the 10 sequences of 3.3 concatenated, you should see 10 malformed         |
+sequences being signalled:                                                    |
+                                                                              |
+   "Àà€ð€€ø€€€ü€€€€ßï¿÷¿¿û¿¿¿ý¿¿¿¿"                                                               |
+                                                                              |
+3.5  Impossible bytes                                                         |
+                                                                              |
+The following two bytes cannot appear in a correct UTF-8 string               |
+                                                                              |
+3.5.1  fe = "þ"                                                               |
+3.5.2  ff = "ÿ"                                                               |
+3.5.3  fe fe ff ff = "þþÿÿ"                                                   |
+                                                                              |
+4  Overlong sequences                                                         |
+                                                                              |
+The following sequences are not malformed according to the letter of          |
+the Unicode 2.0 standard. However, they are longer then necessary and         |
+a correct UTF-8 encoder is not allowed to produce them. A "safe UTF-8         |
+decoder" should reject them just like malformed sequences for two             |
+reasons: (1) It helps to debug applications if overlong sequences are         |
+not treated as valid representations of characters, because this helps        |
+to spot problems more quickly. (2) Overlong sequences provide                 |
+alternative representations of characters, that could maliciously be          |
+used to bypass filters that check only for ASCII characters. For              |
+instance, a 2-byte encoded line feed (LF) would not be caught by a            |
+line counter that counts only 0x0a bytes, but it would still be               |
+processed as a line feed by an unsafe UTF-8 decoder later in the              |
+pipeline. From a security point of view, ASCII compatibility of UTF-8         |
+sequences means also, that ASCII characters are *only* allowed to be          |
+represented by ASCII bytes in the range 0x00-0x7f. To ensure this             |
+aspect of ASCII compatibility, use only "safe UTF-8 decoders" that            |
+reject overlong UTF-8 sequences for which a shorter encoding exists.          |
+                                                                              |
+4.1  Examples of an overlong ASCII character                                  |
+                                                                              |
+With a safe UTF-8 decoder, all of the following five overlong                 |
+representations of the ASCII character slash ("/") should be rejected         |
+like a malformed UTF-8 sequence, for instance by substituting it with         |
+a replacement character. If you see a slash below, you do not have a          |
+safe UTF-8 decoder!                                                           |
+                                                                              |
+4.1.1 U+002F = c0 af             = "À¯"                                        |
+4.1.2 U+002F = e0 80 af          = "à€¯"                                        |
+4.1.3 U+002F = f0 80 80 af       = "ð€€¯"                                        |
+4.1.4 U+002F = f8 80 80 80 af    = "ø€€€¯"                                        |
+4.1.5 U+002F = fc 80 80 80 80 af = "ü€€€€¯"                                        |
+                                                                              |
+4.2  Maximum overlong sequences                                               |
+                                                                              |
+Below you see the highest Unicode value that is still resulting in an         |
+overlong sequence if represented with the given number of bytes. This         |
+is a boundary test for safe UTF-8 decoders. All five characters should        |
+be rejected like malformed UTF-8 sequences.                                   |
+                                                                              |
+4.2.1  U-0000007F = c1 bf             = "Á¿"                                   |
+4.2.2  U-000007FF = e0 9f bf          = "àŸ¿"                                   |
+4.2.3  U-0000FFFF = f0 8f bf bf       = "ð¿¿"                                   |
+4.2.4  U-001FFFFF = f8 87 bf bf bf    = "ø‡¿¿¿"                                   |
+4.2.5  U-03FFFFFF = fc 83 bf bf bf bf = "üƒ¿¿¿¿"                                   |
+                                                                              |
+4.3  Overlong representation of the NUL character                             |
+                                                                              |
+The following five sequences should also be rejected like malformed           |
+UTF-8 sequences and should not be treated like the ASCII NUL                  |
+character.                                                                    |
+                                                                              |
+4.3.1  U+0000 = c0 80             = "À€"                                       |
+4.3.2  U+0000 = e0 80 80          = "à€€"                                       |
+4.3.3  U+0000 = f0 80 80 80       = "ð€€€"                                       |
+4.3.4  U+0000 = f8 80 80 80 80    = "ø€€€€"                                       |
+4.3.5  U+0000 = fc 80 80 80 80 80 = "ü€€€€€"                                       |
+                                                                              |
+5  Illegal code positions                                                     |
+                                                                              |
+The following UTF-8 sequences should be rejected like malformed               |
+sequences, because they never represent valid ISO 10646 characters and        |
+a UTF-8 decoder that accepts them might introduce security problems           |
+comparable to overlong UTF-8 sequences.                                       |
+                                                                              |
+5.1 Single UTF-16 surrogates                                                  |
+                                                                              |
+5.1.1  U+D800 = ed a0 80 = "í €"                                                |
+5.1.2  U+DB7F = ed ad bf = "í­¿"                                                |
+5.1.3  U+DB80 = ed ae 80 = "í®€"                                                |
+5.1.4  U+DBFF = ed af bf = "í¯¿"                                                |
+5.1.5  U+DC00 = ed b0 80 = "í°€"                                                |
+5.1.6  U+DF80 = ed be 80 = "í¾€"                                                |
+5.1.7  U+DFFF = ed bf bf = "í¿¿"                                                |
+                                                                              |
+5.2 Paired UTF-16 surrogates                                                  |
+                                                                              |
+5.2.1  U+D800 U+DC00 = ed a0 80 ed b0 80 = "𐀀"                               |
+5.2.2  U+D800 U+DFFF = ed a0 80 ed bf bf = "𐏿"                               |
+5.2.3  U+DB7F U+DC00 = ed ad bf ed b0 80 = "í­¿í°€"                               |
+5.2.4  U+DB7F U+DFFF = ed ad bf ed bf bf = "í­¿í¿¿"                               |
+5.2.5  U+DB80 U+DC00 = ed ae 80 ed b0 80 = "󰀀"                               |
+5.2.6  U+DB80 U+DFFF = ed ae 80 ed bf bf = "󰏿"                               |
+5.2.7  U+DBFF U+DC00 = ed af bf ed b0 80 = "􏰀"                               |
+5.2.8  U+DBFF U+DFFF = ed af bf ed bf bf = "􏿿"                               |
+                                                                              |
+5.3 Noncharacter code positions                                               |
+                                                                              |
+The following "noncharacters" are "reserved for internal use" by              |
+applications, and according to older versions of the Unicode Standard         |
+"should never be interchanged". Unicode Corrigendum #9 dropped the            |
+latter restriction. Nevertheless, their presence in incoming UTF-8 data       |
+can remain a potential security risk, depending on what use is made of        |
+these codes subsequently. Examples of such internal use:                      |
+                                                                              |
+ - Some file APIs with 16-bit characters may use the integer value -1         |
+   = U+FFFF to signal an end-of-file (EOF) or error condition.                |
+                                                                              |
+ - In some UTF-16 receivers, code point U+FFFE might trigger a                |
+   byte-swap operation (to convert between UTF-16LE and UTF-16BE).            |
+                                                                              |
+With such internal use of noncharacters, it may be desirable and safer        |
+to block those code points in UTF-8 decoders, as they should never            |
+occur legitimately in incoming UTF-8 data, and could trigger unsafe           |
+behaviour in subsequent processing.                                           |
+                                                                              |
+Particularly problematic noncharacters in 16-bit applications:                |
+                                                                              |
+5.3.1  U+FFFE = ef bf be = "￾"                                                |
+5.3.2  U+FFFF = ef bf bf = "ï¿¿"                                                |
+                                                                              |
+Other noncharacters:                                                          |
+                                                                              |
+5.3.3  U+FDD0 .. U+FDEF = "﷐﷑﷒﷓﷔﷕﷖﷗﷘﷙﷚﷛﷜﷝﷞﷟﷠﷡﷢﷣﷤﷥﷦﷧﷨﷩﷪﷫﷬﷭﷮﷯"|
+                                                                              |
+5.3.4  U+nFFFE U+nFFFF (for n = 1..10)                                        |
+                                                                              |
+       "🿾🿿𯿾𯿿𿿾𿿿񏿾񏿿񟿾񟿿񯿾񯿿񿿾񿿿򏿾򏿿                                    |
+        򟿾򟿿򯿾򯿿򿿾򿿿󏿾󏿿󟿾󟿿󯿾󯿿󿿾󿿿􏿾􏿿"                                   |
+                                                                              |
+THE END                                                                       |

Copied: branches/sword-1-8-x/tests/testsuite/gbsReference.imp (from rev 3513, trunk/tests/testsuite/gbsReference.imp)
===================================================================
--- branches/sword-1-8-x/tests/testsuite/gbsReference.imp	                        (rev 0)
+++ branches/sword-1-8-x/tests/testsuite/gbsReference.imp	2017-11-01 11:38:09 UTC (rev 3515)
@@ -0,0 +1,42 @@
+$$$Chapter 1
+Text of chapter 1.
+$$$/Chapter 2
+Text
+of chapter 2.
+$$$/Chapter 3/
+Text
+of
+chapter
+3.
+$$$Chapter 4/
+Text of chapter 4.
+$$$/Chapter 4/Section 1
+Text of section 1 in chapter 4.
+$$$Chapter 5
+Text of chapter 5.
+$$$/Chapter 5/Section 1/
+Text of section 1 in chapter 5.
+$$$Chapter 5/Section 2/
+Text of section 2 in chapter 5.
+$$$Chapter 6
+Text of chapter 6.
+$$$Chapter 6/Section 1
+Text of section 1 in chapter 6.
+$$$Chapter 6/Section 2
+Text of section 2 in chapter 6.
+$$$Chapter 6/Section 3
+Text of section 3 in chapter 6.
+$$$Chapter 7
+Text of chapter 7.
+$$$Chapter 7/Section 1
+Text of section 1 in chapter 7.
+$$$Chapter 7/Section 1/Subsection 1
+Text of subsection 1 in section 1 of chapter 7.
+$$$Chapter 7/Section 1/Subsection 1/Paragraph 1
+Text of paragraph 1 in subsection 1 of section 1 in chapter 7.
+$$$Chapter 7/Section 1/Subsection 1/Paragraph 1/Sentence 1
+Text of sentence 1 in paragraph 1 of subsection 1 in section 1 of chapter 7.
+$$$Chapter 8
+Text of chapter 8.
+
+

Copied: branches/sword-1-8-x/tests/testsuite/gbs_basic.good (from rev 3513, trunk/tests/testsuite/gbs_basic.good)
===================================================================
--- branches/sword-1-8-x/tests/testsuite/gbs_basic.good	                        (rev 0)
+++ branches/sword-1-8-x/tests/testsuite/gbs_basic.good	2017-11-01 11:38:09 UTC (rev 3515)
@@ -0,0 +1,66 @@
+Chapter 1
+/Chapter 2
+/Chapter 3/
+Chapter 4/
+/Chapter 4/Section 1
+Chapter 5
+/Chapter 5/Section 1/
+Chapter 5/Section 2/
+Chapter 6
+Chapter 6/Section 1
+Chapter 6/Section 2
+Chapter 6/Section 3
+Chapter 7
+Chapter 7/Section 1
+Chapter 7/Section 1/Subsection 1
+Chapter 7/Section 1/Subsection 1/Paragraph 1
+Chapter 7/Section 1/Subsection 1/Paragraph 1/Sentence 1
+Chapter 8
+
+-- Plain output
+/Chapter 7: Text of chapter 7.
+
+-- RTF output
+{\rtf1\ansi{\fonttbl{\f0\froman\fcharset0\fprq2 Times New Roman;}{\f1\fdecor\fprq2 Gentium;}{\f7\froman\fcharset2\fprq2 Symbol;}}/Chapter 8: {\f1 Text of chapter 8.}\par 
+}
+
+-- imp dump
+$$$
+
+$$$/Chapter 1
+Text of chapter 1.
+$$$/Chapter 2
+Text of chapter 2.
+$$$/Chapter 3
+Text of chapter 3.
+$$$/Chapter 4
+Text of chapter 4.
+$$$/Chapter 4/Section 1
+Text of section 1 in chapter 4.
+$$$/Chapter 5
+Text of chapter 5.
+$$$/Chapter 5/Section 1
+Text of section 1 in chapter 5.
+$$$/Chapter 5/Section 2
+Text of section 2 in chapter 5.
+$$$/Chapter 6
+Text of chapter 6.
+$$$/Chapter 6/Section 1
+Text of section 1 in chapter 6.
+$$$/Chapter 6/Section 2
+Text of section 2 in chapter 6.
+$$$/Chapter 6/Section 3
+Text of section 3 in chapter 6.
+$$$/Chapter 7
+Text of chapter 7.
+$$$/Chapter 7/Section 1
+Text of section 1 in chapter 7.
+$$$/Chapter 7/Section 1/Subsection 1
+Text of subsection 1 in section 1 of chapter 7.
+$$$/Chapter 7/Section 1/Subsection 1/Paragraph 1
+Text of paragraph 1 in subsection 1 of section 1 in chapter 7.
+$$$/Chapter 7/Section 1/Subsection 1/Paragraph 1/Sentence 1
+Text of sentence 1 in paragraph 1 of subsection 1 in section 1 of chapter 7.
+$$$/Chapter 8
+Text of chapter 8.
+

Copied: branches/sword-1-8-x/tests/testsuite/gbs_basic.sh (from rev 3513, trunk/tests/testsuite/gbs_basic.sh)
===================================================================
--- branches/sword-1-8-x/tests/testsuite/gbs_basic.sh	                        (rev 0)
+++ branches/sword-1-8-x/tests/testsuite/gbs_basic.sh	2017-11-01 11:38:09 UTC (rev 3515)
@@ -0,0 +1,30 @@
+#!/bin/sh
+
+rm -rf tmp/gbs_basic/
+mkdir -p tmp/gbs_basic/mods.d
+mkdir -p tmp/gbs_basic/modules
+
+cat > tmp/gbs_basic/mods.d/gbsreference.conf <<!
+[GBSReference]
+DataPath=./modules/gbsreference
+ModDrv=RawGenBook
+Encoding=UTF-8
+SourceType=OSIS
+Lang=en
+Feature=StrongsNumbers
+!
+
+../../utilities/imp2gbs gbsReference.imp -o tmp/gbs_basic/modules/gbsreference 2>&1 | grep -v \$Rev
+
+cd tmp/gbs_basic
+#../../../gbstest GBSReference
+
+echo
+echo "-- Plain output"
+../../../../utilities/diatheke/diatheke -b GBSReference -f plain -k "Chapter 7" | grep -v GBSReference
+echo
+echo "-- RTF output"
+../../../../utilities/diatheke/diatheke -b GBSReference -f RTF -k "Chapter 8" | grep -v GBSReference
+echo
+echo "-- imp dump"
+../../../../utilities/mod2imp GBSReference

Copied: branches/sword-1-8-x/tests/testsuite/greekaccents.good (from rev 3513, trunk/tests/testsuite/greekaccents.good)
===================================================================
--- branches/sword-1-8-x/tests/testsuite/greekaccents.good	                        (rev 0)
+++ branches/sword-1-8-x/tests/testsuite/greekaccents.good	2017-11-01 11:38:09 UTC (rev 3515)
@@ -0,0 +1,7 @@
+Και καθως Μωυσης υψωσεν τον οφιν εν τη ερημω, ουτως υψωθηναι δει τον υιον του ανθρωπου,
+ινα πας ο πιστευων ⸂εν αυτω⸃ ⸆ εχη ζωην αιωνιον.
+ουτως γαρ ηγαπησεν ο θεος τον κοσμον, ωστε τον υιον ⸆ τον μονογενη εδωκεν, ινα πας ο πιστευων εις αυτον μη αποληται αλλ εχη ζωην αιωνιον.
+ου γαρ απεστειλεν ο θεος τον υιον ⸆ εις τον κοσμον ινα κρινη τον κοσμον, αλλ ινα σωθη ο κοσμος δι αυτου.
+ο πιστευων εις αυτον ου κρινεται· ο °δε μη πιστευων ηδη κεκριται, οτι μη πεπιστευκεν εις το ονομα του μονογενους υιου του θεου.
+αυτη δε εστιν η κρισις οτι °το φως εληλυθεν εις τον κοσμον και ⸉ηγαπησαν οι ανθρωποι μαλλον το σκοτος⸊ η το φως· ην γαρ ⸉¹αυτων πονηρα⸊ τα εργα.
+

Copied: branches/sword-1-8-x/tests/testsuite/greekaccents.sh (from rev 3513, trunk/tests/testsuite/greekaccents.sh)
===================================================================
--- branches/sword-1-8-x/tests/testsuite/greekaccents.sh	                        (rev 0)
+++ branches/sword-1-8-x/tests/testsuite/greekaccents.sh	2017-11-01 11:38:09 UTC (rev 3515)
@@ -0,0 +1,8 @@
+#/bin/sh
+
+# there is an iteration value as the last parameter and can be used
+# for testing speed. Set to 999999 my results on my Dell Precision 5510
+# real	0m8.952s
+# user	0m8.939s
+# sys	0m0.004s
+../utf8norm -ga 999 < greekaccents.txt

Copied: branches/sword-1-8-x/tests/testsuite/greekaccents.txt (from rev 3513, trunk/tests/testsuite/greekaccents.txt)
===================================================================
--- branches/sword-1-8-x/tests/testsuite/greekaccents.txt	                        (rev 0)
+++ branches/sword-1-8-x/tests/testsuite/greekaccents.txt	2017-11-01 11:38:09 UTC (rev 3515)
@@ -0,0 +1,7 @@
+Καὶ καθὼς Μωϋσῆς ὕψωσεν τὸν ὄφιν ἐν τῇ ἐρήμῳ, οὕτως ὑψωθῆναι δεῖ τὸν υἱὸν τοῦ ἀνθρώπου,
+ἵνα πᾶς ὁ πιστεύων ⸂ἐν αὐτῷ⸃ ⸆ ἔχῃ ζωὴν αἰώνιον.
+οὕτως γὰρ ἠγάπησεν ὁ θεὸς τὸν κόσμον, ὥστε τὸν υἱὸν ⸆ τὸν μονογενῆ ἔδωκεν, ἵνα πᾶς ὁ πιστεύων εἰς αὐτὸν μὴ ἀπόληται ἀλλ᾿ ἔχῃ ζωὴν αἰώνιον.
+οὐ γὰρ ἀπέστειλεν ὁ θεὸς τὸν υἱὸν ⸆ εἰς τὸν κόσμον ἵνα κρίνῃ τὸν κόσμον, ἀλλ᾿ ἵνα σωθῇ ὁ κόσμος δι᾿ αὐτοῦ.
+ὁ πιστεύων εἰς αὐτὸν οὐ κρίνεται· ὁ °δὲ μὴ πιστεύων ἤδη κέκριται, ὅτι μὴ πεπίστευκεν εἰς τὸ ὄνομα τοῦ μονογενοῦς υἱοῦ τοῦ θεοῦ.
+αὕτη δέ ἐστιν ἡ κρίσις ὅτι °τὸ φῶς ἐλήλυθεν εἰς τὸν κόσμον καὶ ⸉ἠγάπησαν οἱ ἄνθρωποι μᾶλλον τὸ σκότος⸊ ἢ τὸ φῶς· ἦν γὰρ ⸉¹αὐτῶν πονηρὰ⸊ τὰ ἔργα.
+

Copied: branches/sword-1-8-x/tests/testsuite/utf8basic.good (from rev 3513, trunk/tests/testsuite/utf8basic.good)
===================================================================
--- branches/sword-1-8-x/tests/testsuite/utf8basic.good	                        (rev 0)
+++ branches/sword-1-8-x/tests/testsuite/utf8basic.good	2017-11-01 11:38:09 UTC (rev 3515)
@@ -0,0 +1,300 @@
+UTF-8 decoder capability and stress test
+----------------------------------------
+
+Markus Kuhn <http://www.cl.cam.ac.uk/~mgk25/> - 2015-08-28 - CC BY 4.0
+
+This test file can help you examine, how your UTF-8 decoder handles
+various types of correct, malformed, or otherwise interesting UTF-8
+sequences. This file is not meant to be a conformance test. It does
+not prescribe any particular outcome. Therefore, there is no way to
+"pass" or "fail" this test file, even though the text does suggest a
+preferable decoder behaviour at some places. Its aim is, instead, to
+help you think about, and test, the behaviour of your UTF-8 decoder on a
+systematic collection of unusual inputs. Experience so far suggests
+that most first-time authors of UTF-8 decoders find at least one
+serious problem in their decoder using this file.
+
+The test lines below cover boundary conditions, malformed UTF-8
+sequences, as well as correctly encoded UTF-8 sequences of Unicode code
+points that should never occur in a correct UTF-8 file.
+
+According to ISO 10646-1:2000, sections D.7 and 2.3c, a device
+receiving UTF-8 shall interpret a "malformed sequence in the same way
+that it interprets a character that is outside the adopted subset" and
+"characters that are not within the adopted subset shall be indicated
+to the user" by a receiving device. One commonly used approach in
+UTF-8 decoders is to replace any malformed UTF-8 sequence by a
+replacement character (U+FFFD), which looks a bit like an inverted
+question mark, or a similar symbol. It might be a good idea to
+visually distinguish a malformed UTF-8 sequence from a correctly
+encoded Unicode character that is just not available in the current
+font but otherwise fully legal, even though ISO 10646-1 doesn't
+mandate this. In any case, just ignoring malformed sequences or
+unavailable characters does not conform to ISO 10646, will make
+debugging more difficult, and can lead to user confusion.
+
+Please check, whether a malformed UTF-8 sequence is (1) represented at
+all, (2) represented by exactly one single replacement character (or
+equivalent signal), and (3) the following quotation mark after an
+illegal UTF-8 sequence is correctly displayed, i.e. proper
+resynchronization takes place immediately after any malformed
+sequence. This file says "THE END" in the last line, so if you don't
+see that, your decoder crashed somehow before, which should always be
+cause for concern.
+
+All lines in this file are exactly 79 characters long (plus the line
+feed). In addition, all lines end with "|", except for the two test
+lines 2.1.1 and 2.2.1, which contain non-printable ASCII controls
+U+0000 and U+007F. If you display this file with a fixed-width font,
+these "|" characters should all line up in column 79 (right margin).
+This allows you to test quickly, whether your UTF-8 decoder finds the
+correct number of characters in every line, that is whether each
+malformed sequences is replaced by a single replacement character.
+
+Note that, as an alternative to the notion of malformed sequence used
+here, it is also a perfectly acceptable (and in some situations even
+preferable) solution to represent each individual byte of a malformed
+sequence with a replacement character. If you follow this strategy in
+your decoder, then please ignore the "|" column.
+
+
+Here come the tests:                                                          |
+                                                                              |
+1  Some correct UTF-8 text                                                    |
+                                                                              |
+You should see the Greek word 'kosme':       "κόσμε"                          |
+                                                                              |
+2  Boundary condition test cases                                              |
+                                                                              |
+2.1  First possible sequence of a certain length                              |
+                                                                              |
+2.1.1  1 byte  (U-00000000):        "^@" // SWORD: removed. we don't support null mid-string, <- that's a literal <caret at>
+2.1.2  2 bytes (U-00000080):        "€"                                       |
+2.1.3  3 bytes (U-00000800):        "à €"                                       |
+2.1.4  4 bytes (U-00010000):        "𐀀"                                       |
+2.1.5  5 bytes (U-00200000):        "�"                                       |
+2.1.6  6 bytes (U-04000000):        "�"                                       |
+                                                                              |
+2.2  Last possible sequence of a certain length                               |
+                                                                              |
+2.2.1  1 byte  (U-0000007F):        ""                                        
+2.2.2  2 bytes (U-000007FF):        "ß¿"                                       |
+2.2.3  3 bytes (U-0000FFFF):        "ï¿¿"                                       |
+2.2.4  4 bytes (U-001FFFFF):        "�"                                       |
+2.2.5  5 bytes (U-03FFFFFF):        "�"                                       |
+2.2.6  6 bytes (U-7FFFFFFF):        "�"                                       |
+                                                                              |
+2.3  Other boundary conditions                                                |
+                                                                              |
+2.3.1  U-0000D7FF = ed 9f bf = "퟿"                                            |
+2.3.2  U-0000E000 = ee 80 80 = ""                                            |
+2.3.3  U-0000FFFD = ef bf bd = "�"                                            |
+2.3.4  U-0010FFFF = f4 8f bf bf = "􏿿"                                         |
+2.3.5  U-00110000 = f4 90 80 80 = "�"                                         |
+                                                                              |
+3  Malformed sequences                                                        |
+                                                                              |
+3.1  Unexpected continuation bytes                                            |
+                                                                              |
+Each unexpected continuation byte should be separately signalled as a         |
+malformed sequence of its own.                                                |
+                                                                              |
+3.1.1  First continuation byte 0x80: "�"                                      |
+3.1.2  Last  continuation byte 0xbf: "�"                                      |
+                                                                              |
+3.1.3  2 continuation bytes: "��"                                             |
+3.1.4  3 continuation bytes: "���"                                            |
+3.1.5  4 continuation bytes: "����"                                           |
+3.1.6  5 continuation bytes: "�����"                                          |
+3.1.7  6 continuation bytes: "������"                                         |
+3.1.8  7 continuation bytes: "�������"                                        |
+                                                                              |
+3.1.9  Sequence of all 64 possible continuation bytes (0x80-0xbf):            |
+                                                                              |
+   "����������������                                                          |
+    ����������������                                                          |
+    ����������������                                                          |
+    ����������������"                                                         |
+                                                                              |
+3.2  Lonely start characters                                                  |
+                                                                              |
+3.2.1  All 32 first bytes of 2-byte sequences (0xc0-0xdf),                    |
+       each followed by a space character:                                    |
+                                                                              |
+   "� � � � � � � � � � � � � � � �                                           |
+    � � � � � � � � � � � � � � � � "                                         |
+                                                                              |
+3.2.2  All 16 first bytes of 3-byte sequences (0xe0-0xef),                    |
+       each followed by a space character:                                    |
+                                                                              |
+   "� � � � � � � � � � � � � � � � "                                         |
+                                                                              |
+3.2.3  All 8 first bytes of 4-byte sequences (0xf0-0xf7),                     |
+       each followed by a space character:                                    |
+                                                                              |
+   "� � � � � � � � "                                                         |
+                                                                              |
+3.2.4  All 4 first bytes of 5-byte sequences (0xf8-0xfb),                     |
+       each followed by a space character:                                    |
+                                                                              |
+   "� � � � "                                                                 |
+                                                                              |
+3.2.5  All 2 first bytes of 6-byte sequences (0xfc-0xfd),                     |
+       each followed by a space character:                                    |
+                                                                              |
+   "� � "                                                                     |
+                                                                              |
+3.3  Sequences with last continuation byte missing                            |
+                                                                              |
+All bytes of an incomplete sequence should be signalled as a single           |
+malformed sequence, i.e., you should see only a single replacement            |
+character in each of the next 10 tests. (Characters as in section 2)          |
+                                                                              |
+3.3.1  2-byte sequence with last byte missing (U+0000):     "�"               |
+3.3.2  3-byte sequence with last byte missing (U+0000):     "�"               |
+3.3.3  4-byte sequence with last byte missing (U+0000):     "�"               |
+3.3.4  5-byte sequence with last byte missing (U+0000):     "�"               |
+3.3.5  6-byte sequence with last byte missing (U+0000):     "�"               |
+3.3.6  2-byte sequence with last byte missing (U-000007FF): "�"               |
+3.3.7  3-byte sequence with last byte missing (U-0000FFFF): "�"               |
+3.3.8  4-byte sequence with last byte missing (U-001FFFFF): "�"               |
+3.3.9  5-byte sequence with last byte missing (U-03FFFFFF): "�"               |
+3.3.10 6-byte sequence with last byte missing (U-7FFFFFFF): "�"               |
+                                                                              |
+3.4  Concatenation of incomplete sequences                                    |
+                                                                              |
+All the 10 sequences of 3.3 concatenated, you should see 10 malformed         |
+sequences being signalled:                                                    |
+                                                                              |
+   "����������"                                                               |
+                                                                              |
+3.5  Impossible bytes                                                         |
+                                                                              |
+The following two bytes cannot appear in a correct UTF-8 string               |
+                                                                              |
+3.5.1  fe = "�"                                                               |
+3.5.2  ff = "�"                                                               |
+3.5.3  fe fe ff ff = "����"                                                   |
+                                                                              |
+4  Overlong sequences                                                         |
+                                                                              |
+The following sequences are not malformed according to the letter of          |
+the Unicode 2.0 standard. However, they are longer then necessary and         |
+a correct UTF-8 encoder is not allowed to produce them. A "safe UTF-8         |
+decoder" should reject them just like malformed sequences for two             |
+reasons: (1) It helps to debug applications if overlong sequences are         |
+not treated as valid representations of characters, because this helps        |
+to spot problems more quickly. (2) Overlong sequences provide                 |
+alternative representations of characters, that could maliciously be          |
+used to bypass filters that check only for ASCII characters. For              |
+instance, a 2-byte encoded line feed (LF) would not be caught by a            |
+line counter that counts only 0x0a bytes, but it would still be               |
+processed as a line feed by an unsafe UTF-8 decoder later in the              |
+pipeline. From a security point of view, ASCII compatibility of UTF-8         |
+sequences means also, that ASCII characters are *only* allowed to be          |
+represented by ASCII bytes in the range 0x00-0x7f. To ensure this             |
+aspect of ASCII compatibility, use only "safe UTF-8 decoders" that            |
+reject overlong UTF-8 sequences for which a shorter encoding exists.          |
+                                                                              |
+4.1  Examples of an overlong ASCII character                                  |
+                                                                              |
+With a safe UTF-8 decoder, all of the following five overlong                 |
+representations of the ASCII character slash ("/") should be rejected         |
+like a malformed UTF-8 sequence, for instance by substituting it with         |
+a replacement character. If you see a slash below, you do not have a          |
+safe UTF-8 decoder!                                                           |
+                                                                              |
+4.1.1 U+002F = c0 af             = "�"                                        |
+4.1.2 U+002F = e0 80 af          = "�"                                        |
+4.1.3 U+002F = f0 80 80 af       = "�"                                        |
+4.1.4 U+002F = f8 80 80 80 af    = "�"                                        |
+4.1.5 U+002F = fc 80 80 80 80 af = "�"                                        |
+                                                                              |
+4.2  Maximum overlong sequences                                               |
+                                                                              |
+Below you see the highest Unicode value that is still resulting in an         |
+overlong sequence if represented with the given number of bytes. This         |
+is a boundary test for safe UTF-8 decoders. All five characters should        |
+be rejected like malformed UTF-8 sequences.                                   |
+                                                                              |
+4.2.1  U-0000007F = c1 bf             = "�"                                   |
+4.2.2  U-000007FF = e0 9f bf          = "�"                                   |
+4.2.3  U-0000FFFF = f0 8f bf bf       = "�"                                   |
+4.2.4  U-001FFFFF = f8 87 bf bf bf    = "�"                                   |
+4.2.5  U-03FFFFFF = fc 83 bf bf bf bf = "�"                                   |
+                                                                              |
+4.3  Overlong representation of the NUL character                             |
+                                                                              |
+The following five sequences should also be rejected like malformed           |
+UTF-8 sequences and should not be treated like the ASCII NUL                  |
+character.                                                                    |
+                                                                              |
+4.3.1  U+0000 = c0 80             = "�"                                       |
+4.3.2  U+0000 = e0 80 80          = "�"                                       |
+4.3.3  U+0000 = f0 80 80 80       = "�"                                       |
+4.3.4  U+0000 = f8 80 80 80 80    = "�"                                       |
+4.3.5  U+0000 = fc 80 80 80 80 80 = "�"                                       |
+                                                                              |
+5  Illegal code positions                                                     |
+                                                                              |
+The following UTF-8 sequences should be rejected like malformed               |
+sequences, because they never represent valid ISO 10646 characters and        |
+a UTF-8 decoder that accepts them might introduce security problems           |
+comparable to overlong UTF-8 sequences.                                       |
+                                                                              |
+5.1 Single UTF-16 surrogates                                                  |
+                                                                              |
+5.1.1  U+D800 = ed a0 80 = "í €"                                                |
+5.1.2  U+DB7F = ed ad bf = "í­¿"                                                |
+5.1.3  U+DB80 = ed ae 80 = "í®€"                                                |
+5.1.4  U+DBFF = ed af bf = "í¯¿"                                                |
+5.1.5  U+DC00 = ed b0 80 = "í°€"                                                |
+5.1.6  U+DF80 = ed be 80 = "í¾€"                                                |
+5.1.7  U+DFFF = ed bf bf = "í¿¿"                                                |
+                                                                              |
+5.2 Paired UTF-16 surrogates                                                  |
+                                                                              |
+5.2.1  U+D800 U+DC00 = ed a0 80 ed b0 80 = "𐀀"                               |
+5.2.2  U+D800 U+DFFF = ed a0 80 ed bf bf = "𐏿"                               |
+5.2.3  U+DB7F U+DC00 = ed ad bf ed b0 80 = "í­¿í°€"                               |
+5.2.4  U+DB7F U+DFFF = ed ad bf ed bf bf = "í­¿í¿¿"                               |
+5.2.5  U+DB80 U+DC00 = ed ae 80 ed b0 80 = "󰀀"                               |
+5.2.6  U+DB80 U+DFFF = ed ae 80 ed bf bf = "󰏿"                               |
+5.2.7  U+DBFF U+DC00 = ed af bf ed b0 80 = "􏰀"                               |
+5.2.8  U+DBFF U+DFFF = ed af bf ed bf bf = "􏿿"                               |
+                                                                              |
+5.3 Noncharacter code positions                                               |
+                                                                              |
+The following "noncharacters" are "reserved for internal use" by              |
+applications, and according to older versions of the Unicode Standard         |
+"should never be interchanged". Unicode Corrigendum #9 dropped the            |
+latter restriction. Nevertheless, their presence in incoming UTF-8 data       |
+can remain a potential security risk, depending on what use is made of        |
+these codes subsequently. Examples of such internal use:                      |
+                                                                              |
+ - Some file APIs with 16-bit characters may use the integer value -1         |
+   = U+FFFF to signal an end-of-file (EOF) or error condition.                |
+                                                                              |
+ - In some UTF-16 receivers, code point U+FFFE might trigger a                |
+   byte-swap operation (to convert between UTF-16LE and UTF-16BE).            |
+                                                                              |
+With such internal use of noncharacters, it may be desirable and safer        |
+to block those code points in UTF-8 decoders, as they should never            |
+occur legitimately in incoming UTF-8 data, and could trigger unsafe           |
+behaviour in subsequent processing.                                           |
+                                                                              |
+Particularly problematic noncharacters in 16-bit applications:                |
+                                                                              |
+5.3.1  U+FFFE = ef bf be = "￾"                                                |
+5.3.2  U+FFFF = ef bf bf = "ï¿¿"                                                |
+                                                                              |
+Other noncharacters:                                                          |
+                                                                              |
+5.3.3  U+FDD0 .. U+FDEF = "﷐﷑﷒﷓﷔﷕﷖﷗﷘﷙﷚﷛﷜﷝﷞﷟﷠﷡﷢﷣﷤﷥﷦﷧﷨﷩﷪﷫﷬﷭﷮﷯"|
+                                                                              |
+5.3.4  U+nFFFE U+nFFFF (for n = 1..10)                                        |
+                                                                              |
+       "🿾🿿𯿾𯿿𿿾𿿿񏿾񏿿񟿾񟿿񯿾񯿿񿿾񿿿򏿾򏿿                                    |
+        򟿾򟿿򯿾򯿿򿿾򿿿󏿾󏿿󟿾󟿿󯿾󯿿󿿾󿿿􏿾􏿿"                                   |
+                                                                              |
+THE END                                                                       |

Copied: branches/sword-1-8-x/tests/testsuite/utf8basic.sh (from rev 3513, trunk/tests/testsuite/utf8basic.sh)
===================================================================
--- branches/sword-1-8-x/tests/testsuite/utf8basic.sh	                        (rev 0)
+++ branches/sword-1-8-x/tests/testsuite/utf8basic.sh	2017-11-01 11:38:09 UTC (rev 3515)
@@ -0,0 +1,10 @@
+#/bin/sh
+
+# utf8basic.good originally generated with:
+# uconv --from-code UTF-8 --to-code UTF-8 --from-callback substitute UTF-8-test.txt > utf8basic.good
+# but modified to ignore UTF-16 surrogates which are apparently illegal.  We return multiple replacement
+# characters there, but the spec apparently says we are only supposed to return 1 per UTF-16 surrogate
+# there are comments in the spec about "security vulnerability" but we always check if we're at the
+# end of our buffer before continuing processing each byte (shouldn't all decoders do this?), so there
+# shouldn't be a problem.  Ignoring the UTF-16 non-conformance for now.
+../utf8norm < UTF-8-test.txt

Modified: branches/sword-1-8-x/tests/utf8norm.cpp
===================================================================
--- branches/sword-1-8-x/tests/utf8norm.cpp	2017-11-01 11:33:56 UTC (rev 3514)
+++ branches/sword-1-8-x/tests/utf8norm.cpp	2017-11-01 11:38:09 UTC (rev 3515)
@@ -23,16 +23,62 @@
 #include <iostream>
 #include <utilstr.h>
 #include <swbuf.h>
+#if !defined(__GNUC__) && !defined(_WIN32_WCE)
+#include <io.h>
+#include <direct.h>
+#else
+#include <unistd.h>
+#endif
+#include <utf8greekaccents.h>
 
 using namespace sword;
 using namespace std;
 
 int main(int argc, char **argv) {
-	const char *buf = (argc > 1) ? argv[1] : "Description=German Unrevidierte Luther Ãœbersetzung von 1545";
+	const char *buf = (argc > 1 && argv[1][0] != '-') ? argv[1] : 0; // "Description=German Unrevidierte Luther Ãœbersetzung von 1545";
 
-	SWBuf fixed = assureValidUTF8(buf);
+	if (buf) {
+		SWBuf fixed = assureValidUTF8(buf);
 
-	cout << "input / processed:\n" << buf << "\n" << fixed << endl;
+		cout << "input / processed:\n" << buf << "\n" << fixed << endl;
+	}
+	else {
+		SWOptionFilter *filter = 0;
+		if (argc > 1 && !strcmp(argv[1], "-ga")) filter = new UTF8GreekAccents();
+		if (filter && filter->isBoolean()) filter->setOptionValue("Off");
+		int repeat = 1;
+		if (argc > 2) repeat = atoi(argv[2]);
+		SWBuf contents = "";
+		char chunk[255];
+		int count = 254;
+		while (count > 0) {
+			count = read(STDIN_FILENO, chunk, 254);
+			if (count > 0) {
+				chunk[count] = 0;
+				contents.append(chunk);
+			}
+		}
+		SWBuf filteredContents = contents;
+		if (filter) {
+			for (int i = 0; i < repeat; ++i) {
+				filteredContents = contents;
+				filter->processText(filteredContents);
+			}
+		}
+		const unsigned char *c = (const unsigned char *)filteredContents.getRawData();
+		// UTF-32 BOM
+		__u32 ch = 0xfeff;
+//		write(STDOUT_FILENO, &ch, 4);
+		while (c && *c) {
+			ch = getUniCharFromUTF8(&c);
+//			ch = __swswap32(ch);
+			if (!ch) ch = 0xFFFD;
+			SWBuf c8;
+		        getUTF8FromUniChar(ch, &c8);
+			write(STDOUT_FILENO, c8.getRawData(), c8.length());
+		}
+		delete filter;
+	}
 
 	return 0;
 }

Modified: branches/sword-1-8-x/utilities/diatheke/diathekemgr.cpp
===================================================================
--- branches/sword-1-8-x/utilities/diatheke/diathekemgr.cpp	2017-11-01 11:33:56 UTC (rev 3514)
+++ branches/sword-1-8-x/utilities/diatheke/diathekemgr.cpp	2017-11-01 11:38:09 UTC (rev 3515)
@@ -47,7 +47,7 @@
 	bidireorder = new UTF8BiDiReorder();
 	transliterator = new UTF8Transliterator();
 #endif
-	Load();
+	load();
 
 #ifdef WIN32
 	OSVERSIONINFO osvi;
@@ -73,7 +73,7 @@
 }
 
 
-void DiathekeMgr::AddRenderFilters(SWModule *module, ConfigEntMap &section)
+void DiathekeMgr::addRenderFilters(SWModule *module, ConfigEntMap &section)
 {
 	SWBuf lang;
 	ConfigEntMap::iterator entry;
@@ -91,11 +91,11 @@
 		module->addRenderFilter(bidireorder);
 	}
 #endif
-	SWMgr::AddRenderFilters(module, section);
+	SWMgr::addRenderFilters(module, section);
 }
 
-signed char DiathekeMgr::Load () {
-	signed char retval =  SWMgr::Load();
+signed char DiathekeMgr::load() {
+	signed char retval =  SWMgr::load();
 #ifdef _ICU_
 	optionFilters["UTF8Transliterator"] = transliterator;
 	options.push_back(transliterator->getOptionName());
@@ -103,11 +103,9 @@
 	return retval;
 };
 
-void DiathekeMgr::AddGlobalOptions (SWModule * module, ConfigEntMap & section,
-                                   ConfigEntMap::iterator start,
-                                   ConfigEntMap::iterator end) {
+void DiathekeMgr::addGlobalOptionFilters(SWModule *module, ConfigEntMap &section) {
 
-        SWMgr::AddGlobalOptions(module, section, start, end);
+        SWMgr::addGlobalOptionFilters(module, section);
 #ifdef _ICU_
         module->addOptionFilter(transliterator);
 #endif

Modified: branches/sword-1-8-x/utilities/diatheke/diathekemgr.h
===================================================================
--- branches/sword-1-8-x/utilities/diatheke/diathekemgr.h	2017-11-01 11:33:56 UTC (rev 3514)
+++ branches/sword-1-8-x/utilities/diatheke/diathekemgr.h	2017-11-01 11:38:09 UTC (rev 3515)
@@ -38,9 +38,9 @@
 #endif
 
 protected:
-	virtual void AddRenderFilters(SWModule *module, ConfigEntMap &section);
-	virtual signed char Load ();
-	virtual void AddGlobalOptions (SWModule * module, ConfigEntMap & section, ConfigEntMap::iterator start, ConfigEntMap::iterator end);
+	virtual void addRenderFilters(SWModule *module, ConfigEntMap &section);
+	virtual signed char load();
+	virtual void addGlobalOptionFilters(SWModule * module, ConfigEntMap & section);
 
 public:
 	bool shape;

Modified: branches/sword-1-8-x/utilities/imp2vs.cpp
===================================================================
--- branches/sword-1-8-x/utilities/imp2vs.cpp	2017-11-01 11:33:56 UTC (rev 3514)
+++ branches/sword-1-8-x/utilities/imp2vs.cpp	2017-11-01 11:38:09 UTC (rev 3515)
@@ -44,6 +44,7 @@
 #include <xzcomprs.h>
 #endif
 #include <localemgr.h>
+#include <cipherfil.h>
 
 #ifndef NO_SWORD_NAMESPACE
 using namespace sword;
@@ -72,6 +73,8 @@
 		fprintf(stderr, "\t\t\t\t\t%s\n", (*loop).c_str());
 	}
 	fprintf(stderr, "  -l <locale>\t\t specify a locale scheme to use (default is en)\n");
+	fprintf(stderr, "  -c <cipher_key>\t encipher module using supplied key\n");
+	fprintf(stderr, "\t\t\t\t (default no enciphering)\n");
 	fprintf(stderr, "\n");
 	fprintf(stderr, "'imp' format is a simple standard for importing data into SWORD modules.\n"
 		"Required is a plain text file containing $$$key lines followed by content.\n\n"
@@ -104,6 +107,7 @@
 	bool fourByteSize      = false;
 	bool append	    = false;
 	int iType	      = 4;
+	SWBuf cipherKey        = "";
 	SWCompress *compressor = 0;
 	SWBuf compType	 = "";
 
@@ -150,6 +154,10 @@
 			if (i+1 < argc) locale = argv[++i];
 			else usage(progName, "-l requires <locale>");
 		}
+		else if (!strcmp(argv[i], "-c")) {
+			if (i+1 < argc) cipherKey = argv[++i];
+			else usage(*argv, "-c requires <cipher_key>");
+		}
 		else usage(progName, (((SWBuf)"Unknown argument: ")+ argv[i]).c_str());
 	}
 	// -----------------------------------------------------
@@ -220,6 +228,14 @@
 			? (SWModule *)new RawText(outPath, 0, 0, 0, ENC_UNKNOWN, DIRECTION_LTR, FMT_UNKNOWN, 0, v11n)
 			: (SWModule *)new RawText4(outPath, 0, 0, 0, ENC_UNKNOWN, DIRECTION_LTR, FMT_UNKNOWN, 0, v11n);
 	}
+
+	SWFilter *cipherFilter = 0;
+
+	if (cipherKey.length()) {
+		fprintf(stderr, "Adding cipher filter with phrase: %s\n", cipherKey.c_str() );
+		cipherFilter = new CipherFilter(cipherKey.c_str());
+		module->addRawFilter(cipherFilter);
+	}
 	// -----------------------------------------------------
 	
 	// setup locale manager
@@ -268,6 +284,8 @@
 	}
 
 	delete module;
+	if (cipherFilter)
+		delete cipherFilter;
 	delete vkey;
 
 	FileMgr::getSystemFileMgr()->close(fd);

Modified: branches/sword-1-8-x/utilities/installmgr.cpp
===================================================================
--- branches/sword-1-8-x/utilities/installmgr.cpp	2017-11-01 11:33:56 UTC (rev 3514)
+++ branches/sword-1-8-x/utilities/installmgr.cpp	2017-11-01 11:38:09 UTC (rev 3515)
@@ -48,6 +48,7 @@
 SWBuf confPath;
 
 bool isConfirmed;
+bool isUnvPeerAllowed;
 
 void usage(const char *progName = 0, const char *error = 0);
 
@@ -90,6 +91,30 @@
 
 };
 
+bool isUnverifiedPeerAllowed() {
+	static bool allowed = false;
+	
+	if (isUnvPeerAllowed) { 
+		allowed = true;
+	}
+        if (!allowed) {
+		cout << "\n\n";
+		cout << "While connecting to an encrypted install source, SWORD can allow\n";
+		cout << "unverified peers, e.g., self-signed certificates. While this is\n";
+		cout << "generally considered safe because SWORD only retrieves Bible content\n";
+		cout << "and does not send any data to the server, it could still possibly\n";
+		cout << "allow a malicious actor to sit between you and the server, as with\n";
+		cout << "unencrypted sources.  Type no to turn this off.\n\n";
+		cout << "Would you like to allow unverified peers? [yes] ";
+
+		char prompt[10];
+		fgets(prompt, 9, stdin);
+		allowed = (strcmp(prompt, "no\n"));
+		cout << "\n";
+	}
+	return allowed;
+}
+
 class MyStatusReporter : public StatusReporter {
 	int last;
         virtual void update(unsigned long totalBytes, unsigned long completedBytes) {
@@ -127,7 +152,7 @@
 		if (!mgr->config)
 			usage(0, "ERROR: SWORD configuration not found.  Please configure SWORD before using this program.");
 
-		SWBuf baseDir = mgr->getHomeDir();
+		SWBuf baseDir = FileMgr::getSystemFileMgr()->getHomeDir();
 		if (baseDir.length() < 1) baseDir = ".";
 		baseDir += "/.sword/InstallMgr";
 		confPath = baseDir + "/InstallMgr.conf";
@@ -153,7 +178,7 @@
 }
 
 
-void createBasicConfig(bool enableRemote, bool addCrossWire) {
+void createBasicConfig(bool enableRemote, bool addCrossWire, bool unverifiedPeerAllowed) {
 
 	FileMgr::createParent(confPath.c_str());
 	remove(confPath.c_str());
@@ -165,10 +190,11 @@
 
 	SWConfig config(confPath.c_str());
 	config["General"]["PassiveFTP"] = "true";
+	config["General"]["UnverifiedPeerAllowed"] = (unverifiedPeerAllowed) ? "true" : "false";
 	if (enableRemote) {
 		config["Sources"]["FTPSource"] = is.getConfEnt();
 	}
-	config.Save();
+	config.save();
 }
 
 
@@ -176,11 +202,13 @@
 	init();
 
 	bool enable = installMgr->isUserDisclaimerConfirmed();
+	bool allowed = isUnverifiedPeerAllowed();
 
-	createBasicConfig(enable, true);
+	createBasicConfig(enable, true, allowed);
 
 	cout << "\n\nInitialized basic config file at [" << confPath << "]\n";
 	cout << "with remote source features " << ((enable) ? "ENABLED" : "DISABLED") << "\n";
+	cout << "with unverified peers " << ((allowed) ? "ALLOWED" : "DISALLOWED") << "\n";
 }
 
 
@@ -194,7 +222,7 @@
 
 	// be sure we have at least some config file already out there
 	if (!FileMgr::existsFile(confPath.c_str())) {
-		createBasicConfig(true, false);
+		createBasicConfig(true, false, false);
 		finish(1); // cleanup and don't exit
 		init();    // re-init with InstallMgr which uses our new config
 	}
@@ -277,6 +305,26 @@
 }
 
 
+void remoteDescribeModule(const char *sourceName, const char *modName) {
+	init();
+	InstallSourceMap::iterator source = installMgr->sources.find(sourceName);
+	if (source == installMgr->sources.end()) {
+		fprintf(stderr, "Couldn't find remote source [%s]\n", sourceName);
+		finish(-3);
+	}
+	SWMgr *mgr = source->second->getMgr();
+	SWModule *m = mgr->getModule(modName);
+	if (!m) {
+		fprintf(stderr, "Couldn't find module [%s] in source [%s]\n", modName, sourceName);
+		finish(-3);
+	}
+	cout << "Module Description\n\n";
+	for (ConfigEntMap::const_iterator it = m->getConfig().begin(); it != m->getConfig().end(); ++it) {
+		cout << "[" << it->first << "]:" << it->second << "\n";
+	}
+}
+
+
 void localDirListModules(const char *dir) {
 	cout << "Available Modules:\n\n";
 	SWMgr mgr(dir);
@@ -335,6 +383,9 @@
 		"  In many places this may well be a risky or even foolish undertaking.\n"
 		"  Please take special care before you use this option in scripts, particularly in scripts you want to offer for public download.\n" 
 		"  What may appear to be safe for you, may well not be safe for someone else, who uses your scripts. \n"
+		"\n\t --allow-unverified-tls-peer \n"
+		"\n  This option will allow the program to connect to unverified peers\n"
+		"  (e.g., hosts using self-signed certificates) without asking for user confirmation.\n"
 		"\n  Commands (run in order they are passed):\n\n"
 		"\t-init\t\t\t\tcreate a basic user config file.\n"
 		"\t\t\t\t\t\tWARNING: overwrites existing.\n"
@@ -344,6 +395,7 @@
 		"\t-r  <remoteSrcName>\t\trefresh remote source\n"
 		"\t-rl <remoteSrcName>\t\tlist available modules from remote source\n"
 		"\t-rd <remoteSrcName>\t\tlist new/updated modules from remote source\n"
+		"\t-rdesc <remoteSrcName> <modName>\tdescribe module from remote source\n"
 		"\t-ri <remoteSrcName> <modName>\tinstall module from remote source\n"
 		"\t-l\t\t\t\tlist installed modules\n"
 		"\t-u <modName>\t\t\tuninstall module\n"
@@ -358,6 +410,7 @@
 int main(int argc, char **argv) {
 	
 	isConfirmed = false;
+	isUnvPeerAllowed = false;
 	
 	if (argc < 2) usage(*argv);
 
@@ -368,6 +421,9 @@
 		else if (!strcmp(argv[i], "--allow-internet-access-and-risk-tracing-and-jail-or-martyrdom")) {
 			isConfirmed = true;
 		}
+		else if (!strcmp(argv[i], "--allow-unverified-tls-peer")) {
+			isUnvPeerAllowed = true;
+		}
 		else if (!strcmp(argv[i], "-init")) {
 			initConfig();
 		}
@@ -409,6 +465,14 @@
 			if (i+1 < argc) remoteListModules(argv[++i], true);
 			else usage(*argv, "-rd requires <remoteSrcName>");
 		}
+		else if (!strcmp(argv[i], "-rdesc")) {	// describe remove module
+			if (i+2 < argc) {
+				const char *source = argv[++i];
+				const char *modName = argv[++i];
+				remoteDescribeModule(source, modName);
+			}
+			else usage(*argv, "-rdesc requires <remoteSrcName> <modName>");
+		}
 		else if (!strcmp(argv[i], "-ri")) {	// install from remote directory
 			if (i+2 < argc) {
 				const char *source = argv[++i];

Modified: branches/sword-1-8-x/utilities/mod2osis.cpp
===================================================================
--- branches/sword-1-8-x/utilities/mod2osis.cpp	2017-11-01 11:33:56 UTC (rev 3514)
+++ branches/sword-1-8-x/utilities/mod2osis.cpp	2017-11-01 11:38:09 UTC (rev 3515)
@@ -72,7 +72,7 @@
 	cerr << "In fact, you should never export SWORD modules.\n";
 	cerr << "Many CrossWire modules are licensed for use from publishers\n";
 	cerr << "and you will need to obtain your own permissions.\n";
-	cerr << "We also do not encourage propogating encoding errors\n";
+	cerr << "We also do not encourage propagating encoding errors\n";
 	cerr << "which you will avoid by obtaining text data from the source.\n\n";
 	cerr << "Please see the TextSource entry in the module's .conf file\n";
 	cerr << "for information where to obtain module data from our source.\n\n";




More information about the sword-cvs mailing list