Improved ICU handling and dev Docker image
diff --git a/build.Dockerfile b/build.Dockerfile
index 78ab5e1..8848a34 100644
--- a/build.Dockerfile
+++ b/build.Dockerfile
@@ -2,7 +2,7 @@
 
 FROM debian:bookworm-slim AS build
 WORKDIR /uima-cpp
-RUN apt-get update && apt-get -y install --no-install-suggests libapr1-dev libxerces-c-dev libicu-dev openjdk-17-jdk-headless build-essential pkgconf autoconf file libtool m4 automake swig4.0 libpython3-dev 
+RUN apt-get update && apt-get -y install --no-install-suggests libapr1-dev libxerces-c-dev libicu-dev openjdk-17-jdk-headless build-essential pkgconf autoconf file libtool m4 automake swig4.0 libpython3-dev libperl-dev libuima-core-java
 COPY . .
 RUN ./autogen.sh
 RUN mkdir /usr/local/uimacpp
@@ -17,12 +17,20 @@
 
 # build pythonator
 RUN echo '/usr/local/uimacpp/lib' >> /etc/ld.so.conf.d/uimacpp.conf && ldconfig
-WORKDIR /uima-cpp/scriptators
+WORKDIR /uima-cpp/scriptators/python
 RUN UIMACPP_HOME=/usr/local/uimacpp make
-RUN cp libpythonator.so /usr/local/uimacpp/lib/
-RUN cp Pythonator.xml /usr/local/uimacpp/desc/
+RUN cp _pythonnator.so /usr/local/uimacpp/lib; cd /usr/local/uimacpp/scripts; ln -s ../lib/_pythonnator.so .
+RUN cd /usr/local/uimacpp/lib; ln -s ../scripts/_pythonnator.so ./libpythonnator.so
+RUN cp Pythonnator.xml /usr/local/uimacpp/desc/
 RUN cp ae.py pythonnator.py /usr/local/uimacpp/scripts/
 
+# perltator
+WORKDIR /uima-cpp/scriptators/perl
+RUN UIMACPP_HOME=/usr/local/uimacpp make
+RUN cp perltator.so /usr/local/uimacpp/lib; cd /usr/local/uimacpp/lib; ln -s perltator.so libperltator.so
+RUN cp Perltator.xml /usr/local/uimacpp/desc/
+RUN cp ae.pl perltator.pm /usr/local/uimacpp/scripts/
+
 # dev
 RUN apt-get install -y --no-install-recommends emacs-nox gdb less
 ENTRYPOINT ["/bin/bash"]
diff --git a/examples/src/ExampleApplication.cpp b/examples/src/ExampleApplication.cpp
index 48e0332..b4cc46e 100644
--- a/examples/src/ExampleApplication.cpp
+++ b/examples/src/ExampleApplication.cpp
@@ -24,7 +24,6 @@
 
 #include <sys/stat.h>
 using namespace std;
-using namespace icu_72;
 using namespace uima;
 /**
  * An example application that reads documents from files, sends them
@@ -209,7 +208,7 @@
     fclose(pFile);
 
     /* convert to unicode and set tcas document text*/
-    UnicodeString ustrInputText(pBuffer, filesize, "utf-8");
+    icu::UnicodeString ustrInputText(pBuffer, filesize, "utf-8");
 
     tcas->setDocumentText(ustrInputText.getBuffer(), ustrInputText.length(), true);
 
diff --git a/examples/src/SofaDataAnnotator.cpp b/examples/src/SofaDataAnnotator.cpp
index ff64924..d4a5b6d 100644
--- a/examples/src/SofaDataAnnotator.cpp
+++ b/examples/src/SofaDataAnnotator.cpp
@@ -19,7 +19,6 @@
 
 #include "uima/api.hpp"
 using namespace std;
-using namespace icu_72;
 using namespace uima;
 
 
@@ -94,10 +93,10 @@
     cout << endl;
 
     /** convert to unicode */
-    UnicodeString ustrInputText(pBuffer, streamSize+1, "utf-8");
+    icu::UnicodeString ustrInputText(pBuffer, streamSize+1, "utf-8");
 
     /** find tokens and annotate */
-    UnicodeString delim(" ");
+    icu::UnicodeString delim(" ");
     UChar *myLocalSaveState;
     UChar * pInputText = (UChar*) ustrInputText.getBuffer();
     const UChar * pToken = pInputText;
diff --git a/examples/src/SofaExampleAnnotator.cpp b/examples/src/SofaExampleAnnotator.cpp
index 755e775..94827da 100644
--- a/examples/src/SofaExampleAnnotator.cpp
+++ b/examples/src/SofaExampleAnnotator.cpp
@@ -19,7 +19,7 @@
 
 #include "uima/api.hpp"
 using namespace std;
-using namespace icu_72;
+using namespace icu;
 using namespace uima;
 
 const UChar * translate(UChar *);
@@ -28,7 +28,7 @@
 private:
   Type cross, annot;
   Feature other;
-  icu::UnicodeString us_SofaString;
+  UnicodeString us_SofaString;
   AnnotatorContext * pAnc;
 
 public:
diff --git a/examples/src/SofaExampleApplication.cpp b/examples/src/SofaExampleApplication.cpp
index abd231e..008130e 100644
--- a/examples/src/SofaExampleApplication.cpp
+++ b/examples/src/SofaExampleApplication.cpp
@@ -35,7 +35,6 @@
 #include "uima/envvars.h"
 #include "unicode/ucnv.h"
 using namespace std;
-using namespace icu_72;
 using namespace uima;
 
 /* ----------------------------------------------------------------------- */
@@ -90,7 +89,7 @@
     CheckError(errorInfo);
 
     // Construct a Unicode input string out of our single-byte string.
-    UnicodeString ustrInputText("This is a text document for analysis");
+    icu::UnicodeString ustrInputText("This is a text document for analysis");
 
     if (!runQuiet)
       cout << "SofaExampleApplication.cpp: document length= " << ustrInputText.length() << endl;
diff --git a/examples/src/XCasWriterCasConsumer.cpp b/examples/src/XCasWriterCasConsumer.cpp
index 5b02564..0c75e28 100644
--- a/examples/src/XCasWriterCasConsumer.cpp
+++ b/examples/src/XCasWriterCasConsumer.cpp
@@ -21,14 +21,13 @@
 #include "uima/dirwalk.hpp"
 #include "uima/xmlwriter.hpp"
 using namespace std;
-using namespace icu_72;
 using namespace uima;
 
 
 class XCasWriterCasConsumer : public Annotator {
 private:
-  UnicodeString usOutDir;
-  std::string   strOutDir;
+  icu::UnicodeString usOutDir;
+  string   strOutDir;
   bool writeFile;
   int docnum;
 
diff --git a/scriptators/python/Makefile b/scriptators/python/Makefile
index 19c9514..c08d808 100644
--- a/scriptators/python/Makefile
+++ b/scriptators/python/Makefile
@@ -77,7 +77,7 @@
 uimapywrap.h:
 	$(SWIG) -outdir . -c++ -python -external-runtime $@
 
-pythonnator.o: $(SWIGDEPS)
+pythonnator.o: $(SWIGDEPS) pythonnator.cpp
 
 $(USER_XTARGET): $(TARGET_FILE).$(DLL_SUFFIX)
 	ln -s $(TARGET_FILE).$(DLL_SUFFIX) $(USER_XTARGET)
diff --git a/src/utils/runAECpp.cpp b/src/utils/runAECpp.cpp
index 8f9eb17..a65c6ca 100644
--- a/src/utils/runAECpp.cpp
+++ b/src/utils/runAECpp.cpp
@@ -356,16 +356,15 @@
   try {
     if (xcasInput != textFormat) {
       /* initialize from an xcas or xmicas */
-      //cout << "runAECpp::processing xml file " << in << endl;
-	  XMLCh* native = XMLString::transcode(in.c_str());
-	  LocalFileInputSource fileIS(native);
-	  XMLString::release(&native);
-	  if (xcasInput == xcasFormat) {
-	    XCASDeserializer::deserialize(fileIS, *cas);
-	  }
-	  else {
-		XmiDeserializer::deserialize(fileIS, *cas, lenient);
-	  }
+      // cout << "runAECpp::processing xml file " << in << endl;
+      XMLCh* native = XMLString::transcode(in.c_str());
+      LocalFileInputSource fileIS(native);
+      XMLString::release(&native);
+      if (xcasInput == xcasFormat) {
+          XCASDeserializer::deserialize(fileIS, *cas);
+      } else {
+          XmiDeserializer::deserialize(fileIS, *cas, lenient);
+      }
     } else {
       /* read as text file and set document text of default view */
       FILE * pFile = fopen(in.c_str(),"rb");